parent
b5016f90c0
commit
f49bff2388
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
antialias: best
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
antialias: fast
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ module Squib
|
|||
#
|
||||
# @api public
|
||||
CONFIG_DEFAULTS = {
|
||||
'antialias' => 'best',
|
||||
'backend' => 'memory',
|
||||
'count_format' => SYSTEM_DEFAULTS[:count_format],
|
||||
'custom_colors' => {},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color([:white])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color([:white])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color([:white])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color([:white])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color(["#ccc"])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: rounded_rectangle([300, 300, 400, 400, 0, 0])
|
||||
cairo: set_source_color([:red])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color([:white])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source([LinearPattern])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color([:black])
|
||||
cairo: translate([0, 0])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color(["#0b7c8e"])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -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([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color([:white])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -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([])
|
||||
|
|
|
|||
|
|
@ -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([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color([:white])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color([:white])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
cairo: antialias=(["best"])
|
||||
cairo: save([])
|
||||
cairo: set_source_color(["#ddd"])
|
||||
cairo: paint([])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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…
Reference in New Issue