squib 0.18.0 → 0.19.0a

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.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +39 -39
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +22 -22
  4. data/.github/ISSUE_TEMPLATE/help-wanted.md +13 -13
  5. data/.github/ISSUE_TEMPLATE/release-todo.md +45 -33
  6. data/.github/PULL_REQUEST_TEMPLATE.md +13 -13
  7. data/.github/workflows/tests.yml +22 -22
  8. data/.gitignore +41 -41
  9. data/.vscode/settings.json +4 -3
  10. data/CHANGELOG.md +460 -460
  11. data/CONTRIBUTING.md +40 -40
  12. data/Dockerfile +27 -27
  13. data/Gemfile +2 -2
  14. data/Guardfile +8 -8
  15. data/LICENSE.txt +22 -22
  16. data/README.md +139 -139
  17. data/Rakefile +51 -51
  18. data/bin/squib +5 -5
  19. data/lib/squib/api/settings.rb +21 -21
  20. data/lib/squib/args/arg_loader.rb +138 -138
  21. data/lib/squib/args/box.rb +59 -59
  22. data/lib/squib/args/card_range.rb +34 -34
  23. data/lib/squib/args/color_validator.rb +7 -7
  24. data/lib/squib/args/coords.rb +49 -49
  25. data/lib/squib/args/csv_opts.rb +22 -22
  26. data/lib/squib/args/dir_validator.rb +11 -11
  27. data/lib/squib/args/draw.rb +93 -93
  28. data/lib/squib/args/drop_shadow.rb +39 -39
  29. data/lib/squib/args/embed_adjust.rb +22 -22
  30. data/lib/squib/args/embed_key.rb +12 -12
  31. data/lib/squib/args/hand_special.rb +37 -37
  32. data/lib/squib/args/import.rb +67 -67
  33. data/lib/squib/args/input_file.rb +55 -55
  34. data/lib/squib/args/paint.rb +43 -43
  35. data/lib/squib/args/paragraph.rb +118 -118
  36. data/lib/squib/args/save_batch.rb +65 -65
  37. data/lib/squib/args/scale_box.rb +57 -57
  38. data/lib/squib/args/sheet.rb +165 -165
  39. data/lib/squib/args/showcase_special.rb +41 -41
  40. data/lib/squib/args/sprue_file.rb +44 -44
  41. data/lib/squib/args/svg_special.rb +37 -37
  42. data/lib/squib/args/transform.rb +55 -55
  43. data/lib/squib/args/typographer.rb +115 -115
  44. data/lib/squib/args/unit_conversion.rb +27 -27
  45. data/lib/squib/args/xywh_shorthands.rb +50 -50
  46. data/lib/squib/builtin/layouts/economy.yml +85 -85
  47. data/lib/squib/builtin/layouts/fantasy.yml +101 -101
  48. data/lib/squib/builtin/layouts/hand.yml +62 -62
  49. data/lib/squib/builtin/layouts/party.yml +94 -94
  50. data/lib/squib/builtin/layouts/playing-card.yml +35 -35
  51. data/lib/squib/builtin/layouts/tuck_box.yml +46 -46
  52. data/lib/squib/builtin/projects/advanced/.gitignore +4 -4
  53. data/lib/squib/builtin/projects/advanced/ABOUT.md +19 -19
  54. data/lib/squib/builtin/projects/advanced/Gemfile +11 -11
  55. data/lib/squib/builtin/projects/advanced/Guardfile +21 -21
  56. data/lib/squib/builtin/projects/advanced/IDEAS.md +22 -22
  57. data/lib/squib/builtin/projects/advanced/PLAYTESTING.md +26 -26
  58. data/lib/squib/builtin/projects/advanced/Rakefile +27 -27
  59. data/lib/squib/builtin/projects/advanced/config.yml +49 -49
  60. data/lib/squib/builtin/projects/advanced/docs/PNP NOTES.md +3 -3
  61. data/lib/squib/builtin/projects/advanced/docs/RULES.md +21 -21
  62. data/lib/squib/builtin/projects/advanced/img/example.svg +60 -60
  63. data/lib/squib/builtin/projects/advanced/layouts/deck.yml +27 -27
  64. data/lib/squib/builtin/projects/advanced/src/deck.rb +34 -34
  65. data/lib/squib/builtin/projects/advanced/src/version.rb +3 -3
  66. data/lib/squib/builtin/projects/basic/.gitignore +4 -4
  67. data/lib/squib/builtin/projects/basic/ABOUT.md +19 -19
  68. data/lib/squib/builtin/projects/basic/Gemfile +3 -3
  69. data/lib/squib/builtin/projects/basic/IDEAS.md +22 -22
  70. data/lib/squib/builtin/projects/basic/PLAYTESTING.md +26 -26
  71. data/lib/squib/builtin/projects/basic/PNP NOTES.md +3 -3
  72. data/lib/squib/builtin/projects/basic/RULES.md +21 -21
  73. data/lib/squib/builtin/projects/basic/Rakefile +7 -7
  74. data/lib/squib/builtin/projects/basic/config.yml +50 -50
  75. data/lib/squib/builtin/projects/basic/deck.rb +6 -6
  76. data/lib/squib/builtin/sprues/a4_euro_card.yml +42 -42
  77. data/lib/squib/builtin/sprues/a4_poker_card_8up.yml +40 -40
  78. data/lib/squib/builtin/sprues/a4_poker_card_9up.yml +42 -42
  79. data/lib/squib/builtin/sprues/a4_usa_card.yml +42 -42
  80. data/lib/squib/builtin/sprues/drivethrucards_1up.yml +10 -10
  81. data/lib/squib/builtin/sprues/letter_poker_card_9up.yml +25 -25
  82. data/lib/squib/builtin/sprues/letter_poker_foldable_8up.yml +52 -52
  83. data/lib/squib/builtin/sprues/printplaygames_18up.yml +68 -68
  84. data/lib/squib/card.rb +75 -75
  85. data/lib/squib/commands/cli.rb +39 -39
  86. data/lib/squib/commands/data/template_option.rb +109 -109
  87. data/lib/squib/commands/make_sprue.rb +277 -277
  88. data/lib/squib/commands/new.rb +77 -77
  89. data/lib/squib/conf.rb +149 -149
  90. data/lib/squib/constants.rb +17 -17
  91. data/lib/squib/deck.rb +138 -138
  92. data/lib/squib/dsl/background.rb +35 -35
  93. data/lib/squib/dsl/circle.rb +39 -39
  94. data/lib/squib/dsl/csv.rb +42 -42
  95. data/lib/squib/dsl/curve.rb +35 -35
  96. data/lib/squib/dsl/cut_zone.rb +47 -47
  97. data/lib/squib/dsl/ellipse.rb +37 -37
  98. data/lib/squib/dsl/grid.rb +35 -35
  99. data/lib/squib/dsl/groups.rb +54 -54
  100. data/lib/squib/dsl/hand.rb +42 -42
  101. data/lib/squib/dsl/line.rb +35 -35
  102. data/lib/squib/dsl/png.rb +57 -57
  103. data/lib/squib/dsl/polygon.rb +36 -36
  104. data/lib/squib/dsl/rect.rb +37 -37
  105. data/lib/squib/dsl/safe_zone.rb +48 -48
  106. data/lib/squib/dsl/save.rb +21 -21
  107. data/lib/squib/dsl/save_pdf.rb +50 -50
  108. data/lib/squib/dsl/save_png.rb +48 -48
  109. data/lib/squib/dsl/save_sheet.rb +53 -53
  110. data/lib/squib/dsl/showcase.rb +43 -43
  111. data/lib/squib/dsl/star.rb +37 -37
  112. data/lib/squib/dsl/svg.rb +63 -63
  113. data/lib/squib/dsl/text.rb +54 -54
  114. data/lib/squib/dsl/text_embed.rb +79 -79
  115. data/lib/squib/dsl/triangle.rb +35 -35
  116. data/lib/squib/dsl/units.rb +37 -37
  117. data/lib/squib/dsl/xlsx.rb +40 -40
  118. data/lib/squib/dsl/yaml.rb +40 -40
  119. data/lib/squib/errors_warnings/warn_unexpected_params.rb +14 -14
  120. data/lib/squib/graphics/background.rb +14 -14
  121. data/lib/squib/graphics/cairo_context_wrapper.rb +115 -115
  122. data/lib/squib/graphics/embedding_utils.rb +28 -28
  123. data/lib/squib/graphics/gradient_regex.rb +47 -47
  124. data/lib/squib/graphics/hand.rb +42 -42
  125. data/lib/squib/graphics/image.rb +123 -123
  126. data/lib/squib/graphics/save_doc.rb +77 -77
  127. data/lib/squib/graphics/save_images.rb +91 -91
  128. data/lib/squib/graphics/save_pdf.rb +90 -90
  129. data/lib/squib/graphics/save_sprue.rb +231 -231
  130. data/lib/squib/graphics/shapes.rb +143 -143
  131. data/lib/squib/graphics/showcase.rb +85 -85
  132. data/lib/squib/graphics/text.rb +202 -202
  133. data/lib/squib/import/csv_importer.rb +45 -45
  134. data/lib/squib/import/data_frame.rb +108 -108
  135. data/lib/squib/import/quantity_exploder.rb +17 -17
  136. data/lib/squib/import/xlsx_importer.rb +28 -28
  137. data/lib/squib/import/yaml_importer.rb +30 -30
  138. data/lib/squib/layout_parser.rb +155 -155
  139. data/lib/squib/progress.rb +38 -38
  140. data/lib/squib/sample_helpers.rb +34 -34
  141. data/lib/squib/sprues/crop_line.rb +28 -28
  142. data/lib/squib/sprues/crop_line_dash.rb +35 -35
  143. data/lib/squib/sprues/invalid_sprue_definition.rb +9 -9
  144. data/lib/squib/sprues/sprue.rb +208 -208
  145. data/lib/squib/sprues/sprue_schema.rb +51 -51
  146. data/lib/squib/system_fonts.rb +16 -16
  147. data/lib/squib/version.rb +11 -11
  148. data/lib/squib.rb +35 -35
  149. data/samples/autoscale_font/_autoscale_font.rb +98 -98
  150. data/samples/backend/_backend.rb +26 -26
  151. data/samples/basic.rb +19 -19
  152. data/samples/build_groups/build_groups.rb +36 -36
  153. data/samples/colors/_colors.rb +44 -44
  154. data/samples/colors/_gradients.rb +34 -34
  155. data/samples/colors/_switch_color.rb +33 -33
  156. data/samples/config/config_text_markup.rb +20 -20
  157. data/samples/config/custom_config.rb +18 -18
  158. data/samples/data/_csv.rb +33 -33
  159. data/samples/data/_excel.rb +55 -55
  160. data/samples/data/_yaml.rb +12 -12
  161. data/samples/hello_world.rb +6 -6
  162. data/samples/images/_cairo_access.rb +39 -39
  163. data/samples/images/_images.rb +104 -104
  164. data/samples/images/_more_load_images.rb +102 -102
  165. data/samples/images/_placeholders.rb +48 -48
  166. data/samples/intro/01_hello.rb +8 -8
  167. data/samples/intro/02_options.rb +14 -14
  168. data/samples/intro/03_layout.rb +11 -11
  169. data/samples/intro/04_arrays.rb +15 -15
  170. data/samples/intro/05_excel.rb +14 -14
  171. data/samples/layouts/builtin_layouts.rb +97 -97
  172. data/samples/layouts/layouts.rb +71 -71
  173. data/samples/project/src/characters.rb +8 -8
  174. data/samples/project/src/skills.rb +7 -7
  175. data/samples/proofs/_tgc_proofs.rb +16 -16
  176. data/samples/ranges/_ranges.rb +64 -64
  177. data/samples/saves/_hand.rb +23 -23
  178. data/samples/saves/_portrait_landscape.rb +23 -23
  179. data/samples/saves/_save_filenames.rb +28 -28
  180. data/samples/saves/_save_pdf.rb +29 -29
  181. data/samples/saves/_saves.rb +75 -75
  182. data/samples/saves/_showcase.rb +25 -25
  183. data/samples/shadows/_shadow.rb +71 -71
  184. data/samples/shapes/_draw_shapes.rb +60 -60
  185. data/samples/shapes/_proofs.rb +22 -22
  186. data/samples/sprues/_advanced_sprues.rb +25 -25
  187. data/samples/sprues/_builtin_sprues.rb +22 -22
  188. data/samples/sprues/_fold_sheet.rb +30 -30
  189. data/samples/sprues/_hex_tiles.rb +15 -15
  190. data/samples/sprues/_mints.rb +11 -11
  191. data/samples/sprues/_negative_coords.rb +6 -6
  192. data/samples/sprues/_sprue_example.rb +11 -11
  193. data/samples/system_font_debug/_list_fonts.rb +14 -14
  194. data/samples/text/_embed_text.rb +128 -128
  195. data/samples/text/_text.rb +52 -52
  196. data/samples/text/_text_options.rb +103 -103
  197. data/samples/text/bug134.rb +14 -14
  198. data/samples/units/_cells.rb +50 -50
  199. data/samples/units/_shorthands.rb +48 -48
  200. data/samples/units/_units.rb +39 -39
  201. data/squib.gemspec +58 -58
  202. metadata +21 -21
@@ -1,143 +1,143 @@
1
- module Squib
2
- # @api private
3
- class Card
4
-
5
- # :nodoc:
6
- # @api private
7
- def rect(box, draw, trans)
8
- use_cairo do |cc|
9
- cc.rotate_about(box.x, box.y, trans.angle)
10
- cc.rounded_rectangle(box.x, box.y, box.width, box.height,
11
- box.x_radius, box.y_radius)
12
- cc.fill_n_stroke(draw)
13
- end
14
- end
15
-
16
- # :nodoc:
17
- # @api private
18
- def circle(box, draw)
19
- x, y, r = box.x, box.y, box.radius
20
- use_cairo do |cc|
21
- if box.arc_direction == :clockwise
22
- cc.arc(x, y, r, box.arc_start, box.arc_end)
23
- else
24
- cc.arc_negative(x, y, r, box.arc_start, box.arc_end)
25
- end
26
- if box.arc_close
27
- cc.close_path();
28
- end
29
- cc.fill_n_stroke(draw)
30
- end
31
- end
32
-
33
- # Ellipse drawing taken from looking at the control points in Inkscape
34
- # Think of it like a rectangle. Curves go from mid-points of the sides
35
- # of the rectangle. Control points are at 1/4 and 3/4 of the side.
36
- # :nodoc:
37
- # @api private
38
- def ellipse(box, draw, trans)
39
- x, y, w, h = box.x, box.y, box.width, box.height
40
- use_cairo do |cc|
41
- cc.rotate_about(box.x, box.y, trans.angle)
42
- cc.move_to(x, y + 0.5 * h) # start west
43
- cc.curve_to(x, y + 0.25 * h, # west to north
44
- x + 0.25 * w, y,
45
- x + 0.5 * w, y)
46
- cc.curve_to(x + 0.75 * w, y, # north to east
47
- x + w, y + 0.25 * h,
48
- x + w, y + 0.5 * h)
49
- cc.curve_to(x + w, y + 0.75 * h, # east to south
50
- x + 0.75 * w, y + h,
51
- x + 0.5 * w, y + h)
52
- cc.curve_to(x + 0.25 * w, y + h, # south to west
53
- x, y + 0.75 * h,
54
- x, y + 0.5 * h)
55
- cc.fill_n_stroke(draw)
56
- end
57
- end
58
-
59
- # :nodoc:
60
- # @api private
61
- def grid(box, draw)
62
- x, y, w, h = box.x, box.y, box.width, box.height
63
- use_cairo do |cc|
64
- (x..@width + w).step(w) { |ix| line_xy(ix, y - @height, ix, @height + y, draw) }
65
- (y..@height + h).step(h) { |iy| line_xy(x - @width, iy, @width + x, iy, draw) }
66
- end
67
- end
68
-
69
- # :nodoc:
70
- # @api private
71
- def triangle(tri, draw)
72
- use_cairo do |cc|
73
- cc.triangle(tri.x1, tri.y1, tri.x2, tri.y2, tri.x3, tri.y3)
74
- cc.fill_n_stroke(draw)
75
- end
76
- end
77
-
78
- # :nodoc:
79
- # @api private
80
- def line(coord, draw)
81
- line_xy(coord.x1, coord.y1, coord.x2, coord.y2, draw)
82
- end
83
-
84
- # :nodoc:
85
- # @api private
86
- def line_xy(x1, y1, x2, y2, draw)
87
- use_cairo do |cc|
88
- cc.move_to(x1, y1)
89
- cc.line_to(x2, y2)
90
- cc.fancy_stroke(draw)
91
- end
92
- end
93
-
94
- # :nodoc:
95
- # @api private
96
- def curve(bez, draw)
97
- x1, y1, cx1, cy1 = bez.x1, bez.y1, bez.cx1, bez.cy1
98
- cx2, cy2, x2, y2 = bez.cx2, bez.cy2, bez.x2, bez.y2
99
- use_cairo do |cc|
100
- cc.move_to(x1, y1)
101
- cc.curve_to(cx1, cy1, cx2, cy2, x2, y2)
102
- cc.fill_n_stroke(draw)
103
- end
104
- end
105
-
106
- # :nodoc:
107
- # @api private
108
- def star(poly, trans, draw)
109
- x, y, n = poly.x, poly.y, poly.n
110
- inner_radius, outer_radius = poly.inner_radius, poly.outer_radius
111
- use_cairo do |cc|
112
- cc.rotate_about(x, y, trans.angle)
113
- cc.move_to(x + outer_radius, y) # i = 0, so cos(0)=1 and sin(0)=0
114
- theta = Math::PI / n.to_f # i.e. (2*pi) / (2*n)
115
- 0.upto(2 * n) do |i|
116
- radius = i.even? ? outer_radius : inner_radius
117
- cc.line_to(x + radius * Math::cos(i * theta),
118
- y + radius * Math::sin(i * theta))
119
- end
120
- cc.close_path
121
- cc.fill_n_stroke(draw)
122
- end
123
- end
124
-
125
- # :nodoc:
126
- # @api private
127
- def polygon(poly, trans, draw)
128
- x, y, n, radius = poly.x, poly.y, poly.n, poly.radius
129
- use_cairo do |cc|
130
- cc.rotate_about(x, y, trans.angle)
131
- cc.move_to(x + radius, y) # i = 0, so cos(0)=1 and sin(0)=0
132
- theta = (2 * Math::PI) / n.to_f
133
- 0.upto(n) do |i|
134
- cc.line_to(x + radius * Math::cos(i * theta),
135
- y + radius * Math::sin(i * theta))
136
- end
137
- cc.close_path
138
- cc.fill_n_stroke(draw)
139
- end
140
- end
141
-
142
- end
143
- end
1
+ module Squib
2
+ # @api private
3
+ class Card
4
+
5
+ # :nodoc:
6
+ # @api private
7
+ def rect(box, draw, trans)
8
+ use_cairo do |cc|
9
+ cc.rotate_about(box.x, box.y, trans.angle)
10
+ cc.rounded_rectangle(box.x, box.y, box.width, box.height,
11
+ box.x_radius, box.y_radius)
12
+ cc.fill_n_stroke(draw)
13
+ end
14
+ end
15
+
16
+ # :nodoc:
17
+ # @api private
18
+ def circle(box, draw)
19
+ x, y, r = box.x, box.y, box.radius
20
+ use_cairo do |cc|
21
+ if box.arc_direction == :clockwise
22
+ cc.arc(x, y, r, box.arc_start, box.arc_end)
23
+ else
24
+ cc.arc_negative(x, y, r, box.arc_start, box.arc_end)
25
+ end
26
+ if box.arc_close
27
+ cc.close_path();
28
+ end
29
+ cc.fill_n_stroke(draw)
30
+ end
31
+ end
32
+
33
+ # Ellipse drawing taken from looking at the control points in Inkscape
34
+ # Think of it like a rectangle. Curves go from mid-points of the sides
35
+ # of the rectangle. Control points are at 1/4 and 3/4 of the side.
36
+ # :nodoc:
37
+ # @api private
38
+ def ellipse(box, draw, trans)
39
+ x, y, w, h = box.x, box.y, box.width, box.height
40
+ use_cairo do |cc|
41
+ cc.rotate_about(box.x, box.y, trans.angle)
42
+ cc.move_to(x, y + 0.5 * h) # start west
43
+ cc.curve_to(x, y + 0.25 * h, # west to north
44
+ x + 0.25 * w, y,
45
+ x + 0.5 * w, y)
46
+ cc.curve_to(x + 0.75 * w, y, # north to east
47
+ x + w, y + 0.25 * h,
48
+ x + w, y + 0.5 * h)
49
+ cc.curve_to(x + w, y + 0.75 * h, # east to south
50
+ x + 0.75 * w, y + h,
51
+ x + 0.5 * w, y + h)
52
+ cc.curve_to(x + 0.25 * w, y + h, # south to west
53
+ x, y + 0.75 * h,
54
+ x, y + 0.5 * h)
55
+ cc.fill_n_stroke(draw)
56
+ end
57
+ end
58
+
59
+ # :nodoc:
60
+ # @api private
61
+ def grid(box, draw)
62
+ x, y, w, h = box.x, box.y, box.width, box.height
63
+ use_cairo do |cc|
64
+ (x..@width + w).step(w) { |ix| line_xy(ix, y - @height, ix, @height + y, draw) }
65
+ (y..@height + h).step(h) { |iy| line_xy(x - @width, iy, @width + x, iy, draw) }
66
+ end
67
+ end
68
+
69
+ # :nodoc:
70
+ # @api private
71
+ def triangle(tri, draw)
72
+ use_cairo do |cc|
73
+ cc.triangle(tri.x1, tri.y1, tri.x2, tri.y2, tri.x3, tri.y3)
74
+ cc.fill_n_stroke(draw)
75
+ end
76
+ end
77
+
78
+ # :nodoc:
79
+ # @api private
80
+ def line(coord, draw)
81
+ line_xy(coord.x1, coord.y1, coord.x2, coord.y2, draw)
82
+ end
83
+
84
+ # :nodoc:
85
+ # @api private
86
+ def line_xy(x1, y1, x2, y2, draw)
87
+ use_cairo do |cc|
88
+ cc.move_to(x1, y1)
89
+ cc.line_to(x2, y2)
90
+ cc.fancy_stroke(draw)
91
+ end
92
+ end
93
+
94
+ # :nodoc:
95
+ # @api private
96
+ def curve(bez, draw)
97
+ x1, y1, cx1, cy1 = bez.x1, bez.y1, bez.cx1, bez.cy1
98
+ cx2, cy2, x2, y2 = bez.cx2, bez.cy2, bez.x2, bez.y2
99
+ use_cairo do |cc|
100
+ cc.move_to(x1, y1)
101
+ cc.curve_to(cx1, cy1, cx2, cy2, x2, y2)
102
+ cc.fill_n_stroke(draw)
103
+ end
104
+ end
105
+
106
+ # :nodoc:
107
+ # @api private
108
+ def star(poly, trans, draw)
109
+ x, y, n = poly.x, poly.y, poly.n
110
+ inner_radius, outer_radius = poly.inner_radius, poly.outer_radius
111
+ use_cairo do |cc|
112
+ cc.rotate_about(x, y, trans.angle)
113
+ cc.move_to(x + outer_radius, y) # i = 0, so cos(0)=1 and sin(0)=0
114
+ theta = Math::PI / n.to_f # i.e. (2*pi) / (2*n)
115
+ 0.upto(2 * n) do |i|
116
+ radius = i.even? ? outer_radius : inner_radius
117
+ cc.line_to(x + radius * Math::cos(i * theta),
118
+ y + radius * Math::sin(i * theta))
119
+ end
120
+ cc.close_path
121
+ cc.fill_n_stroke(draw)
122
+ end
123
+ end
124
+
125
+ # :nodoc:
126
+ # @api private
127
+ def polygon(poly, trans, draw)
128
+ x, y, n, radius = poly.x, poly.y, poly.n, poly.radius
129
+ use_cairo do |cc|
130
+ cc.rotate_about(x, y, trans.angle)
131
+ cc.move_to(x + radius, y) # i = 0, so cos(0)=1 and sin(0)=0
132
+ theta = (2 * Math::PI) / n.to_f
133
+ 0.upto(n) do |i|
134
+ cc.line_to(x + radius * Math::cos(i * theta),
135
+ y + radius * Math::sin(i * theta))
136
+ end
137
+ cc.close_path
138
+ cc.fill_n_stroke(draw)
139
+ end
140
+ end
141
+
142
+ end
143
+ end
@@ -1,85 +1,85 @@
1
- require_relative 'cairo_context_wrapper'
2
-
3
- module Squib
4
- class Deck
5
-
6
- # So the Cairo people have said over and over again that they won't support the 3x3 matrices that would handle perspective transforms.
7
- # Since our perspective transform needs are a bit simpler, we can use a "striping method" that does the job for us.
8
- # It's a little bit involved, but it works well enough for limited ranges of our parameters.
9
- # These were also helpful:
10
- # http://kapo-cpp.blogspot.com/2008/01/perspective-effect-using-cairo.html
11
- # http://zetcode.com/gui/pygtk/drawingII/
12
- # :nodoc:
13
- # @api private
14
- def render_showcase(range, sheet, showcase)
15
- out_width = range.size * ((@width - 2 * sheet.trim) * showcase.scale * showcase.offset) + 2 * sheet.margin
16
- out_height = showcase.reflect_offset + (1.0 + showcase.reflect_percent) * (@height - 2 * sheet.trim) + 2 * sheet.margin
17
- out_cc = Cairo::Context.new(Cairo::ImageSurface.new(out_width, out_height))
18
- wrapper = Squib::Graphics::CairoContextWrapper.new(out_cc)
19
- wrapper.set_source_squibcolor(sheet.fill_color)
20
- wrapper.paint
21
-
22
- cards = range.collect { |i| @cards[i] }
23
- cards.each_with_index do |card, i|
24
- trimmed = trim_rounded(card.cairo_surface, showcase.trim, showcase.trim_radius)
25
- reflected = reflect(trimmed, showcase.reflect_offset, showcase.reflect_percent, showcase.reflect_strength)
26
- perspectived = perspective(reflected, showcase.scale, showcase.face_right?)
27
- out_cc.set_source(perspectived, sheet.margin + i * perspectived.width * showcase.offset, sheet.margin)
28
- out_cc.paint
29
- end
30
- out_cc.target.write_to_png("#{sheet.dir}/#{sheet.file}")
31
- end
32
-
33
- # :nodoc:
34
- # @api private
35
- def trim_rounded(src, trim, radius)
36
- trim_cc = Cairo::Context.new(Cairo::ImageSurface.new(@width - 2.0 * trim, @height - 2.0 * trim))
37
- trim_cc.rounded_rectangle(0, 0, trim_cc.target.width, trim_cc.target.height, radius, radius)
38
- trim_cc.set_source(src, -1 * trim, -1 * trim)
39
- trim_cc.clip
40
- trim_cc.paint
41
- return trim_cc.target
42
- end
43
-
44
- # :nodoc:
45
- # @api private
46
- def reflect(src, roffset, rpercent, rstrength)
47
- tmp_cc = Cairo::Context.new(Cairo::ImageSurface.new(src.width, src.height * (1.0 + rpercent) + roffset))
48
- tmp_cc.set_source(src, 0, 0)
49
- tmp_cc.paint
50
- # Flip affine magic from: http://cairographics.org/matrix_transform/
51
- matrix = Cairo::Matrix.new(1, 0, 0, -1, 0, 2 * src.height + roffset)
52
- tmp_cc.transform(matrix) # flips the coordinate system
53
- top_y = src.height # top of the reflection
54
- bottom_y = src.height * (1.0 - rpercent) + roffset # bottom of the reflection
55
- gradient = Cairo::LinearPattern.new(0, top_y, 0, bottom_y)
56
- gradient.add_color_stop_rgba(0.0, 0, 0, 0, rstrength) # start a little reflected
57
- gradient.add_color_stop_rgba(1.0, 0, 0, 0, 0.0) # fade to nothing
58
- tmp_cc.set_source(src, 0, 0)
59
- tmp_cc.mask(gradient)
60
- return tmp_cc.target
61
- end
62
-
63
- # :nodoc:
64
- # @api private
65
- def perspective(src, scale, face_right)
66
- dest_cxt = Cairo::Context.new(Cairo::ImageSurface.new(src.width * scale, src.height))
67
- in_thickness = 1 # Take strip 1 pixel-width at a time
68
- out_thickness = 3 # Scale it to 3 pixels wider to cover any gaps
69
- (0..src.width).step(in_thickness) do |i|
70
- percentage = i / src.width.to_f
71
- i = src.width - i if face_right
72
- factor = scale + (percentage * (1.0 - scale)) # linear interpolation
73
- dest_cxt.save
74
- dest_cxt.translate 0, src.height / 2.0 * (1.0 - factor)
75
- dest_cxt.scale factor * scale, factor
76
- dest_cxt.set_source src, 0, 0
77
- dest_cxt.rounded_rectangle i, 0, out_thickness, src.height, 0, 0
78
- dest_cxt.fill
79
- dest_cxt.restore
80
- end
81
- return dest_cxt.target
82
- end
83
-
84
- end
85
- end
1
+ require_relative 'cairo_context_wrapper'
2
+
3
+ module Squib
4
+ class Deck
5
+
6
+ # So the Cairo people have said over and over again that they won't support the 3x3 matrices that would handle perspective transforms.
7
+ # Since our perspective transform needs are a bit simpler, we can use a "striping method" that does the job for us.
8
+ # It's a little bit involved, but it works well enough for limited ranges of our parameters.
9
+ # These were also helpful:
10
+ # http://kapo-cpp.blogspot.com/2008/01/perspective-effect-using-cairo.html
11
+ # http://zetcode.com/gui/pygtk/drawingII/
12
+ # :nodoc:
13
+ # @api private
14
+ def render_showcase(range, sheet, showcase)
15
+ out_width = range.size * ((@width - 2 * sheet.trim) * showcase.scale * showcase.offset) + 2 * sheet.margin
16
+ out_height = showcase.reflect_offset + (1.0 + showcase.reflect_percent) * (@height - 2 * sheet.trim) + 2 * sheet.margin
17
+ out_cc = Cairo::Context.new(Cairo::ImageSurface.new(out_width, out_height))
18
+ wrapper = Squib::Graphics::CairoContextWrapper.new(out_cc)
19
+ wrapper.set_source_squibcolor(sheet.fill_color)
20
+ wrapper.paint
21
+
22
+ cards = range.collect { |i| @cards[i] }
23
+ cards.each_with_index do |card, i|
24
+ trimmed = trim_rounded(card.cairo_surface, showcase.trim, showcase.trim_radius)
25
+ reflected = reflect(trimmed, showcase.reflect_offset, showcase.reflect_percent, showcase.reflect_strength)
26
+ perspectived = perspective(reflected, showcase.scale, showcase.face_right?)
27
+ out_cc.set_source(perspectived, sheet.margin + i * perspectived.width * showcase.offset, sheet.margin)
28
+ out_cc.paint
29
+ end
30
+ out_cc.target.write_to_png("#{sheet.dir}/#{sheet.file}")
31
+ end
32
+
33
+ # :nodoc:
34
+ # @api private
35
+ def trim_rounded(src, trim, radius)
36
+ trim_cc = Cairo::Context.new(Cairo::ImageSurface.new(@width - 2.0 * trim, @height - 2.0 * trim))
37
+ trim_cc.rounded_rectangle(0, 0, trim_cc.target.width, trim_cc.target.height, radius, radius)
38
+ trim_cc.set_source(src, -1 * trim, -1 * trim)
39
+ trim_cc.clip
40
+ trim_cc.paint
41
+ return trim_cc.target
42
+ end
43
+
44
+ # :nodoc:
45
+ # @api private
46
+ def reflect(src, roffset, rpercent, rstrength)
47
+ tmp_cc = Cairo::Context.new(Cairo::ImageSurface.new(src.width, src.height * (1.0 + rpercent) + roffset))
48
+ tmp_cc.set_source(src, 0, 0)
49
+ tmp_cc.paint
50
+ # Flip affine magic from: http://cairographics.org/matrix_transform/
51
+ matrix = Cairo::Matrix.new(1, 0, 0, -1, 0, 2 * src.height + roffset)
52
+ tmp_cc.transform(matrix) # flips the coordinate system
53
+ top_y = src.height # top of the reflection
54
+ bottom_y = src.height * (1.0 - rpercent) + roffset # bottom of the reflection
55
+ gradient = Cairo::LinearPattern.new(0, top_y, 0, bottom_y)
56
+ gradient.add_color_stop_rgba(0.0, 0, 0, 0, rstrength) # start a little reflected
57
+ gradient.add_color_stop_rgba(1.0, 0, 0, 0, 0.0) # fade to nothing
58
+ tmp_cc.set_source(src, 0, 0)
59
+ tmp_cc.mask(gradient)
60
+ return tmp_cc.target
61
+ end
62
+
63
+ # :nodoc:
64
+ # @api private
65
+ def perspective(src, scale, face_right)
66
+ dest_cxt = Cairo::Context.new(Cairo::ImageSurface.new(src.width * scale, src.height))
67
+ in_thickness = 1 # Take strip 1 pixel-width at a time
68
+ out_thickness = 3 # Scale it to 3 pixels wider to cover any gaps
69
+ (0..src.width).step(in_thickness) do |i|
70
+ percentage = i / src.width.to_f
71
+ i = src.width - i if face_right
72
+ factor = scale + (percentage * (1.0 - scale)) # linear interpolation
73
+ dest_cxt.save
74
+ dest_cxt.translate 0, src.height / 2.0 * (1.0 - factor)
75
+ dest_cxt.scale factor * scale, factor
76
+ dest_cxt.set_source src, 0, 0
77
+ dest_cxt.rounded_rectangle i, 0, out_thickness, src.height, 0, 0
78
+ dest_cxt.fill
79
+ dest_cxt.restore
80
+ end
81
+ return dest_cxt.target
82
+ end
83
+
84
+ end
85
+ end