png 1.1.0 → 1.2.0
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.tar.gz.sig +2 -0
- data/History.txt +59 -17
- data/Manifest.txt +5 -0
- data/Rakefile +11 -10
- data/example/lines.rb +4 -12
- data/lib/png.rb +260 -190
- data/lib/png/default_font.png +0 -0
- data/lib/png/font.rb +73 -0
- data/lib/png/pie.rb +1 -1
- data/lib/png/reader.rb +142 -0
- data/test/test_png.rb +179 -69
- data/test/test_png_font.rb +84 -0
- data/test/test_png_reader.rb +94 -0
- metadata +88 -52
- metadata.gz.sig +0 -0
Binary file
|
data/lib/png/font.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
require 'png/reader'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Implements a simple bitmap font by extracting letters from a PNG.
|
7
|
+
|
8
|
+
class PNG::Font
|
9
|
+
LETTERS = (('A'..'Z').to_a +
|
10
|
+
('a'..'z').to_a +
|
11
|
+
('0'..'9').to_a + [" "] * 16 +
|
12
|
+
'({[<!@#$%^&*?_+-=;,"/~>]})'.split(//))
|
13
|
+
|
14
|
+
attr_reader :height, :width, :canvas
|
15
|
+
|
16
|
+
def self.default
|
17
|
+
@@default ||= new(File.join(File.dirname(__FILE__), "default_font.png"))
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(png_file)
|
21
|
+
@canvas = PNG.load_file png_file
|
22
|
+
@height, @width = canvas.height / 4, canvas.width / 26
|
23
|
+
@cache = {}
|
24
|
+
end
|
25
|
+
|
26
|
+
def coordinates c
|
27
|
+
i = LETTERS.index c
|
28
|
+
|
29
|
+
raise ArgumentError, "Can't find #{c.inspect}" unless i
|
30
|
+
|
31
|
+
x = (i % 26) * width
|
32
|
+
y = (3 - (i / 26)) * height # start from the top (3rd row)
|
33
|
+
|
34
|
+
return x, y, x+width-1, y+height-1
|
35
|
+
end
|
36
|
+
|
37
|
+
def [] c
|
38
|
+
c = c.chr unless String === c
|
39
|
+
x0, y0, x1, y1 = coordinates c
|
40
|
+
|
41
|
+
@cache[c] ||= @canvas.extract(x0, y0, x1, y1)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class PNG::Canvas
|
46
|
+
##
|
47
|
+
# Write a string at [x, y] with font, optionally specifying a font,
|
48
|
+
# an alignment of :left, :center, or :right and the style to draw
|
49
|
+
# the annotation (see #composite).
|
50
|
+
#
|
51
|
+
# require 'png/font'
|
52
|
+
|
53
|
+
def annotate(string, x, y,
|
54
|
+
font = PNG::Font.default, align = :left, style = :overwrite)
|
55
|
+
case align
|
56
|
+
when :left then
|
57
|
+
# do nothing
|
58
|
+
when :center then
|
59
|
+
x -= string.length * font.width / 2
|
60
|
+
when :right then
|
61
|
+
x -= string.length * font.width
|
62
|
+
else
|
63
|
+
raise ArgumentError, "Unknown align: #{align.inspect}"
|
64
|
+
end
|
65
|
+
|
66
|
+
x_offset, width = 0, font.width
|
67
|
+
|
68
|
+
string.split(//).each do |char|
|
69
|
+
self.composite font[char], x + x_offset, y
|
70
|
+
x_offset += width
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/png/pie.rb
CHANGED
data/lib/png/reader.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
require 'png'
|
4
|
+
require 'enumerator'
|
5
|
+
|
6
|
+
class PNG
|
7
|
+
def self.load_file path, metadata_only = false
|
8
|
+
file = File.open(path, 'rb') { |f| f.read }
|
9
|
+
self.load file, metadata_only
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.load png, metadata_only = false
|
13
|
+
png = png.dup
|
14
|
+
signature = png.slice! 0, 8
|
15
|
+
raise ArgumentError, 'Invalid PNG signature' unless signature == SIGNATURE
|
16
|
+
|
17
|
+
ihdr = read_chunk 'IHDR', png
|
18
|
+
|
19
|
+
bit_depth, color_type, width, height = read_IHDR ihdr, metadata_only
|
20
|
+
|
21
|
+
return [width, height, bit_depth] if metadata_only
|
22
|
+
|
23
|
+
canvas = PNG::Canvas.new width, height
|
24
|
+
|
25
|
+
type = png.slice(4, 4).unpack('a4').first
|
26
|
+
read_chunk type, png if type == 'iCCP' # Ignore color profile
|
27
|
+
|
28
|
+
read_IDAT read_chunk('IDAT', png), bit_depth, color_type, canvas
|
29
|
+
read_chunk 'IEND', png
|
30
|
+
|
31
|
+
canvas
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.read_chunk expected_type, png
|
35
|
+
size, type = png.slice!(0, 8).unpack 'Na4'
|
36
|
+
data, crc = png.slice!(0, size + 4).unpack "a#{size}N"
|
37
|
+
|
38
|
+
check_crc type, data, crc
|
39
|
+
|
40
|
+
raise ArgumentError, "Expected #{expected_type} chunk, not #{type}" unless
|
41
|
+
type == expected_type
|
42
|
+
|
43
|
+
return data
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.check_crc type, data, crc
|
47
|
+
return true if (type + data).png_crc == crc
|
48
|
+
raise ArgumentError, "Invalid CRC encountered in #{type} chunk"
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.read_IHDR data, metadata_only = false
|
52
|
+
width, height, bit_depth, color_type, *rest = data.unpack 'N2C5'
|
53
|
+
|
54
|
+
unless metadata_only then
|
55
|
+
raise ArgumentError, "Wrong bit depth: #{bit_depth}" unless
|
56
|
+
bit_depth == 8
|
57
|
+
raise ArgumentError, "Wrong color type: #{color_type}" unless
|
58
|
+
color_type == RGBA or color_type = RGB
|
59
|
+
raise ArgumentError, "Unsupported options: #{rest.inspect}" unless
|
60
|
+
rest == [0, 0, 0]
|
61
|
+
end
|
62
|
+
|
63
|
+
return bit_depth, color_type, width, height
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.read_IDAT data, bit_depth, color_type, canvas
|
67
|
+
data = Zlib::Inflate.inflate(data).unpack 'C*'
|
68
|
+
|
69
|
+
pixel_size = color_type == RGBA ? 4 : 3
|
70
|
+
|
71
|
+
height = canvas.height
|
72
|
+
scanline_length = pixel_size * canvas.width + 1 # for filter
|
73
|
+
|
74
|
+
row = canvas.height - 1
|
75
|
+
until data.empty? do
|
76
|
+
row_data = data.slice! 0, scanline_length
|
77
|
+
|
78
|
+
filter = row_data.shift
|
79
|
+
case filter
|
80
|
+
when NONE then
|
81
|
+
when SUB then
|
82
|
+
row_data.each_with_index do |byte, index|
|
83
|
+
left = index < pixel_size ? 0 : row_data[index - pixel_size]
|
84
|
+
row_data[index] = (byte + left) % 256
|
85
|
+
end
|
86
|
+
when UP then
|
87
|
+
row_data.each_with_index do |byte, index|
|
88
|
+
col = index / pixel_size
|
89
|
+
upper = row == 0 ? 0 : canvas[col, row + 1].values[index % pixel_size]
|
90
|
+
row_data[index] = (upper + byte) % 256
|
91
|
+
end
|
92
|
+
when AVG then
|
93
|
+
row_data.each_with_index do |byte, index|
|
94
|
+
col = index / pixel_size
|
95
|
+
upper = row == 0 ? 0 : canvas[col, row + 1].values[index % pixel_size]
|
96
|
+
left = index < pixel_size ? 0 : row_data[index - pixel_size]
|
97
|
+
|
98
|
+
row_data[index] = (byte + ((left + upper)/2).floor) % 256
|
99
|
+
end
|
100
|
+
when PAETH then
|
101
|
+
left = upper = upper_left = nil
|
102
|
+
row_data.each_with_index do |byte, index|
|
103
|
+
col = index / pixel_size
|
104
|
+
|
105
|
+
left = index < pixel_size ? 0 : row_data[index - pixel_size]
|
106
|
+
if row == height then
|
107
|
+
upper = upper_left = 0
|
108
|
+
else
|
109
|
+
upper = canvas[col, row + 1].values[index % pixel_size]
|
110
|
+
upper_left = col == 0 ? 0 :
|
111
|
+
canvas[col - 1, row + 1].values[index % pixel_size]
|
112
|
+
end
|
113
|
+
|
114
|
+
paeth = paeth left, upper, upper_left
|
115
|
+
row_data[index] = (byte + paeth) % 256
|
116
|
+
end
|
117
|
+
else
|
118
|
+
raise ArgumentError, "invalid filter algorithm #{filter}"
|
119
|
+
end
|
120
|
+
|
121
|
+
col = 0
|
122
|
+
row_data.each_slice pixel_size do |slice|
|
123
|
+
slice << 0xFF if pixel_size == 3
|
124
|
+
canvas[col, row] = PNG::Color.new(*slice)
|
125
|
+
col += 1
|
126
|
+
end
|
127
|
+
|
128
|
+
row -= 1
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.paeth a, b, c # left, above, upper left
|
133
|
+
p = a + b - c
|
134
|
+
pa = (p - a).abs
|
135
|
+
pb = (p - b).abs
|
136
|
+
pc = (p - c).abs
|
137
|
+
|
138
|
+
return a if pa <= pb && pa <= pc
|
139
|
+
return b if pb <= pc
|
140
|
+
c
|
141
|
+
end
|
142
|
+
end
|
data/test/test_png.rb
CHANGED
@@ -1,43 +1,37 @@
|
|
1
|
-
|
1
|
+
dir = File.expand_path "~/.ruby_inline"
|
2
|
+
if test ?d, dir then
|
3
|
+
require 'fileutils'
|
4
|
+
puts "nuking #{dir}"
|
5
|
+
# force removal, Windoze is bitching at me, something to hunt later...
|
6
|
+
FileUtils.rm_r dir, :force => true
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'minitest/autorun'
|
2
10
|
require 'rubygems'
|
3
11
|
require 'png'
|
12
|
+
require 'png/reader'
|
4
13
|
require 'png/pie'
|
5
14
|
|
6
|
-
class TestPng <
|
7
|
-
|
15
|
+
class TestPng < MiniTest::Unit::TestCase
|
8
16
|
def setup
|
9
17
|
@canvas = PNG::Canvas.new 5, 10, PNG::Color::White
|
10
18
|
@png = PNG.new @canvas
|
11
19
|
|
12
|
-
@IHDR_length = "\000\000\000\r"
|
13
|
-
@IHDR_crc = "\2152\317\275"
|
14
|
-
@IHDR_crc_value = @IHDR_crc.unpack('N').first
|
15
|
-
@IHDR_data = "\000\000\000\n\000\000\000\n\b\006\000\000\000"
|
16
|
-
@IHDR_chunk = "#{@IHDR_length}IHDR#{@IHDR_data}#{@IHDR_crc}"
|
17
|
-
|
18
20
|
@blob = <<-EOF.unpack('m*').first
|
19
21
|
iVBORw0KGgoAAAANSUhEUgAAAAUAAAAKCAYAAAB8OZQwAAAAD0lEQVR4nGP4
|
20
22
|
jwUwDGVBALuJxzlQugpEAAAAAElFTkSuQmCC
|
21
23
|
EOF
|
22
24
|
end
|
23
25
|
|
24
|
-
def test_class_check_crc
|
25
|
-
assert PNG.check_crc('IHDR', @IHDR_data, @IHDR_crc_value)
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_class_check_crc_exception
|
29
|
-
begin
|
30
|
-
PNG.check_crc('IHDR', @IHDR_data, @IHDR_crc_value + 1)
|
31
|
-
rescue ArgumentError => e
|
32
|
-
assert_equal "Invalid CRC encountered in IHDR chunk", e.message
|
33
|
-
else
|
34
|
-
flunk "exception wasn't raised"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
26
|
def test_class_chunk
|
39
27
|
chunk = PNG.chunk 'IHDR', [10, 10, 8, 6, 0, 0, 0 ].pack('N2C5')
|
40
|
-
|
28
|
+
|
29
|
+
header_crc = "\2152\317\275"
|
30
|
+
header_data = "\000\000\000\n\000\000\000\n\b\006\000\000\000"
|
31
|
+
header_length = "\000\000\000\r"
|
32
|
+
header_chunk = "#{header_length}IHDR#{header_data}#{header_crc}"
|
33
|
+
|
34
|
+
assert_equal header_chunk, chunk
|
41
35
|
end
|
42
36
|
|
43
37
|
def test_class_chunk_empty
|
@@ -53,17 +47,104 @@ jwUwDGVBALuJxzlQugpEAAAAAElFTkSuQmCC
|
|
53
47
|
def test_save
|
54
48
|
path = "blah.png"
|
55
49
|
@png.save(path)
|
56
|
-
|
50
|
+
file = File.open(path, 'rb') { |f| f.read }
|
51
|
+
assert_equal @blob, file
|
57
52
|
ensure
|
58
53
|
assert_equal 1, File.unlink(path)
|
59
54
|
end
|
60
55
|
|
61
|
-
|
56
|
+
end
|
57
|
+
|
58
|
+
class TestCanvas < MiniTest::Unit::TestCase
|
62
59
|
|
63
60
|
def setup
|
64
61
|
@canvas = PNG::Canvas.new 5, 10, PNG::Color::White
|
65
62
|
end
|
66
63
|
|
64
|
+
def test_composite_default
|
65
|
+
canvas1, canvas2 = util_composite_canvases
|
66
|
+
|
67
|
+
canvas1.composite canvas2, 1, 1
|
68
|
+
|
69
|
+
expected = " xxxxxxxx
|
70
|
+
xxxxxxxx
|
71
|
+
xx..xxxx
|
72
|
+
..xxxxxx
|
73
|
+
".gsub(/ /, '')
|
74
|
+
|
75
|
+
assert_equal expected, canvas1.to_s.gsub(/ /, 'x')
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_composite_underlay
|
79
|
+
canvas1, canvas2 = util_composite_canvases
|
80
|
+
|
81
|
+
canvas1.composite canvas2, 1, 1, :add
|
82
|
+
|
83
|
+
expected = " xxxxxxxx
|
84
|
+
xxxx..xx
|
85
|
+
xx00xxxx
|
86
|
+
..xxxxxx
|
87
|
+
".gsub(/ /, '')
|
88
|
+
|
89
|
+
assert_equal expected, canvas1.to_s.gsub(/ /, 'x')
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_composite_overlay
|
93
|
+
canvas1, canvas2 = util_composite_canvases
|
94
|
+
|
95
|
+
canvas1.composite canvas2, 1, 1, :overlay
|
96
|
+
|
97
|
+
expected = " xxxxxxxx
|
98
|
+
xxxx..xx
|
99
|
+
xx..xxxx
|
100
|
+
..xxxxxx
|
101
|
+
".gsub(/ /, '')
|
102
|
+
|
103
|
+
assert_equal expected, canvas1.to_s.gsub(/ /, 'x')
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_composite_blend
|
107
|
+
canvas1, canvas2 = util_composite_canvases
|
108
|
+
|
109
|
+
canvas1.composite canvas2, 1, 1, :blend
|
110
|
+
|
111
|
+
expected = " xxxxxxxx
|
112
|
+
xxxx..xx
|
113
|
+
xx,,xxxx
|
114
|
+
..xxxxxx
|
115
|
+
".gsub(/ /, '')
|
116
|
+
|
117
|
+
assert_equal expected, canvas1.to_s.gsub(/ /, 'x')
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_composite_bad_style
|
121
|
+
canvas1, canvas2 = util_composite_canvases
|
122
|
+
|
123
|
+
assert_raises RuntimeError do
|
124
|
+
canvas1.composite canvas2, 1, 1, :bad
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_extract
|
129
|
+
canvas1, _ = util_composite_canvases
|
130
|
+
|
131
|
+
expected = " xxxxxxxx
|
132
|
+
xxxx..xx
|
133
|
+
xx00xxxx
|
134
|
+
..xxxxxx
|
135
|
+
".gsub(/ /, '')
|
136
|
+
|
137
|
+
assert_equal expected, canvas1.to_s.gsub(/ /, 'x')
|
138
|
+
|
139
|
+
canvas2 = canvas1.extract(1, 1, 2, 2)
|
140
|
+
|
141
|
+
expected = " xx..
|
142
|
+
00xx
|
143
|
+
".gsub(/ /, '')
|
144
|
+
|
145
|
+
assert_equal expected, canvas2.to_s.gsub(/ /, 'x')
|
146
|
+
end
|
147
|
+
|
67
148
|
def test_index
|
68
149
|
assert_equal PNG::Color::White, @canvas[1, 2]
|
69
150
|
assert_same @canvas[1, 2], @canvas.data[1][2]
|
@@ -162,7 +243,7 @@ class TestCanvas < Test::Unit::TestCase
|
|
162
243
|
end
|
163
244
|
|
164
245
|
def test_point
|
165
|
-
assert_equal PNG::Color.new(
|
246
|
+
assert_equal PNG::Color.new(0xff, 0x7f, 0xff, 0xff),
|
166
247
|
@canvas.point(0, 0, PNG::Color::Magenta)
|
167
248
|
# flunk "this doesn't test ANYTHING"
|
168
249
|
end
|
@@ -171,15 +252,15 @@ class TestCanvas < Test::Unit::TestCase
|
|
171
252
|
@canvas.line 0, 9, 4, 0, PNG::Color::Black
|
172
253
|
|
173
254
|
expected = <<-EOF
|
174
|
-
..00000000
|
175
255
|
,,00000000
|
176
|
-
|
256
|
+
,,00000000
|
257
|
+
,,,,000000
|
177
258
|
00..000000
|
178
|
-
00
|
259
|
+
00,,,,0000
|
179
260
|
0000..0000
|
180
|
-
0000
|
261
|
+
0000,,,,00
|
181
262
|
000000..00
|
182
|
-
000000
|
263
|
+
000000,,,,
|
183
264
|
00000000..
|
184
265
|
EOF
|
185
266
|
|
@@ -190,25 +271,21 @@ class TestCanvas < Test::Unit::TestCase
|
|
190
271
|
@canvas.line 0, 0, 4, 9, PNG::Color::Black
|
191
272
|
|
192
273
|
expected = <<-EOF
|
193
|
-
00000000..
|
194
274
|
00000000,,
|
195
|
-
|
275
|
+
00000000,,
|
276
|
+
000000,,,,
|
196
277
|
000000..00
|
197
|
-
0000
|
278
|
+
0000,,,,00
|
198
279
|
0000..0000
|
199
|
-
00
|
280
|
+
00,,,,0000
|
200
281
|
00..000000
|
201
|
-
|
282
|
+
,,,,000000
|
202
283
|
..00000000
|
203
284
|
EOF
|
204
285
|
|
205
286
|
assert_equal expected, @canvas.to_s
|
206
287
|
end
|
207
288
|
|
208
|
-
def util_ascii_art(width, height)
|
209
|
-
(("0" * width * 2) + "\n") * height
|
210
|
-
end
|
211
|
-
|
212
289
|
def test_to_s_normal
|
213
290
|
@canvas = PNG::Canvas.new 5, 10, PNG::Color::White
|
214
291
|
expected = util_ascii_art(5, 10)
|
@@ -233,31 +310,39 @@ class TestCanvas < Test::Unit::TestCase
|
|
233
310
|
assert_equal expected, @canvas.to_s
|
234
311
|
end
|
235
312
|
|
236
|
-
|
237
|
-
|
313
|
+
def util_composite_canvases
|
314
|
+
canvas1 = PNG::Canvas.new 4, 4
|
315
|
+
canvas1[0, 0] = PNG::Color::Black
|
316
|
+
canvas1[1, 1] = PNG::Color::White
|
317
|
+
canvas1[2, 2] = PNG::Color::Black
|
238
318
|
|
239
|
-
|
240
|
-
|
241
|
-
|
319
|
+
expected = " xxxxxxxx
|
320
|
+
xxxx..xx
|
321
|
+
xx00xxxx
|
322
|
+
..xxxxxx
|
323
|
+
".gsub(/ /, '')
|
242
324
|
|
243
|
-
|
244
|
-
# canvas = PNG::Canvas.new 10, 10, PNG::Color::White
|
325
|
+
assert_equal expected, canvas1.to_s.gsub(/ /, 'x')
|
245
326
|
|
246
|
-
# data = "x\332c\370O$`\030UH_\205\000#\373\216\200"
|
247
327
|
|
248
|
-
|
328
|
+
canvas2 = PNG::Canvas.new 2, 2
|
329
|
+
canvas2[0, 0] = PNG::Color::Black
|
249
330
|
|
250
|
-
|
251
|
-
|
331
|
+
expected = " xxxx
|
332
|
+
..xx
|
333
|
+
".gsub(/ /, '')
|
252
334
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
335
|
+
assert_equal expected, canvas2.to_s.gsub(/ /, 'x')
|
336
|
+
|
337
|
+
return canvas1, canvas2
|
338
|
+
end
|
339
|
+
|
340
|
+
def util_ascii_art(width, height)
|
341
|
+
(("0" * width * 2) + "\n") * height
|
342
|
+
end
|
258
343
|
end
|
259
344
|
|
260
|
-
class TestPng::TestColor <
|
345
|
+
class TestPng::TestColor < MiniTest::Unit::TestCase
|
261
346
|
def setup
|
262
347
|
@color = PNG::Color.new 0x01, 0x02, 0x03, 0x04
|
263
348
|
end
|
@@ -295,10 +380,16 @@ class TestPng::TestColor < Test::Unit::TestCase
|
|
295
380
|
end
|
296
381
|
|
297
382
|
def test_blend
|
298
|
-
|
299
|
-
|
383
|
+
# c1 = @color
|
384
|
+
# c2 = PNG::Color.new 0xFF, 0xFE, 0xFD, 0xFC
|
385
|
+
|
386
|
+
# assert_equal PNG::Color.new(0xFB, 0xFA, 0xF9, 0xF8), c1.blend(c2)
|
387
|
+
|
388
|
+
c1 = PNG::Color::White
|
389
|
+
c2 = PNG::Color::Black
|
300
390
|
|
301
|
-
assert_equal PNG::Color
|
391
|
+
assert_equal PNG::Color::Gray, c2.blend(c1)
|
392
|
+
assert_equal PNG::Color::Gray, c1.blend(c2)
|
302
393
|
end
|
303
394
|
|
304
395
|
def test_intensity
|
@@ -313,6 +404,21 @@ class TestPng::TestColor < Test::Unit::TestCase
|
|
313
404
|
assert_equal "#<PNG::Color Red>", PNG::Color::Red.inspect
|
314
405
|
end
|
315
406
|
|
407
|
+
def test_pipe
|
408
|
+
b = PNG::Color::Black
|
409
|
+
w = PNG::Color::White
|
410
|
+
t = PNG::Color::Background
|
411
|
+
|
412
|
+
# first non-transparent
|
413
|
+
assert_equal b, b | t
|
414
|
+
assert_equal b, t | b
|
415
|
+
|
416
|
+
assert_equal b, b | w
|
417
|
+
assert_equal w, w | b
|
418
|
+
|
419
|
+
assert_equal t, t | t
|
420
|
+
end
|
421
|
+
|
316
422
|
def test_to_ascii
|
317
423
|
assert_equal '00', PNG::Color::White.to_ascii, "white"
|
318
424
|
assert_equal '++', PNG::Color::Yellow.to_ascii, "yellow"
|
@@ -325,7 +431,7 @@ class TestPng::TestColor < Test::Unit::TestCase
|
|
325
431
|
assert_equal '00', PNG::Color.new(255,255,255,255).to_ascii
|
326
432
|
assert_equal '00', PNG::Color.new(255,255,255,192).to_ascii
|
327
433
|
assert_equal '++', PNG::Color.new(255,255,255,191).to_ascii
|
328
|
-
assert_equal '
|
434
|
+
assert_equal ',,', PNG::Color.new(255,255,255,127).to_ascii
|
329
435
|
assert_equal ',,', PNG::Color.new(255,255,255,126).to_ascii
|
330
436
|
assert_equal ',,', PNG::Color.new(255,255,255, 64).to_ascii
|
331
437
|
assert_equal '..', PNG::Color.new(255,255,255, 63).to_ascii
|
@@ -342,18 +448,22 @@ class TestPng::TestColor < Test::Unit::TestCase
|
|
342
448
|
assert_equal '#<PNG::Color:0xXXXXXX>', obj.to_s.sub(/0x[0-9a-f]+/, '0xXXXXXX')
|
343
449
|
end
|
344
450
|
|
451
|
+
def test_equals2
|
452
|
+
assert_equal PNG::Color.new(255,255,255, 0), PNG::Color.new(255,255,255, 0)
|
453
|
+
end
|
454
|
+
|
455
|
+
def test_hash
|
456
|
+
a = PNG::Color.new(255,255,255, 0)
|
457
|
+
b = PNG::Color.new(255,255,255, 0)
|
458
|
+
assert_equal a.hash, b.hash
|
459
|
+
end
|
460
|
+
|
345
461
|
# def test_values
|
346
462
|
# raise NotImplementedError, 'Need to write test_values'
|
347
463
|
# end
|
348
464
|
end
|
349
465
|
|
350
|
-
|
351
|
-
|
352
|
-
class TestPng::TestPie < Test::Unit::TestCase
|
353
|
-
def setup
|
354
|
-
|
355
|
-
end
|
356
|
-
|
466
|
+
class TestPng::TestPie < MiniTest::Unit::TestCase
|
357
467
|
def test_pie_chart_odd
|
358
468
|
expected =
|
359
469
|
[" .. ",
|