squib 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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
+