chunky_png 1.3.0 → 1.3.1

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.
@@ -54,6 +54,9 @@ provides a massive speed boost to encoding and decoding.
54
54
  png_stream = ChunkyPNG::Datastream.from_file('filename.png')
55
55
  png_stream.each_chunk { |chunk| p chunk.type }
56
56
 
57
+ Also check out the following screencast by John Davison, which illustrates
58
+ basic usage of the library: http://devcasts.co/ruby-chunky_png-a-great-gem-for-on-the-fly-png-manipulation.
59
+
57
60
  For more information, see the project wiki on http://github.com/wvanbergen/chunky_png/wiki
58
61
  or the RDOC documentation on http://rdoc.info/gems/chunky_png/frames
59
62
 
@@ -11,7 +11,6 @@ require 'chunky_png/canvas/resampling'
11
11
  require 'chunky_png/canvas/masking'
12
12
 
13
13
  module ChunkyPNG
14
-
15
14
  # The ChunkyPNG::Canvas class represents a raster image as a matrix of
16
15
  # pixels.
17
16
  #
@@ -32,7 +31,6 @@ module ChunkyPNG
32
31
  # the whole canvas, like cropping and alpha compositing. Simple drawing
33
32
  # functions are imported from the {ChunkyPNG::Canvas::Drawing} module.
34
33
  class Canvas
35
-
36
34
  include PNGEncoding
37
35
  extend PNGDecoding
38
36
  extend Adam7Interlacing
@@ -55,7 +53,7 @@ module ChunkyPNG
55
53
  attr_reader :height
56
54
 
57
55
  # @return [Array<ChunkyPNG::Color>] The list of pixels in this canvas.
58
- # This array always should have +width * height+ elements.
56
+ # This array always should have +width * height+ elements.
59
57
  attr_reader :pixels
60
58
 
61
59
 
@@ -68,26 +66,28 @@ module ChunkyPNG
68
66
  # @overload initialize(width, height, background_color)
69
67
  # @param [Integer] width The width in pixels of this canvas
70
68
  # @param [Integer] height The height in pixels of this canvas
71
- # @param [Integer, ...] background_color The initial background color of this canvas.
72
- # This can be a color value or any value that {ChunkyPNG::Color.parse} can handle.
69
+ # @param [Integer, ...] background_color The initial background color of
70
+ # this canvas. This can be a color value or any value that
71
+ # {ChunkyPNG::Color.parse} can handle.
73
72
  #
74
73
  # @overload initialize(width, height, initial)
75
74
  # @param [Integer] width The width in pixels of this canvas
76
75
  # @param [Integer] height The height in pixels of this canvas
77
- # @param [Array<Integer>] initial The initial pizel values. Must be an array with
78
- # <tt>width * height</tt> elements.
76
+ # @param [Array<Integer>] initial The initial pizel values. Must be an
77
+ # array with <tt>width * height</tt> elements.
79
78
  def initialize(width, height, initial = ChunkyPNG::Color::TRANSPARENT)
80
-
81
79
  @width, @height = width, height
82
80
 
83
81
  if initial.kind_of?(Array)
84
- raise ArgumentError, "The initial array should have #{width}x#{height} = #{width*height} elements!" unless initial.length == width * height
82
+ unless initial.length == width * height
83
+ raise ArgumentError, "The initial array should have #{width}x#{height} = #{width*height} elements!"
84
+ end
85
85
  @pixels = initial
86
86
  else
87
87
  @pixels = Array.new(width * height, ChunkyPNG::Color.parse(initial))
88
88
  end
89
89
  end
90
-
90
+
91
91
  # Initializes a new Canvas instances when being cloned.
92
92
  # @param [ChunkyPNG::Canvas] other The canvas to duplicate
93
93
  # @return [void]
@@ -101,7 +101,7 @@ module ChunkyPNG
101
101
  # @param [ChunkyPNG::Canvas] canvas The canvas to duplicate
102
102
  # @return [ChunkyPNG::Canvas] The newly constructed canvas instance.
103
103
  def self.from_canvas(canvas)
104
- self.new(canvas.width, canvas.height, canvas.pixels.dup)
104
+ new(canvas.width, canvas.height, canvas.pixels.dup)
105
105
  end
106
106
 
107
107
 
@@ -110,11 +110,12 @@ module ChunkyPNG
110
110
  #################################################################
111
111
 
112
112
  # Returns the dimension (width x height) for this canvas.
113
- # @return [ChunkyPNG::Dimension] A dimension instance with the width and height set for this canvas.
113
+ # @return [ChunkyPNG::Dimension] A dimension instance with the width and
114
+ # height set for this canvas.
114
115
  def dimension
115
116
  ChunkyPNG::Dimension.new(width, height)
116
117
  end
117
-
118
+
118
119
  # Returns the area of this canvas in number of pixels.
119
120
  # @return [Integer] The number of pixels in this canvas
120
121
  def area
@@ -125,8 +126,10 @@ module ChunkyPNG
125
126
  # @param [Integer] x The x-coordinate of the pixel (column)
126
127
  # @param [Integer] y The y-coordinate of the pixel (row)
127
128
  # @param [Integer] color The new color for the provided coordinates.
128
- # @return [Integer] The new color value for this pixel, i.e. <tt>color</tt>.
129
- # @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the image's dimensions.
129
+ # @return [Integer] The new color value for this pixel, i.e.
130
+ # <tt>color</tt>.
131
+ # @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the
132
+ # image's dimensions.
130
133
  # @see #set_pixel
131
134
  def []=(x, y, color)
132
135
  assert_xy!(x, y)
@@ -135,25 +138,26 @@ module ChunkyPNG
135
138
 
136
139
  # Replaces a single pixel in this canvas, without bounds checking.
137
140
  #
138
- # This method return value and effects are undefined for coordinates
141
+ # This method return value and effects are undefined for coordinates
139
142
  # out of bounds of the canvas.
140
143
  #
141
144
  # @param [Integer] x The x-coordinate of the pixel (column)
142
145
  # @param [Integer] y The y-coordinate of the pixel (row)
143
146
  # @param [Integer] pixel The new color for the provided coordinates.
144
- # @return [Integer] The new color value for this pixel, i.e. <tt>color</tt>.
147
+ # @return [Integer] The new color value for this pixel, i.e.
148
+ # <tt>color</tt>.
145
149
  def set_pixel(x, y, color)
146
150
  @pixels[y * width + x] = color
147
151
  end
148
-
152
+
149
153
  # Replaces a single pixel in this canvas, with bounds checking. It will do
150
154
  # noting if the provided coordinates are out of bounds.
151
155
  #
152
156
  # @param [Integer] x The x-coordinate of the pixel (column)
153
157
  # @param [Integer] y The y-coordinate of the pixel (row)
154
158
  # @param [Integer] pixel The new color value for the provided coordinates.
155
- # @return [Integer] The new color value for this pixel, i.e. <tt>color</tt>, or
156
- # <tt>nil</tt> if the coordinates are out of bounds.
159
+ # @return [Integer] The new color value for this pixel, i.e.
160
+ # <tt>color</tt>, or <tt>nil</tt> if the coordinates are out of bounds.
157
161
  def set_pixel_if_within_bounds(x, y, color)
158
162
  return unless include_xy?(x, y)
159
163
  @pixels[y * width + x] = color
@@ -163,15 +167,18 @@ module ChunkyPNG
163
167
  # @param [Integer] x The x-coordinate of the pixel (column)
164
168
  # @param [Integer] y The y-coordinate of the pixel (row)
165
169
  # @return [Integer] The current color value at the provided coordinates.
166
- # @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the image's dimensions.
170
+ # @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the
171
+ # image's dimensions.
167
172
  # @see #get_pixel
168
173
  def [](x, y)
169
174
  assert_xy!(x, y)
170
175
  @pixels[y * width + x]
171
176
  end
172
177
 
173
- # Returns a single pixel from this canvas, without checking bounds. The return value for
174
- # this method is undefined if the coordinates are out of bounds.
178
+ # Returns a single pixel from this canvas, without checking bounds. The
179
+ # return value for this method is undefined if the coordinates are out of
180
+ # bounds.
181
+ #
175
182
  # @param (see #[])
176
183
  # @return [Integer] The current pixel at the provided coordinates.
177
184
  def get_pixel(x, y)
@@ -196,7 +203,8 @@ module ChunkyPNG
196
203
 
197
204
  # Replaces a row of pixels on this canvas.
198
205
  # @param [Integer] y The 0-based row index.
199
- # @param [Array<Integer>] vector The vector of pixels to replace the row with.
206
+ # @param [Array<Integer>] vector The vector of pixels to replace the row
207
+ # with.
200
208
  # @return [void]
201
209
  def replace_row!(y, vector)
202
210
  assert_y!(y) && assert_width!(vector.length)
@@ -205,7 +213,8 @@ module ChunkyPNG
205
213
 
206
214
  # Replaces a column of pixels on this canvas.
207
215
  # @param [Integer] x The 0-based column index.
208
- # @param [Array<Integer>] vector The vector of pixels to replace the column with.
216
+ # @param [Array<Integer>] vector The vector of pixels to replace the column
217
+ # with.
209
218
  # @return [void]
210
219
  def replace_column!(x, vector)
211
220
  assert_x!(x) && assert_height!(vector.length)
@@ -215,49 +224,55 @@ module ChunkyPNG
215
224
  end
216
225
 
217
226
  # Checks whether the given coordinates are in the range of the canvas
218
- # @param [ChunkyPNG::Point, Array, Hash, String] point_like The point to check.
219
- # @return [true, false] True if the x and y coordinates of the point are
220
- # within the limits of this canvas.
227
+ # @param [ChunkyPNG::Point, Array, Hash, String] point_like The point to
228
+ # check.
229
+ # @return [true, false] True if the x and y coordinates of the point are
230
+ # within the limits of this canvas.
221
231
  # @see ChunkyPNG.Point
222
232
  def include_point?(*point_like)
223
233
  dimension.include?(ChunkyPNG::Point(*point_like))
224
234
  end
225
-
235
+
226
236
  alias_method :include?, :include_point?
227
-
228
- # Checks whether the given x- and y-coordinate are in the range of the canvas
237
+
238
+ # Checks whether the given x- and y-coordinate are in the range of the
239
+ # canvas
240
+ #
229
241
  # @param [Integer] x The x-coordinate of the pixel (column)
230
242
  # @param [Integer] y The y-coordinate of the pixel (row)
231
- # @return [true, false] True if the x- and y-coordinate is in the range of this canvas.
243
+ # @return [true, false] True if the x- and y-coordinate is in the range of
244
+ # this canvas.
232
245
  def include_xy?(x, y)
233
246
  y >= 0 && y < height && x >= 0 && x < width
234
247
  end
235
-
248
+
236
249
  # Checks whether the given y-coordinate is in the range of the canvas
237
250
  # @param [Integer] y The y-coordinate of the pixel (row)
238
- # @return [true, false] True if the y-coordinate is in the range of this canvas.
251
+ # @return [true, false] True if the y-coordinate is in the range of this
252
+ # canvas.
239
253
  def include_y?(y)
240
254
  y >= 0 && y < height
241
255
  end
242
256
 
243
257
  # Checks whether the given x-coordinate is in the range of the canvas
244
258
  # @param [Integer] x The y-coordinate of the pixel (column)
245
- # @return [true, false] True if the x-coordinate is in the range of this canvas.
259
+ # @return [true, false] True if the x-coordinate is in the range of this
260
+ # canvas.
246
261
  def include_x?(x)
247
262
  x >= 0 && x < width
248
263
  end
249
264
 
250
265
  # Returns the palette used for this canvas.
251
- # @return [ChunkyPNG::Palette] A palette which contains all the colors that are
252
- # being used for this image.
266
+ # @return [ChunkyPNG::Palette] A palette which contains all the colors that
267
+ # are being used for this image.
253
268
  def palette
254
269
  ChunkyPNG::Palette.from_canvas(self)
255
270
  end
256
271
 
257
272
  # Equality check to compare this canvas with other matrices.
258
273
  # @param other The object to compare this Matrix to.
259
- # @return [true, false] True if the size and pixel values of the other canvas
260
- # are exactly the same as this canvas's size and pixel values.
274
+ # @return [true, false] True if the size and pixel values of the other
275
+ # canvas are exactly the same as this canvas's size and pixel values.
261
276
  def eql?(other)
262
277
  other.kind_of?(self.class) && other.pixels == self.pixels &&
263
278
  other.width == self.width && other.height == self.height
@@ -274,7 +289,7 @@ module ChunkyPNG
274
289
  def to_image
275
290
  ChunkyPNG::Image.from_canvas(self)
276
291
  end
277
-
292
+
278
293
  # Alternative implementation of the inspect method.
279
294
  # @return [String] A nicely formatted string representation of this canvas.
280
295
  # @private
@@ -285,51 +300,73 @@ module ChunkyPNG
285
300
  end
286
301
  inspected << "\n]>"
287
302
  end
288
-
303
+
289
304
  protected
290
-
305
+
291
306
  # Replaces the image, given a new width, new height, and a new pixel array.
292
307
  def replace_canvas!(new_width, new_height, new_pixels)
293
- raise ArgumentError, "The provided pixel array should have #{new_width * new_height} items" unless new_pixels.length == new_width * new_height
308
+ unless new_pixels.length == new_width * new_height
309
+ raise ArgumentError, "The provided pixel array should have #{new_width * new_height} items"
310
+ end
294
311
  @width, @height, @pixels = new_width, new_height, new_pixels
295
- return self
312
+ self
296
313
  end
297
-
314
+
298
315
  # Throws an exception if the x-coordinate is out of bounds.
299
316
  def assert_x!(x)
300
- raise ChunkyPNG::OutOfBounds, "Column index #{x} out of bounds!" unless include_x?(x)
301
- return true
317
+ unless include_x?(x)
318
+ raise ChunkyPNG::OutOfBounds, "Column index #{x} out of bounds!"
319
+ end
320
+ true
302
321
  end
303
-
322
+
304
323
  # Throws an exception if the y-coordinate is out of bounds.
305
324
  def assert_y!(y)
306
- raise ChunkyPNG::OutOfBounds, "Row index #{y} out of bounds!" unless include_y?(y)
307
- return true
325
+ unless include_y?(y)
326
+ raise ChunkyPNG::OutOfBounds, "Row index #{y} out of bounds!"
327
+ end
328
+ true
308
329
  end
309
-
330
+
310
331
  # Throws an exception if the x- or y-coordinate is out of bounds.
311
332
  def assert_xy!(x, y)
312
- raise ChunkyPNG::OutOfBounds, "Coordinates (#{x},#{y}) out of bounds!" unless include_xy?(x, y)
313
- return true
333
+ unless include_xy?(x, y)
334
+ raise ChunkyPNG::OutOfBounds, "Coordinates (#{x},#{y}) out of bounds!"
335
+ end
336
+ true
314
337
  end
315
338
 
316
- # Throws an exception if the vector_length does not match this canvas' height.
339
+ # Throws an exception if the vector_length does not match this canvas'
340
+ # height.
317
341
  def assert_height!(vector_length)
318
- raise ChunkyPNG::ExpectationFailed, "The length of the vector (#{vector_length}) does not match the canvas height (#{height})!" if height != vector_length
319
- return true
342
+ if height != vector_length
343
+ raise ChunkyPNG::ExpectationFailed,
344
+ "The length of the vector (#{vector_length}) does not match the canvas height (#{height})!"
345
+ end
346
+ true
320
347
  end
321
348
 
322
- # Throws an exception if the vector_length does not match this canvas' width.
349
+ # Throws an exception if the vector_length does not match this canvas'
350
+ # width.
323
351
  def assert_width!(vector_length)
324
- raise ChunkyPNG::ExpectationFailed, "The length of the vector (#{vector_length}) does not match the canvas width (#{width})!" if width != vector_length
325
- return true
352
+ if width != vector_length
353
+ raise ChunkyPNG::ExpectationFailed,
354
+ "The length of the vector (#{vector_length}) does not match the canvas width (#{width})!"
355
+ end
356
+ true
326
357
  end
327
358
 
328
359
  # Throws an exception if the matrix width and height does not match this canvas' dimensions.
329
360
  def assert_size!(matrix_width, matrix_height)
330
- raise ChunkyPNG::ExpectationFailed, "The width of the matrix does not match the canvas width!" if width != matrix_width
331
- raise ChunkyPNG::ExpectationFailed, "The height of the matrix does not match the canvas height!" if height != matrix_height
332
- return true
361
+ if width != matrix_width
362
+ raise ChunkyPNG::ExpectationFailed,
363
+ 'The width of the matrix does not match the canvas width!'
364
+ end
365
+ if height != matrix_height
366
+ raise ChunkyPNG::ExpectationFailed,
367
+ 'The height of the matrix does not match the canvas height!'
368
+ end
369
+ true
333
370
  end
334
371
  end
335
372
  end
@@ -1,17 +1,19 @@
1
1
  module ChunkyPNG
2
2
  class Canvas
3
-
3
+
4
4
  # Module that adds some primitive drawing methods to {ChunkyPNG::Canvas}.
5
5
  #
6
- # All of these methods change the current canvas instance and do not create a new one,
7
- # even though the method names do not end with a bang.
6
+ # All of these methods change the current canvas instance and do not create
7
+ # a new one, even though the method names do not end with a bang.
8
8
  #
9
- # @note Drawing operations will not fail when something is drawn outside of the bounds
10
- # of the canvas; these pixels will simply be ignored.
9
+ # @note Drawing operations will not fail when something is drawn outside of
10
+ # the bounds of the canvas; these pixels will simply be ignored.
11
11
  # @see ChunkyPNG::Canvas
12
12
  module Drawing
13
-
14
- # Composes a pixel on the canvas by alpha blending a color with its background color.
13
+
14
+ # Composes a pixel on the canvas by alpha blending a color with its
15
+ # background color.
16
+ #
15
17
  # @param [Integer] x The x-coordinate of the pixel to blend.
16
18
  # @param [Integer] y The y-coordinate of the pixel to blend.
17
19
  # @param [Integer] color The foreground color to blend with
@@ -20,49 +22,49 @@ module ChunkyPNG
20
22
  return unless include_xy?(x, y)
21
23
  compose_pixel_unsafe(x, y, ChunkyPNG::Color.parse(color))
22
24
  end
23
-
24
- # Composes a pixel on the canvas by alpha blending a color with its background color,
25
- # without bounds checking.
25
+
26
+ # Composes a pixel on the canvas by alpha blending a color with its
27
+ # background color, without bounds checking.
28
+ #
26
29
  # @param (see #compose_pixel)
27
30
  # @return [Integer] The composed color.
28
31
  def compose_pixel_unsafe(x, y, color)
29
32
  set_pixel(x, y, ChunkyPNG::Color.compose(color, get_pixel(x, y)))
30
33
  end
31
-
34
+
32
35
  # Draws a Bezier curve
33
36
  # @param [Array, Point] A collection of control points
34
37
  # @return [Chunky:PNG::Canvas] Itself, with the curve drawn
35
38
  def bezier_curve(points, stroke_color = ChunkyPNG::Color::BLACK)
36
-
37
39
  points = ChunkyPNG::Vector(*points)
38
40
  case points.length
39
41
  when 0, 1; return self
40
42
  when 2; return line(points[0].x, points[0].y, points[1].x, points[1].y, stroke_color)
41
43
  end
42
-
44
+
43
45
  curve_points = Array.new
44
-
45
- t = 0
46
- n = points.length - 1
46
+
47
+ t = 0
48
+ n = points.length - 1
47
49
  bicof = 0
48
-
50
+
49
51
  while t <= 100
50
52
  cur_p = ChunkyPNG::Point.new(0,0)
51
-
53
+
52
54
  # Generate a float of t.
53
55
  t_f = t / 100.00
54
-
56
+
55
57
  cur_p.x += ((1 - t_f) ** n) * points[0].x
56
58
  cur_p.y += ((1 - t_f) ** n) * points[0].y
57
-
59
+
58
60
  for i in 1...points.length - 1
59
61
  bicof = binomial_coefficient(n , i)
60
-
61
- cur_p.x += (bicof * (1 - t_f) ** (n - i)) * (t_f ** i) * points[i].x
62
- cur_p.y += (bicof * (1 - t_f) ** (n - i)) * (t_f ** i) * points[i].y
62
+
63
+ cur_p.x += (bicof * (1 - t_f) ** (n - i)) * (t_f ** i) * points[i].x
64
+ cur_p.y += (bicof * (1 - t_f) ** (n - i)) * (t_f ** i) * points[i].y
63
65
  i += 1
64
66
  end
65
-
67
+
66
68
  cur_p.x += (t_f ** n) * points[n].x
67
69
  cur_p.y += (t_f ** n) * points[n].y
68
70
 
@@ -76,10 +78,9 @@ module ChunkyPNG
76
78
  line_xiaolin_wu(p1.x.round, p1.y.round, p2.x.round, p2.y.round, stroke_color)
77
79
  end
78
80
 
79
- return self
81
+ self
80
82
  end
81
-
82
-
83
+
83
84
  # Draws an anti-aliased line using Xiaolin Wu's algorithm.
84
85
  #
85
86
  # @param [Integer] x0 The x-coordinate of the first control point.
@@ -87,81 +88,93 @@ module ChunkyPNG
87
88
  # @param [Integer] x1 The x-coordinate of the second control point.
88
89
  # @param [Integer] y1 The y-coordinate of the second control point.
89
90
  # @param [Integer] stroke_color The color to use for this line.
90
- # @param [true, false] inclusive Whether to draw the last pixel.
91
- # Set to false when drawing multiple lines in a path.
91
+ # @param [true, false] inclusive Whether to draw the last pixel. Set to
92
+ # false when drawing multiple lines in a path.
92
93
  # @return [ChunkyPNG::Canvas] Itself, with the line drawn.
93
94
  def line_xiaolin_wu(x0, y0, x1, y1, stroke_color, inclusive = true)
94
-
95
95
  stroke_color = ChunkyPNG::Color.parse(stroke_color)
96
-
96
+
97
97
  dx = x1 - x0
98
98
  sx = dx < 0 ? -1 : 1
99
99
  dx *= sx
100
100
  dy = y1 - y0
101
101
  sy = dy < 0 ? -1 : 1
102
102
  dy *= sy
103
-
103
+
104
104
  if dy == 0 # vertical line
105
105
  x0.step(inclusive ? x1 : x1 - sx, sx) do |x|
106
106
  compose_pixel(x, y0, stroke_color)
107
107
  end
108
-
108
+
109
109
  elsif dx == 0 # horizontal line
110
110
  y0.step(inclusive ? y1 : y1 - sy, sy) do |y|
111
111
  compose_pixel(x0, y, stroke_color)
112
112
  end
113
-
113
+
114
114
  elsif dx == dy # diagonal
115
115
  x0.step(inclusive ? x1 : x1 - sx, sx) do |x|
116
116
  compose_pixel(x, y0, stroke_color)
117
117
  y0 += sy
118
118
  end
119
-
119
+
120
120
  elsif dy > dx # vertical displacement
121
121
  compose_pixel(x0, y0, stroke_color)
122
122
  e_acc = 0
123
123
  e = ((dx << 16) / dy.to_f).round
124
124
  (dy - 1).downto(0) do |i|
125
125
  e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
126
- x0 += sx if (e_acc <= e_acc_temp)
126
+ x0 += sx if e_acc <= e_acc_temp
127
127
  w = 0xff - (e_acc >> 8)
128
128
  compose_pixel(x0, y0, ChunkyPNG::Color.fade(stroke_color, w))
129
- compose_pixel(x0 + sx, y0 + sy, ChunkyPNG::Color.fade(stroke_color, 0xff - w)) if inclusive || i > 0
129
+ if inclusive || i > 0
130
+ compose_pixel(x0 + sx,
131
+ y0 + sy,
132
+ ChunkyPNG::Color.fade(stroke_color, 0xff - w))
133
+ end
130
134
  y0 += sy
131
135
  end
132
136
  compose_pixel(x1, y1, stroke_color) if inclusive
133
-
137
+
134
138
  else # horizontal displacement
135
139
  compose_pixel(x0, y0, stroke_color)
136
140
  e_acc = 0
137
141
  e = ((dy << 16) / dx.to_f).round
138
142
  (dx - 1).downto(0) do |i|
139
143
  e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
140
- y0 += sy if (e_acc <= e_acc_temp)
144
+ y0 += sy if e_acc <= e_acc_temp
141
145
  w = 0xff - (e_acc >> 8)
142
146
  compose_pixel(x0, y0, ChunkyPNG::Color.fade(stroke_color, w))
143
- compose_pixel(x0 + sx, y0 + sy, ChunkyPNG::Color.fade(stroke_color, 0xff - w)) if inclusive || i > 0
147
+ if inclusive || i > 0
148
+ compose_pixel(x0 + sx,
149
+ y0 + sy,
150
+ ChunkyPNG::Color.fade(stroke_color, 0xff - w))
151
+ end
144
152
  x0 += sx
145
153
  end
146
154
  compose_pixel(x1, y1, stroke_color) if inclusive
147
155
  end
148
-
149
- return self
156
+
157
+ self
150
158
  end
151
-
159
+
152
160
  alias_method :line, :line_xiaolin_wu
153
-
154
-
155
- # Draws a polygon on the canvas using the stroke_color, filled using the fill_color if any.
161
+
162
+ # Draws a polygon on the canvas using the stroke_color, filled using the
163
+ # fill_color if any.
156
164
  #
157
- # @param [Array, String] The control point vector. Accepts everything {ChunkyPNG.Vector} accepts.
165
+ # @param [Array, String] The control point vector. Accepts everything
166
+ # {ChunkyPNG.Vector} accepts.
158
167
  # @param [Integer] stroke_color The stroke color to use for this polygon.
159
168
  # @param [Integer] fill_color The fill color to use for this polygon.
160
169
  # @return [ChunkyPNG::Canvas] Itself, with the polygon drawn.
161
- def polygon(path, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
162
-
170
+ def polygon(path,
171
+ stroke_color = ChunkyPNG::Color::BLACK,
172
+ fill_color = ChunkyPNG::Color::TRANSPARENT)
173
+
163
174
  vector = ChunkyPNG::Vector(*path)
164
- raise ArgumentError, "A polygon requires at least 3 points" if path.length < 3
175
+ if path.length < 3
176
+ raise ArgumentError, 'A polygon requires at least 3 points'
177
+ end
165
178
 
166
179
  stroke_color = ChunkyPNG::Color.parse(stroke_color)
167
180
  fill_color = ChunkyPNG::Color.parse(fill_color)
@@ -184,15 +197,15 @@ module ChunkyPNG
184
197
  end
185
198
  end
186
199
  end
187
-
200
+
188
201
  # Stroke
189
202
  vector.each_edge do |(from_x, from_y), (to_x, to_y)|
190
203
  line(from_x, from_y, to_x, to_y, stroke_color, false)
191
204
  end
192
205
 
193
- return self
206
+ self
194
207
  end
195
-
208
+
196
209
  # Draws a rectangle on the canvas, using two control points.
197
210
  #
198
211
  # @param [Integer] x0 The x-coordinate of the first control point.
@@ -202,11 +215,13 @@ module ChunkyPNG
202
215
  # @param [Integer] stroke_color The line color to use for this rectangle.
203
216
  # @param [Integer] fill_color The fill color to use for this rectangle.
204
217
  # @return [ChunkyPNG::Canvas] Itself, with the rectangle drawn.
205
- def rect(x0, y0, x1, y1, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
206
-
218
+ def rect(x0, y0, x1, y1,
219
+ stroke_color = ChunkyPNG::Color::BLACK,
220
+ fill_color = ChunkyPNG::Color::TRANSPARENT)
221
+
207
222
  stroke_color = ChunkyPNG::Color.parse(stroke_color)
208
223
  fill_color = ChunkyPNG::Color.parse(fill_color)
209
-
224
+
210
225
  # Fill
211
226
  unless fill_color == ChunkyPNG::Color::TRANSPARENT
212
227
  [x0, x1].min.upto([x0, x1].max) do |x|
@@ -215,16 +230,16 @@ module ChunkyPNG
215
230
  end
216
231
  end
217
232
  end
218
-
233
+
219
234
  # Stroke
220
235
  line(x0, y0, x0, y1, stroke_color, false)
221
236
  line(x0, y1, x1, y1, stroke_color, false)
222
237
  line(x1, y1, x1, y0, stroke_color, false)
223
238
  line(x1, y0, x0, y0, stroke_color, false)
224
-
225
- return self
239
+
240
+ self
226
241
  end
227
-
242
+
228
243
  # Draws a circle on the canvas.
229
244
  #
230
245
  # @param [Integer] x0 The x-coordinate of the center of the circle.
@@ -233,7 +248,9 @@ module ChunkyPNG
233
248
  # @param [Integer] stroke_color The color to use for the line.
234
249
  # @param [Integer] fill_color The color to use that fills the circle.
235
250
  # @return [ChunkyPNG::Canvas] Itself, with the circle drawn.
236
- def circle(x0, y0, radius, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
251
+ def circle(x0, y0, radius,
252
+ stroke_color = ChunkyPNG::Color::BLACK,
253
+ fill_color = ChunkyPNG::Color::TRANSPARENT)
237
254
 
238
255
  stroke_color = ChunkyPNG::Color.parse(stroke_color)
239
256
  fill_color = ChunkyPNG::Color.parse(fill_color)
@@ -283,20 +300,26 @@ module ChunkyPNG
283
300
 
284
301
  unless fill_color == ChunkyPNG::Color::TRANSPARENT
285
302
  lines.each_with_index do |length, y|
286
- line(x0 - length, y0 - y, x0 + length, y0 - y, fill_color) if length > 0
287
- line(x0 - length, y0 + y, x0 + length, y0 + y, fill_color) if length > 0 && y > 0
303
+ if length > 0
304
+ line(x0 - length, y0 - y, x0 + length, y0 - y, fill_color)
305
+ end
306
+ if length > 0 && y > 0
307
+ line(x0 - length, y0 + y, x0 + length, y0 + y, fill_color)
308
+ end
288
309
  end
289
310
  end
290
311
 
291
- return self
312
+ self
292
313
  end
293
-
314
+
294
315
  private
295
-
316
+
296
317
  # Calculates the binomial coefficient for n over k.
297
318
  #
298
- # @param [Integer] n first parameter in coeffient (the number on top when looking at the mathematic formula)
299
- # @param [Integer] k k-element, second parameter in coeffient (the number on the bottom when looking at the mathematic formula)
319
+ # @param [Integer] n first parameter in coeffient (the number on top when
320
+ # looking at the mathematic formula)
321
+ # @param [Integer] k k-element, second parameter in coeffient (the number
322
+ # on the bottom when looking at the mathematic formula)
300
323
  # @return [Integer] The binomial coeffcient of (n,k)
301
324
  def binomial_coefficient(n, k)
302
325
  return 1 if n == k || k == 0