Browse Source

Add antialias config option

Closes #41
dev
Andy Meneely 11 years ago
parent
commit
f49bff2388
  1. 6
      CHANGELOG.md
  2. 1
      README.md
  3. 13
      benchmarks/antialias_best.rb
  4. 1
      benchmarks/antialias_best.yml
  5. 13
      benchmarks/antialias_fast.rb
  6. 1
      benchmarks/antialias_fast.yml
  7. 1
      lib/squib/card.rb
  8. 1
      lib/squib/constants.rb
  9. 4
      lib/squib/deck.rb
  10. 3
      lib/squib/graphics/cairo_context_wrapper.rb
  11. 6
      lib/squib/project_template/config.yml
  12. 3
      spec/data/samples/autoscale_font.rb.txt
  13. 3
      spec/data/samples/basic.rb.txt
  14. 2
      spec/data/samples/cairo_access.rb.txt
  15. 2
      spec/data/samples/csv_import.rb.txt
  16. 1
      spec/data/samples/custom_config.rb.txt
  17. 1
      spec/data/samples/draw_shapes.rb.txt
  18. 3
      spec/data/samples/excel.rb.txt
  19. 1
      spec/data/samples/gradients.rb.txt
  20. 2
      spec/data/samples/hello_world.rb.txt
  21. 1
      spec/data/samples/load_images.rb.txt
  22. 2
      spec/data/samples/portrait-landscape.rb.txt
  23. 3
      spec/data/samples/ranges.rb.txt
  24. 16
      spec/data/samples/saves.rb.txt
  25. 4
      spec/data/samples/showcase.rb.txt
  26. 3
      spec/data/samples/text_options.rb.txt
  27. 1
      spec/data/samples/tgc_proofs.rb.txt
  28. 1
      spec/data/samples/units.rb.txt
  29. 4
      spec/graphics/graphics_images_spec.rb
  30. 3
      spec/graphics/graphics_save_doc_spec.rb
  31. 5
      spec/graphics/graphics_shapes_spec.rb
  32. 3
      spec/graphics/graphics_text_spec.rb
  33. 3
      spec/spec_helper.rb

6
CHANGELOG.md

@ -2,11 +2,13 @@
# v0.4.0
* SVG backend support! You can now set the deck's back end to work with SVGs instead of images, making the resulting PDFs vectorized. (You can still save to PNGs too.) This was a big change for Squib, and it's got a few known issues here and there. See discussion on the README for more details.
* Bugfix: Stray stroke on circles (#35)
* Added config option for antialiasing method. My benchmarks showed that 'best' is only 10% slower than 'fast' on extremely alias-intensive tasks, so that's the Squib default now.
* Bugfix: Stray stroke on circles after text (#35)
* Bugfix: Progress bar increment error (#34)
Known issues
*
* Masking SVGs onto an SVG backend will rasterize as an intermediate step.
* Scale on vectorized PDFs is not perfect.
## v0.3.0
* Masks! The `png` and `svg` commands can be used as if they are a mask, so you can color the icon with any color you like. Can be handy for switching to black-and-white, or for reusing the same image but different colors across cards.

1
README.md

@ -295,6 +295,7 @@ Squib supports various configuration properties that can be specified in an exte
* `dpi` (Integer, default: 300). Used in calculations when units are used (e.g. for PDF rendering and unit conversion).
* `hint` (ColorString, default: off). Text hints are used to show the boundaries of text boxes. Can be enabled/disabled for individual commands, or set globally with the `set` command. This setting is overriden by `set` and individual commands.
* `custom_colors` (Hash of Colors, default: {}). Defines globally-available colors available to the deck that can be specified in commands.
* `antialias` (`fast, good, best, none`, default: best). Set the algorithm that Cairo will use for antialiasing. Using our benchmarks on large decks, `best` is only X% slower anyway. For more info see the [Cairo docs](http://www.cairographics.org/manual/cairo-cairo-t.html#cairo-antialias-t).
The following sample demonstrates the config file.

13
benchmarks/antialias_best.rb

@ -0,0 +1,13 @@
require 'squib'
Squib::Deck.new(cards: 200, config: 'antialias_best.yml') do
background color: :white
# alphabet = 'a'.upto('z').to_a.join + ' ' + 'A'.upto('Z').to_a.join + ' '
# text str: alphabet * 36 , font: 'Sans Bold 18', width: 825, height: 1125, hint: :red
0.upto(500).each do |i|
circle radius: 50,
x: (i % 17) * 50,
y: (i / 17) * 50
end
save_png prefix: 'antialias_best_'
end

1
benchmarks/antialias_best.yml

@ -0,0 +1 @@
antialias: best

13
benchmarks/antialias_fast.rb

@ -0,0 +1,13 @@
require 'squib'
Squib::Deck.new(cards: 200, config: 'antialias_fast.yml') do
background color: :white
# alphabet = 'a'.upto('z').to_a.join + ' ' + 'A'.upto('Z').to_a.join + ' '
# text str: alphabet * 36 , font: 'Sans Bold 18', width: 825, height: 1125, hint: :red
0.upto(500).each do |i|
circle radius: 50,
x: (i % 17) * 50,
y: (i / 17) * 50
end
save_png prefix: 'antialias_fast_'
end

1
benchmarks/antialias_fast.yml

@ -0,0 +1 @@
antialias: fast

1
lib/squib/card.rb

@ -25,6 +25,7 @@ module Squib
@svgfile = "#{deck.dir}/#{deck.prefix}#{deck.count_format % index}.svg"
@cairo_surface = make_surface(@svgfile, backend)
@cairo_context = Squib::Graphics::CairoContextWrapper.new(Cairo::Context.new(@cairo_surface))
@cairo_context.antialias = @deck.antialias
end
def make_surface(svgfile, backend)

1
lib/squib/constants.rb

@ -63,6 +63,7 @@ module Squib
#
# @api public
CONFIG_DEFAULTS = {
'antialias' => 'best',
'backend' => 'memory',
'count_format' => SYSTEM_DEFAULTS[:count_format],
'custom_colors' => {},

4
lib/squib/deck.rb

@ -30,7 +30,7 @@ module Squib
# :nodoc:
# @api private
attr_reader :text_hint
attr_reader :text_hint, :antialias
# :nodoc:
# @api private
@ -58,6 +58,7 @@ module Squib
# @param block [Block] the main body of the script.
# @api public
def initialize(width: 825, height: 1125, cards: 1, dpi: 300, config: 'config.yml', layout: nil, &block)
@antialias = CONFIG_DEFAULTS['antialias']
@dpi = dpi
@font = SYSTEM_DEFAULTS[:default_font]
@cards = []
@ -109,6 +110,7 @@ module Squib
@dir = config['dir']
@prefix = config['prefix']
@count_format = config['count_format']
@antialias = config['antialias']
end
end

3
lib/squib/graphics/cairo_context_wrapper.rb

@ -15,7 +15,8 @@ module Squib
:translate, :rotate, :move_to, :update_pango_layout, :width, :height,
:show_pango_layout, :rounded_rectangle, :set_line_width, :stroke, :fill,
:set_source, :scale, :render_rsvg_handle, :circle, :triangle, :line_to,
:operator=, :show_page, :clip, :transform, :mask, :create_pango_layout
:operator=, :show_page, :clip, :transform, :mask, :create_pango_layout,
:antialias=
def set_source_squibcolor(arg)
if match = arg.match(LINEAR_GRADIENT)

6
lib/squib/project_template/config.yml

@ -4,6 +4,9 @@
# Default: 300
#dpi: 72
#antialias: best #recommended. Only about 10% slower than fast
#antialias: default # set the anti-aliasing algorithm. default defers to the underlying graphics device. See http://www.cairographics.org/manual/cairo-cairo-t.html#cairo-antialias-t
# Text hints are used to show the boundaries of text boxes.
# Can be enabled/disabled at the command-level, or set globally with `set`
#text_hint: '#F00'
@ -21,5 +24,4 @@
# Use a SVG cairo back end, instead of an in-memory buffer
# backend: :memory # default
# backend: :svg # slower, but can create scalable pdfs
# tmp_dir: _tmp # for SVG backend, you MUST specify a tmp_dir
# backend: :svg # can create scalable pdfs, but rendering done at the printer level is not as good as Cairo.

3
spec/data/samples/autoscale_font.rb.txt

@ -1,3 +1,6 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:white])
cairo: paint([])

3
spec/data/samples/basic.rb.txt

@ -1,3 +1,6 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:white])
cairo: paint([])

2
spec/data/samples/cairo_access.rb.txt

@ -1,3 +1,5 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:white])
cairo: paint([])

2
spec/data/samples/csv_import.rb.txt

@ -1,3 +1,5 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:white])
cairo: paint([])

1
spec/data/samples/custom_config.rb.txt

@ -1,3 +1,4 @@
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color(["#ccc"])
cairo: paint([])

1
spec/data/samples/draw_shapes.rb.txt

@ -1,3 +1,4 @@
cairo: antialias=(["best"])
cairo: save([])
cairo: rounded_rectangle([300, 300, 400, 400, 0, 0])
cairo: set_source_color([:red])

3
spec/data/samples/excel.rb.txt

@ -1,3 +1,6 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:white])
cairo: paint([])

1
spec/data/samples/gradients.rb.txt

@ -1,3 +1,4 @@
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source([LinearPattern])
cairo: paint([])

2
spec/data/samples/hello_world.rb.txt

@ -1,3 +1,5 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:black])
cairo: translate([0, 0])

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

@ -1,3 +1,4 @@
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color(["#0b7c8e"])
cairo: paint([])

2
spec/data/samples/portrait-landscape.rb.txt

@ -1,3 +1,4 @@
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color(["#aaa"])
cairo: paint([])
@ -20,6 +21,7 @@ cairo: update_pango_layout([MockDouble])
cairo: show_pango_layout([MockDouble])
cairo: restore([])
surface: write_to_png(["_output/portrait_00.png"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color(["#aaa"])
cairo: paint([])

3
spec/data/samples/ranges.rb.txt

@ -1,3 +1,6 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:white])
cairo: paint([])

16
spec/data/samples/saves.rb.txt

@ -1,3 +1,19 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:gray])
cairo: paint([])

4
spec/data/samples/showcase.rb.txt

@ -1,3 +1,7 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color(["#CE534D"])
cairo: paint([])

3
spec/data/samples/text_options.rb.txt

@ -1,3 +1,6 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:white])
cairo: paint([])

1
spec/data/samples/tgc_proofs.rb.txt

@ -1,3 +1,4 @@
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color([:white])
cairo: paint([])

1
spec/data/samples/units.rb.txt

@ -1,3 +1,4 @@
cairo: antialias=(["best"])
cairo: save([])
cairo: set_source_color(["#ddd"])
cairo: paint([])

4
spec/graphics/graphics_images_spec.rb

@ -15,10 +15,13 @@ describe Squib::Card do
allow(@deck).to receive(:dir).and_return('_output')
allow(@deck).to receive(:count_format).and_return('%02d')
allow(@deck).to receive(:prefix).and_return('card_')
allow(@deck).to receive(:antialias).and_return('best')
end
context '#png' do
it 'makes all the expected calls on a smoke test' do
expect(@context).to receive(:antialias=).with('best')
expect(@context).to receive(:save).once
expect(@context).to receive(:translate).with(-37, -38).once
expect(@context).to receive(:rotate).with(0.0).once
@ -45,6 +48,7 @@ describe Squib::Card do
it 'makes all the expected calls on a smoke test' do
expect(@svg).to receive(:width).and_return(100).twice
expect(@svg).to receive(:height).and_return(100).twice
expect(@context).to receive(:antialias=).with('best').once
expect(@context).to receive(:save).once
expect(@context).to receive(:rotate).with(0.0).once
expect(@context).to receive(:translate).with(37, 38).once

3
spec/graphics/graphics_save_doc_spec.rb

@ -20,13 +20,14 @@ describe Squib::Deck, '#save_pdf' do
before(:each) do
allow(Cairo::PDFSurface).to receive(:new).and_return(nil) #don't create the file
allow(Cairo::Context).to receive(:new).and_return(cxt)
allow(cxt).to receive(:antialias=)
end
it 'make all the expected calls on a smoke test' do
num_cards = 9
deck = Squib::Deck.new(cards: 9, width: 825, height: 1125)
expect(Squib.logger).to receive(:debug).at_least(:once)
expect(deck).to receive(:dirify) { |arg| arg } #don't create the dir
expect(Squib.logger).to receive(:debug).at_least(:once)
expect_card_place(75, 75)
expect_card_place(831, 75)

5
spec/graphics/graphics_shapes_spec.rb

@ -18,10 +18,12 @@ describe Squib::Card do
allow(@deck).to receive(:dir).and_return('_output')
allow(@deck).to receive(:count_format).and_return('%02d')
allow(@deck).to receive(:prefix).and_return('card_')
allow(@deck).to receive(:antialias).and_return('best')
end
context 'rect' do
it 'make all the expected calls on a smoke test' do
expect(@context).to receive(:antialias=).with('best')
expect(@context).to receive(:save).once
expect(@context).to receive(:rounded_rectangle).with(37, 38, 50, 100, 10, 15).twice
expect_stroke('#fff', '#f00', 2.0)
@ -36,6 +38,7 @@ describe Squib::Card do
context 'circle' do
it 'make all the expected calls on a smoke test' do
expect(@context).to receive(:antialias=).with('best')
expect(@context).to receive(:save).once
expect(@context).to receive(:move_to).with(137, 38)
expect(@context).to receive(:circle).with(37, 38, 100).twice
@ -51,6 +54,7 @@ describe Squib::Card do
context 'triangle' do
it 'make all the expected calls on a smoke test' do
expect(@context).to receive(:antialias=).with('best')
expect(@context).to receive(:save).once
expect(@context).to receive(:triangle).with(1, 2, 3, 4, 5, 6).twice
expect_stroke('#fff', '#f00', 2.0)
@ -63,6 +67,7 @@ describe Squib::Card do
context 'line' do
it 'make all the expected calls on a smoke test' do
expect(@context).to receive(:antialias=).with('best')
expect(@context).to receive(:save).once
expect(@context).to receive(:move_to).with(1, 2).once
expect(@context).to receive(:line_to).with(3, 4).once

3
spec/graphics/graphics_text_spec.rb

@ -14,11 +14,13 @@ describe Squib::Card, '#text' do
allow(deck).to receive(:dir).and_return('_output')
allow(deck).to receive(:count_format).and_return('%02d')
allow(deck).to receive(:prefix).and_return('card_')
allow(deck).to receive(:antialias).and_return('best')
end
it 'make all the expected calls on a smoke test' do
extent = Pango::Rectangle.new(50,60,100,200)
expect(Squib.logger).to receive(:debug).once
expect(context).to receive(:antialias=).with('best').once
expect(context).to receive(:save).once
expect(context).to receive(:set_source_color).once
expect(context).to receive(:move_to).with(10, 15).once
@ -67,6 +69,7 @@ describe Squib::Card, '#text' do
allow(deck).to receive(:dir).and_return('_output')
allow(deck).to receive(:count_format).and_return('%02d')
allow(deck).to receive(:prefix).and_return('card_')
allow(deck).to receive(:antialias).and_return('best')
end
it 'aligns right with strings' do

3
spec/spec_helper.rb

@ -76,7 +76,8 @@ def mock_cairo(strio)
%w(save set_source_color paint restore translate rotate move_to
update_pango_layout width height show_pango_layout rounded_rectangle
set_line_width stroke fill set_source scale render_rsvg_handle circle
triangle line_to operator= show_page clip transform mask rectangle reset_clip).each do |m|
triangle line_to operator= show_page clip transform mask rectangle
reset_clip antialias=).each do |m|
allow(cxt).to receive(m) { |*args| strio << scrub_hex("cairo: #{m}(#{args})\n") }
end

Loading…
Cancel
Save