processing 0.5.31 → 0.5.32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +15 -0
- data/VERSION +1 -1
- data/lib/processing/font.rb +30 -3
- data/lib/processing/graphics.rb +0 -11
- data/lib/processing/graphics_context.rb +304 -55
- data/lib/processing/image.rb +38 -10
- data/lib/processing/shape.rb +138 -27
- data/processing.gemspec +3 -3
- data/test/helper.rb +2 -3
- data/test/p5.rb +5 -4
- data/test/test_font.rb +33 -2
- data/test/test_graphics_context.rb +220 -0
- data/test/test_image.rb +21 -0
- data/test/test_shape.rb +125 -0
- metadata +8 -8
data/lib/processing/image.rb
CHANGED
@@ -10,6 +10,7 @@ module Processing
|
|
10
10
|
# @private
|
11
11
|
def initialize(image)
|
12
12
|
@image = image
|
13
|
+
@pixels, @error = nil, false
|
13
14
|
end
|
14
15
|
|
15
16
|
# Gets width of image.
|
@@ -17,7 +18,7 @@ module Processing
|
|
17
18
|
# @return [Numeric] width of image
|
18
19
|
#
|
19
20
|
def width()
|
20
|
-
@image
|
21
|
+
@image&.width || (@error ? -1 : 0)
|
21
22
|
end
|
22
23
|
|
23
24
|
# Gets height of image.
|
@@ -25,7 +26,7 @@ module Processing
|
|
25
26
|
# @return [Numeric] height of image
|
26
27
|
#
|
27
28
|
def height()
|
28
|
-
@image
|
29
|
+
@image&.height || (@error ? -1 : 0)
|
29
30
|
end
|
30
31
|
|
31
32
|
alias w width
|
@@ -36,7 +37,7 @@ module Processing
|
|
36
37
|
# @return [Array<Numeric>] [width, height]
|
37
38
|
#
|
38
39
|
def size()
|
39
|
-
|
40
|
+
[width, height]
|
40
41
|
end
|
41
42
|
|
42
43
|
# Sets the color of the pixel.
|
@@ -48,21 +49,43 @@ module Processing
|
|
48
49
|
# @return [nil] nil
|
49
50
|
#
|
50
51
|
def set(x, y, c)
|
51
|
-
|
52
|
+
getInternal__.bitmap[x, y] = self.class.fromColor__ c
|
52
53
|
nil
|
53
54
|
end
|
54
55
|
|
55
|
-
|
56
56
|
# Returns the color of the pixel.
|
57
57
|
#
|
58
58
|
# @return [Integer] color value (0xAARRGGBB)
|
59
59
|
#
|
60
60
|
def get(x, y)
|
61
|
-
|
61
|
+
getInternal__.bitmap[x, y]
|
62
62
|
.map {|n| (n * 255).to_i.clamp 0, 255}
|
63
63
|
.then {|r, g, b, a| self.class.toColor__ r, g, b, a}
|
64
64
|
end
|
65
65
|
|
66
|
+
# Loads all pixels to the 'pixels' array.
|
67
|
+
#
|
68
|
+
# @return [nil] nil
|
69
|
+
#
|
70
|
+
def loadPixels()
|
71
|
+
@pixels = getInternal__.pixels
|
72
|
+
end
|
73
|
+
|
74
|
+
# Update the image pixels with the 'pixels' array.
|
75
|
+
#
|
76
|
+
# @return [nil] nil
|
77
|
+
#
|
78
|
+
def updatePixels()
|
79
|
+
return unless @pixels
|
80
|
+
getInternal__.pixels = @pixels
|
81
|
+
@pixels = nil
|
82
|
+
end
|
83
|
+
|
84
|
+
# An array of all pixels.
|
85
|
+
# Call loadPixels() before accessing the array.
|
86
|
+
#
|
87
|
+
attr_reader :pixels
|
88
|
+
|
66
89
|
# Applies an image filter.
|
67
90
|
#
|
68
91
|
# overload filter(shader)
|
@@ -86,7 +109,7 @@ module Processing
|
|
86
109
|
#
|
87
110
|
def resize(width, height)
|
88
111
|
@image = Rays::Image.new(width, height).paint do |painter|
|
89
|
-
painter.image
|
112
|
+
painter.image getInternal__, 0, 0, width, height
|
90
113
|
end
|
91
114
|
nil
|
92
115
|
end
|
@@ -132,7 +155,7 @@ module Processing
|
|
132
155
|
#
|
133
156
|
def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
134
157
|
img ||= self
|
135
|
-
|
158
|
+
getInternal__.paint do |painter|
|
136
159
|
img.drawImage__ painter, sx, sy, sw, sh, dx, dy, dw, dh, blend_mode: mode
|
137
160
|
end
|
138
161
|
nil
|
@@ -145,13 +168,18 @@ module Processing
|
|
145
168
|
# @return [nil] nil
|
146
169
|
#
|
147
170
|
def save(filename)
|
148
|
-
|
171
|
+
getInternal__.save filename
|
149
172
|
nil
|
150
173
|
end
|
151
174
|
|
152
175
|
# @private
|
153
176
|
def getInternal__()
|
154
|
-
@image
|
177
|
+
@image or raise 'Invalid image object'
|
178
|
+
end
|
179
|
+
|
180
|
+
# @private
|
181
|
+
def setInternal__(image, error = false)
|
182
|
+
@image, @error = image, error
|
155
183
|
end
|
156
184
|
|
157
185
|
# @private
|
data/lib/processing/shape.rb
CHANGED
@@ -7,10 +7,11 @@ module Processing
|
|
7
7
|
|
8
8
|
# @private
|
9
9
|
def initialize(polygon = nil, children = nil, context: nil)
|
10
|
-
@polygon, @children
|
11
|
-
@context
|
12
|
-
@visible, @matrix
|
13
|
-
@
|
10
|
+
@polygon, @children = polygon, children
|
11
|
+
@context = context || Context.context__
|
12
|
+
@visible, @fill, @matrix = true, nil, nil
|
13
|
+
@type = @points = @curvePoints = @colors = @texcoords = @close = nil
|
14
|
+
@contours = @contourPoints = @contourColors = @contourTexCoords = nil
|
14
15
|
end
|
15
16
|
|
16
17
|
# Gets width of shape.
|
@@ -53,22 +54,105 @@ module Processing
|
|
53
54
|
nil
|
54
55
|
end
|
55
56
|
|
56
|
-
def beginShape(
|
57
|
-
|
58
|
-
@
|
59
|
-
@
|
57
|
+
def beginShape(type = nil)
|
58
|
+
raise "beginShape() cannot be called twice" if drawingShape__
|
59
|
+
@type = type
|
60
|
+
@points ||= []
|
61
|
+
@curvePoints = []
|
62
|
+
@colors ||= []
|
63
|
+
@texcoords ||= []
|
64
|
+
@close = nil
|
65
|
+
@contours ||= []
|
66
|
+
clearCache__
|
60
67
|
nil
|
61
68
|
end
|
62
69
|
|
63
70
|
def endShape(close = nil)
|
64
|
-
raise "endShape() must be called after beginShape()" unless
|
65
|
-
@
|
71
|
+
raise "endShape() must be called after beginShape()" unless drawingShape__
|
72
|
+
@close = close == GraphicsContext::CLOSE || @contours.size > 0
|
73
|
+
if @close && @curvePoints.size >= 8
|
74
|
+
x, y = @curvePoints[0, 2]
|
75
|
+
2.times {curveVertex x, y}
|
76
|
+
end
|
77
|
+
@curvePoints = nil
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def beginContour()
|
82
|
+
raise "beginContour() must be called after beginShape()" unless drawingShape__
|
83
|
+
@contourPoints, @contourColors, @contourTexCoords = [], [], []
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def endContour()
|
88
|
+
raise "endContour() must be called after beginContour()" unless drawingContour__
|
89
|
+
@contours << Rays::Polyline.new(
|
90
|
+
*@contourPoints, colors: @contourColors, texcoords: @contourTexCoords,
|
91
|
+
loop: true, hole: true)
|
92
|
+
@contoursPoints = @contoursColors = @contoursTexCoords = nil
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
96
|
+
def vertex(x, y, u = nil, v = nil)
|
97
|
+
raise "vertex() must be called after beginShape()" unless drawingShape__
|
98
|
+
raise "Either 'u' or 'v' is missing" if (u == nil) != (v == nil)
|
99
|
+
u ||= x
|
100
|
+
v ||= y
|
101
|
+
color = @fill || @context.getFill__
|
102
|
+
if drawingContour__
|
103
|
+
@contourPoints << x << y
|
104
|
+
@contourColors << color
|
105
|
+
@contourTexCoords << u << v
|
106
|
+
else
|
107
|
+
@points << x << y
|
108
|
+
@colors << color
|
109
|
+
@texcoords << u << v
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def curveVertex(x, y)
|
114
|
+
raise "curveVertex() must be called after beginShape()" unless drawingShape__
|
115
|
+
@curvePoints << x << y
|
116
|
+
if @curvePoints.size >= 8
|
117
|
+
Rays::Polygon.curve(*@curvePoints[-8, 8])
|
118
|
+
.first.to_a.tap {|a| a.shift if @curvePoints.size > 8}
|
119
|
+
.each {|p| vertex p.x, p.y}
|
120
|
+
end
|
66
121
|
nil
|
67
122
|
end
|
68
123
|
|
69
|
-
def
|
70
|
-
raise "
|
71
|
-
|
124
|
+
def bezierVertex(x2, y2, x3, y3, x4, y4)
|
125
|
+
raise "bezierVertex() must be called after beginShape()" unless drawingShape__
|
126
|
+
x1, y1 = @points[-2, 2]
|
127
|
+
raise "vertex() is required before calling bezierVertex()" unless x1 && y1
|
128
|
+
Rays::Polygon.bezier(x1, y1, x2, y2, x3, y3, x4, y4)
|
129
|
+
.first.to_a.tap {|a| a.shift}
|
130
|
+
.each {|p| vertex p.x, p.y}
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
|
134
|
+
def quadraticVertex(cx, cy, x3, y3)
|
135
|
+
x1, y1 = @points[-2, 2]
|
136
|
+
raise "vertex() is required before calling quadraticVertex()" unless x1 && y1
|
137
|
+
bezierVertex(
|
138
|
+
x1 + (cx - x1) * 2.0 / 3.0, y1 + (cy - y1) * 2.0 / 3.0,
|
139
|
+
x3 + (cx - x3) * 2.0 / 3.0, y3 + (cy - y3) * 2.0 / 3.0,
|
140
|
+
x3, y3)
|
141
|
+
nil
|
142
|
+
end
|
143
|
+
|
144
|
+
# @private
|
145
|
+
def drawingShape__()
|
146
|
+
@curvePoints
|
147
|
+
end
|
148
|
+
|
149
|
+
# @private
|
150
|
+
def drawingContour__()
|
151
|
+
@contourPoints
|
152
|
+
end
|
153
|
+
|
154
|
+
def fill(*args)
|
155
|
+
@fill = @context.toRaysColor__(*args)
|
72
156
|
end
|
73
157
|
|
74
158
|
def setVertex(index, point)
|
@@ -88,6 +172,23 @@ module Processing
|
|
88
172
|
@points.size / 2
|
89
173
|
end
|
90
174
|
|
175
|
+
def setFill(*args)
|
176
|
+
color = @context.toRaysColor__(*args)
|
177
|
+
count = getVertexCount
|
178
|
+
if count > 0
|
179
|
+
if @colors
|
180
|
+
@colors.fill color
|
181
|
+
else
|
182
|
+
@colors = [color] * count
|
183
|
+
end
|
184
|
+
clearCache__
|
185
|
+
elsif @polygon
|
186
|
+
@polygon = @polygon.transform do |polylines|
|
187
|
+
polylines.map {|pl| pl.with colors: pl.points.map {color}}
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
91
192
|
def addChild(child)
|
92
193
|
return unless @children
|
93
194
|
@children.push child
|
@@ -125,6 +226,11 @@ module Processing
|
|
125
226
|
def rotateY = nil
|
126
227
|
def rotateZ = nil
|
127
228
|
|
229
|
+
# @private
|
230
|
+
def clearCache__()
|
231
|
+
@polygon = nil# clear cache
|
232
|
+
end
|
233
|
+
|
128
234
|
# @private
|
129
235
|
def matrix__()
|
130
236
|
@matrix ||= Rays::Matrix.new
|
@@ -133,8 +239,10 @@ module Processing
|
|
133
239
|
# @private
|
134
240
|
def getInternal__()
|
135
241
|
unless @polygon
|
136
|
-
return nil unless @points && @
|
137
|
-
@polygon = self.class.createPolygon__
|
242
|
+
return nil unless @points && @close != nil
|
243
|
+
@polygon = self.class.createPolygon__(
|
244
|
+
@type, @points, @close, @colors, @texcoords)
|
245
|
+
@polygon += @contours if @polygon
|
138
246
|
end
|
139
247
|
@polygon
|
140
248
|
end
|
@@ -162,18 +270,21 @@ module Processing
|
|
162
270
|
end
|
163
271
|
|
164
272
|
# @private
|
165
|
-
def self.createPolygon__(
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
when g::
|
172
|
-
when g::
|
173
|
-
when g::
|
174
|
-
when g::
|
175
|
-
when g::
|
176
|
-
|
273
|
+
def self.createPolygon__(
|
274
|
+
type, points, close = false, colors = nil, texcoords = nil)
|
275
|
+
|
276
|
+
kwargs = {colors: colors, texcoords: texcoords}
|
277
|
+
g, p = GraphicsContext, Rays::Polygon
|
278
|
+
case type
|
279
|
+
when g::POINTS then p.points( *points)
|
280
|
+
when g::LINES then p.lines( *points)
|
281
|
+
when g::TRIANGLES then p.triangles( *points, **kwargs)
|
282
|
+
when g::TRIANGLE_FAN then p.triangle_fan( *points, **kwargs)
|
283
|
+
when g::TRIANGLE_STRIP then p.triangle_strip(*points, **kwargs)
|
284
|
+
when g::QUADS then p.quads( *points, **kwargs)
|
285
|
+
when g::QUAD_STRIP then p.quad_strip( *points, **kwargs)
|
286
|
+
when g::TESS, nil then p.new( *points, **kwargs, loop: close)
|
287
|
+
else raise ArgumentError, "invalid polygon type '#{type}'"
|
177
288
|
end
|
178
289
|
end
|
179
290
|
|
data/processing.gemspec
CHANGED
@@ -26,9 +26,9 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.required_ruby_version = '>= 3.0.0'
|
27
27
|
|
28
28
|
s.add_runtime_dependency 'xot', '~> 0.1.41'
|
29
|
-
s.add_runtime_dependency 'rucy', '~> 0.1.
|
30
|
-
s.add_runtime_dependency 'rays', '~> 0.1.
|
31
|
-
s.add_runtime_dependency 'reflexion', '~> 0.1.
|
29
|
+
s.add_runtime_dependency 'rucy', '~> 0.1.43'
|
30
|
+
s.add_runtime_dependency 'rays', '~> 0.1.48'
|
31
|
+
s.add_runtime_dependency 'reflexion', '~> 0.1.56'
|
32
32
|
|
33
33
|
s.files = `git ls-files`.split $/
|
34
34
|
s.test_files = s.files.grep %r{^(test|spec|features)/}
|
data/test/helper.rb
CHANGED
@@ -59,7 +59,6 @@ def get_pixels(image)
|
|
59
59
|
.map {image.instance_variable_get _1}
|
60
60
|
.compact
|
61
61
|
.first
|
62
|
-
.bitmap
|
63
62
|
.pixels
|
64
63
|
end
|
65
64
|
|
@@ -107,14 +106,14 @@ end
|
|
107
106
|
|
108
107
|
def assert_p5_draw(
|
109
108
|
*sources, default_header: DEFAULT_DRAW_HEADER,
|
110
|
-
width: 1000, height: 1000, threshold: 0.99, label: test_label)
|
109
|
+
width: 1000, height: 1000, threshold: 0.99, label: test_label, **kwargs)
|
111
110
|
|
112
111
|
return unless test_with_p5?
|
113
112
|
|
114
113
|
source = [default_header, *sources].compact.join("\n")
|
115
114
|
path = draw_output_path "#{label}_expected", source
|
116
115
|
|
117
|
-
pd = draw_p5rb width, height, source, path,
|
116
|
+
pd = draw_p5rb width, height, source, path, **kwargs
|
118
117
|
actual = test_draw source, width: width, height: height, pixelDensity: pd
|
119
118
|
actual.save path.sub('_expected', '_actual')
|
120
119
|
|
data/test/p5.rb
CHANGED
@@ -13,7 +13,7 @@ def browser(width, height, headless: true)
|
|
13
13
|
hash[key] ||= Ferrum::Browser.new headless: headless, window_size: [width, height]
|
14
14
|
end
|
15
15
|
|
16
|
-
def get_p5rb_html(width, height, draw_src)
|
16
|
+
def get_p5rb_html(width, height, draw_src, webgl: false)
|
17
17
|
<<~END
|
18
18
|
<html>
|
19
19
|
<head>
|
@@ -34,9 +34,10 @@ def get_p5rb_html(width, height, draw_src)
|
|
34
34
|
</script>
|
35
35
|
<script type="text/ruby">
|
36
36
|
def setup()
|
37
|
-
createCanvas #{width}, #{height}
|
37
|
+
createCanvas #{width}, #{height}#{webgl ? ', WEBGL' : ''}
|
38
38
|
end
|
39
39
|
def draw()
|
40
|
+
#{webgl ? 'translate -width / 2, -height / 2' : ''}
|
40
41
|
#{draw_src}
|
41
42
|
JS.global.completed
|
42
43
|
end
|
@@ -62,11 +63,11 @@ def sleep_until (try: 3, timeout: 10, &block)
|
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
65
|
-
def draw_p5rb(width, height, draw_src, path, headless: true)
|
66
|
+
def draw_p5rb(width, height, draw_src, path, headless: true, webgl: false)
|
66
67
|
b = browser width, height, headless: headless
|
67
68
|
unless File.exist? path
|
68
69
|
b.reset
|
69
|
-
b.main_frame.content = get_p5rb_html width, height, draw_src
|
70
|
+
b.main_frame.content = get_p5rb_html width, height, draw_src, webgl: webgl
|
70
71
|
sleep_until do
|
71
72
|
b.evaluate 'document.querySelector("#completed") != null'
|
72
73
|
end
|
data/test/test_font.rb
CHANGED
@@ -5,12 +5,43 @@ class TestFont < Test::Unit::TestCase
|
|
5
5
|
|
6
6
|
P = Processing
|
7
7
|
|
8
|
-
def font()
|
9
|
-
P::Font.new
|
8
|
+
def font(*args)
|
9
|
+
P::Font.new(Rays::Font.new *args).tap {|font|
|
10
|
+
def font.intern()
|
11
|
+
getInternal__
|
12
|
+
end
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_initialize()
|
17
|
+
assert_not_nil font(nil) .intern.name
|
18
|
+
assert_equal 'Arial', font('Arial').intern.name
|
19
|
+
|
20
|
+
assert_equal 12, font .intern.size
|
21
|
+
assert_equal 10, font(nil, 10).intern.size
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_size()
|
25
|
+
f = font nil, 10
|
26
|
+
id = f.intern.object_id
|
27
|
+
|
28
|
+
assert_equal 10, f.intern.size
|
29
|
+
|
30
|
+
f.setSize__ 11
|
31
|
+
assert_equal 11, f.intern.size
|
32
|
+
assert_not_equal id, f.intern.object_id
|
33
|
+
|
34
|
+
f.setSize__ 10
|
35
|
+
assert_equal 10, f.intern.size
|
36
|
+
assert_equal id, f.intern.object_id
|
10
37
|
end
|
11
38
|
|
12
39
|
def test_inspect()
|
13
40
|
assert_match %r|#<Processing::Font: name:'[\w\s]+' size:[\d\.]+>|, font.inspect
|
14
41
|
end
|
15
42
|
|
43
|
+
def test_list()
|
44
|
+
assert_not P::Font.list.empty?
|
45
|
+
end
|
46
|
+
|
16
47
|
end# TestFont
|
@@ -76,6 +76,67 @@ class TestGraphicsContext < Test::Unit::TestCase
|
|
76
76
|
END
|
77
77
|
end
|
78
78
|
|
79
|
+
def test_textFont()
|
80
|
+
graphics do |g|
|
81
|
+
arial10 = g.createFont 'Arial', 10
|
82
|
+
helvetica11 = g.createFont 'Helvetica', 11
|
83
|
+
|
84
|
+
font = -> {g.instance_variable_get(:@textFont__).getInternal__}
|
85
|
+
painterFont = -> {g.instance_variable_get(:@painter__).font}
|
86
|
+
|
87
|
+
assert_not_nil font[] .name
|
88
|
+
assert_not_equal 'Arial', font[] .name
|
89
|
+
assert_equal 12, font[] .size
|
90
|
+
assert_equal 12, painterFont[].size
|
91
|
+
|
92
|
+
g.textFont arial10
|
93
|
+
assert_equal 'Arial', font[] .name
|
94
|
+
assert_equal 10, font[] .size
|
95
|
+
assert_equal 10, painterFont[].size
|
96
|
+
|
97
|
+
g.push do
|
98
|
+
g.textFont helvetica11
|
99
|
+
assert_equal 'Helvetica', font[] .name
|
100
|
+
assert_equal 11, font[] .size
|
101
|
+
assert_equal 11, painterFont[].size
|
102
|
+
end
|
103
|
+
|
104
|
+
assert_equal 'Arial', font[] .name
|
105
|
+
assert_equal 10, font[] .size
|
106
|
+
assert_equal 10, painterFont[].size
|
107
|
+
|
108
|
+
g.push do
|
109
|
+
g.textFont arial10, 13
|
110
|
+
assert_equal 'Arial', font[] .name
|
111
|
+
assert_equal 13, font[] .size
|
112
|
+
assert_equal 13, painterFont[].size
|
113
|
+
end
|
114
|
+
|
115
|
+
assert_equal 'Arial', font[] .name
|
116
|
+
assert_equal 10, font[] .size
|
117
|
+
assert_equal 10, painterFont[].size
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_textSize()
|
122
|
+
graphics do |g|
|
123
|
+
font = -> {g.instance_variable_get(:@textFont__).getInternal__}
|
124
|
+
painterFont = -> {g.instance_variable_get(:@painter__).font}
|
125
|
+
|
126
|
+
assert_equal 12, font[] .size
|
127
|
+
assert_equal 12, painterFont[].size
|
128
|
+
|
129
|
+
g.push do
|
130
|
+
g.textSize 10
|
131
|
+
assert_equal 10, font[] .size
|
132
|
+
assert_equal 10, painterFont[].size
|
133
|
+
end
|
134
|
+
|
135
|
+
assert_equal 12, font[] .size
|
136
|
+
assert_equal 12, painterFont[].size
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
79
140
|
def test_clear()
|
80
141
|
colors = -> g {get_pixels(g).uniq}
|
81
142
|
|
@@ -468,6 +529,155 @@ class TestGraphicsContext < Test::Unit::TestCase
|
|
468
529
|
assert_p5_fill_stroke src, 'endShape CLOSE'
|
469
530
|
end
|
470
531
|
|
532
|
+
def test_beginShape_with_fill()
|
533
|
+
assert_equal_draw <<~HEADER, <<~EXPECTED, <<~ACTUAL
|
534
|
+
noStroke
|
535
|
+
HEADER
|
536
|
+
fill 0, 255, 0
|
537
|
+
rect 100, 100, 500, 400
|
538
|
+
EXPECTED
|
539
|
+
beginShape
|
540
|
+
fill 0, 255, 0
|
541
|
+
vertex 100, 100
|
542
|
+
vertex 600, 100
|
543
|
+
vertex 600, 500
|
544
|
+
vertex 100, 500
|
545
|
+
endShape
|
546
|
+
ACTUAL
|
547
|
+
end
|
548
|
+
|
549
|
+
def test_curveVertex()
|
550
|
+
src = <<~END
|
551
|
+
beginShape
|
552
|
+
curveVertex 100, 100
|
553
|
+
curveVertex 800, 100
|
554
|
+
curveVertex 800, 800
|
555
|
+
curveVertex 100, 800
|
556
|
+
END
|
557
|
+
assert_p5_fill src, 'endShape'
|
558
|
+
assert_p5_stroke src, 'endShape'
|
559
|
+
assert_p5_fill_stroke src, 'endShape'
|
560
|
+
assert_p5_fill src, 'endShape CLOSE'
|
561
|
+
assert_p5_stroke src, 'endShape CLOSE'
|
562
|
+
assert_p5_fill_stroke src, 'endShape CLOSE'
|
563
|
+
|
564
|
+
src = <<~END
|
565
|
+
beginShape
|
566
|
+
curveVertex 200, 200
|
567
|
+
curveVertex 200, 200
|
568
|
+
curveVertex 800, 200
|
569
|
+
curveVertex 800, 400
|
570
|
+
curveVertex 200, 400
|
571
|
+
curveVertex 200, 800
|
572
|
+
curveVertex 800, 800
|
573
|
+
curveVertex 800, 700
|
574
|
+
curveVertex 800, 700
|
575
|
+
END
|
576
|
+
assert_p5_fill src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
|
577
|
+
assert_p5_stroke src, 'endShape'
|
578
|
+
assert_p5_fill_stroke src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
|
579
|
+
assert_p5_fill src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
|
580
|
+
assert_p5_stroke src, 'endShape CLOSE'
|
581
|
+
assert_p5_fill_stroke src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
|
582
|
+
end
|
583
|
+
|
584
|
+
def test_bezierVertex()
|
585
|
+
src = <<~END
|
586
|
+
beginShape
|
587
|
+
vertex 100, 100
|
588
|
+
bezierVertex 900, 100, 900, 900, 200, 500
|
589
|
+
END
|
590
|
+
assert_p5_fill src, 'endShape'
|
591
|
+
assert_p5_stroke src, 'endShape'
|
592
|
+
assert_p5_fill_stroke src, 'endShape'
|
593
|
+
assert_p5_fill src, 'endShape CLOSE'
|
594
|
+
assert_p5_stroke src, 'endShape CLOSE'
|
595
|
+
assert_p5_fill_stroke src, 'endShape CLOSE'
|
596
|
+
|
597
|
+
src = <<~END
|
598
|
+
beginShape
|
599
|
+
vertex 100, 100
|
600
|
+
bezierVertex 900, 100, 900, 500, 300, 500
|
601
|
+
bezierVertex 100, 900, 900, 900, 900, 600
|
602
|
+
END
|
603
|
+
assert_p5_fill src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
|
604
|
+
assert_p5_stroke src, 'endShape'
|
605
|
+
assert_p5_fill_stroke src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
|
606
|
+
assert_p5_fill src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
|
607
|
+
assert_p5_stroke src, 'endShape CLOSE'
|
608
|
+
assert_p5_fill_stroke src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
|
609
|
+
end
|
610
|
+
|
611
|
+
def test_quadraticVertex()
|
612
|
+
src = <<~END
|
613
|
+
beginShape
|
614
|
+
vertex 100, 100
|
615
|
+
quadraticVertex 800, 500, 200, 800
|
616
|
+
END
|
617
|
+
assert_p5_fill src, 'endShape'
|
618
|
+
assert_p5_stroke src, 'endShape'
|
619
|
+
assert_p5_fill_stroke src, 'endShape'
|
620
|
+
assert_p5_fill src, 'endShape CLOSE'
|
621
|
+
assert_p5_stroke src, 'endShape CLOSE'
|
622
|
+
assert_p5_fill_stroke src, 'endShape CLOSE'
|
623
|
+
|
624
|
+
src = <<~END
|
625
|
+
beginShape
|
626
|
+
vertex 100, 100
|
627
|
+
quadraticVertex 800, 100, 500, 500
|
628
|
+
quadraticVertex 100, 800, 800, 800
|
629
|
+
END
|
630
|
+
assert_p5_fill src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
|
631
|
+
assert_p5_stroke src, 'endShape'
|
632
|
+
assert_p5_fill_stroke src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
|
633
|
+
assert_p5_fill src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
|
634
|
+
assert_p5_stroke src, 'endShape CLOSE'
|
635
|
+
assert_p5_fill_stroke src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
|
636
|
+
end
|
637
|
+
|
638
|
+
def test_contour()
|
639
|
+
src = <<~END
|
640
|
+
beginShape
|
641
|
+
vertex 100, 100
|
642
|
+
vertex 100, 900
|
643
|
+
vertex 900, 900
|
644
|
+
vertex 900, 100
|
645
|
+
beginContour
|
646
|
+
vertex 200, 200
|
647
|
+
vertex 800, 200
|
648
|
+
vertex 700, 700
|
649
|
+
vertex 200, 800
|
650
|
+
endContour
|
651
|
+
END
|
652
|
+
assert_p5_fill src, 'endShape'
|
653
|
+
assert_p5_stroke src, 'endShape'
|
654
|
+
assert_p5_fill_stroke src, 'endShape'
|
655
|
+
assert_p5_fill src, 'endShape CLOSE'
|
656
|
+
assert_p5_stroke src, 'endShape CLOSE'
|
657
|
+
assert_p5_fill_stroke src, 'endShape CLOSE'
|
658
|
+
end
|
659
|
+
|
660
|
+
def test_pixels()
|
661
|
+
g = graphics 2, 2
|
662
|
+
|
663
|
+
g.loadPixels
|
664
|
+
assert_equal [0] * 4, g.pixels
|
665
|
+
assert_equal [0] * 4, g.getInternal__.pixels
|
666
|
+
|
667
|
+
g.pixels.replace [0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000]
|
668
|
+
assert_equal [0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000], g.pixels
|
669
|
+
assert_equal [0] * 4, g.getInternal__.pixels
|
670
|
+
|
671
|
+
g.updatePixels
|
672
|
+
assert_nil g.pixels
|
673
|
+
assert_equal [0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000], g.getInternal__.pixels
|
674
|
+
assert_nothing_raised {g.updatePixels}
|
675
|
+
|
676
|
+
g.loadPixels
|
677
|
+
g.pixels.replace [0xff000000]
|
678
|
+
assert_raise(ArgumentError) {g.updatePixels}
|
679
|
+
end
|
680
|
+
|
471
681
|
def test_lerp()
|
472
682
|
g = graphics
|
473
683
|
|
@@ -491,6 +701,16 @@ class TestGraphicsContext < Test::Unit::TestCase
|
|
491
701
|
assert_equal c[ 70, 80, 90], g.lerpColor(c[10, 20, 30], c[50, 60, 70], 1.5)
|
492
702
|
end
|
493
703
|
|
704
|
+
def test_createFont()
|
705
|
+
g = graphics
|
706
|
+
|
707
|
+
assert_not_nil g.createFont(nil, nil).getInternal__.name
|
708
|
+
assert_equal 'Arial', g.createFont('Arial', nil).getInternal__.name
|
709
|
+
|
710
|
+
assert_equal 12, g.createFont(nil, nil).getInternal__.size
|
711
|
+
assert_equal 10, g.createFont(nil, 10) .getInternal__.size
|
712
|
+
end
|
713
|
+
|
494
714
|
def test_createShape_line()
|
495
715
|
assert_equal_draw <<~EXPECTED, <<~ACTUAL
|
496
716
|
line 100, 200, 800, 900
|