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 # 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. * 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) * Bugfix: Progress bar increment error (#34)
Known issues Known issues
* * Masking SVGs onto an SVG backend will rasterize as an intermediate step.
* Scale on vectorized PDFs is not perfect.
## v0.3.0 ## 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. * 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). * `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. * `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. * `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. 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" @svgfile = "#{deck.dir}/#{deck.prefix}#{deck.count_format % index}.svg"
@cairo_surface = make_surface(@svgfile, backend) @cairo_surface = make_surface(@svgfile, backend)
@cairo_context = Squib::Graphics::CairoContextWrapper.new(Cairo::Context.new(@cairo_surface)) @cairo_context = Squib::Graphics::CairoContextWrapper.new(Cairo::Context.new(@cairo_surface))
@cairo_context.antialias = @deck.antialias
end end
def make_surface(svgfile, backend) def make_surface(svgfile, backend)

1
lib/squib/constants.rb

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

4
lib/squib/deck.rb

@ -30,7 +30,7 @@ module Squib
# :nodoc: # :nodoc:
# @api private # @api private
attr_reader :text_hint attr_reader :text_hint, :antialias
# :nodoc: # :nodoc:
# @api private # @api private
@ -58,6 +58,7 @@ module Squib
# @param block [Block] the main body of the script. # @param block [Block] the main body of the script.
# @api public # @api public
def initialize(width: 825, height: 1125, cards: 1, dpi: 300, config: 'config.yml', layout: nil, &block) def initialize(width: 825, height: 1125, cards: 1, dpi: 300, config: 'config.yml', layout: nil, &block)
@antialias = CONFIG_DEFAULTS['antialias']
@dpi = dpi @dpi = dpi
@font = SYSTEM_DEFAULTS[:default_font] @font = SYSTEM_DEFAULTS[:default_font]
@cards = [] @cards = []
@ -109,6 +110,7 @@ module Squib
@dir = config['dir'] @dir = config['dir']
@prefix = config['prefix'] @prefix = config['prefix']
@count_format = config['count_format'] @count_format = config['count_format']
@antialias = config['antialias']
end end
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, :translate, :rotate, :move_to, :update_pango_layout, :width, :height,
:show_pango_layout, :rounded_rectangle, :set_line_width, :stroke, :fill, :show_pango_layout, :rounded_rectangle, :set_line_width, :stroke, :fill,
:set_source, :scale, :render_rsvg_handle, :circle, :triangle, :line_to, :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) def set_source_squibcolor(arg)
if match = arg.match(LINEAR_GRADIENT) if match = arg.match(LINEAR_GRADIENT)

6
lib/squib/project_template/config.yml

@ -4,6 +4,9 @@
# Default: 300 # Default: 300
#dpi: 72 #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. # Text hints are used to show the boundaries of text boxes.
# Can be enabled/disabled at the command-level, or set globally with `set` # Can be enabled/disabled at the command-level, or set globally with `set`
#text_hint: '#F00' #text_hint: '#F00'
@ -21,5 +24,4 @@
# Use a SVG cairo back end, instead of an in-memory buffer # Use a SVG cairo back end, instead of an in-memory buffer
# backend: :memory # default # backend: :memory # default
# backend: :svg # slower, but can create scalable pdfs # backend: :svg # can create scalable pdfs, but rendering done at the printer level is not as good as Cairo.
# tmp_dir: _tmp # for SVG backend, you MUST specify a tmp_dir

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

@ -1,3 +1,6 @@
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: antialias=(["best"])
cairo: save([]) cairo: save([])
cairo: set_source_color([:white]) cairo: set_source_color([:white])
cairo: paint([]) 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: save([])
cairo: set_source_color([:white]) cairo: set_source_color([:white])
cairo: paint([]) cairo: paint([])

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

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

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

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

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

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

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

@ -1,3 +1,4 @@
cairo: antialias=(["best"])
cairo: save([]) cairo: save([])
cairo: rounded_rectangle([300, 300, 400, 400, 0, 0]) cairo: rounded_rectangle([300, 300, 400, 400, 0, 0])
cairo: set_source_color([:red]) 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: save([])
cairo: set_source_color([:white]) cairo: set_source_color([:white])
cairo: paint([]) cairo: paint([])

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

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

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

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

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

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

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

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

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

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

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

@ -1,3 +1,4 @@
cairo: antialias=(["best"])
cairo: save([]) cairo: save([])
cairo: set_source_color(["#ddd"]) cairo: set_source_color(["#ddd"])
cairo: paint([]) 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(:dir).and_return('_output')
allow(@deck).to receive(:count_format).and_return('%02d') allow(@deck).to receive(:count_format).and_return('%02d')
allow(@deck).to receive(:prefix).and_return('card_') allow(@deck).to receive(:prefix).and_return('card_')
allow(@deck).to receive(:antialias).and_return('best')
end end
context '#png' do context '#png' do
it 'makes all the expected calls on a smoke test' 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(:save).once
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
@ -45,6 +48,7 @@ describe Squib::Card do
it 'makes all the expected calls on a smoke test' 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(:width).and_return(100).twice
expect(@svg).to receive(:height).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(:save).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

3
spec/graphics/graphics_save_doc_spec.rb

@ -20,13 +20,14 @@ describe Squib::Deck, '#save_pdf' do
before(:each) do before(:each) do
allow(Cairo::PDFSurface).to receive(:new).and_return(nil) #don't create the file allow(Cairo::PDFSurface).to receive(:new).and_return(nil) #don't create the file
allow(Cairo::Context).to receive(:new).and_return(cxt) allow(Cairo::Context).to receive(:new).and_return(cxt)
allow(cxt).to receive(:antialias=)
end end
it 'make all the expected calls on a smoke test' do it 'make all the expected calls on a smoke test' do
num_cards = 9 num_cards = 9
deck = Squib::Deck.new(cards: 9, width: 825, height: 1125) 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(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(75, 75)
expect_card_place(831, 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(:dir).and_return('_output')
allow(@deck).to receive(:count_format).and_return('%02d') allow(@deck).to receive(:count_format).and_return('%02d')
allow(@deck).to receive(:prefix).and_return('card_') allow(@deck).to receive(:prefix).and_return('card_')
allow(@deck).to receive(:antialias).and_return('best')
end end
context 'rect' do context 'rect' do
it 'make all the expected calls on a smoke test' 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(:save).once
expect(@context).to receive(:rounded_rectangle).with(37, 38, 50, 100, 10, 15).twice expect(@context).to receive(:rounded_rectangle).with(37, 38, 50, 100, 10, 15).twice
expect_stroke('#fff', '#f00', 2.0) expect_stroke('#fff', '#f00', 2.0)
@ -36,6 +38,7 @@ describe Squib::Card do
context 'circle' do context 'circle' do
it 'make all the expected calls on a smoke test' 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(:save).once
expect(@context).to receive(:move_to).with(137, 38) expect(@context).to receive(:move_to).with(137, 38)
expect(@context).to receive(:circle).with(37, 38, 100).twice expect(@context).to receive(:circle).with(37, 38, 100).twice
@ -51,6 +54,7 @@ describe Squib::Card do
context 'triangle' do context 'triangle' do
it 'make all the expected calls on a smoke test' 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(:save).once
expect(@context).to receive(:triangle).with(1, 2, 3, 4, 5, 6).twice expect(@context).to receive(:triangle).with(1, 2, 3, 4, 5, 6).twice
expect_stroke('#fff', '#f00', 2.0) expect_stroke('#fff', '#f00', 2.0)
@ -63,6 +67,7 @@ describe Squib::Card do
context 'line' do context 'line' do
it 'make all the expected calls on a smoke test' 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(:save).once
expect(@context).to receive(:move_to).with(1, 2).once expect(@context).to receive(:move_to).with(1, 2).once
expect(@context).to receive(:line_to).with(3, 4).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(:dir).and_return('_output')
allow(deck).to receive(:count_format).and_return('%02d') allow(deck).to receive(:count_format).and_return('%02d')
allow(deck).to receive(:prefix).and_return('card_') allow(deck).to receive(:prefix).and_return('card_')
allow(deck).to receive(:antialias).and_return('best')
end end
it 'make all the expected calls on a smoke test' do it 'make all the expected calls on a smoke test' do
extent = Pango::Rectangle.new(50,60,100,200) extent = Pango::Rectangle.new(50,60,100,200)
expect(Squib.logger).to receive(:debug).once 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(:save).once
expect(context).to receive(:set_source_color).once expect(context).to receive(:set_source_color).once
expect(context).to receive(:move_to).with(10, 15).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(:dir).and_return('_output')
allow(deck).to receive(:count_format).and_return('%02d') allow(deck).to receive(:count_format).and_return('%02d')
allow(deck).to receive(:prefix).and_return('card_') allow(deck).to receive(:prefix).and_return('card_')
allow(deck).to receive(:antialias).and_return('best')
end end
it 'aligns right with strings' do 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 %w(save set_source_color paint restore translate rotate move_to
update_pango_layout width height show_pango_layout rounded_rectangle update_pango_layout width height show_pango_layout rounded_rectangle
set_line_width stroke fill set_source scale render_rsvg_handle circle 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") } allow(cxt).to receive(m) { |*args| strio << scrub_hex("cairo: #{m}(#{args})\n") }
end end

Loading…
Cancel
Save