chunky_png 1.0.0 → 1.0.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.
- data/chunky_png.gemspec +2 -2
- data/lib/chunky_png.rb +1 -1
- data/lib/chunky_png/canvas.rb +15 -10
- data/lib/chunky_png/canvas/drawing.rb +22 -19
- data/lib/chunky_png/color.rb +20 -9
- data/spec/chunky_png/canvas/drawing_spec.rb +3 -9
- data/spec/chunky_png/color_spec.rb +35 -19
- metadata +3 -3
data/chunky_png.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
|
4
4
|
# Do not change the version and date fields by hand. This will be done
|
5
5
|
# automatically by the gem release script.
|
6
|
-
s.version = "1.0.
|
7
|
-
s.date = "2011-03-
|
6
|
+
s.version = "1.0.1"
|
7
|
+
s.date = "2011-03-08"
|
8
8
|
|
9
9
|
s.summary = "Pure ruby library for read/write, chunk-level access to PNG files"
|
10
10
|
s.description = <<-EOT
|
data/lib/chunky_png.rb
CHANGED
@@ -25,7 +25,7 @@ module ChunkyPNG
|
|
25
25
|
|
26
26
|
# The current version of ChunkyPNG. This value will be updated
|
27
27
|
# automatically by them <tt>gem:release</tt> rake task.
|
28
|
-
VERSION = "1.0.
|
28
|
+
VERSION = "1.0.1"
|
29
29
|
|
30
30
|
###################################################
|
31
31
|
# PNG international standard defined constants
|
data/lib/chunky_png/canvas.rb
CHANGED
@@ -74,7 +74,7 @@ module ChunkyPNG
|
|
74
74
|
if initial.kind_of?(Array) && initial.length == width * height
|
75
75
|
@pixels = initial
|
76
76
|
else
|
77
|
-
@pixels = Array.new(width * height, ChunkyPNG::Color(initial))
|
77
|
+
@pixels = Array.new(width * height, ChunkyPNG::Color.parse(initial))
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -128,10 +128,9 @@ module ChunkyPNG
|
|
128
128
|
#
|
129
129
|
# @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the image's dimensions.
|
130
130
|
# @see #set_pixel
|
131
|
-
def []=(
|
132
|
-
|
133
|
-
|
134
|
-
@pixels[point.y * width + point.x] = args.last
|
131
|
+
def []=(x, y, color)
|
132
|
+
assert_xy!(x, y)
|
133
|
+
@pixels[y * width + x] = ChunkyPNG::Color.parse(color)
|
135
134
|
end
|
136
135
|
|
137
136
|
# Replaces a single pixel in this canvas, without bounds checking.
|
@@ -175,10 +174,9 @@ module ChunkyPNG
|
|
175
174
|
#
|
176
175
|
# @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the image's dimensions.
|
177
176
|
# @see #get_pixel
|
178
|
-
def [](
|
179
|
-
|
180
|
-
|
181
|
-
@pixels[point.y * width + point.x]
|
177
|
+
def [](x, y)
|
178
|
+
assert_xy!(x, y)
|
179
|
+
@pixels[y * width + x]
|
182
180
|
end
|
183
181
|
|
184
182
|
# Returns a single pixel from this canvas, without checking bounds. The return value for
|
@@ -235,7 +233,14 @@ module ChunkyPNG
|
|
235
233
|
end
|
236
234
|
|
237
235
|
alias_method :include?, :include_point?
|
238
|
-
|
236
|
+
|
237
|
+
# Checks whether the given x- and y-coordinate are in the range of the canvas
|
238
|
+
# @param [Integer] x The x-coordinate of the pixel (column)
|
239
|
+
# @param [Integer] y The y-coordinate of the pixel (row)
|
240
|
+
# @return [true, false] True if the x- and y-coordinate is in the range of this canvas.
|
241
|
+
def include_xy?(x, y)
|
242
|
+
y >= 0 && y < height && x >= 0 && x < width
|
243
|
+
end
|
239
244
|
|
240
245
|
# Checks whether the given y-coordinate is in the range of the canvas
|
241
246
|
# @param [Integer] y The y-coordinate of the pixel (row)
|
@@ -12,18 +12,21 @@ module ChunkyPNG
|
|
12
12
|
module Drawing
|
13
13
|
|
14
14
|
# Composes a pixel on the canvas by alpha blending a color with its background color.
|
15
|
-
# @
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
15
|
+
# @param [Integer] x The x-coordinate of the pixel to blend.
|
16
|
+
# @param [Integer] y The y-coordinate of the pixel to blend.
|
17
|
+
# @param [Integer] color The foreground color to blend with
|
18
|
+
# @return [Integer] The composed color.
|
19
|
+
def compose_pixel(x, y, color)
|
20
|
+
return unless include_xy?(x, y)
|
21
|
+
compose_pixel_unsafe(x, y, ChunkyPNG::Color.parse(color))
|
22
|
+
end
|
23
|
+
|
24
|
+
# Composes a pixel on the canvas by alpha blending a color with its background color,
|
25
|
+
# without bounds checking.
|
26
|
+
# @param (see #compose_pixel)
|
27
|
+
# @return [Integer] The composed color.
|
28
|
+
def compose_pixel_unsafe(x, y, color)
|
29
|
+
set_pixel(x, y, ChunkyPNG::Color.compose(color, get_pixel(x, y)))
|
27
30
|
end
|
28
31
|
|
29
32
|
# Draws an anti-aliased line using Xiaolin Wu's algorithm.
|
@@ -38,7 +41,7 @@ module ChunkyPNG
|
|
38
41
|
# @return [ChunkyPNG::Canvas] Itself, with the line drawn.
|
39
42
|
def line_xiaolin_wu(x0, y0, x1, y1, stroke_color, inclusive = true)
|
40
43
|
|
41
|
-
stroke_color = ChunkyPNG::Color(stroke_color)
|
44
|
+
stroke_color = ChunkyPNG::Color.parse(stroke_color)
|
42
45
|
|
43
46
|
dx = x1 - x0
|
44
47
|
sx = dx < 0 ? -1 : 1
|
@@ -109,8 +112,8 @@ module ChunkyPNG
|
|
109
112
|
vector = ChunkyPNG::Vector(*path)
|
110
113
|
raise ArgumentError, "A polygon requires at least 3 points" if path.length < 3
|
111
114
|
|
112
|
-
stroke_color = ChunkyPNG::Color(stroke_color)
|
113
|
-
fill_color = ChunkyPNG::Color(fill_color)
|
115
|
+
stroke_color = ChunkyPNG::Color.parse(stroke_color)
|
116
|
+
fill_color = ChunkyPNG::Color.parse(fill_color)
|
114
117
|
|
115
118
|
# Fill
|
116
119
|
unless fill_color == ChunkyPNG::Color::TRANSPARENT
|
@@ -150,8 +153,8 @@ module ChunkyPNG
|
|
150
153
|
# @return [ChunkyPNG::Canvas] Itself, with the rectangle drawn.
|
151
154
|
def rect(x0, y0, x1, y1, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
|
152
155
|
|
153
|
-
stroke_color = ChunkyPNG::Color(stroke_color)
|
154
|
-
fill_color = ChunkyPNG::Color(fill_color)
|
156
|
+
stroke_color = ChunkyPNG::Color.parse(stroke_color)
|
157
|
+
fill_color = ChunkyPNG::Color.parse(fill_color)
|
155
158
|
|
156
159
|
# Fill
|
157
160
|
unless fill_color == ChunkyPNG::Color::TRANSPARENT
|
@@ -181,8 +184,8 @@ module ChunkyPNG
|
|
181
184
|
# @return [ChunkyPNG::Canvas] Itself, with the circle drawn.
|
182
185
|
def circle(x0, y0, radius, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
|
183
186
|
|
184
|
-
stroke_color = ChunkyPNG::Color(stroke_color)
|
185
|
-
fill_color = ChunkyPNG::Color(fill_color)
|
187
|
+
stroke_color = ChunkyPNG::Color.parse(stroke_color)
|
188
|
+
fill_color = ChunkyPNG::Color.parse(fill_color)
|
186
189
|
|
187
190
|
f = 1 - radius
|
188
191
|
ddF_x = 1
|
data/lib/chunky_png/color.rb
CHANGED
@@ -25,18 +25,13 @@ module ChunkyPNG
|
|
25
25
|
# @return [Integer] The determined color value as RGBA integer.
|
26
26
|
# @raise [ArgumentError] if the arguments weren't understood as a color.
|
27
27
|
# @see ChunkyPNG::Color
|
28
|
+
# @see ChunkyPNG::Color.parse
|
28
29
|
def self.Color(*args)
|
29
30
|
case args.length
|
30
|
-
when
|
31
|
+
when 1; ChunkyPNG::Color.parse(args.first)
|
32
|
+
when 2; (ChunkyPNG::Color.parse(args.first) & 0xffffff00) | args[1].to_i
|
31
33
|
when 3; ChunkyPNG::Color.rgb(*args)
|
32
|
-
when
|
33
|
-
when 1
|
34
|
-
case source = args.first.to_s
|
35
|
-
when Integer, /^\d+$/; source.to_i
|
36
|
-
when ChunkyPNG::Color::HEX_COLOR_REGEXP; ChunkyPNG::Color.from_hex(source)
|
37
|
-
when ChunkyPNG::Color::HTML_COLOR_REGEXP; ChunkyPNG::Color.html_color(source)
|
38
|
-
else raise ArgumentError, "Don't know how to create a color from #{source.inspect}!"
|
39
|
-
end
|
34
|
+
when 4; ChunkyPNG::Color.rgba(*args)
|
40
35
|
else raise ArgumentError, "Don't know how to create a color from #{args.inspect}!"
|
41
36
|
end
|
42
37
|
end
|
@@ -72,6 +67,22 @@ module ChunkyPNG
|
|
72
67
|
# CONSTRUCTING COLOR VALUES
|
73
68
|
####################################################################
|
74
69
|
|
70
|
+
# Parses a color value given a numeric or string argument.
|
71
|
+
#
|
72
|
+
# It supports color numbers, colors in hex notation and named HTML colors.
|
73
|
+
#
|
74
|
+
# @param [Integer, String] The color value.
|
75
|
+
# @return [Integer] The color value, with the opacity applied if one was given.
|
76
|
+
def parse(source)
|
77
|
+
return source if source.kind_of?(Integer)
|
78
|
+
case source.to_s
|
79
|
+
when /^\d+$/; source.to_s.to_i
|
80
|
+
when ChunkyPNG::Color::HEX_COLOR_REGEXP; ChunkyPNG::Color.from_hex(source.to_s)
|
81
|
+
when ChunkyPNG::Color::HTML_COLOR_REGEXP; ChunkyPNG::Color.html_color(source.to_s)
|
82
|
+
else raise ArgumentError, "Don't know how to create a color from #{source.inspect}!"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
75
86
|
# Creates a new color using an r, g, b triple and an alpha value.
|
76
87
|
# @param [Integer] r The r-component (0-255)
|
77
88
|
# @param [Integer] g The g-component (0-255)
|
@@ -2,27 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas::Drawing do
|
4
4
|
|
5
|
-
describe '#
|
5
|
+
describe '#compose_pixel' do
|
6
6
|
subject { ChunkyPNG::Canvas.new(1, 1, ChunkyPNG::Color.rgb(200, 150, 100)) }
|
7
7
|
|
8
8
|
it "should compose colors correctly" do
|
9
9
|
subject.compose_pixel(0,0, ChunkyPNG::Color(100, 150, 200, 128))
|
10
|
-
subject[
|
10
|
+
subject[0, 0].should == ChunkyPNG::Color(150, 150, 150)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should return the composed color" do
|
14
14
|
subject.compose_pixel(0, 0, ChunkyPNG::Color.rgba(100, 150, 200, 128)).should == ChunkyPNG::Color.rgb(150, 150, 150)
|
15
15
|
end
|
16
16
|
|
17
|
-
it "should accept point-like arguments as well" do
|
18
|
-
lambda { subject.compose_pixel('0,0', ChunkyPNG::Color.rgba(100, 150, 200, 128)) }.should change { subject['0,0'] }
|
19
|
-
lambda { subject.compose_pixel({:x => 0, :y => 0}, ChunkyPNG::Color.rgba(100, 150, 200, 128)) }.should change { subject['0,0'] }
|
20
|
-
lambda { subject.compose_pixel(ChunkyPNG::Point.new(0, 0), ChunkyPNG::Color.rgba(100, 150, 200, 128)) } .should change { subject['0,0'] }
|
21
|
-
end
|
22
|
-
|
23
17
|
it "should do nothing when the coordinates are out of bounds" do
|
24
18
|
subject.compose_pixel(1, -1, :black).should be_nil
|
25
|
-
lambda { subject.compose_pixel(1, -1, :black) }.should_not change { subject[
|
19
|
+
lambda { subject.compose_pixel(1, -1, :black) }.should_not change { subject[0, 0] }
|
26
20
|
end
|
27
21
|
end
|
28
22
|
|
@@ -1,5 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
describe 'ChunyPNG.Color' do
|
4
|
+
it "should interpret 4 arguments as RGBA values" do
|
5
|
+
ChunkyPNG::Color(1, 2, 3, 4).should == ChunkyPNG::Color.rgba(1, 2, 3, 4)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should interpret 3 arguments as RGBA values" do
|
9
|
+
ChunkyPNG::Color(1, 2, 3).should == ChunkyPNG::Color.rgb(1, 2, 3)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should interpret 2 arguments as a color to parse and an opacity value" do
|
13
|
+
ChunkyPNG::Color('0x0a649664', 0xaa).should == 0x0a6496aa
|
14
|
+
ChunkyPNG::Color('spring green @ 0.6666', 0xff).should == 0x00ff7fff
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should interpret 1 argument as a color to parse" do
|
18
|
+
ChunkyPNG::Color.should_receive(:parse).with('0x0a649664')
|
19
|
+
ChunkyPNG::Color('0x0a649664')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
3
23
|
describe ChunkyPNG::Color do
|
4
24
|
include ChunkyPNG::Color
|
5
25
|
|
@@ -11,25 +31,21 @@ describe ChunkyPNG::Color do
|
|
11
31
|
@fully_transparent = 0x0a649600
|
12
32
|
end
|
13
33
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
ChunkyPNG::Color('spring green').should == 0x00ff7fff
|
30
|
-
ChunkyPNG::Color('spring green @ 0.6666').should == 0x00ff7faa
|
31
|
-
ChunkyPNG::Color('spring green', 0xaa).should == 0x00ff7faa
|
32
|
-
ChunkyPNG::Color('spring green @ 0.6666', 0xff).should == 0x00ff7fff
|
34
|
+
describe '#parse' do
|
35
|
+
it "should interpret a hex string correctly" do
|
36
|
+
parse('0x0a649664').should == ChunkyPNG::Color.from_hex('#0a649664')
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should interpret a color name correctly" do
|
40
|
+
parse(:spring_green).should == 0x00ff7fff
|
41
|
+
parse('spring green').should == 0x00ff7fff
|
42
|
+
parse('spring green @ 0.6666').should == 0x00ff7faa
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return numbers as is" do
|
46
|
+
parse('12345').should == 12345
|
47
|
+
parse(12345).should == 12345
|
48
|
+
end
|
33
49
|
end
|
34
50
|
|
35
51
|
describe '#pixel_bytesize' do
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 1
|
9
|
+
version: 1.0.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Willem van Bergen
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-03-
|
17
|
+
date: 2011-03-08 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|