processing 0.5.31 → 0.5.32
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.
- 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
|