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