chunky_png 1.3.0 → 1.3.1

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