squib 0.8.0 → 0.9.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/.gitmodules +14 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +201 -175
- data/Gemfile +2 -4
- data/README.md +650 -645
- data/RELEASE TODO.md +18 -18
- data/Rakefile +106 -99
- data/appveyor.yml +29 -0
- data/lib/squib.rb +32 -32
- data/lib/squib/api/background.rb +20 -20
- data/lib/squib/api/data.rb +131 -131
- data/lib/squib/api/image.rb +108 -90
- data/lib/squib/api/save.rb +151 -149
- data/lib/squib/api/settings.rb +35 -35
- data/lib/squib/api/shapes.rb +255 -230
- data/lib/squib/api/text.rb +65 -65
- data/lib/squib/api/text_embed.rb +96 -96
- data/lib/squib/args/arg_loader.rb +138 -138
- data/lib/squib/args/box.rb +54 -54
- data/lib/squib/args/card_range.rb +32 -32
- data/lib/squib/args/color_validator.rb +11 -11
- data/lib/squib/args/coords.rb +32 -32
- data/lib/squib/args/dir_validator.rb +16 -16
- data/lib/squib/args/draw.rb +92 -92
- data/lib/squib/args/embed_adjust.rb +25 -25
- data/lib/squib/args/embed_key.rb +17 -17
- data/lib/squib/args/hand_special.rb +37 -37
- data/lib/squib/args/import.rb +39 -39
- data/lib/squib/args/input_file.rb +37 -37
- data/lib/squib/args/paint.rb +43 -43
- data/lib/squib/args/paragraph.rb +116 -115
- data/lib/squib/args/save_batch.rb +63 -60
- data/lib/squib/args/scale_box.rb +53 -53
- data/lib/squib/args/sheet.rb +72 -72
- data/lib/squib/args/showcase_special.rb +38 -38
- data/lib/squib/args/svg_special.rb +37 -37
- data/lib/squib/args/transform.rb +60 -24
- data/lib/squib/args/typographer.rb +117 -117
- data/lib/squib/card.rb +66 -67
- data/lib/squib/conf.rb +131 -117
- data/lib/squib/constants.rb +12 -178
- data/lib/squib/deck.rb +113 -113
- data/lib/squib/graphics/cairo_context_wrapper.rb +113 -99
- data/lib/squib/graphics/gradient_regex.rb +46 -46
- data/lib/squib/graphics/hand.rb +42 -42
- data/lib/squib/graphics/image.rb +103 -76
- data/lib/squib/graphics/save_doc.rb +103 -103
- data/lib/squib/graphics/save_images.rb +39 -33
- data/lib/squib/graphics/shapes.rb +135 -119
- data/lib/squib/graphics/showcase.rb +85 -85
- data/lib/squib/graphics/text.rb +176 -176
- data/lib/squib/layout_parser.rb +91 -91
- data/lib/squib/layouts/economy.yml +85 -85
- data/lib/squib/layouts/fantasy.yml +101 -101
- data/lib/squib/layouts/hand.yml +62 -62
- data/lib/squib/layouts/playing-card.yml +35 -35
- data/lib/squib/layouts/tuck_box.yml +45 -45
- data/lib/squib/project_template/IDEAS.md +22 -0
- data/lib/squib/project_template/PLAYTESTING.md +26 -0
- data/lib/squib/project_template/RULES.md +21 -0
- data/lib/squib/project_template/config.yml +49 -45
- data/lib/squib/sample_helpers.rb +34 -0
- data/lib/squib/version.rb +10 -10
- data/samples/autoscale_font/_autoscale_font.rb +29 -0
- data/samples/color_shortcuts.rb +6 -6
- data/samples/csv_import.rb +26 -26
- data/samples/custom-config.yml +5 -5
- data/samples/custom_config.rb +18 -18
- data/samples/draw_shapes.rb +48 -45
- data/samples/embed_text.rb +88 -88
- data/samples/excel.rb +55 -55
- data/samples/hand.rb +24 -24
- data/samples/images/_images.rb +104 -0
- data/samples/intro/01_hello.rb +9 -0
- data/samples/intro/02_options.rb +15 -0
- data/samples/intro/03_layout.rb +12 -0
- data/samples/intro/04_arrays.rb +16 -0
- data/samples/intro/05_excel.rb +15 -0
- data/samples/layouts.rb +62 -62
- data/samples/layouts_builtin.rb +51 -51
- data/samples/load_images.rb +99 -78
- data/samples/load_images_config.yml +1 -0
- data/samples/quantity_explosion.csv +2 -2
- data/samples/ranges.rb +64 -64
- data/samples/sample.csv +2 -2
- data/samples/saves.rb +9 -1
- data/samples/sprites.png +0 -0
- data/samples/text/_text.rb +46 -0
- data/samples/text_options.rb +102 -102
- data/spec/api/api_data_spec.rb +117 -117
- data/spec/api/api_settings_spec.rb +37 -37
- data/spec/args/box_spec.rb +127 -127
- data/spec/args/draw_spec.rb +101 -95
- data/spec/args/embed_key_spec.rb +13 -13
- data/spec/args/input_file_spec.rb +21 -21
- data/spec/args/paint_spec.rb +21 -21
- data/spec/args/paragraph_spec.rb +152 -152
- data/spec/args/range_spec.rb +40 -40
- data/spec/args/save_batch_spec.rb +51 -51
- data/spec/args/scale_box_spec.rb +71 -71
- data/spec/args/sheet_spec.rb +58 -58
- data/spec/args/showcase_special_spec.rb +15 -15
- data/spec/args/transform_spec.rb +25 -0
- data/spec/card_spec.rb +11 -0
- data/spec/conf_spec.rb +13 -3
- data/spec/data/conf/unrecognized.yml +4 -0
- data/spec/data/csv/qty.csv +2 -2
- data/spec/data/csv/qty_named.csv +2 -2
- data/spec/data/csv/with_spaces.csv +2 -2
- data/spec/data/samples/autoscale_font.rb.txt +84 -84
- data/spec/data/samples/basic.rb.txt +227 -209
- data/spec/data/samples/config_text_markup.rb.txt +72 -72
- data/spec/data/samples/csv_import.rb.txt +213 -213
- data/spec/data/samples/custom_config.rb.txt +57 -48
- data/spec/data/samples/draw_shapes.rb.txt +555 -3
- data/spec/data/samples/embed_text.rb.txt +283 -283
- data/spec/data/samples/excel.rb.txt +661 -661
- data/spec/data/samples/gradients.rb.txt +77 -79
- data/spec/data/samples/hand.rb.txt +538 -538
- data/spec/data/samples/hello_world.rb.txt +36 -36
- data/spec/data/samples/load_images.rb.txt +170 -0
- data/spec/data/samples/portrait-landscape.rb.txt +51 -49
- data/spec/data/samples/ranges.rb.txt +472 -460
- data/spec/data/samples/saves.rb.txt +810 -801
- data/spec/data/samples/showcase.rb.txt +5926 -5910
- data/spec/data/samples/text_options.rb.txt +1125 -1125
- data/spec/data/samples/tgc_proofs.rb.txt +95 -81
- data/spec/graphics/cairo_context_wrapper_spec.rb +104 -84
- data/spec/graphics/graphics_save_doc_spec.rb +67 -67
- data/spec/samples/diff-with-css.example.html +39 -0
- data/spec/samples/expected/load_images_00.png +0 -0
- data/spec/samples/expected/shape_00.png +0 -0
- data/spec/samples/run_samples_spec.rb +17 -0
- data/spec/samples/samples_regression_spec.rb +72 -82
- data/spec/spec_helper.rb +9 -1
- data/squib.gemspec +49 -48
- data/squib.sublime-project +42 -42
- metadata +94 -48
- data/spec/graphics/graphics_images_spec.rb +0 -94
@@ -1,103 +1,103 @@
|
|
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
|
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
|
@@ -1,33 +1,39 @@
|
|
1
|
-
module Squib
|
2
|
-
class Card
|
3
|
-
|
4
|
-
# :nodoc:
|
5
|
-
# @api private
|
6
|
-
def save_png(batch)
|
7
|
-
surface = if batch
|
8
|
-
|
9
|
-
else
|
10
|
-
|
11
|
-
end
|
12
|
-
write_png(surface, index, batch.dir, batch.prefix, batch.count_format)
|
13
|
-
end
|
14
|
-
|
15
|
-
# :nodoc:
|
16
|
-
# @api private
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
1
|
+
module Squib
|
2
|
+
class Card
|
3
|
+
|
4
|
+
# :nodoc:
|
5
|
+
# @api private
|
6
|
+
def save_png(batch)
|
7
|
+
surface = if preprocess_save?(batch)
|
8
|
+
preprocessed_save(batch.angle, batch.trim, batch.trim_radius)
|
9
|
+
else
|
10
|
+
@cairo_surface
|
11
|
+
end
|
12
|
+
write_png(surface, index, batch.dir, batch.prefix, batch.count_format)
|
13
|
+
end
|
14
|
+
|
15
|
+
# :nodoc:
|
16
|
+
# @api private
|
17
|
+
def preprocess_save?(batch)
|
18
|
+
batch.rotate || batch.trim > 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def preprocessed_save(angle, trim, trim_radius)
|
22
|
+
new_width, new_height = @width - 2*trim, @height - 2*trim
|
23
|
+
new_cc = Cairo::Context.new(Cairo::ImageSurface.new(new_width, new_height))
|
24
|
+
new_cc.translate(new_width * 0.5, new_height * 0.5)
|
25
|
+
new_cc.rotate(angle)
|
26
|
+
new_cc.translate(new_width * -0.5, new_height * -0.5)
|
27
|
+
new_cc.set_source(@cairo_surface, -trim, -trim)
|
28
|
+
new_cc.rounded_rectangle(0, 0, new_width, new_height, trim_radius, trim_radius)
|
29
|
+
new_cc.clip
|
30
|
+
new_cc.paint
|
31
|
+
new_cc.target
|
32
|
+
end
|
33
|
+
|
34
|
+
def write_png(surface, i, dir, prefix, count_format)
|
35
|
+
surface.write_to_png("#{dir}/#{prefix}#{count_format % i}.png")
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -1,119 +1,135 @@
|
|
1
|
-
module Squib
|
2
|
-
# @api private
|
3
|
-
class Card
|
4
|
-
|
5
|
-
# :nodoc:
|
6
|
-
# @api private
|
7
|
-
def rect(box, draw)
|
8
|
-
use_cairo do |cc|
|
9
|
-
cc.rounded_rectangle(box.x, box.y, box.width, box.height, box.x_radius, box.y_radius)
|
10
|
-
cc.fill_n_stroke(draw)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# :nodoc:
|
15
|
-
# @api private
|
16
|
-
def circle(box, draw)
|
17
|
-
x, y, r = box.x, box.y, box.radius
|
18
|
-
use_cairo do |cc|
|
19
|
-
cc.move_to(x + r, y)
|
20
|
-
cc.circle(x, y, r)
|
21
|
-
cc.fill_n_stroke(draw)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# Ellipse drawing taken from looking at the control points in Inkscape
|
26
|
-
# Think of it like a rectangle. Curves go from mid-points of the sides
|
27
|
-
# of the rectangle. Control points are at 1/4 and 3/4 of the side.
|
28
|
-
# :nodoc:
|
29
|
-
# @api private
|
30
|
-
def ellipse(box, draw)
|
31
|
-
x, y, w, h = box.x, box.y, box.width, box.height
|
32
|
-
use_cairo do |cc|
|
33
|
-
cc.move_to(x, y + 0.5*h) # start west
|
34
|
-
cc.curve_to(x, y + 0.25*h, # west to north
|
35
|
-
x + 0.25*w, y,
|
36
|
-
x + 0.5*w, y)
|
37
|
-
cc.curve_to(x + 0.75*w, y, # north to east
|
38
|
-
x + w, y + 0.25*h,
|
39
|
-
x + w, y + 0.5*h)
|
40
|
-
cc.curve_to(x + w, y + 0.75*h, # east to south
|
41
|
-
x + 0.75*w, y + h,
|
42
|
-
x + 0.5*w, y + h)
|
43
|
-
cc.curve_to(x + 0.25*w, y + h, # south to west
|
44
|
-
x, y + 0.75*h,
|
45
|
-
x, y + 0.5*h)
|
46
|
-
cc.fill_n_stroke(draw)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# :nodoc:
|
51
|
-
# @api private
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
#
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
cc.
|
65
|
-
cc.fill_n_stroke(draw)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
|
70
|
-
# @api private
|
71
|
-
def
|
72
|
-
x1, y1,
|
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
cc.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
1
|
+
module Squib
|
2
|
+
# @api private
|
3
|
+
class Card
|
4
|
+
|
5
|
+
# :nodoc:
|
6
|
+
# @api private
|
7
|
+
def rect(box, draw)
|
8
|
+
use_cairo do |cc|
|
9
|
+
cc.rounded_rectangle(box.x, box.y, box.width, box.height, box.x_radius, box.y_radius)
|
10
|
+
cc.fill_n_stroke(draw)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# :nodoc:
|
15
|
+
# @api private
|
16
|
+
def circle(box, draw)
|
17
|
+
x, y, r = box.x, box.y, box.radius
|
18
|
+
use_cairo do |cc|
|
19
|
+
cc.move_to(x + r, y)
|
20
|
+
cc.circle(x, y, r)
|
21
|
+
cc.fill_n_stroke(draw)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Ellipse drawing taken from looking at the control points in Inkscape
|
26
|
+
# Think of it like a rectangle. Curves go from mid-points of the sides
|
27
|
+
# of the rectangle. Control points are at 1/4 and 3/4 of the side.
|
28
|
+
# :nodoc:
|
29
|
+
# @api private
|
30
|
+
def ellipse(box, draw)
|
31
|
+
x, y, w, h = box.x, box.y, box.width, box.height
|
32
|
+
use_cairo do |cc|
|
33
|
+
cc.move_to(x, y + 0.5*h) # start west
|
34
|
+
cc.curve_to(x, y + 0.25*h, # west to north
|
35
|
+
x + 0.25*w, y,
|
36
|
+
x + 0.5*w, y)
|
37
|
+
cc.curve_to(x + 0.75*w, y, # north to east
|
38
|
+
x + w, y + 0.25*h,
|
39
|
+
x + w, y + 0.5*h)
|
40
|
+
cc.curve_to(x + w, y + 0.75*h, # east to south
|
41
|
+
x + 0.75*w, y + h,
|
42
|
+
x + 0.5*w, y + h)
|
43
|
+
cc.curve_to(x + 0.25*w, y + h, # south to west
|
44
|
+
x, y + 0.75*h,
|
45
|
+
x, y + 0.5*h)
|
46
|
+
cc.fill_n_stroke(draw)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# :nodoc:
|
51
|
+
# @api private
|
52
|
+
def grid(box, draw)
|
53
|
+
x, y, w, h = box.x, box.y, box.width, box.height
|
54
|
+
use_cairo do |cc|
|
55
|
+
(x..@width + w).step(w) { |ix| line_xy( ix, y - @height, ix, @height + y, draw) }
|
56
|
+
(y..@height + h).step(h) { |iy| line_xy( x - @width, iy, @width + x, iy, draw) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# :nodoc:
|
61
|
+
# @api private
|
62
|
+
def triangle(tri, draw)
|
63
|
+
use_cairo do |cc|
|
64
|
+
cc.triangle(tri.x1, tri.y1, tri.x2, tri.y2, tri.x3, tri.y3)
|
65
|
+
cc.fill_n_stroke(draw)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# :nodoc:
|
70
|
+
# @api private
|
71
|
+
def line(coord, draw)
|
72
|
+
line_xy(coord.x1, coord.y1, coord.x2, coord.y2, draw)
|
73
|
+
end
|
74
|
+
|
75
|
+
# :nodoc:
|
76
|
+
# @api private
|
77
|
+
def line_xy(x1, y1, x2, y2, draw)
|
78
|
+
use_cairo do |cc|
|
79
|
+
cc.move_to(x1, y1)
|
80
|
+
cc.line_to(x2, y2)
|
81
|
+
cc.fancy_stroke(draw)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# :nodoc:
|
86
|
+
# @api private
|
87
|
+
def curve(bez, draw)
|
88
|
+
x1, y1, cx1, cy1 = bez.x1, bez.y1, bez.cx1, bez.cy1
|
89
|
+
cx2, cy2, x2, y2 = bez.cx2, bez.cy2, bez.x2, bez.y2
|
90
|
+
use_cairo do |cc|
|
91
|
+
cc.move_to(x1, y1)
|
92
|
+
cc.curve_to(cx1, cy1, cx2, cy2, x2, y2)
|
93
|
+
cc.fill_n_stroke(draw)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# :nodoc:
|
98
|
+
# @api private
|
99
|
+
def star(poly, trans, draw)
|
100
|
+
x, y, n = poly.x, poly.y, poly.n
|
101
|
+
inner_radius, outer_radius = poly.inner_radius, poly.outer_radius
|
102
|
+
use_cairo do |cc|
|
103
|
+
cc.rotate_about(x, y, trans.angle)
|
104
|
+
cc.move_to(x + outer_radius, y) #i = 0, so cos(0)=1 and sin(0)=0
|
105
|
+
theta = Math::PI / n.to_f # i.e. (2*pi) / (2*n)
|
106
|
+
0.upto(2 * n) do |i|
|
107
|
+
radius = i.even? ? outer_radius : inner_radius
|
108
|
+
cc.line_to(x + radius * Math::cos(i * theta),
|
109
|
+
y + radius * Math::sin(i * theta))
|
110
|
+
end
|
111
|
+
cc.close_path
|
112
|
+
cc.fill_n_stroke(draw)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# :nodoc:
|
117
|
+
# @api private
|
118
|
+
def polygon(poly, trans, draw)
|
119
|
+
x, y, n, radius = poly.x, poly.y, poly.n, poly.radius
|
120
|
+
use_cairo do |cc|
|
121
|
+
cc.rotate_about(x, y, trans.angle)
|
122
|
+
cc.move_to(x + radius, y) # i = 0, so cos(0)=1 and sin(0)=0
|
123
|
+
theta = (2 * Math::PI) / n.to_f
|
124
|
+
0.upto(n) do |i|
|
125
|
+
cc.line_to(x + radius * Math::cos(i * theta),
|
126
|
+
y + radius * Math::sin(i * theta))
|
127
|
+
end
|
128
|
+
cc.close_path
|
129
|
+
cc.fill_n_stroke(draw)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|