Browse Source

Support png scaling, but warns on use.

dev
Andy Meneely 11 years ago
parent
commit
f8f65f3de7
  1. 2
      CHANGELOG.md
  2. 8
      lib/squib/api/image.rb
  3. 8
      lib/squib/graphics/image.rb
  4. 6
      samples/load_images.rb
  5. 2
      spec/api/api_image_spec.rb
  6. 8
      spec/data/samples/load_images.rb.txt
  7. 26
      spec/graphics/graphics_images_spec.rb
  8. 1
      spec/samples/samples_regression_spec.rb
  9. 1
      spec/spec_helper.rb

2
CHANGELOG.md

@ -1,5 +1,7 @@
# Squib CHANGELOG
* `png` now supports resizing, but warns you about it since it's non-ideal. Documented in yard, tested.
## v0.0.6
* 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.

8
lib/squib/api/image.rb

@ -4,7 +4,6 @@ module Squib
# 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.
# Note: scaling not currently supported for PNGs.
# @example
# 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 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 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 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}
@ -19,11 +20,12 @@ module Squib
# @return [nil] Returns nil
# @api public
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
@progress_bar.start('Loading PNG(s)', opts[:range].size) do |bar|
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])
bar.increment
end

8
lib/squib/graphics/image.rb

@ -14,12 +14,18 @@ module Squib
# :nodoc:
# @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}"}
return if file.nil? or file.eql? ''
png = Squib.cache_load_image(file)
use_cairo do |cc|
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.translate(-1 * x, -1 * y)
cc.set_source(png, x, y)

6
samples/load_images.rb

@ -4,11 +4,13 @@ Squib::Deck.new(width: 825, height: 1125, cards: 1) do
background color: '#0b7c8e'
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
# 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
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
# Squib prepends a #-sign if one is not specified

2
spec/api/api_image_spec.rb

@ -7,7 +7,7 @@ describe Squib::Deck, 'images' do
it 'calls Card#png, Dir, and progress bar' do
card = instance_double(Squib::Card)
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(progress).to receive(:start).and_yield(progress).once
expect(progress).to receive(:increment).once

8
spec/data/samples/load_images.rb.txt

@ -36,6 +36,14 @@ cairo: translate([-50, -50])
cairo: set_source([MockDouble, 50, 50])
cairo: paint([1.0])
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: render_rsvg_handle([RSVG::Handle, "#backdrop"])
cairo: save([])

26
spec/graphics/graphics_images_spec.rb

@ -3,14 +3,15 @@ require 'squib'
describe Squib::Card do
before(:each) do
@deck = double(Squib::Deck)
@context = double(Cairo::Context)
@svg = double(RSVG::Handle)
allow(Cairo::Context).to receive(:new).and_return(@context)
allow(Cairo::ImageSurface).to receive(:from_png).and_return(nil)
allow(Cairo::ImageSurface).to receive(:new).and_return(nil)
allow(RSVG::Handle).to receive(:new_from_file).and_return(@svg)
before(:example) do
@deck = double(Squib::Deck)
@context = double(Cairo::Context)
@svg = double(RSVG::Handle)
@png = double(Cairo::ImageSurface)
allow(Cairo::Context).to receive(:new).and_return(@context)
allow(Cairo::ImageSurface).to receive(:from_png).and_return(@png)
allow(Cairo::ImageSurface).to receive(:new).and_return(@png)
allow(RSVG::Handle).to receive(:new_from_file).and_return(@svg)
end
context '#png' do
@ -19,13 +20,13 @@ describe Squib::Card do
expect(@context).to receive(:translate).with(-37, -38).once
expect(@context).to receive(:rotate).with(0.0).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(:restore).once
card = Squib::Card.new(@deck, 100, 150)
# 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
it 'sets blend when needed' do
@ -33,8 +34,9 @@ describe Squib::Card do
expect(@context).to receive(:operator=).with(:overlay).once
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
context '#svg' do
@ -47,7 +49,7 @@ describe Squib::Card do
expect(@context).to receive(:translate).with(37, 38).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(: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(:restore).once

1
spec/samples/samples_regression_spec.rb

@ -12,6 +12,7 @@ describe "Squib samples" do
end
it 'should execute with no errors' do
allow(Squib.logger).to receive(:warn) {}
allow(ProgressBar).to receive(:create).and_return(Squib::DoNothing.new)
Dir["#{samples_dir}/**/*.rb"].each do |sample|
load sample

1
spec/spec_helper.rb

@ -54,6 +54,7 @@ def mock_cairo(strio)
cxt = double(Cairo::Context)
surface = double(Cairo::ImageSurface)
pango = double(Pango::Layout)
allow(Squib.logger).to receive(:warn) {}
allow(ProgressBar).to receive(:create).and_return(Squib::DoNothing.new)
allow(Cairo::ImageSurface).to receive(:new).and_return(surface)
allow(surface).to receive(:width).and_return(100)

Loading…
Cancel
Save