chunky_png 1.3.7 → 1.3.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.standard.yml +16 -0
  3. data/.travis.yml +8 -6
  4. data/.yardopts +1 -1
  5. data/CHANGELOG.rdoc +17 -1
  6. data/CONTRIBUTING.rdoc +17 -8
  7. data/Gemfile +3 -3
  8. data/LICENSE +1 -1
  9. data/README.md +6 -1
  10. data/Rakefile +3 -3
  11. data/benchmarks/decoding_benchmark.rb +17 -17
  12. data/benchmarks/encoding_benchmark.rb +22 -19
  13. data/benchmarks/filesize_benchmark.rb +6 -6
  14. data/bin/rake +29 -0
  15. data/bin/standardrb +29 -0
  16. data/chunky_png.gemspec +19 -15
  17. data/lib/chunky_png.rb +49 -39
  18. data/lib/chunky_png/canvas.rb +28 -27
  19. data/lib/chunky_png/canvas/adam7_interlacing.rb +14 -10
  20. data/lib/chunky_png/canvas/data_url_exporting.rb +1 -3
  21. data/lib/chunky_png/canvas/data_url_importing.rb +1 -3
  22. data/lib/chunky_png/canvas/drawing.rb +28 -43
  23. data/lib/chunky_png/canvas/masking.rb +12 -14
  24. data/lib/chunky_png/canvas/operations.rb +26 -24
  25. data/lib/chunky_png/canvas/png_decoding.rb +36 -32
  26. data/lib/chunky_png/canvas/png_encoding.rb +106 -100
  27. data/lib/chunky_png/canvas/resampling.rb +26 -33
  28. data/lib/chunky_png/canvas/stream_exporting.rb +6 -8
  29. data/lib/chunky_png/canvas/stream_importing.rb +6 -8
  30. data/lib/chunky_png/chunk.rb +141 -52
  31. data/lib/chunky_png/color.rb +211 -206
  32. data/lib/chunky_png/datastream.rb +27 -23
  33. data/lib/chunky_png/dimension.rb +16 -11
  34. data/lib/chunky_png/image.rb +9 -11
  35. data/lib/chunky_png/palette.rb +4 -9
  36. data/lib/chunky_png/point.rb +25 -26
  37. data/lib/chunky_png/rmagick.rb +8 -10
  38. data/lib/chunky_png/vector.rb +26 -29
  39. data/lib/chunky_png/version.rb +1 -1
  40. data/spec/chunky_png/canvas/adam7_interlacing_spec.rb +20 -21
  41. data/spec/chunky_png/canvas/data_url_exporting_spec.rb +8 -5
  42. data/spec/chunky_png/canvas/data_url_importing_spec.rb +5 -6
  43. data/spec/chunky_png/canvas/drawing_spec.rb +46 -38
  44. data/spec/chunky_png/canvas/masking_spec.rb +15 -16
  45. data/spec/chunky_png/canvas/operations_spec.rb +68 -67
  46. data/spec/chunky_png/canvas/png_decoding_spec.rb +37 -38
  47. data/spec/chunky_png/canvas/png_encoding_spec.rb +59 -50
  48. data/spec/chunky_png/canvas/resampling_spec.rb +19 -21
  49. data/spec/chunky_png/canvas/stream_exporting_spec.rb +47 -27
  50. data/spec/chunky_png/canvas/stream_importing_spec.rb +10 -11
  51. data/spec/chunky_png/canvas_spec.rb +57 -52
  52. data/spec/chunky_png/color_spec.rb +115 -114
  53. data/spec/chunky_png/datastream_spec.rb +110 -13
  54. data/spec/chunky_png/dimension_spec.rb +10 -10
  55. data/spec/chunky_png/image_spec.rb +11 -14
  56. data/spec/chunky_png/point_spec.rb +21 -23
  57. data/spec/chunky_png/rmagick_spec.rb +7 -8
  58. data/spec/chunky_png/vector_spec.rb +21 -17
  59. data/spec/chunky_png_spec.rb +2 -2
  60. data/spec/png_suite_spec.rb +35 -40
  61. data/spec/resources/itxt_chunk.png +0 -0
  62. data/spec/spec_helper.rb +15 -9
  63. data/tasks/benchmarks.rake +7 -8
  64. metadata +53 -20
  65. data/lib/chunky_png/compatibility.rb +0 -15
@@ -1,33 +1,31 @@
1
- require 'rmagick'
1
+ require "rmagick"
2
2
 
3
3
  module ChunkyPNG
4
-
5
4
  # Methods for importing and exporting RMagick image objects.
6
5
  #
7
6
  # By default, this module is disabled because of the dependency on RMagick.
8
- # You need to include this module yourself if you want to use it.
7
+ # You need to include this module yourself if you want to use it.
9
8
  #
10
9
  # @example
11
10
  #
12
11
  # require 'rmagick'
13
12
  # require 'chunky_png/rmagick'
14
- #
13
+ #
15
14
  # canvas = ChunkyPNG::Canvas.from_file('filename.png')
16
15
  # image = ChunkyPNG::RMagick.export(canvas)
17
- #
16
+ #
18
17
  # # do something with the image using RMagick
19
- #
18
+ #
20
19
  # updated_canvas = ChunkyPNG::RMagick.import(image)
21
20
  #
22
21
  module RMagick
23
-
24
22
  extend self
25
-
23
+
26
24
  # Imports an RMagick image as Canvas object.
27
25
  # @param [Magick::Image] image The image to import
28
26
  # @return [ChunkyPNG::Canvas] The canvas, constructed from the RMagick image.
29
27
  def import(image)
30
- pixels = image.export_pixels_to_str(0, 0, image.columns, image.rows, 'RGBA')
28
+ pixels = image.export_pixels_to_str(0, 0, image.columns, image.rows, "RGBA")
31
29
  ChunkyPNG::Canvas.from_rgba_stream(image.columns, image.rows, pixels)
32
30
  end
33
31
 
@@ -36,7 +34,7 @@ module ChunkyPNG
36
34
  # @return [Magick::Image] The RMagick image constructed from the Canvas instance.
37
35
  def export(canvas)
38
36
  image = Magick::Image.new(canvas.width, canvas.height)
39
- image.import_pixels(0,0, canvas.width, canvas.height, 'RGBA', canvas.pixels.pack('N*'))
37
+ image.import_pixels(0, 0, canvas.width, canvas.height, "RGBA", canvas.pixels.pack("N*"))
40
38
  image
41
39
  end
42
40
  end
@@ -1,9 +1,8 @@
1
1
  module ChunkyPNG
2
-
3
2
  # Factory method for {ChunkyPNG::Vector} instances.
4
3
  #
5
4
  # @overload Vector(x0, y0, x1, y1, x2, y2, ...)
6
- # Creates a vector by parsing two subsequent values in the argument list
5
+ # Creates a vector by parsing two subsequent values in the argument list
7
6
  # as x- and y-coordinate of a point.
8
7
  # @return [ChunkyPNG::Vector] The instantiated vector.
9
8
  # @overload Vector(string)
@@ -17,27 +16,25 @@ module ChunkyPNG
17
16
  # @raise [ArgumentError] If the given arguments could not be understood as a vector.
18
17
  # @see ChunkyPNG::Vector
19
18
  def self.Vector(*args)
20
-
21
- return args.first if args.length == 1 && args.first.kind_of?(ChunkyPNG::Vector)
22
-
19
+ return args.first if args.length == 1 && args.first.is_a?(ChunkyPNG::Vector)
20
+
23
21
  if args.length == 1 && args.first.respond_to?(:scan)
24
22
  ChunkyPNG::Vector.new(ChunkyPNG::Vector.multiple_from_string(args.first)) # e.g. ['1,1 2,2 3,3']
25
23
  else
26
24
  ChunkyPNG::Vector.new(ChunkyPNG::Vector.multiple_from_array(args)) # e.g. [[1,1], [2,2], [3,3]] or [1,1,2,2,3,3]
27
25
  end
28
26
  end
29
-
27
+
30
28
  # Class that represents a vector of points, i.e. a list of {ChunkyPNG::Point} instances.
31
29
  #
32
- # Vectors can be created quite flexibly. See the {ChunkyPNG.Vector} factory methods for
30
+ # Vectors can be created quite flexibly. See the {ChunkyPNG.Vector} factory methods for
33
31
  # more information on how to construct vectors.
34
32
  class Vector
35
-
36
33
  include Enumerable
37
-
34
+
38
35
  # @return [Array<ChunkyPNG::Point>] The array that holds all the points in this vector.
39
36
  attr_reader :points
40
-
37
+
41
38
  # Initializes a vector based on a list of Point instances.
42
39
  #
43
40
  # You usually do not want to use this method directly, but call {ChunkyPNG.Vector} instead.
@@ -47,7 +44,7 @@ module ChunkyPNG
47
44
  def initialize(points = [])
48
45
  @points = points
49
46
  end
50
-
47
+
51
48
  # Iterates over all the edges in this vector.
52
49
  #
53
50
  # An edge is a combination of two subsequent points in the vector. Together, they will form
@@ -63,14 +60,14 @@ module ChunkyPNG
63
60
  points.each_cons(2) { |a, b| yield(a, b) }
64
61
  yield(points.last, points.first) if close
65
62
  end
66
-
63
+
67
64
  # Returns the point with the given indexof this vector.
68
65
  # @param [Integer] index The 0-based index of the point in this vector.
69
- # @param [ChunkyPNG::Point] The point instance.
66
+ # @return [ChunkyPNG::Point] The point instance.
70
67
  def [](index)
71
68
  points[index]
72
69
  end
73
-
70
+
74
71
  # Returns an enumerator that will iterate over all the edges in this vector.
75
72
  # @param (see #each_edge)
76
73
  # @return [Enumerator] The enumerator that iterates over the edges.
@@ -79,28 +76,28 @@ module ChunkyPNG
79
76
  def edges(close = true)
80
77
  to_enum(:each_edge, close)
81
78
  end
82
-
79
+
83
80
  # Returns the number of points in this vector.
84
81
  # @return [Integer] The length of the points array.
85
82
  def length
86
83
  points.length
87
84
  end
88
-
85
+
89
86
  # Iterates over all the points in this vector
90
87
  # @yield [ChunkyPNG::Point] The points in the correct order.
91
88
  # @return [void]
92
89
  def each(&block)
93
90
  points.each(&block)
94
91
  end
95
-
92
+
96
93
  # Comparison between two vectors for quality.
97
94
  # @param [ChunkyPNG::Vector] other The vector to compare with.
98
95
  # @return [true, false] true if the list of points are identical
99
96
  def eql?(other)
100
97
  other.points == points
101
98
  end
102
-
103
- alias_method :==, :eql?
99
+
100
+ alias == eql?
104
101
 
105
102
  # Returns the range in x-coordinates for all the points in this vector.
106
103
  # @return [Range] The (inclusive) range of x-coordinates.
@@ -113,13 +110,13 @@ module ChunkyPNG
113
110
  def y_range
114
111
  Range.new(*points.map { |p| p.y }.minmax)
115
112
  end
116
-
113
+
117
114
  # Finds the lowest x-coordinate in this vector.
118
115
  # @return [Integer] The lowest x-coordinate of all the points in the vector.
119
116
  def min_x
120
117
  x_range.first
121
118
  end
122
-
119
+
123
120
  # Finds the highest x-coordinate in this vector.
124
121
  # @return [Integer] The highest x-coordinate of all the points in the vector.
125
122
  def max_x
@@ -131,13 +128,13 @@ module ChunkyPNG
131
128
  def min_y
132
129
  y_range.first
133
130
  end
134
-
131
+
135
132
  # Finds the highest y-coordinate in this vector.
136
133
  # @return [Integer] The highest y-coordinate of all the points in the vector.
137
134
  def max_y
138
135
  y_range.last
139
136
  end
140
-
137
+
141
138
  # Returns the offset from (0,0) of the minimal bounding box of all the
142
139
  # points in this vector
143
140
  # @return [ChunkyPNG::Point] A point that describes the top left corner if a
@@ -145,7 +142,7 @@ module ChunkyPNG
145
142
  def offset
146
143
  ChunkyPNG::Point.new(min_x, min_y)
147
144
  end
148
-
145
+
149
146
  # Returns the width of the minimal bounding box of all the points in this vector.
150
147
  # @return [Integer] The x-distance between the points that are farthest from each other.
151
148
  def width
@@ -157,17 +154,17 @@ module ChunkyPNG
157
154
  def height
158
155
  1 + (max_y - min_y)
159
156
  end
160
-
157
+
161
158
  # Returns the dimension of the minimal bounding rectangle of the points in this vector.
162
- # @return [ChunkyPNG::Dimension] The dimension instance with the width and height
159
+ # @return [ChunkyPNG::Dimension] The dimension instance with the width and height
163
160
  def dimension
164
161
  ChunkyPNG::Dimension.new(width, height)
165
162
  end
166
-
163
+
167
164
  # @return [Array<ChunkyPNG::Point>] The list of points interpreted from the input array.
168
165
  def self.multiple_from_array(source)
169
166
  return [] if source.empty?
170
- if source.first.kind_of?(Numeric) || source.first =~ /^\d+$/
167
+ if source.first.is_a?(Numeric) || source.first =~ /^\d+$/
171
168
  raise ArgumentError, "The points array is expected to have an even number of items!" if source.length % 2 != 0
172
169
 
173
170
  points = []
@@ -177,7 +174,7 @@ module ChunkyPNG
177
174
  source.map { |p| ChunkyPNG::Point(p) }
178
175
  end
179
176
  end
180
-
177
+
181
178
  # @return [Array<ChunkyPNG::Point>] The list of points parsed from the string.
182
179
  def self.multiple_from_string(source_str)
183
180
  multiple_from_array(source_str.scan(/[\(\[\{]?(\d+)\s*[,x]?\s*(\d+)[\)\]\}]?/))
@@ -1,5 +1,5 @@
1
1
  module ChunkyPNG
2
2
  # The current version of ChunkyPNG.
3
3
  # Set it and commit the change this before running rake release.
4
- VERSION = "1.3.7"
4
+ VERSION = "1.3.12"
5
5
  end
@@ -1,48 +1,48 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe ChunkyPNG::Canvas::Adam7Interlacing do
4
4
  include ChunkyPNG::Canvas::Adam7Interlacing
5
5
 
6
- describe '#adam7_pass_sizes' do
6
+ describe "#adam7_pass_sizes" do
7
7
  it "should get the pass sizes for a 8x8 image correctly" do
8
8
  expect(adam7_pass_sizes(8, 8)).to eql [
9
- [1, 1], [1, 1], [2, 1], [2, 2], [4, 2], [4, 4], [8, 4]
10
- ]
9
+ [1, 1], [1, 1], [2, 1], [2, 2], [4, 2], [4, 4], [8, 4],
10
+ ]
11
11
  end
12
12
 
13
13
  it "should get the pass sizes for a 12x12 image correctly" do
14
14
  expect(adam7_pass_sizes(12, 12)).to eql [
15
- [2, 2], [1, 2], [3, 1], [3, 3], [6, 3], [6, 6], [12, 6]
16
- ]
15
+ [2, 2], [1, 2], [3, 1], [3, 3], [6, 3], [6, 6], [12, 6],
16
+ ]
17
17
  end
18
18
 
19
19
  it "should get the pass sizes for a 33x47 image correctly" do
20
20
  expect(adam7_pass_sizes(33, 47)).to eql [
21
- [5, 6], [4, 6], [9, 6], [8, 12], [17, 12], [16, 24], [33, 23]
22
- ]
21
+ [5, 6], [4, 6], [9, 6], [8, 12], [17, 12], [16, 24], [33, 23],
22
+ ]
23
23
  end
24
24
 
25
25
  it "should get the pass sizes for a 1x1 image correctly" do
26
26
  expect(adam7_pass_sizes(1, 1)).to eql [
27
- [1, 1], [0, 1], [1, 0], [0, 1], [1, 0], [0, 1], [1, 0]
28
- ]
27
+ [1, 1], [0, 1], [1, 0], [0, 1], [1, 0], [0, 1], [1, 0],
28
+ ]
29
29
  end
30
30
 
31
31
  it "should get the pass sizes for a 0x0 image correctly" do
32
32
  expect(adam7_pass_sizes(0, 0)).to eql [
33
- [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]
34
- ]
33
+ [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
34
+ ]
35
35
  end
36
36
 
37
37
  it "should always maintain the same amount of pixels in total" do
38
38
  [[8, 8], [12, 12], [33, 47], [1, 1], [0, 0]].each do |(width, height)|
39
39
  pass_sizes = adam7_pass_sizes(width, height)
40
- expect(pass_sizes.inject(0) { |sum, (w, h)| sum + (w*h) }).to eql width * height
40
+ expect(pass_sizes.inject(0) { |sum, (w, h)| sum + (w * h) }).to eql width * height
41
41
  end
42
42
  end
43
43
  end
44
44
 
45
- describe '#adam7_multiplier_offset' do
45
+ describe "#adam7_multiplier_offset" do
46
46
  it "should get the multiplier and offset values for pass 1 correctly" do
47
47
  expect(adam7_multiplier_offset(0)).to eql [3, 0, 3, 0]
48
48
  end
@@ -72,7 +72,7 @@ describe ChunkyPNG::Canvas::Adam7Interlacing do
72
72
  end
73
73
  end
74
74
 
75
- describe '#adam7_merge_pass' do
75
+ describe "#adam7_merge_pass" do
76
76
  it "should merge the submatrices correctly" do
77
77
  submatrices = [
78
78
  ChunkyPNG::Canvas.new(1, 1, 168430335), # r = 10
@@ -84,23 +84,22 @@ describe ChunkyPNG::Canvas::Adam7Interlacing do
84
84
  ChunkyPNG::Canvas.new(8, 4, 1175063295), # r = 70
85
85
  ]
86
86
 
87
- canvas = ChunkyPNG::Image.new(8,8)
87
+ canvas = ChunkyPNG::Image.new(8, 8)
88
88
  submatrices.each_with_index { |m, pass| adam7_merge_pass(pass, canvas, m) }
89
- expect(canvas).to eql reference_image('adam7')
89
+ expect(canvas).to eql reference_image("adam7")
90
90
  end
91
91
  end
92
92
 
93
- describe '#adam7_extract_pass' do
94
- before(:each) { @canvas = reference_canvas('adam7') }
93
+ describe "#adam7_extract_pass" do
94
+ before(:each) { @canvas = reference_canvas("adam7") }
95
95
 
96
96
  1.upto(7) do |pass|
97
97
  it "should extract pass #{pass} correctly" do
98
98
  sm = adam7_extract_pass(pass - 1, @canvas)
99
99
  expect(sm.pixels.length).to eql sm.width * sm.height
100
100
  expect(sm.pixels.uniq.length).to eql 1
101
- expect(ChunkyPNG::Color.r(sm[0,0])).to eql pass * 10
101
+ expect(ChunkyPNG::Color.r(sm[0, 0])).to eql pass * 10
102
102
  end
103
103
  end
104
104
  end
105
-
106
105
  end
@@ -1,11 +1,14 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe ChunkyPNG::Canvas do
4
-
5
- describe '#to_data_url' do
4
+ describe "#to_data_url" do
6
5
  it "should export a sample canvas to an RGBA stream correctly" do
7
- canvas = ChunkyPNG::Canvas.new(2, 2, [ChunkyPNG::Color.rgba(1,2,3,4), ChunkyPNG::Color.rgba(5,6,7,8),
8
- ChunkyPNG::Color.rgba(4,3,2,1), ChunkyPNG::Color.rgba(8,7,6,5)])
6
+ canvas = ChunkyPNG::Canvas.new(2, 2, [
7
+ ChunkyPNG::Color.rgba(1, 2, 3, 4),
8
+ ChunkyPNG::Color.rgba(5, 6, 7, 8),
9
+ ChunkyPNG::Color.rgba(4, 3, 2, 1),
10
+ ChunkyPNG::Color.rgba(8, 7, 6, 5),
11
+ ])
9
12
 
10
13
  expect(canvas.to_data_url).to eql "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEUBAgMEAwIFBgcIBwazgAAdAAAABHRSTlMEAQgFhYDlfQAAAAxJREFUeJxjUmAKAAAAwAB1GNhIEwAAAABJRU5ErkJggg=="
11
14
  end
@@ -1,15 +1,14 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe ChunkyPNG::Canvas do
4
-
5
- describe '.from_data_url' do
4
+ describe ".from_data_url" do
6
5
  it "should import an image from a data URL" do
7
- data_url = reference_canvas('operations').to_data_url
8
- expect(ChunkyPNG::Canvas.from_data_url(data_url)).to eql reference_canvas('operations')
6
+ data_url = reference_canvas("operations").to_data_url
7
+ expect(ChunkyPNG::Canvas.from_data_url(data_url)).to eql reference_canvas("operations")
9
8
  end
10
9
 
11
10
  it "should raise an exception if the string is not a proper data URL" do
12
- expect { ChunkyPNG::Canvas.from_data_url('whatever') }.to raise_error(ChunkyPNG::SignatureMismatch)
11
+ expect { ChunkyPNG::Canvas.from_data_url("whatever") }.to raise_error(ChunkyPNG::SignatureMismatch)
13
12
  end
14
13
  end
15
14
  end
@@ -1,12 +1,11 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe ChunkyPNG::Canvas::Drawing do
4
-
5
- describe '#compose_pixel' do
4
+ describe "#compose_pixel" do
6
5
  subject { ChunkyPNG::Canvas.new(1, 1, ChunkyPNG::Color.rgb(200, 150, 100)) }
7
6
 
8
7
  it "should compose colors correctly" do
9
- subject.compose_pixel(0,0, ChunkyPNG::Color(100, 150, 200, 128))
8
+ subject.compose_pixel(0, 0, ChunkyPNG::Color(100, 150, 200, 128))
10
9
  expect(subject[0, 0]).to eql ChunkyPNG::Color(150, 150, 150)
11
10
  end
12
11
 
@@ -20,11 +19,11 @@ describe ChunkyPNG::Canvas::Drawing do
20
19
  end
21
20
  end
22
21
 
23
- describe '#line' do
22
+ describe "#line" do
24
23
  it "should draw lines correctly with anti-aliasing" do
25
-
26
24
  canvas = ChunkyPNG::Canvas.new(31, 31, ChunkyPNG::Color::WHITE)
27
25
 
26
+ # rubocop:disable Layout/SpaceInsideParens # for improved readability
28
27
  canvas.line( 0, 0, 30, 30, ChunkyPNG::Color::BLACK)
29
28
  canvas.line( 0, 30, 30, 0, ChunkyPNG::Color::BLACK)
30
29
  canvas.line(15, 30, 15, 0, ChunkyPNG::Color.rgba(200, 0, 0, 128))
@@ -33,13 +32,14 @@ describe ChunkyPNG::Canvas::Drawing do
33
32
  canvas.line( 0, 15, 30, 0, ChunkyPNG::Color.rgba( 0, 200, 0, 128))
34
33
  canvas.line( 0, 30, 15, 0, ChunkyPNG::Color.rgba( 0, 0, 200, 128), false)
35
34
  canvas.line(15, 0, 30, 30, ChunkyPNG::Color.rgba( 0, 0, 200, 128))
35
+ # rubocop:enable Layout/SpaceInsideParens
36
36
 
37
- expect(canvas).to eql reference_canvas('lines')
37
+ expect(canvas).to eql reference_canvas("lines")
38
38
  end
39
39
 
40
40
  it "should draw partial lines if the coordinates are partially out of bounds" do
41
41
  canvas = ChunkyPNG::Canvas.new(1, 2, ChunkyPNG::Color::WHITE)
42
- canvas.line(-5, -5, 0, 0, '#000000')
42
+ canvas.line(-5, -5, 0, 0, "#000000")
43
43
  expect(canvas.pixels).to eql [ChunkyPNG::Color::BLACK, ChunkyPNG::Color::WHITE]
44
44
  end
45
45
 
@@ -47,15 +47,23 @@ describe ChunkyPNG::Canvas::Drawing do
47
47
  canvas = ChunkyPNG::Canvas.new(16, 16, ChunkyPNG::Color::WHITE)
48
48
  expect(canvas.line(1, 1, 10, 10, :black)).to equal(canvas)
49
49
  end
50
+
51
+ it "should draw a single pixel when the start and end point are the same" do
52
+ canvas = ChunkyPNG::Canvas.new(5, 5, ChunkyPNG::Color::WHITE)
53
+ canvas.line(2, 2, 2, 2, ChunkyPNG::Color::BLACK)
54
+
55
+ non_white_pixels = canvas.pixels.count { |pixel| pixel != ChunkyPNG::Color::WHITE }
56
+ expect(non_white_pixels).to eql 1
57
+ end
50
58
  end
51
59
 
52
- describe '#rect' do
53
- subject { ChunkyPNG::Canvas.new(16, 16, '#ffffff') }
60
+ describe "#rect" do
61
+ subject { ChunkyPNG::Canvas.new(16, 16, "#ffffff") }
54
62
 
55
63
  it "should draw a rectangle with the correct colors" do
56
- subject.rect(1, 1, 10, 10, ChunkyPNG::Color.rgba(0, 255, 0, 80), ChunkyPNG::Color.rgba(255, 0, 0, 100))
64
+ subject.rect(1, 1, 10, 10, ChunkyPNG::Color.rgba(0, 255, 0, 80), ChunkyPNG::Color.rgba(255, 0, 0, 100))
57
65
  subject.rect(5, 5, 14, 14, ChunkyPNG::Color.rgba(0, 0, 255, 160), ChunkyPNG::Color.rgba(255, 255, 0, 100))
58
- expect(subject).to eql reference_canvas('rect')
66
+ expect(subject).to eql reference_canvas("rect")
59
67
  end
60
68
 
61
69
  it "should return itself to allow chaining" do
@@ -73,19 +81,19 @@ describe ChunkyPNG::Canvas::Drawing do
73
81
  end
74
82
  end
75
83
 
76
- describe '#circle' do
84
+ describe "#circle" do
77
85
  subject { ChunkyPNG::Canvas.new(32, 32, ChunkyPNG::Color.rgba(0, 0, 255, 128)) }
78
86
 
79
87
  it "should draw circles" do
80
- subject.circle(11, 11, 10, ChunkyPNG::Color('red @ 0.5'), ChunkyPNG::Color('white @ 0.2'))
81
- subject.circle(21, 21, 10, ChunkyPNG::Color('green @ 0.5'))
82
- expect(subject).to eql reference_canvas('circles')
88
+ subject.circle(11, 11, 10, ChunkyPNG::Color("red @ 0.5"), ChunkyPNG::Color("white @ 0.2"))
89
+ subject.circle(21, 21, 10, ChunkyPNG::Color("green @ 0.5"))
90
+ expect(subject).to eql reference_canvas("circles")
83
91
  end
84
92
 
85
93
  it "should draw partial circles when going of the canvas bounds" do
86
94
  subject.circle(0, 0, 10, ChunkyPNG::Color(:red))
87
95
  subject.circle(31, 16, 10, ChunkyPNG::Color(:black), ChunkyPNG::Color(:white, 0xaa))
88
- expect(subject).to eql reference_canvas('partial_circles')
96
+ expect(subject).to eql reference_canvas("partial_circles")
89
97
  end
90
98
 
91
99
  it "should return itself to allow chaining" do
@@ -93,78 +101,78 @@ describe ChunkyPNG::Canvas::Drawing do
93
101
  end
94
102
  end
95
103
 
96
- describe '#polygon' do
104
+ describe "#polygon" do
97
105
  subject { ChunkyPNG::Canvas.new(22, 22) }
98
106
 
99
107
  it "should draw an filled triangle when using 3 control points" do
100
- subject.polygon('(2,2) (20,5) (5,20)', ChunkyPNG::Color(:black, 0xaa), ChunkyPNG::Color(:red, 0x44))
101
- expect(subject).to eql reference_canvas('polygon_triangle_filled')
108
+ subject.polygon("(2,2) (20,5) (5,20)", ChunkyPNG::Color(:black, 0xaa), ChunkyPNG::Color(:red, 0x44))
109
+ expect(subject).to eql reference_canvas("polygon_triangle_filled")
102
110
  end
103
111
 
104
112
  it "should draw a unfilled polygon with 6 control points" do
105
- subject.polygon('(2,2) (12, 1) (20,5) (18,18) (5,20) (1,12)', ChunkyPNG::Color(:black))
106
- expect(subject).to eql reference_canvas('polygon_unfilled')
113
+ subject.polygon("(2,2) (12, 1) (20,5) (18,18) (5,20) (1,12)", ChunkyPNG::Color(:black))
114
+ expect(subject).to eql reference_canvas("polygon_unfilled")
107
115
  end
108
116
 
109
117
  it "should draw a vertically crossed filled polygon with 4 control points" do
110
- subject.polygon('(2,2) (21,2) (2,21) (21,21)', ChunkyPNG::Color(:black), ChunkyPNG::Color(:red))
111
- expect(subject).to eql reference_canvas('polygon_filled_vertical')
118
+ subject.polygon("(2,2) (21,2) (2,21) (21,21)", ChunkyPNG::Color(:black), ChunkyPNG::Color(:red))
119
+ expect(subject).to eql reference_canvas("polygon_filled_vertical")
112
120
  end
113
121
 
114
122
  it "should draw a vertically crossed filled polygon with 4 control points" do
115
- subject.polygon('(2,2) (2,21) (21,2) (21,21)', ChunkyPNG::Color(:black), ChunkyPNG::Color(:red))
116
- expect(subject).to eql reference_canvas('polygon_filled_horizontal')
123
+ subject.polygon("(2,2) (2,21) (21,2) (21,21)", ChunkyPNG::Color(:black), ChunkyPNG::Color(:red))
124
+ expect(subject).to eql reference_canvas("polygon_filled_horizontal")
117
125
  end
118
126
 
119
127
  it "should return itself to allow chaining" do
120
- expect(subject.polygon('(2,2) (20,5) (5,20)')).to equal(subject)
128
+ expect(subject.polygon("(2,2) (20,5) (5,20)")).to equal(subject)
121
129
  end
122
130
  end
123
131
 
124
- describe '#bezier_curve' do
132
+ describe "#bezier_curve" do
125
133
  subject { ChunkyPNG::Canvas.new(24, 24, ChunkyPNG::Color::WHITE) }
126
134
 
127
135
  it "should draw a bezier curve starting at the first point" do
128
- subject.bezier_curve('3,20 10,10, 20,20')
136
+ subject.bezier_curve("3,20 10,10, 20,20")
129
137
  expect(subject[3, 20]).to eql ChunkyPNG::Color::BLACK
130
138
  end
131
139
 
132
140
  it "should draw a bezier curve ending at the last point" do
133
- subject.bezier_curve('3,20 10,10, 20,20')
141
+ subject.bezier_curve("3,20 10,10, 20,20")
134
142
  expect(subject[20, 20]).to eql ChunkyPNG::Color::BLACK
135
143
  end
136
144
 
137
145
  it "should draw a bezier curve with a color of green" do
138
- subject.bezier_curve('3,20 10,10, 20,20', :green)
146
+ subject.bezier_curve("3,20 10,10, 20,20", :green)
139
147
  expect(subject[3, 20]).to eql ChunkyPNG::Color(:green)
140
148
  end
141
149
 
142
150
  it "should draw a three point bezier curve" do
143
- expect(subject.bezier_curve('1,23 12,10 23,23')).to eql reference_canvas('bezier_three_point')
151
+ expect(subject.bezier_curve("1,23 12,10 23,23")).to eql reference_canvas("bezier_three_point")
144
152
  end
145
153
 
146
154
  it "should draw a three point bezier curve flipped" do
147
- expect(subject.bezier_curve('1,1 12,15 23,1')).to eql reference_canvas('bezier_three_point_flipped')
155
+ expect(subject.bezier_curve("1,1 12,15 23,1")).to eql reference_canvas("bezier_three_point_flipped")
148
156
  end
149
157
 
150
158
  it "should draw a four point bezier curve" do
151
- expect(subject.bezier_curve('1,23 1,5 22,5 22,23')).to eql reference_canvas('bezier_four_point')
159
+ expect(subject.bezier_curve("1,23 1,5 22,5 22,23")).to eql reference_canvas("bezier_four_point")
152
160
  end
153
161
 
154
162
  it "should draw a four point bezier curve flipped" do
155
- expect(subject.bezier_curve('1,1 1,19 22,19 22,1')).to eql reference_canvas('bezier_four_point_flipped')
163
+ expect(subject.bezier_curve("1,1 1,19 22,19 22,1")).to eql reference_canvas("bezier_four_point_flipped")
156
164
  end
157
165
 
158
166
  it "should draw a four point bezier curve with a shape of an s" do
159
- expect(subject.bezier_curve('1,23 1,5 22,23 22,5')).to eql reference_canvas('bezier_four_point_s')
167
+ expect(subject.bezier_curve("1,23 1,5 22,23 22,5")).to eql reference_canvas("bezier_four_point_s")
160
168
  end
161
169
 
162
170
  it "should draw a five point bezier curve" do
163
- expect(subject.bezier_curve('10,23 1,10 12,5 23,10 14,23')).to eql reference_canvas('bezier_five_point')
171
+ expect(subject.bezier_curve("10,23 1,10 12,5 23,10 14,23")).to eql reference_canvas("bezier_five_point")
164
172
  end
165
173
 
166
174
  it "should draw a six point bezier curve" do
167
- expect(subject.bezier_curve('1,23 4,15 8,20 2,2 23,15 23,1')).to eql reference_canvas('bezier_six_point')
175
+ expect(subject.bezier_curve("1,23 4,15 8,20 2,2 23,15 23,1")).to eql reference_canvas("bezier_six_point")
168
176
  end
169
177
  end
170
178
  end