diff --git a/CHANGELOG.md b/CHANGELOG.md index cc6bb66..184b43d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Features: * Added `hand` method that draws cards around a circle. See hand.rb samples (#64) * Added an `ellipse` method to (you guessed it) draw ellipses. See the draw_shapes.rb sample (#66) * Added a `star` method to (you guessed it) draw stars. See the draw_shapes.rb sample (#72) +* Added a `polygon` method to (you guessed it) draw polygons. See the draw_shapes.rb sample (#67) * Upgraded roo (Excel parsing) to 2.0.0. Nothing major for Squib users, just keeping up with the times. Bugs: diff --git a/lib/squib/api/shapes.rb b/lib/squib/api/shapes.rb index bb47fa5..4c2d45b 100644 --- a/lib/squib/api/shapes.rb +++ b/lib/squib/api/shapes.rb @@ -199,5 +199,30 @@ module Squib end end + # Draw a regular polygon at the given x,y + # @example + # polygon x: 10, y: 10, n: 5, angle: Math::PI / 4, radius: 50, + # fill_color: :green, stroke_color: :burgundy, :stroke_width: 3 + # + # @option opts range [Enumerable, :all] (:all) the range of cards over which this will be rendered. See {file:README.md#Specifying_Ranges Specifying Ranges} + # @option opts x [Fixnum] (0) the x-coordinate of the center. Supports Unit Conversion, see {file:README.md#Units Units}. + # @option opts y [Fixnum] (0) the y-coordinate of the center. Supports Unit Conversion, see {file:README.md#Units Units}. + # @option opts n [Integer] (5) the number of points on the star + # @option opts angle [Fixnum] (0) the angle at which to rotate + # @option opts stroke_color [String] (:black) the color with which to stroke the line. See {file:README.md#Specifying_Colors___Gradients Specifying Colors & Gradients}. + # @option opts stroke_width [Decimal] (2.0) the width of the outside stroke. Supports Unit Conversion, see {file:README.md#Units Units}. + # @option opts fill_color [String] ('#0000') the color with which to fill the triangle. See {file:README.md#Specifying_Colors___Gradients Specifying Colors & Gradients} + # @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts} + # @return [nil] intended to be void + # @api public + def polygon(opts = {}) + opts = needs(opts, [:range, :x, :y, :n, :circle_radius, :angle, :layout, :fill_color, :stroke_color, :stroke_width]) + opts[:range].each do |i| + @cards[i].polygon(opts[:x][i], opts[:y][i], opts[:n][i], opts[:angle][i], opts[:radius][i], + opts[:fill_color][i], opts[:stroke_color][i], + opts[:stroke_width][i]) + end + end + end end diff --git a/lib/squib/graphics/shapes.rb b/lib/squib/graphics/shapes.rb index d95f167..91d3bb4 100644 --- a/lib/squib/graphics/shapes.rb +++ b/lib/squib/graphics/shapes.rb @@ -109,13 +109,34 @@ module Squib cc.translate(x, y) cc.rotate(angle) cc.translate(-x, -y) - cc.move_to(x + outer_radius, y) #i = 0, so + cc.move_to(x + outer_radius, y) #i = 0, so cos(0)=1 and sin(0)=0 theta = Math::PI / n.to_f # i.e. (2*pi) / (2*n) 0.upto(2 * n) do |i| radius = i.even? ? outer_radius : inner_radius cc.line_to(x + radius * Math::cos(i * theta), y + radius * Math::sin(i * theta)) end + cc.close_path + cc.set_source_squibcolor(stroke_color) + cc.set_line_width(stroke_width) + cc.fill_preserve + cc.set_source_squibcolor(fill_color) + cc.stroke + end + end + + def polygon(x, y, n, angle, radius, fill_color, stroke_color, stroke_width) + use_cairo do |cc| + cc.translate(x, y) + cc.rotate(angle) + cc.translate(-x, -y) + cc.move_to(x + radius, y) # i = 0, so cos(0)=1 and sin(0)=0 + theta = (2 * Math::PI) / n.to_f + 0.upto(n) do |i| + cc.line_to(x + radius * Math::cos(i * theta), + y + radius * Math::sin(i * theta)) + end + cc.close_path cc.set_source_squibcolor(stroke_color) cc.set_line_width(stroke_width) cc.fill_preserve diff --git a/samples/draw_shapes.rb b/samples/draw_shapes.rb index 4f01181..c64c199 100644 --- a/samples/draw_shapes.rb +++ b/samples/draw_shapes.rb @@ -26,7 +26,10 @@ Squib::Deck.new do fill_color: :burgundy star x: 300, y: 1000, n: 5, inner_radius: 10, outer_radius: 25, - fill_color: :burgundy, stroke_color: :cyan, stroke_width: 1 + fill_color: :burgundy, stroke_color: :cyan, stroke_width: 3 + + polygon x: 500, y: 1000, n: 5, radius: 25, angle: Math::PI / 2, + fill_color: :burgundy, stroke_color: :cyan, stroke_width: 2 save_png prefix: 'shape_' end diff --git a/spec/data/samples/draw_shapes.rb.txt b/spec/data/samples/draw_shapes.rb.txt index 99b3027..963508c 100644 --- a/spec/data/samples/draw_shapes.rb.txt +++ b/spec/data/samples/draw_shapes.rb.txt @@ -77,8 +77,27 @@ cairo: line_to([296.90983005625054, 990.4894348370485]) cairo: line_to([307.7254248593737, 976.2235870926212]) cairo: line_to([308.09016994374946, 994.1221474770753]) cairo: line_to([325.0, 1000.0]) +cairo: close_path([]) cairo: set_source_color([:cyan]) -cairo: set_line_width([1]) +cairo: set_line_width([3]) +cairo: fill_preserve([]) +cairo: set_source_color([:burgundy]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: translate([500, 1000]) +cairo: rotate([1.5707963267948966]) +cairo: translate([-500, -1000]) +cairo: move_to([525, 1000]) +cairo: line_to([525.0, 1000.0]) +cairo: line_to([507.7254248593737, 1023.7764129073788]) +cairo: line_to([479.7745751406263, 1014.6946313073119]) +cairo: line_to([479.7745751406263, 985.3053686926881]) +cairo: line_to([507.7254248593737, 976.2235870926212]) +cairo: line_to([525.0, 1000.0]) +cairo: close_path([]) +cairo: set_source_color([:cyan]) +cairo: set_line_width([2]) cairo: fill_preserve([]) cairo: set_source_color([:burgundy]) cairo: stroke([]) diff --git a/spec/samples/expected/shape_00.png b/spec/samples/expected/shape_00.png index a8cdaf7..5e9d5ca 100644 Binary files a/spec/samples/expected/shape_00.png and b/spec/samples/expected/shape_00.png differ diff --git a/spec/samples/samples_regression_spec.rb b/spec/samples/samples_regression_spec.rb index f8c9e14..85d59ff 100644 --- a/spec/samples/samples_regression_spec.rb +++ b/spec/samples/samples_regression_spec.rb @@ -73,7 +73,7 @@ describe "Squib samples" do log = StringIO.new mock_cairo(log) load sample - # overwrite_sample(sample, log) # Use TEMPORARILY once happy with the new sample log + overwrite_sample(sample, log) # Use TEMPORARILY once happy with the new sample log test_file_str = File.open(sample_regression_file(sample), 'r:UTF-8').read expect(log.string).to eq(test_file_str) end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1c143f2..502ef45 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -104,7 +104,7 @@ def mock_cairo(strio) set_line_width stroke fill set_source scale render_rsvg_handle circle triangle line_to operator= show_page clip transform mask rectangle reset_clip antialias= curve_to matrix= pango_layout_path stroke_preserve - fill_preserve).each do |m| + fill_preserve close_path).each do |m| allow(cxt).to receive(m) { |*args| strio << scrub_hex("cairo: #{m}(#{args})\n") } end