squib 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +162 -133
- data/Gemfile +4 -4
- data/README.md +630 -550
- data/RELEASE TODO.md +18 -18
- data/Rakefile +99 -99
- data/lib/squib.rb +32 -32
- data/lib/squib/api/background.rb +20 -19
- data/lib/squib/api/data.rb +100 -99
- data/lib/squib/api/image.rb +90 -76
- data/lib/squib/api/save.rb +149 -103
- data/lib/squib/api/settings.rb +35 -37
- data/lib/squib/api/shapes.rb +230 -228
- data/lib/squib/api/text.rb +65 -66
- data/lib/squib/api/text_embed.rb +96 -66
- data/lib/squib/args/arg_loader.rb +138 -0
- data/lib/squib/args/box.rb +55 -0
- data/lib/squib/args/card_range.rb +32 -0
- data/lib/squib/args/color_validator.rb +12 -0
- data/lib/squib/args/coords.rb +33 -0
- data/lib/squib/args/dir_validator.rb +16 -0
- data/lib/squib/args/draw.rb +92 -0
- data/lib/squib/args/embed_adjust.rb +25 -0
- data/lib/squib/args/embed_key.rb +17 -0
- data/lib/squib/args/hand_special.rb +37 -0
- data/lib/squib/args/input_file.rb +37 -0
- data/lib/squib/args/paint.rb +44 -0
- data/lib/squib/args/paragraph.rb +115 -0
- data/lib/squib/args/save_batch.rb +60 -0
- data/lib/squib/args/scale_box.rb +53 -0
- data/lib/squib/args/sheet.rb +72 -0
- data/lib/squib/args/showcase_special.rb +38 -0
- data/lib/squib/args/svg_special.rb +37 -0
- data/lib/squib/args/transform.rb +25 -0
- data/lib/squib/args/typographer.rb +117 -117
- data/lib/squib/card.rb +67 -67
- data/lib/squib/conf.rb +117 -111
- data/lib/squib/constants.rb +178 -178
- data/lib/squib/deck.rb +113 -111
- data/lib/squib/graphics/cairo_context_wrapper.rb +99 -53
- data/lib/squib/graphics/gradient_regex.rb +46 -46
- data/lib/squib/graphics/hand.rb +42 -43
- data/lib/squib/graphics/image.rb +76 -73
- data/lib/squib/graphics/save_doc.rb +103 -137
- data/lib/squib/graphics/save_images.rb +33 -33
- data/lib/squib/graphics/shapes.rb +119 -152
- data/lib/squib/graphics/showcase.rb +85 -88
- data/lib/squib/graphics/text.rb +176 -216
- data/lib/squib/layout_parser.rb +91 -89
- data/lib/squib/layouts/economy.yml +85 -0
- data/lib/squib/layouts/fantasy.yml +101 -0
- data/lib/squib/layouts/hand.yml +62 -46
- data/lib/squib/layouts/playing-card.yml +35 -18
- data/lib/squib/project_template/config.yml +45 -40
- data/lib/squib/version.rb +10 -10
- data/samples/color_shortcuts.rb +6 -0
- data/samples/csv_import.rb +18 -18
- data/samples/custom-config.yml +5 -5
- data/samples/custom_config.rb +18 -18
- data/samples/draw_shapes.rb +45 -35
- data/samples/embed_text.rb +88 -90
- data/samples/hand.rb +24 -24
- data/samples/layouts.rb +62 -61
- data/samples/layouts_builtin.rb +51 -0
- data/samples/load_images.rb +78 -64
- data/samples/ranges.rb +64 -53
- data/samples/sample.csv +2 -2
- data/samples/text_options.rb +102 -94
- data/spec/api/api_data_spec.rb +57 -50
- data/spec/api/api_settings_spec.rb +37 -17
- data/spec/args/box_spec.rb +127 -0
- data/spec/args/draw_spec.rb +95 -0
- data/spec/args/embed_key_spec.rb +13 -0
- data/spec/args/input_file_spec.rb +21 -0
- data/spec/args/paint_spec.rb +22 -0
- data/spec/args/paragraph_spec.rb +153 -0
- data/spec/args/range_spec.rb +36 -0
- data/spec/args/save_batch_spec.rb +51 -0
- data/spec/args/scale_box_spec.rb +71 -0
- data/spec/args/sheet_spec.rb +58 -0
- data/spec/args/showcase_special_spec.rb +15 -0
- data/spec/data/samples/autoscale_font.rb.txt +84 -87
- data/spec/data/samples/basic.rb.txt +209 -203
- data/spec/data/samples/cairo_access.rb.txt +2 -2
- data/spec/data/samples/config_text_markup.rb.txt +72 -75
- data/spec/data/samples/csv_import.rb.txt +76 -80
- data/spec/data/samples/custom_config.rb.txt +48 -49
- data/spec/data/samples/draw_shapes.rb.txt +100 -42
- data/spec/data/samples/embed_text.rb.txt +283 -295
- data/spec/data/samples/excel.rb.txt +162 -171
- data/spec/data/samples/gradients.rb.txt +79 -67
- data/spec/data/samples/hand.rb.txt +538 -514
- data/spec/data/samples/hello_world.rb.txt +36 -38
- data/spec/data/samples/load_images.rb.txt +41 -5
- data/spec/data/samples/portrait-landscape.rb.txt +49 -51
- data/spec/data/samples/ranges.rb.txt +460 -429
- data/spec/data/samples/saves.rb.txt +801 -785
- data/spec/data/samples/showcase.rb.txt +5910 -5906
- data/spec/data/samples/text_options.rb.txt +1125 -981
- data/spec/data/samples/tgc_proofs.rb.txt +81 -79
- data/spec/data/samples/units.rb.txt +18 -12
- data/spec/data/xlsx/with_macros.xlsm +0 -0
- data/spec/graphics/cairo_context_wrapper_spec.rb +84 -75
- data/spec/graphics/graphics_images_spec.rb +94 -85
- data/spec/graphics/graphics_save_doc_spec.rb +67 -65
- data/spec/samples/expected/hand.png +0 -0
- data/spec/samples/expected/hand_pretty.png +0 -0
- data/spec/samples/expected/layout_00.png +0 -0
- data/spec/samples/expected/load_images_00.png +0 -0
- data/spec/samples/expected/ranges_00.png +0 -0
- data/spec/samples/expected/shape_00.png +0 -0
- data/spec/samples/expected/showcase.png +0 -0
- data/spec/samples/expected/showcase2.png +0 -0
- data/spec/samples/expected/showcase_individual_00.png +0 -0
- data/spec/samples/expected/showcase_individual_01.png +0 -0
- data/spec/samples/expected/showcase_individual_02.png +0 -0
- data/spec/samples/expected/showcase_individual_03.png +0 -0
- data/spec/samples/expected/text_00.png +0 -0
- data/spec/samples/expected/text_01.png +0 -0
- data/spec/samples/expected/text_02.png +0 -0
- data/spec/samples/samples_regression_spec.rb +82 -82
- data/spec/spec_helper.rb +3 -2
- data/squib.gemspec +48 -48
- data/squib.sublime-project +42 -36
- metadata +61 -33
- data/lib/squib/input_helpers.rb +0 -238
- data/spec/api/api_image_spec.rb +0 -38
- data/spec/api/api_text_spec.rb +0 -37
- data/spec/graphics/graphics_shapes_spec.rb +0 -85
- data/spec/graphics/graphics_text_spec.rb +0 -164
- data/spec/input_helpers_spec.rb +0 -238
- data/spec/samples/expected/embed_multi_00.png +0 -0
- data/spec/samples/expected/embed_multi_01.png +0 -0
- data/spec/samples/expected/embed_multi_02.png +0 -0
- data/spec/samples/expected/ranges_01.png +0 -0
- data/spec/samples/expected/ranges_02.png +0 -0
data/lib/squib/graphics/hand.rb
CHANGED
|
@@ -1,43 +1,42 @@
|
|
|
1
|
-
require 'squib/graphics/cairo_context_wrapper'
|
|
2
|
-
|
|
3
|
-
module Squib
|
|
4
|
-
class Deck
|
|
5
|
-
|
|
6
|
-
# Draw cards in a fan.
|
|
7
|
-
# @api private
|
|
8
|
-
def render_hand(range,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
cxt
|
|
16
|
-
cxt.
|
|
17
|
-
cxt.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
cxt.
|
|
21
|
-
cxt.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
cxt.
|
|
28
|
-
cxt.
|
|
29
|
-
cxt.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
png_cxt
|
|
35
|
-
png_cxt.
|
|
36
|
-
png_cxt.
|
|
37
|
-
png_cxt.
|
|
38
|
-
png_cxt.
|
|
39
|
-
png_cxt.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
end
|
|
1
|
+
require 'squib/graphics/cairo_context_wrapper'
|
|
2
|
+
|
|
3
|
+
module Squib
|
|
4
|
+
class Deck
|
|
5
|
+
|
|
6
|
+
# Draw cards in a fan.
|
|
7
|
+
# @api private
|
|
8
|
+
def render_hand(range, sheet, hand)
|
|
9
|
+
cards = range.collect { |i| @cards[i] }
|
|
10
|
+
center_x = width / 2.0
|
|
11
|
+
center_y = hand.radius + height
|
|
12
|
+
out_size = 3.0 * center_y
|
|
13
|
+
angle_delta = (hand.angle_range.last - hand.angle_range.first) / cards.size
|
|
14
|
+
cxt = Cairo::Context.new(Cairo::RecordingSurface.new(0, 0, out_size, out_size))
|
|
15
|
+
cxt.translate(out_size / 2.0, out_size / 2.0)
|
|
16
|
+
cxt.rotate(hand.angle_range.first)
|
|
17
|
+
cxt.translate(-width, -width)
|
|
18
|
+
cards.each_with_index do |card, i|
|
|
19
|
+
cxt.translate(center_x, center_y)
|
|
20
|
+
cxt.rotate(angle_delta)
|
|
21
|
+
cxt.translate(-center_x, -center_y)
|
|
22
|
+
card.use_cairo do |card_cxt|
|
|
23
|
+
cxt.rounded_rectangle(sheet.trim, sheet.trim,
|
|
24
|
+
width - (2 * sheet.trim), height - (2 * sheet.trim),
|
|
25
|
+
sheet.trim_radius, sheet.trim_radius)
|
|
26
|
+
cxt.clip
|
|
27
|
+
cxt.set_source(card_cxt.target)
|
|
28
|
+
cxt.paint
|
|
29
|
+
cxt.reset_clip
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
x, y, w, h = cxt.target.ink_extents # I love Ruby assignment ;)
|
|
33
|
+
png_cxt = Squib::Graphics::CairoContextWrapper.new(Cairo::Context.new(Cairo::ImageSurface.new(w + 2*sheet.margin, h + 2*sheet.margin)))
|
|
34
|
+
png_cxt.set_source_squibcolor(sheet.fill_color)
|
|
35
|
+
png_cxt.paint
|
|
36
|
+
png_cxt.translate(-x + sheet.margin, -y + sheet.margin)
|
|
37
|
+
png_cxt.set_source(cxt.target)
|
|
38
|
+
png_cxt.paint
|
|
39
|
+
png_cxt.target.write_to_png sheet.full_filename
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/squib/graphics/image.rb
CHANGED
|
@@ -1,73 +1,76 @@
|
|
|
1
|
-
module Squib
|
|
2
|
-
|
|
3
|
-
# Cache all pngs we've already loaded
|
|
4
|
-
#
|
|
5
|
-
# :nodoc:
|
|
6
|
-
# @api private
|
|
7
|
-
def cache_load_image(file)
|
|
8
|
-
@img_cache ||= {}
|
|
9
|
-
@img_cache[file] || @img_cache[file] = Cairo::ImageSurface.from_png(file)
|
|
10
|
-
end
|
|
11
|
-
module_function :cache_load_image
|
|
12
|
-
|
|
13
|
-
class Card
|
|
14
|
-
|
|
15
|
-
# :nodoc:
|
|
16
|
-
# @api private
|
|
17
|
-
def png(file,
|
|
18
|
-
Squib.logger.debug {"
|
|
19
|
-
return if file.nil? or file.eql? ''
|
|
20
|
-
png = Squib.cache_load_image(file)
|
|
21
|
-
use_cairo do |cc|
|
|
22
|
-
cc.translate(x, y)
|
|
23
|
-
if width != :native || height != :native
|
|
24
|
-
width
|
|
25
|
-
height
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
cc.
|
|
32
|
-
cc.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
cc.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
data
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
end
|
|
1
|
+
module Squib
|
|
2
|
+
|
|
3
|
+
# Cache all pngs we've already loaded
|
|
4
|
+
#
|
|
5
|
+
# :nodoc:
|
|
6
|
+
# @api private
|
|
7
|
+
def cache_load_image(file)
|
|
8
|
+
@img_cache ||= {}
|
|
9
|
+
@img_cache[file] || @img_cache[file] = Cairo::ImageSurface.from_png(file)
|
|
10
|
+
end
|
|
11
|
+
module_function :cache_load_image
|
|
12
|
+
|
|
13
|
+
class Card
|
|
14
|
+
|
|
15
|
+
# :nodoc:
|
|
16
|
+
# @api private
|
|
17
|
+
def png(file, box, paint, trans)
|
|
18
|
+
Squib.logger.debug {"RENDERING PNG: \n file: #{file}\n box: #{box}\n paint: #{paint}\n trans: #{trans}"}
|
|
19
|
+
return if file.nil? or file.eql? ''
|
|
20
|
+
png = Squib.cache_load_image(file)
|
|
21
|
+
use_cairo do |cc|
|
|
22
|
+
cc.translate(box.x, box.y)
|
|
23
|
+
if box.width != :native || box.height != :native
|
|
24
|
+
box.width = png.width.to_f if box.width == :native
|
|
25
|
+
box.height = png.height.to_f if box.height == :native
|
|
26
|
+
box.width = png.width.to_f * box.height.to_f / png.height.to_f if box.width == :scale
|
|
27
|
+
box.height = png.height.to_f * box.width.to_f / png.width.to_f if box.height == :scale
|
|
28
|
+
Squib.logger.warn "PNG scaling results in aliasing."
|
|
29
|
+
cc.scale(box.width.to_f / png.width.to_f, box.height.to_f / png.height.to_f)
|
|
30
|
+
end
|
|
31
|
+
cc.rotate(trans.angle)
|
|
32
|
+
cc.translate(-box.x, -box.y)
|
|
33
|
+
cc.set_source(png, box.x, box.y)
|
|
34
|
+
cc.operator = paint.blend unless paint.blend == :none
|
|
35
|
+
if paint.mask.empty?
|
|
36
|
+
cc.paint(paint.alpha)
|
|
37
|
+
else
|
|
38
|
+
cc.set_source_squibcolor(paint.mask)
|
|
39
|
+
cc.mask(png, box.x, box.y)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# :nodoc:
|
|
45
|
+
# @api private
|
|
46
|
+
def svg(file, svg_args, box, paint, trans)
|
|
47
|
+
Squib.logger.debug {"Rendering: #{file}, id: #{id} @#{x},#{y} #{width}x#{height}, alpha: #{alpha}, blend: #{blend}, angle: #{angle}, mask: #{mask}"}
|
|
48
|
+
Squib.logger.warn 'Both an SVG file and SVG data were specified' unless file.to_s.empty? || svg_args.data.to_s.empty?
|
|
49
|
+
return if (file.nil? or file.eql? '') and svg_args.data.nil? # nothing specified TODO Move this out to arg validator
|
|
50
|
+
svg_args.data = File.read(file) if svg_args.data.to_s.empty?
|
|
51
|
+
svg = RSVG::Handle.new_from_data(svg_args.data)
|
|
52
|
+
box.width = svg.width if box.width == :native
|
|
53
|
+
box.height = svg.height if box.height == :native
|
|
54
|
+
box.width = svg.width.to_f * box.height.to_f / svg.height.to_f if box.width == :scale
|
|
55
|
+
box.height = svg.height.to_f * box.width.to_f / svg.width.to_f if box.height == :scale
|
|
56
|
+
scale_width = box.width.to_f / svg.width.to_f
|
|
57
|
+
scale_height = box.height.to_f / svg.height.to_f
|
|
58
|
+
use_cairo do |cc|
|
|
59
|
+
cc.translate(box.x, box.y)
|
|
60
|
+
cc.rotate(trans.angle)
|
|
61
|
+
cc.scale(scale_width, scale_height)
|
|
62
|
+
cc.operator = paint.blend unless paint.blend == :none
|
|
63
|
+
if paint.mask.to_s.empty?
|
|
64
|
+
cc.render_rsvg_handle(svg, svg_args.id)
|
|
65
|
+
else
|
|
66
|
+
tmp = Cairo::ImageSurface.new(box.width / scale_width, box.height / scale_height)
|
|
67
|
+
tmp_cc = Cairo::Context.new(tmp)
|
|
68
|
+
tmp_cc.render_rsvg_handle(svg, svg_args.id)
|
|
69
|
+
cc.set_source_squibcolor(paint.mask)
|
|
70
|
+
cc.mask(tmp, 0, 0)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -1,137 +1,103 @@
|
|
|
1
|
-
module Squib
|
|
2
|
-
class Deck
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
cc.
|
|
34
|
-
cc.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
cc.paint
|
|
105
|
-
num_this_sheet += 1
|
|
106
|
-
x += surface.width + p[:gap]
|
|
107
|
-
if num_this_sheet % p[:columns] == 0 # new row
|
|
108
|
-
x = p[:margin]
|
|
109
|
-
y += surface.height + p[:gap]
|
|
110
|
-
end
|
|
111
|
-
bar.increment
|
|
112
|
-
end
|
|
113
|
-
cc.target.write_to_png("#{p[:dir]}/#{p[:prefix]}#{p[:count_format] % sheet_num}.png")
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# Return a new Cairo::ImageSurface that is trimmed from the original
|
|
118
|
-
#
|
|
119
|
-
# @param surface The surface to trim
|
|
120
|
-
# @param trim The number of pixels around the edge to trim
|
|
121
|
-
# @param width The width of the surface prior to the trim
|
|
122
|
-
# @param height The height of the surface prior to the trim
|
|
123
|
-
# :nodoc:
|
|
124
|
-
# @api private
|
|
125
|
-
def trim(surface, trim, width, height)
|
|
126
|
-
if trim > 0
|
|
127
|
-
tmp = Cairo::ImageSurface.new(width-2*trim, height-2*trim)
|
|
128
|
-
cc = Cairo::Context.new(tmp)
|
|
129
|
-
cc.set_source(surface,-1*trim, -1*trim)
|
|
130
|
-
cc.paint
|
|
131
|
-
surface = tmp
|
|
132
|
-
end
|
|
133
|
-
surface
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
end
|
|
137
|
-
end
|
|
1
|
+
module Squib
|
|
2
|
+
class Deck
|
|
3
|
+
|
|
4
|
+
# :nodoc:
|
|
5
|
+
# @api private
|
|
6
|
+
def render_pdf(range, sheet)
|
|
7
|
+
file = "#{sheet.dir}/#{sheet.file}"
|
|
8
|
+
cc = Cairo::Context.new(Cairo::PDFSurface.new(file, sheet.width * 72.0 / @dpi, sheet.height * 72.0 / @dpi))
|
|
9
|
+
cc.scale(72.0 / @dpi, 72.0 / @dpi) # for bug #62
|
|
10
|
+
x, y = sheet.margin, sheet.margin
|
|
11
|
+
card_width = @width - 2 * sheet.trim
|
|
12
|
+
card_height = @height - 2 * sheet.trim
|
|
13
|
+
@progress_bar.start("Saving PDF to #{file}", range.size) do |bar|
|
|
14
|
+
range.each do |i|
|
|
15
|
+
card = @cards[i]
|
|
16
|
+
cc.translate(x,y)
|
|
17
|
+
cc.rectangle(sheet.trim, sheet.trim, card_width, card_height)
|
|
18
|
+
cc.clip
|
|
19
|
+
case card.backend.downcase.to_sym
|
|
20
|
+
when :memory
|
|
21
|
+
cc.set_source(card.cairo_surface, 0, 0)
|
|
22
|
+
cc.paint
|
|
23
|
+
when :svg
|
|
24
|
+
card.cairo_surface.finish
|
|
25
|
+
cc.save
|
|
26
|
+
cc.scale(0.8,0.8) # I really don't know why I needed to do this at all. But 0.8 is the magic number to get this to scale right
|
|
27
|
+
cc.render_rsvg_handle(RSVG::Handle.new_from_file(card.svgfile), nil)
|
|
28
|
+
cc.restore
|
|
29
|
+
else
|
|
30
|
+
abort "No such back end supported for save_pdf: #{backend}"
|
|
31
|
+
end
|
|
32
|
+
bar.increment
|
|
33
|
+
cc.reset_clip
|
|
34
|
+
cc.translate(-x,-y)
|
|
35
|
+
x += card.width + sheet.gap - 2*sheet.trim
|
|
36
|
+
if x > (sheet.width - card_width - sheet.margin)
|
|
37
|
+
x = sheet.margin
|
|
38
|
+
y += card.height + sheet.gap - 2*sheet.trim
|
|
39
|
+
if y > (sheet.height - card_height - sheet.margin)
|
|
40
|
+
cc.show_page # next page
|
|
41
|
+
x,y = sheet.margin,sheet.margin
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# :nodoc:
|
|
49
|
+
# @api private
|
|
50
|
+
def render_sheet(range, batch, sheet)
|
|
51
|
+
sheet_width = (sheet.columns * (@width + 2 * sheet.gap - 2 * sheet.trim)) + (2 * sheet.margin)
|
|
52
|
+
sheet_height = (sheet.rows * (@height + 2 * sheet.gap - 2 * sheet.trim)) + (2 * sheet.margin)
|
|
53
|
+
cc = Cairo::Context.new(Cairo::ImageSurface.new(sheet_width, sheet_height))
|
|
54
|
+
num_this_sheet = 0
|
|
55
|
+
sheet_num = 0
|
|
56
|
+
x, y = sheet.margin, sheet.margin
|
|
57
|
+
@progress_bar.start("Saving PNG sheet to #{batch.summary}", @cards.size + 1) do |bar|
|
|
58
|
+
range.each do |i|
|
|
59
|
+
if num_this_sheet >= (sheet.columns * sheet.rows) # new sheet
|
|
60
|
+
filename = batch.full_filename(sheet_num)
|
|
61
|
+
cc.target.write_to_png(filename)
|
|
62
|
+
new_sheet = false
|
|
63
|
+
num_this_sheet = 0
|
|
64
|
+
sheet_num += 1
|
|
65
|
+
x, y = sheet.margin, sheet.margin
|
|
66
|
+
cc = Cairo::Context.new(Cairo::ImageSurface.new(sheet_width, sheet_height))
|
|
67
|
+
end
|
|
68
|
+
surface = trim(@cards[i].cairo_surface, sheet.trim, @width, @height)
|
|
69
|
+
cc.set_source(surface, x, y)
|
|
70
|
+
cc.paint
|
|
71
|
+
num_this_sheet += 1
|
|
72
|
+
x += surface.width + sheet.gap
|
|
73
|
+
if num_this_sheet % sheet.columns == 0 # new row
|
|
74
|
+
x = sheet.margin
|
|
75
|
+
y += surface.height + sheet.gap
|
|
76
|
+
end
|
|
77
|
+
bar.increment
|
|
78
|
+
end
|
|
79
|
+
cc.target.write_to_png(batch.full_filename(sheet_num))
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Return a new Cairo::ImageSurface that is trimmed from the original
|
|
84
|
+
#
|
|
85
|
+
# @param surface The surface to trim
|
|
86
|
+
# @param trim The number of pixels around the edge to trim
|
|
87
|
+
# @param width The width of the surface prior to the trim
|
|
88
|
+
# @param height The height of the surface prior to the trim
|
|
89
|
+
# :nodoc:
|
|
90
|
+
# @api private
|
|
91
|
+
def trim(surface, trim, width, height)
|
|
92
|
+
if trim > 0
|
|
93
|
+
tmp = Cairo::ImageSurface.new(width-2*trim, height-2*trim)
|
|
94
|
+
cc = Cairo::Context.new(tmp)
|
|
95
|
+
cc.set_source(surface,-1*trim, -1*trim)
|
|
96
|
+
cc.paint
|
|
97
|
+
surface = tmp
|
|
98
|
+
end
|
|
99
|
+
surface
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
end
|