processing 0.5.31 → 0.5.33
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +57 -0
- data/VERSION +1 -1
- data/lib/processing/all.rb +3 -1
- data/lib/processing/context.rb +103 -16
- data/lib/processing/events.rb +22 -0
- data/lib/processing/font.rb +30 -3
- data/lib/processing/graphics.rb +2 -13
- data/lib/processing/graphics_context.rb +820 -107
- data/lib/processing/image.rb +38 -10
- data/lib/processing/shape.rb +152 -33
- data/lib/processing/window.rb +96 -58
- data/processing.gemspec +4 -4
- data/test/helper.rb +7 -5
- data/test/p5.rb +6 -5
- data/test/test_font.rb +33 -2
- data/test/test_graphics_context.rb +662 -8
- data/test/test_image.rb +21 -0
- data/test/test_shape.rb +125 -0
- data/test/test_utility.rb +0 -19
- metadata +12 -11
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(true)[x, y] = self.class.fromColor__(c).map {|n| n / 255.0}
|
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
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
|
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)
|
66
141
|
nil
|
67
142
|
end
|
68
143
|
|
69
|
-
|
70
|
-
|
71
|
-
@
|
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.rawColor__(*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.rawColor__(*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
|
@@ -103,17 +204,17 @@ module Processing
|
|
103
204
|
end
|
104
205
|
|
105
206
|
def translate(x, y, z = 0)
|
106
|
-
matrix__.translate x, y, z
|
207
|
+
matrix__.translate! x, y, z
|
107
208
|
nil
|
108
209
|
end
|
109
210
|
|
110
211
|
def rotate(angle)
|
111
|
-
matrix__.rotate @context.toDegrees__(angle)
|
212
|
+
matrix__.rotate! @context.toDegrees__(angle)
|
112
213
|
nil
|
113
214
|
end
|
114
215
|
|
115
216
|
def scale(x, y, z = 1)
|
116
|
-
matrix__.scale x, y, z
|
217
|
+
matrix__.scale! x, y, z
|
117
218
|
nil
|
118
219
|
end
|
119
220
|
|
@@ -121,9 +222,22 @@ module Processing
|
|
121
222
|
@matrix = nil
|
122
223
|
end
|
123
224
|
|
124
|
-
def rotateX
|
125
|
-
|
126
|
-
|
225
|
+
def rotateX(angle)
|
226
|
+
matrix__.rotate! @context.toDegrees__(angle), 1, 0, 0
|
227
|
+
end
|
228
|
+
|
229
|
+
def rotateY(angle)
|
230
|
+
matrix__.rotate! @context.toDegrees__(angle), 0, 1, 0
|
231
|
+
end
|
232
|
+
|
233
|
+
def rotateZ(angle)
|
234
|
+
matrix__.rotate! @context.toDegrees__(angle), 0, 0, 1
|
235
|
+
end
|
236
|
+
|
237
|
+
# @private
|
238
|
+
def clearCache__()
|
239
|
+
@polygon = nil# clear cache
|
240
|
+
end
|
127
241
|
|
128
242
|
# @private
|
129
243
|
def matrix__()
|
@@ -133,8 +247,10 @@ module Processing
|
|
133
247
|
# @private
|
134
248
|
def getInternal__()
|
135
249
|
unless @polygon
|
136
|
-
return nil unless @points && @
|
137
|
-
@polygon = self.class.createPolygon__
|
250
|
+
return nil unless @points && @close != nil
|
251
|
+
@polygon = self.class.createPolygon__(
|
252
|
+
@type, @points, @close, @colors, @texcoords)
|
253
|
+
@polygon += @contours if @polygon
|
138
254
|
end
|
139
255
|
@polygon
|
140
256
|
end
|
@@ -162,18 +278,21 @@ module Processing
|
|
162
278
|
end
|
163
279
|
|
164
280
|
# @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
|
-
|
281
|
+
def self.createPolygon__(
|
282
|
+
type, points, close = false, colors = nil, texcoords = nil)
|
283
|
+
|
284
|
+
kwargs = {colors: colors, texcoords: texcoords}
|
285
|
+
g, p = GraphicsContext, Rays::Polygon
|
286
|
+
case type
|
287
|
+
when g::POINTS then p.points( *points)
|
288
|
+
when g::LINES then p.lines( *points)
|
289
|
+
when g::TRIANGLES then p.triangles( *points, **kwargs)
|
290
|
+
when g::TRIANGLE_FAN then p.triangle_fan( *points, **kwargs)
|
291
|
+
when g::TRIANGLE_STRIP then p.triangle_strip(*points, **kwargs)
|
292
|
+
when g::QUADS then p.quads( *points, **kwargs)
|
293
|
+
when g::QUAD_STRIP then p.quad_strip( *points, **kwargs)
|
294
|
+
when g::TESS, nil then p.new( *points, **kwargs, loop: close)
|
295
|
+
else raise ArgumentError, "invalid polygon type '#{type}'"
|
177
296
|
end
|
178
297
|
end
|
179
298
|
|
data/lib/processing/window.rb
CHANGED
@@ -6,14 +6,6 @@ module Processing
|
|
6
6
|
|
7
7
|
include Xot::Inspectable
|
8
8
|
|
9
|
-
attr_accessor :setup, :update, :draw,
|
10
|
-
:key_down, :key_up,
|
11
|
-
:pointer_down, :pointer_up, :pointer_move,
|
12
|
-
:move, :resize, :motion,
|
13
|
-
:before_draw, :after_draw, :update_window, :update_canvas
|
14
|
-
|
15
|
-
attr_accessor :auto_resize
|
16
|
-
|
17
9
|
def initialize(width = 500, height = 500, *args, **kwargs, &block)
|
18
10
|
Processing.instance_variable_set :@window, self
|
19
11
|
|
@@ -26,19 +18,16 @@ module Processing
|
|
26
18
|
@overlay_view = @canvas_view.add Reflex::View.new name: :overlay
|
27
19
|
|
28
20
|
super(*args, size: [width, height], **kwargs, &block)
|
21
|
+
self.center = screen.center
|
29
22
|
end
|
30
23
|
|
31
|
-
|
32
|
-
|
33
|
-
|
24
|
+
attr_accessor :setup, :update, :draw, :move, :resize, :motion,
|
25
|
+
:key_down, :key_up, :pointer_down, :pointer_up, :pointer_move, :wheel,
|
26
|
+
:before_draw, :after_draw, :update_window, :update_canvas
|
34
27
|
|
35
|
-
|
36
|
-
@canvas.painter
|
37
|
-
end
|
28
|
+
attr_accessor :auto_resize
|
38
29
|
|
39
|
-
|
40
|
-
self.painter
|
41
|
-
end
|
30
|
+
attr_reader :canvas
|
42
31
|
|
43
32
|
def event()
|
44
33
|
@events.last
|
@@ -64,7 +53,9 @@ module Processing
|
|
64
53
|
end
|
65
54
|
|
66
55
|
def on_change_pixel_density(pixel_density)
|
67
|
-
resize_canvas
|
56
|
+
resize_canvas(
|
57
|
+
@canvas.width, @canvas.height,
|
58
|
+
window_pixel_density: pixel_density)
|
68
59
|
end
|
69
60
|
|
70
61
|
def on_activate(e)
|
@@ -80,7 +71,7 @@ module Processing
|
|
80
71
|
end
|
81
72
|
|
82
73
|
def on_draw(e)
|
83
|
-
|
74
|
+
painter.pixel_density.tap do |pd|
|
84
75
|
prev, @prev_pixel_density = @prev_pixel_density, pd
|
85
76
|
on_change_pixel_density pd if prev && pd != prev
|
86
77
|
end
|
@@ -127,28 +118,35 @@ module Processing
|
|
127
118
|
draw_canvas {call_block block, e} if block
|
128
119
|
end
|
129
120
|
|
121
|
+
def on_canvas_wheel(e)
|
122
|
+
draw_canvas {call_block @wheel, e} if @wheel
|
123
|
+
end
|
124
|
+
|
130
125
|
def on_canvas_resize(e)
|
131
126
|
resize_canvas e.width, e.height if @auto_resize
|
132
127
|
draw_canvas {call_block @resize, e} if @resize
|
133
128
|
end
|
134
129
|
|
135
|
-
def resize_canvas(
|
136
|
-
|
137
|
-
|
130
|
+
def resize_canvas(
|
131
|
+
width, height,
|
132
|
+
pixel_density = nil,
|
133
|
+
window_pixel_density: nil,
|
134
|
+
antialiasing: nil)
|
135
|
+
|
136
|
+
painting = @canvas.painter.painting?
|
137
|
+
@canvas.painter.__send__ :end_paint if painting
|
138
138
|
|
139
139
|
@pixel_density = pixel_density if pixel_density
|
140
140
|
|
141
141
|
resized =
|
142
142
|
begin
|
143
|
-
|
143
|
+
pd = @pixel_density || window_pixel_density
|
144
|
+
@canvas.resize width, height, pd, antialiasing
|
144
145
|
ensure
|
145
|
-
|
146
|
+
@canvas.painter.__send__ :begin_paint if painting
|
146
147
|
end
|
147
148
|
|
148
|
-
if resized
|
149
|
-
@update_canvas.call canvas_image, canvas_painter if @update_canvas
|
150
|
-
size width, height
|
151
|
-
end
|
149
|
+
@update_canvas&.call @canvas.image, @canvas.painter if resized
|
152
150
|
end
|
153
151
|
|
154
152
|
private
|
@@ -157,12 +155,12 @@ module Processing
|
|
157
155
|
scrollx, scrolly, zoom = get_scroll_and_zoom
|
158
156
|
@canvas_view.scroll_to scrollx, scrolly
|
159
157
|
@canvas_view.zoom = zoom
|
160
|
-
@overlay_view.size =
|
158
|
+
@overlay_view.size = @canvas.image.size
|
161
159
|
end
|
162
160
|
|
163
161
|
def get_scroll_and_zoom()
|
164
|
-
ww, wh =
|
165
|
-
cw, ch =
|
162
|
+
ww, wh = width.to_f, height.to_f
|
163
|
+
cw, ch = @canvas.image.width.to_f, @canvas.image.height.to_f
|
166
164
|
return [0, 0, 1] if ww == 0 || wh == 0 || cw == 0 || ch == 0
|
167
165
|
|
168
166
|
wratio, cratio = ww / wh, cw / ch
|
@@ -184,21 +182,21 @@ module Processing
|
|
184
182
|
end
|
185
183
|
|
186
184
|
def begin_draw()
|
187
|
-
|
185
|
+
@canvas.painter.__send__ :begin_paint
|
188
186
|
@before_draw&.call
|
189
187
|
end
|
190
188
|
|
191
189
|
def end_draw()
|
192
190
|
@after_draw&.call
|
193
|
-
|
191
|
+
@canvas.painter.__send__ :end_paint
|
194
192
|
end
|
195
193
|
|
196
194
|
def drawing?()
|
197
|
-
|
195
|
+
@canvas.painter.painting?
|
198
196
|
end
|
199
197
|
|
200
198
|
def draw_screen(painter)
|
201
|
-
|
199
|
+
painter.image @canvas.render
|
202
200
|
end
|
203
201
|
|
204
202
|
def call_block(block, event, *args)
|
@@ -216,49 +214,84 @@ module Processing
|
|
216
214
|
|
217
215
|
class Window::Canvas
|
218
216
|
|
219
|
-
attr_reader :image, :painter
|
220
|
-
|
221
217
|
def initialize(window, width, height)
|
222
|
-
@
|
223
|
-
@
|
218
|
+
@framebuffer = nil
|
219
|
+
@paintable = nil
|
220
|
+
@painter = window.painter
|
221
|
+
|
222
|
+
@painter.miter_limit = 10
|
224
223
|
|
225
224
|
resize width, height
|
226
|
-
painter.miter_limit = 10
|
227
225
|
end
|
228
226
|
|
229
|
-
|
227
|
+
attr_reader :painter
|
228
|
+
|
229
|
+
def resize(width, height, pixel_density = nil, antialiasing = nil)
|
230
230
|
return false if width <= 0 || height <= 0
|
231
231
|
|
232
|
+
cs = @framebuffer&.color_space || Rays::RGBA
|
233
|
+
pd = pixel_density || (@framebuffer || @painter).pixel_density
|
234
|
+
aa = antialiasing == nil ? antialiasing? : (antialiasing && pd < 2)
|
232
235
|
return false if
|
233
|
-
width
|
234
|
-
height
|
235
|
-
|
236
|
+
width == @framebuffer&.width &&
|
237
|
+
height == @framebuffer&.height &&
|
238
|
+
pd == @framebuffer&.pixel_density &&
|
239
|
+
aa == antialiasing?
|
236
240
|
|
237
|
-
|
238
|
-
old_painter = @painter
|
239
|
-
cs = old_image&.color_space || Rays::RGBA
|
240
|
-
pd = pixel_density || old_painter.pixel_density
|
241
|
+
old_paintable, old_painter = @paintable, @painter
|
241
242
|
|
242
|
-
@
|
243
|
-
@
|
243
|
+
@framebuffer = Rays::Image.new width, height, cs, pd
|
244
|
+
@paintable = aa ? Rays::Image.new(width, height, cs, pd * 2) : @framebuffer
|
245
|
+
@painter = @paintable.painter
|
244
246
|
|
245
|
-
@painter.paint {image
|
247
|
+
@painter.paint {image old_paintable} if old_paintable
|
246
248
|
copy_painter old_painter, @painter
|
247
249
|
|
248
250
|
GC.start
|
249
251
|
return true
|
250
252
|
end
|
251
253
|
|
254
|
+
def render()
|
255
|
+
@framebuffer.paint {|p| p.image @paintable} if antialiasing?
|
256
|
+
@framebuffer
|
257
|
+
end
|
258
|
+
|
259
|
+
def image()
|
260
|
+
@paintable
|
261
|
+
end
|
262
|
+
|
263
|
+
def width()
|
264
|
+
@framebuffer.width
|
265
|
+
end
|
266
|
+
|
267
|
+
def height()
|
268
|
+
@framebuffer.height
|
269
|
+
end
|
270
|
+
|
271
|
+
def pixel_density()
|
272
|
+
@framebuffer.pixel_density
|
273
|
+
end
|
274
|
+
|
275
|
+
def antialiasing?()
|
276
|
+
!!@framebuffer && !!@paintable && @framebuffer != @paintable
|
277
|
+
end
|
278
|
+
|
252
279
|
private
|
253
280
|
|
254
281
|
def copy_painter(from, to)
|
255
|
-
to.fill
|
256
|
-
to.stroke
|
257
|
-
to.stroke_width
|
258
|
-
to.stroke_cap
|
259
|
-
to.stroke_join
|
260
|
-
to.miter_limit
|
261
|
-
to.
|
282
|
+
to.fill = from.fill
|
283
|
+
to.stroke = from.stroke
|
284
|
+
to.stroke_width = from.stroke_width
|
285
|
+
to.stroke_cap = from.stroke_cap
|
286
|
+
to.stroke_join = from.stroke_join
|
287
|
+
to.miter_limit = from.miter_limit
|
288
|
+
to.clip = from.clip
|
289
|
+
to.blend_mode = from.blend_mode
|
290
|
+
to.font = from.font
|
291
|
+
to.texture = from.texture
|
292
|
+
to.texcoord_mode = from.texcoord_mode
|
293
|
+
to.texcoord_wrap = from.texcoord_wrap
|
294
|
+
to.shader = from.shader
|
262
295
|
end
|
263
296
|
|
264
297
|
end# Window::Canvas
|
@@ -268,6 +301,7 @@ module Processing
|
|
268
301
|
|
269
302
|
def on_update(e)
|
270
303
|
window.on_canvas_update e
|
304
|
+
Thread.pass
|
271
305
|
end
|
272
306
|
|
273
307
|
def on_draw(e)
|
@@ -278,6 +312,10 @@ module Processing
|
|
278
312
|
window.on_canvas_pointer e
|
279
313
|
end
|
280
314
|
|
315
|
+
def on_wheel(e)
|
316
|
+
window.on_canvas_wheel e
|
317
|
+
end
|
318
|
+
|
281
319
|
def on_resize(e)
|
282
320
|
window.on_canvas_resize e
|
283
321
|
end
|
data/processing.gemspec
CHANGED
@@ -25,10 +25,10 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.platform = Gem::Platform::RUBY
|
26
26
|
s.required_ruby_version = '>= 3.0.0'
|
27
27
|
|
28
|
-
s.add_runtime_dependency 'xot', '~> 0.1.
|
29
|
-
s.add_runtime_dependency 'rucy', '~> 0.1.
|
30
|
-
s.add_runtime_dependency 'rays', '~> 0.1.
|
31
|
-
s.add_runtime_dependency 'reflexion', '~> 0.1.
|
28
|
+
s.add_runtime_dependency 'xot', '~> 0.1.42'
|
29
|
+
s.add_runtime_dependency 'rucy', '~> 0.1.44'
|
30
|
+
s.add_runtime_dependency 'rays', '~> 0.1.49'
|
31
|
+
s.add_runtime_dependency 'reflexion', '~> 0.1.57'
|
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
@@ -34,8 +34,10 @@ def mkdir(dir: nil, filename: nil)
|
|
34
34
|
FileUtils.mkdir_p path unless File.exist? path
|
35
35
|
end
|
36
36
|
|
37
|
-
def test_label(
|
38
|
-
|
37
|
+
def test_label(frame_offset = 1, suffix: nil)
|
38
|
+
suffix = suffix ? "_#{suffix}" : ''
|
39
|
+
caller_locations[frame_offset]
|
40
|
+
.then {|loc| "#{loc.label}_#{loc.lineno}#{suffix}"}
|
39
41
|
end
|
40
42
|
|
41
43
|
def temp_path(ext: nil, &block)
|
@@ -59,7 +61,6 @@ def get_pixels(image)
|
|
59
61
|
.map {image.instance_variable_get _1}
|
60
62
|
.compact
|
61
63
|
.first
|
62
|
-
.bitmap
|
63
64
|
.pixels
|
64
65
|
end
|
65
66
|
|
@@ -71,6 +72,7 @@ end
|
|
71
72
|
|
72
73
|
def test_draw(*sources, width: 1000, height: 1000, pixelDensity: 1, label: nil)
|
73
74
|
graphics(width, height, pixelDensity).tap do |g|
|
75
|
+
g.renderMode :p5js
|
74
76
|
g.beginDraw {g.instance_eval sources.compact.join("\n")}
|
75
77
|
g.save draw_output_path(label, *sources) if label
|
76
78
|
end
|
@@ -107,14 +109,14 @@ end
|
|
107
109
|
|
108
110
|
def assert_p5_draw(
|
109
111
|
*sources, default_header: DEFAULT_DRAW_HEADER,
|
110
|
-
width: 1000, height: 1000, threshold: 0.99, label: test_label)
|
112
|
+
width: 1000, height: 1000, threshold: 0.99, label: test_label, **kwargs)
|
111
113
|
|
112
114
|
return unless test_with_p5?
|
113
115
|
|
114
116
|
source = [default_header, *sources].compact.join("\n")
|
115
117
|
path = draw_output_path "#{label}_expected", source
|
116
118
|
|
117
|
-
pd = draw_p5rb width, height, source, path,
|
119
|
+
pd = draw_p5rb width, height, source, path, **kwargs
|
118
120
|
actual = test_draw source, width: width, height: height, pixelDensity: pd
|
119
121
|
actual.save path.sub('_expected', '_actual')
|
120
122
|
|