Support png scaling, but warns on use.
parent
52b1037296
commit
f8f65f3de7
|
|
@ -1,5 +1,7 @@
|
||||||
# Squib CHANGELOG
|
# Squib CHANGELOG
|
||||||
|
|
||||||
|
* `png` now supports resizing, but warns you about it since it's non-ideal. Documented in yard, tested.
|
||||||
|
|
||||||
## v0.0.6
|
## v0.0.6
|
||||||
* Added a `csv` command that works just like `xslx`. Uses Ruby's CSV inside, with some extra checking and warnings.
|
* Added a `csv` command that works just like `xslx`. Uses Ruby's CSV inside, with some extra checking and warnings.
|
||||||
* Custom layouts now support loading & merging multiple Yaml files! Updated README, docs, and sample to document it.
|
* Custom layouts now support loading & merging multiple Yaml files! Updated README, docs, and sample to document it.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ module Squib
|
||||||
# Renders a png file at the given location.
|
# Renders a png file at the given location.
|
||||||
#
|
#
|
||||||
# See {file:samples/image.rb samples/image.rb} and {file:samples/tgc-overlay.rb samples/tgc-overlay.rb} as examples.
|
# See {file:samples/image.rb samples/image.rb} and {file:samples/tgc-overlay.rb samples/tgc-overlay.rb} as examples.
|
||||||
# Note: scaling not currently supported for PNGs.
|
|
||||||
# @example
|
# @example
|
||||||
# png file: 'img.png', x: 50, y: 50
|
# png file: 'img.png', x: 50, y: 50
|
||||||
#
|
#
|
||||||
|
|
@ -12,6 +11,8 @@ module Squib
|
||||||
# @option opts file [String] ((empty)) file(s) to read in. If it's a single file, then it's use for every card in range. If the parameter is an Array of files, then each file is looked up for each card. If any of them are nil or '', nothing is done. See {file:README.md#Specifying_Files Specifying Files}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
# @option opts file [String] ((empty)) file(s) to read in. If it's a single file, then it's use for every card in range. If the parameter is an Array of files, then each file is looked up for each card. If any of them are nil or '', nothing is done. See {file:README.md#Specifying_Files Specifying Files}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
||||||
# @option opts x [Integer] (0) the x-coordinate to place. Supports Arrays, see {file:README#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
# @option opts x [Integer] (0) the x-coordinate to place. Supports Arrays, see {file:README#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
||||||
# @option opts y [Integer] (0) the y-coordinate to place. Supports Arrays, see {file:README#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
# @option opts y [Integer] (0) the y-coordinate to place. Supports Arrays, see {file:README#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
||||||
|
# @option opts width [Integer] (:native) the pixel width that the image should scale to. Scaling PNGs is not recommended for professional-looking cards. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
||||||
|
# @option opts height [Integer] (:native) the pixel width that the image should scale to. Scaling PNGs is not recommended for professional-looking cards. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
||||||
# @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
# @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
||||||
# @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
# @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
||||||
# @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
# @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
|
||||||
|
|
@ -19,11 +20,12 @@ module Squib
|
||||||
# @return [nil] Returns nil
|
# @return [nil] Returns nil
|
||||||
# @api public
|
# @api public
|
||||||
def png(opts = {})
|
def png(opts = {})
|
||||||
opts = needs(opts, [:range, :files, :x, :y, :alpha, :layout, :blend, :angle])
|
opts = needs(opts, [:range, :files, :x, :y, :width, :height, :alpha, :layout, :blend, :angle])
|
||||||
Dir.chdir(@img_dir) do
|
Dir.chdir(@img_dir) do
|
||||||
@progress_bar.start('Loading PNG(s)', opts[:range].size) do |bar|
|
@progress_bar.start('Loading PNG(s)', opts[:range].size) do |bar|
|
||||||
opts[:range].each do |i|
|
opts[:range].each do |i|
|
||||||
@cards[i].png(opts[:file][i], opts[:x][i], opts[:y][i],
|
@cards[i].png(opts[:file][i],
|
||||||
|
opts[:x][i], opts[:y][i], opts[:width][i], opts[:height][i],
|
||||||
opts[:alpha][i], opts[:blend][i], opts[:angle][i])
|
opts[:alpha][i], opts[:blend][i], opts[:angle][i])
|
||||||
bar.increment
|
bar.increment
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,18 @@ module Squib
|
||||||
|
|
||||||
# :nodoc:
|
# :nodoc:
|
||||||
# @api private
|
# @api private
|
||||||
def png(file, x, y, alpha, blend, angle)
|
def png(file, x, y, width, height, alpha, blend, angle)
|
||||||
Squib.logger.debug {"Rendering: #{file} @#{x},#{y} #{width}x#{height}, alpha: #{alpha}, blend: #{blend}, angle: #{angle}"}
|
Squib.logger.debug {"Rendering: #{file} @#{x},#{y} #{width}x#{height}, alpha: #{alpha}, blend: #{blend}, angle: #{angle}"}
|
||||||
return if file.nil? or file.eql? ''
|
return if file.nil? or file.eql? ''
|
||||||
png = Squib.cache_load_image(file)
|
png = Squib.cache_load_image(file)
|
||||||
use_cairo do |cc|
|
use_cairo do |cc|
|
||||||
cc.translate(x, y)
|
cc.translate(x, y)
|
||||||
|
if width != :native || height != :native
|
||||||
|
width == :native && width = png.width.to_f
|
||||||
|
height == :native && height = png.height.to_f
|
||||||
|
Squib.logger.warn "PNG scaling results in antialiasing."
|
||||||
|
cc.scale(width.to_f / png.width.to_f, height.to_f / png.height.to_f)
|
||||||
|
end
|
||||||
cc.rotate(angle)
|
cc.rotate(angle)
|
||||||
cc.translate(-1 * x, -1 * y)
|
cc.translate(-1 * x, -1 * y)
|
||||||
cc.set_source(png, x, y)
|
cc.set_source(png, x, y)
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,13 @@ Squib::Deck.new(width: 825, height: 1125, cards: 1) do
|
||||||
background color: '#0b7c8e'
|
background color: '#0b7c8e'
|
||||||
rect x: 38, y: 38, width: 750, height: 1050, x_radius: 38, y_radius: 38
|
rect x: 38, y: 38, width: 750, height: 1050, x_radius: 38, y_radius: 38
|
||||||
|
|
||||||
png file: 'shiny-purse.png', x: 620, y: 75
|
png file: 'shiny-purse.png', x: 620, y: 75 # no scaling is done by default
|
||||||
svg file: 'spanner.svg', x: 620, y: 218
|
svg file: 'spanner.svg', x: 620, y: 218
|
||||||
|
|
||||||
# SVGs can be scaled too
|
# Can be scaled if width and height are set
|
||||||
svg file: 'spanner.svg', x: 50, y: 50, width: 250, height: 250
|
svg file: 'spanner.svg', x: 50, y: 50, width: 250, height: 250
|
||||||
|
png file: 'shiny-purse.png', x: 305, y: 50, width: 250, height: 250
|
||||||
|
#...but PNGs will warn if it's an upscale
|
||||||
|
|
||||||
# We can also limit our rendering to a single object, if the SVG ID is set
|
# We can also limit our rendering to a single object, if the SVG ID is set
|
||||||
# Squib prepends a #-sign if one is not specified
|
# Squib prepends a #-sign if one is not specified
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ describe Squib::Deck, 'images' do
|
||||||
it 'calls Card#png, Dir, and progress bar' do
|
it 'calls Card#png, Dir, and progress bar' do
|
||||||
card = instance_double(Squib::Card)
|
card = instance_double(Squib::Card)
|
||||||
progress = double(Squib::Progress)
|
progress = double(Squib::Progress)
|
||||||
expect(card).to receive(:png).with('foo', 0, 1, 0.5, :overlay, 0.75).once
|
expect(card).to receive(:png).with('foo', 0, 1, :native, :native, 0.5, :overlay, 0.75).once
|
||||||
expect(Dir).to receive(:chdir).with('.').and_yield.once
|
expect(Dir).to receive(:chdir).with('.').and_yield.once
|
||||||
expect(progress).to receive(:start).and_yield(progress).once
|
expect(progress).to receive(:start).and_yield(progress).once
|
||||||
expect(progress).to receive(:increment).once
|
expect(progress).to receive(:increment).once
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,14 @@ cairo: translate([-50, -50])
|
||||||
cairo: set_source([MockDouble, 50, 50])
|
cairo: set_source([MockDouble, 50, 50])
|
||||||
cairo: paint([1.0])
|
cairo: paint([1.0])
|
||||||
cairo: restore([])
|
cairo: restore([])
|
||||||
|
cairo: save([])
|
||||||
|
cairo: translate([305, 50])
|
||||||
|
cairo: scale([1.953125, 1.953125])
|
||||||
|
cairo: rotate([0])
|
||||||
|
cairo: translate([-305, -50])
|
||||||
|
cairo: set_source([ImageSurface, 305, 50])
|
||||||
|
cairo: paint([1.0])
|
||||||
|
cairo: restore([])
|
||||||
cairo: scale([0.5859375, 0.5859375])
|
cairo: scale([0.5859375, 0.5859375])
|
||||||
cairo: render_rsvg_handle([RSVG::Handle, "#backdrop"])
|
cairo: render_rsvg_handle([RSVG::Handle, "#backdrop"])
|
||||||
cairo: save([])
|
cairo: save([])
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@ require 'squib'
|
||||||
|
|
||||||
describe Squib::Card do
|
describe Squib::Card do
|
||||||
|
|
||||||
before(:each) do
|
before(:example) do
|
||||||
@deck = double(Squib::Deck)
|
@deck = double(Squib::Deck)
|
||||||
@context = double(Cairo::Context)
|
@context = double(Cairo::Context)
|
||||||
@svg = double(RSVG::Handle)
|
@svg = double(RSVG::Handle)
|
||||||
|
@png = double(Cairo::ImageSurface)
|
||||||
allow(Cairo::Context).to receive(:new).and_return(@context)
|
allow(Cairo::Context).to receive(:new).and_return(@context)
|
||||||
allow(Cairo::ImageSurface).to receive(:from_png).and_return(nil)
|
allow(Cairo::ImageSurface).to receive(:from_png).and_return(@png)
|
||||||
allow(Cairo::ImageSurface).to receive(:new).and_return(nil)
|
allow(Cairo::ImageSurface).to receive(:new).and_return(@png)
|
||||||
allow(RSVG::Handle).to receive(:new_from_file).and_return(@svg)
|
allow(RSVG::Handle).to receive(:new_from_file).and_return(@svg)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -19,13 +20,13 @@ describe Squib::Card do
|
||||||
expect(@context).to receive(:translate).with(-37, -38).once
|
expect(@context).to receive(:translate).with(-37, -38).once
|
||||||
expect(@context).to receive(:rotate).with(0.0).once
|
expect(@context).to receive(:rotate).with(0.0).once
|
||||||
expect(@context).to receive(:translate).with(37, 38).once
|
expect(@context).to receive(:translate).with(37, 38).once
|
||||||
expect(@context).to receive(:set_source).with(nil, 37, 38).once
|
expect(@context).to receive(:set_source).with(@png, 37, 38).once
|
||||||
expect(@context).to receive(:paint).with(0.9).once
|
expect(@context).to receive(:paint).with(0.9).once
|
||||||
expect(@context).to receive(:restore).once
|
expect(@context).to receive(:restore).once
|
||||||
|
|
||||||
card = Squib::Card.new(@deck, 100, 150)
|
card = Squib::Card.new(@deck, 100, 150)
|
||||||
# png(file, x, y, alpha, blend, angle)
|
# png(file, x, y, alpha, blend, angle)
|
||||||
card.png('foo.png', 37, 38, 0.9, :none, 0.0)
|
card.png('foo.png', 37, 38, :native, :native, 0.9, :none, 0.0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets blend when needed' do
|
it 'sets blend when needed' do
|
||||||
|
|
@ -33,8 +34,9 @@ describe Squib::Card do
|
||||||
expect(@context).to receive(:operator=).with(:overlay).once
|
expect(@context).to receive(:operator=).with(:overlay).once
|
||||||
|
|
||||||
card = Squib::Card.new(@deck, 100, 150)
|
card = Squib::Card.new(@deck, 100, 150)
|
||||||
card.png('foo.png', 37, 38, 0.9, :overlay, 0.0)
|
card.png('foo.png', 37, 38, :native, :native, 0.9, :overlay, 0.0)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context '#svg' do
|
context '#svg' do
|
||||||
|
|
@ -47,7 +49,7 @@ describe Squib::Card do
|
||||||
expect(@context).to receive(:translate).with(37, 38).once
|
expect(@context).to receive(:translate).with(37, 38).once
|
||||||
expect(@context).to receive(:scale).with(1.0, 1.0).once
|
expect(@context).to receive(:scale).with(1.0, 1.0).once
|
||||||
expect(@context).to receive(:render_rsvg_handle).with(@svg, 'id').once
|
expect(@context).to receive(:render_rsvg_handle).with(@svg, 'id').once
|
||||||
expect(@context).to receive(:set_source).with(nil, 37, 38).once
|
expect(@context).to receive(:set_source).with(@png, 37, 38).once
|
||||||
expect(@context).to receive(:paint).with(0.9).once
|
expect(@context).to receive(:paint).with(0.9).once
|
||||||
expect(@context).to receive(:restore).once
|
expect(@context).to receive(:restore).once
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ describe "Squib samples" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should execute with no errors' do
|
it 'should execute with no errors' do
|
||||||
|
allow(Squib.logger).to receive(:warn) {}
|
||||||
allow(ProgressBar).to receive(:create).and_return(Squib::DoNothing.new)
|
allow(ProgressBar).to receive(:create).and_return(Squib::DoNothing.new)
|
||||||
Dir["#{samples_dir}/**/*.rb"].each do |sample|
|
Dir["#{samples_dir}/**/*.rb"].each do |sample|
|
||||||
load sample
|
load sample
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ def mock_cairo(strio)
|
||||||
cxt = double(Cairo::Context)
|
cxt = double(Cairo::Context)
|
||||||
surface = double(Cairo::ImageSurface)
|
surface = double(Cairo::ImageSurface)
|
||||||
pango = double(Pango::Layout)
|
pango = double(Pango::Layout)
|
||||||
|
allow(Squib.logger).to receive(:warn) {}
|
||||||
allow(ProgressBar).to receive(:create).and_return(Squib::DoNothing.new)
|
allow(ProgressBar).to receive(:create).and_return(Squib::DoNothing.new)
|
||||||
allow(Cairo::ImageSurface).to receive(:new).and_return(surface)
|
allow(Cairo::ImageSurface).to receive(:new).and_return(surface)
|
||||||
allow(surface).to receive(:width).and_return(100)
|
allow(surface).to receive(:width).and_return(100)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue