processing 0.5.30 → 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/.github/workflows/test-draw.yml +0 -1
- data/.github/workflows/test.yml +0 -1
- data/ChangeLog.md +26 -0
- data/Rakefile +14 -6
- data/VERSION +1 -1
- data/lib/processing/all.rb +1 -0
- data/lib/processing/font.rb +30 -3
- data/lib/processing/graphics.rb +0 -11
- data/lib/processing/graphics_context.rb +526 -53
- data/lib/processing/image.rb +38 -10
- data/lib/processing/shape.rb +294 -0
- data/lib/processing/vector.rb +3 -3
- data/processing.gemspec +4 -4
- data/test/helper.rb +86 -4
- data/test/{draw/p5.rb → p5.rb} +22 -8
- data/test/test_font.rb +33 -2
- data/test/test_graphics.rb +1 -7
- data/test/test_graphics_context.rb +671 -5
- data/test/test_image.rb +21 -0
- data/test/test_shape.rb +512 -0
- data/test/test_vector.rb +1 -1
- metadata +15 -16
- data/test/draw/helper.rb +0 -31
- data/test/draw/test_draw.rb +0 -22
@@ -45,15 +45,16 @@ module Processing
|
|
45
45
|
#
|
46
46
|
DEGREES = :degrees
|
47
47
|
|
48
|
-
# Mode for rectMode(), ellipseMode() and
|
48
|
+
# Mode for rectMode(), ellipseMode(), imageMode(), and shapeMode().
|
49
49
|
#
|
50
50
|
CORNER = :corner
|
51
51
|
|
52
|
-
# Mode for rectMode(), ellipseMode() and
|
52
|
+
# Mode for rectMode(), ellipseMode(), imageMode(), and shapeMode().
|
53
53
|
#
|
54
54
|
CORNERS = :corners
|
55
55
|
|
56
|
-
# Mode for rectMode(), ellipseMode(), imageMode()
|
56
|
+
# Mode for rectMode(), ellipseMode(), imageMode(), shapeMode(),
|
57
|
+
# and textAlign().
|
57
58
|
#
|
58
59
|
CENTER = :center
|
59
60
|
|
@@ -128,6 +129,18 @@ module Processing
|
|
128
129
|
# Mode for textAlign().
|
129
130
|
BASELINE = :baseline
|
130
131
|
|
132
|
+
# Mode for textureMode().
|
133
|
+
IMAGE = :image
|
134
|
+
|
135
|
+
# Mode for textureMode().
|
136
|
+
NORMAL = :normal
|
137
|
+
|
138
|
+
# Mode for textureWrap().
|
139
|
+
CLAMP = :clamp
|
140
|
+
|
141
|
+
# Mode for textureWrap().
|
142
|
+
REPEAT = :repeat
|
143
|
+
|
131
144
|
# Filter type for filter()
|
132
145
|
THRESHOLD = :threshold
|
133
146
|
|
@@ -140,6 +153,57 @@ module Processing
|
|
140
153
|
# Filter type for filter()
|
141
154
|
BLUR = :blur
|
142
155
|
|
156
|
+
# Shape mode for createShape()
|
157
|
+
LINE = :line
|
158
|
+
|
159
|
+
# Shape mode for createShape()
|
160
|
+
RECT = :rect
|
161
|
+
|
162
|
+
# Shape mode for createShape()
|
163
|
+
ELLIPSE = :ellipse
|
164
|
+
|
165
|
+
# Shape mode for createShape()
|
166
|
+
ARC = :arc
|
167
|
+
|
168
|
+
# Shape mode for createShape()
|
169
|
+
TRIANGLE = :triangle
|
170
|
+
|
171
|
+
# Shape mode for createShape()
|
172
|
+
QUAD = :quad
|
173
|
+
|
174
|
+
# Shape mode for createShape()
|
175
|
+
GROUP = :group
|
176
|
+
|
177
|
+
# Shape mode for beginShape()
|
178
|
+
POINTS = :points
|
179
|
+
|
180
|
+
# Shape mode for beginShape()
|
181
|
+
LINES = :lines
|
182
|
+
|
183
|
+
# Shape mode for beginShape()
|
184
|
+
TRIANGLES = :triangles
|
185
|
+
|
186
|
+
# Shape mode for beginShape()
|
187
|
+
TRIANGLE_FAN = :triangle_fan
|
188
|
+
|
189
|
+
# Shape mode for beginShape()
|
190
|
+
TRIANGLE_STRIP = :triangle_strip
|
191
|
+
|
192
|
+
# Shape mode for beginShape()
|
193
|
+
QUADS = :quads
|
194
|
+
|
195
|
+
# Shape mode for beginShape()
|
196
|
+
QUAD_STRIP = :quad_strip
|
197
|
+
|
198
|
+
# Shape mode for beginShape()
|
199
|
+
TESS = :tess
|
200
|
+
|
201
|
+
# OPEN flag for endShape()
|
202
|
+
OPEN = :open
|
203
|
+
|
204
|
+
# CLOSE flag for endShape()
|
205
|
+
CLOSE = :close
|
206
|
+
|
143
207
|
# Key codes.
|
144
208
|
ENTER = :enter
|
145
209
|
SPACE = :space
|
@@ -195,6 +259,12 @@ module Processing
|
|
195
259
|
# @private
|
196
260
|
RAD2DEG__ = 180.0 / Math::PI
|
197
261
|
|
262
|
+
# @private
|
263
|
+
FONT_SIZE_DEFAULT__ = 12
|
264
|
+
|
265
|
+
# @private
|
266
|
+
FONT_SIZE_MAX__ = 256
|
267
|
+
|
198
268
|
# @private
|
199
269
|
def init__(image, painter)
|
200
270
|
@drawing__ = false
|
@@ -206,14 +276,16 @@ module Processing
|
|
206
276
|
@rectMode__ = nil
|
207
277
|
@ellipseMode__ = nil
|
208
278
|
@imageMode__ = nil
|
279
|
+
@shapeMode__ = nil
|
209
280
|
@blendMode__ = nil
|
210
281
|
@textAlignH__ = nil
|
211
282
|
@textAlignV__ = nil
|
283
|
+
@textFont__ = nil
|
212
284
|
@tint__ = nil
|
213
285
|
@filter__ = nil
|
286
|
+
@pixels__ = nil
|
214
287
|
@matrixStack__ = []
|
215
288
|
@styleStack__ = []
|
216
|
-
@fontCache__ = {}
|
217
289
|
|
218
290
|
updateCanvas__ image, painter
|
219
291
|
|
@@ -222,10 +294,14 @@ module Processing
|
|
222
294
|
rectMode CORNER
|
223
295
|
ellipseMode CENTER
|
224
296
|
imageMode CORNER
|
297
|
+
shapeMode CORNER
|
225
298
|
blendMode BLEND
|
226
299
|
strokeCap ROUND
|
227
300
|
strokeJoin MITER
|
228
301
|
textAlign LEFT
|
302
|
+
textFont createFont(nil, nil)
|
303
|
+
textureMode IMAGE
|
304
|
+
textureWrap CLAMP
|
229
305
|
|
230
306
|
fill 255
|
231
307
|
stroke 0
|
@@ -235,7 +311,9 @@ module Processing
|
|
235
311
|
|
236
312
|
# @private
|
237
313
|
def updateCanvas__(image, painter)
|
238
|
-
@image__, @painter__
|
314
|
+
@image__, @painter__ = image, painter
|
315
|
+
@painter__.miter_limit = 10
|
316
|
+
@painter__.stroke_outset = 0.5
|
239
317
|
end
|
240
318
|
|
241
319
|
# @private
|
@@ -257,7 +335,7 @@ module Processing
|
|
257
335
|
# @return [Numeric] width
|
258
336
|
#
|
259
337
|
def width()
|
260
|
-
|
338
|
+
getInternal__.width
|
261
339
|
end
|
262
340
|
|
263
341
|
# Returns the height of the graphics object.
|
@@ -265,7 +343,7 @@ module Processing
|
|
265
343
|
# @return [Numeric] height
|
266
344
|
#
|
267
345
|
def height()
|
268
|
-
|
346
|
+
getInternal__.height
|
269
347
|
end
|
270
348
|
|
271
349
|
# Returns the width of the graphics object in pixels.
|
@@ -387,17 +465,21 @@ module Processing
|
|
387
465
|
|
388
466
|
# @private
|
389
467
|
private def toRGBA__(*args)
|
390
|
-
a, b
|
468
|
+
a, b = args
|
391
469
|
return parseColor__(a, b || alphaMax__) if a.kind_of?(String)
|
470
|
+
toRaysColor__(*args).to_a
|
471
|
+
end
|
392
472
|
|
473
|
+
# @private
|
474
|
+
def toRaysColor__(*args)
|
475
|
+
a, b, c, d = args
|
393
476
|
rgba = case args.size
|
394
477
|
when 1, 2 then [a, a, a, b || alphaMax__]
|
395
478
|
when 3, 4 then [a, b, c, d || alphaMax__]
|
396
479
|
else raise ArgumentError
|
397
480
|
end
|
398
|
-
rgba
|
399
|
-
|
400
|
-
color.to_a
|
481
|
+
rgba = rgba.map.with_index {|value, i| value / @colorMaxes__[i]}
|
482
|
+
@hsbColor__ ? Rays::Color.hsv(*rgba) : Rays::Color.new(*rgba)
|
401
483
|
end
|
402
484
|
|
403
485
|
# @private
|
@@ -434,7 +516,7 @@ module Processing
|
|
434
516
|
end
|
435
517
|
|
436
518
|
# @private
|
437
|
-
def
|
519
|
+
def toDegrees__(angle)
|
438
520
|
angle * @angleScale__
|
439
521
|
end
|
440
522
|
|
@@ -460,8 +542,8 @@ module Processing
|
|
460
542
|
#
|
461
543
|
# CORNER -> rect(left, top, width, height)
|
462
544
|
# CORNERS -> rect(left, top, right, bottom)
|
463
|
-
# CENTER -> rect(
|
464
|
-
# RADIUS -> rect(
|
545
|
+
# CENTER -> rect(centerX, centerY, width, height)
|
546
|
+
# RADIUS -> rect(centerX, centerY, radiusH, radiusV)
|
465
547
|
#
|
466
548
|
# @param mode [CORNER, CORNERS, CENTER, RADIUS]
|
467
549
|
#
|
@@ -475,8 +557,8 @@ module Processing
|
|
475
557
|
#
|
476
558
|
# CORNER -> ellipse(left, top, width, height)
|
477
559
|
# CORNERS -> ellipse(left, top, right, bottom)
|
478
|
-
# CENTER -> ellipse(
|
479
|
-
# RADIUS -> ellipse(
|
560
|
+
# CENTER -> ellipse(centerX, centerY, width, height)
|
561
|
+
# RADIUS -> ellipse(centerX, centerY, radiusH, radiusV)
|
480
562
|
#
|
481
563
|
# @param mode [CORNER, CORNERS, CENTER, RADIUS]
|
482
564
|
#
|
@@ -490,7 +572,7 @@ module Processing
|
|
490
572
|
#
|
491
573
|
# CORNER -> image(img, left, top, width, height)
|
492
574
|
# CORNERS -> image(img, left, top, right, bottom)
|
493
|
-
# CENTER -> image(img,
|
575
|
+
# CENTER -> image(img, centerX, centerY, width, height)
|
494
576
|
#
|
495
577
|
# @param mode [CORNER, CORNERS, CENTER]
|
496
578
|
#
|
@@ -500,6 +582,20 @@ module Processing
|
|
500
582
|
@imageMode__ = mode
|
501
583
|
end
|
502
584
|
|
585
|
+
# Sets shape mode. Default is CORNER.
|
586
|
+
#
|
587
|
+
# CORNER -> shape(shp, left, top, width, height)
|
588
|
+
# CORNERS -> shape(shp, left, top, right, bottom)
|
589
|
+
# CENTER -> shape(shp, centerX, centerY, width, height)
|
590
|
+
#
|
591
|
+
# @param mode [CORNER, CORNERS, CENTER]
|
592
|
+
#
|
593
|
+
# @return [nil] nil
|
594
|
+
#
|
595
|
+
def shapeMode(mode)
|
596
|
+
@shapeMode__ = mode
|
597
|
+
end
|
598
|
+
|
503
599
|
# @private
|
504
600
|
private def toXYWH__(mode, a, b, c, d)
|
505
601
|
case mode
|
@@ -548,6 +644,11 @@ module Processing
|
|
548
644
|
nil
|
549
645
|
end
|
550
646
|
|
647
|
+
# @private
|
648
|
+
def getFill__()
|
649
|
+
@painter__.fill
|
650
|
+
end
|
651
|
+
|
551
652
|
# Disables filling.
|
552
653
|
#
|
553
654
|
# @return [nil] nil
|
@@ -653,6 +754,11 @@ module Processing
|
|
653
754
|
@tint__ = nil
|
654
755
|
end
|
655
756
|
|
757
|
+
# @private
|
758
|
+
def getTint__()
|
759
|
+
@tint__ ? toRGBA__(*@tint__) : 1
|
760
|
+
end
|
761
|
+
|
656
762
|
# Limits the drawable rectangle.
|
657
763
|
#
|
658
764
|
# The parameters a, b, c, and d are determined by rectMode().
|
@@ -679,7 +785,9 @@ module Processing
|
|
679
785
|
nil
|
680
786
|
end
|
681
787
|
|
682
|
-
# Sets font.
|
788
|
+
# Sets text font.
|
789
|
+
#
|
790
|
+
# (Passing a font name as the first parameter is deprecated)
|
683
791
|
#
|
684
792
|
# @overload textFont(font)
|
685
793
|
# @overload textFont(name)
|
@@ -690,11 +798,18 @@ module Processing
|
|
690
798
|
# @param name [String] font name
|
691
799
|
# @param size [Numeric] font size (max 256)
|
692
800
|
#
|
693
|
-
# @return [
|
801
|
+
# @return [nil] nil
|
694
802
|
#
|
695
|
-
def textFont(font
|
696
|
-
|
697
|
-
|
803
|
+
def textFont(font, size = nil)
|
804
|
+
size = FONT_SIZE_MAX__ if size && size > FONT_SIZE_MAX__
|
805
|
+
if font.nil? || font.kind_of?(String)
|
806
|
+
font = createFont font, size
|
807
|
+
elsif size
|
808
|
+
font.setSize__ size
|
809
|
+
end
|
810
|
+
@textFont__ = font
|
811
|
+
@painter__.font = font.getInternal__
|
812
|
+
nil
|
698
813
|
end
|
699
814
|
|
700
815
|
# Sets text size.
|
@@ -704,8 +819,7 @@ module Processing
|
|
704
819
|
# @return [nil] nil
|
705
820
|
#
|
706
821
|
def textSize(size)
|
707
|
-
|
708
|
-
nil
|
822
|
+
textFont @textFont__, size
|
709
823
|
end
|
710
824
|
|
711
825
|
def textWidth(str)
|
@@ -725,16 +839,46 @@ module Processing
|
|
725
839
|
@textAlignV__ = vertical
|
726
840
|
end
|
727
841
|
|
842
|
+
def texture(image)
|
843
|
+
@painter__.texture image&.getInternal__
|
844
|
+
nil
|
845
|
+
end
|
846
|
+
|
728
847
|
# @private
|
729
|
-
def
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
848
|
+
def drawWithTexture__(&block)
|
849
|
+
if @painter__.texture
|
850
|
+
@painter__.push fill: getTint__, &block
|
851
|
+
else
|
852
|
+
block.call
|
853
|
+
end
|
854
|
+
end
|
855
|
+
|
856
|
+
# Sets the coordinate space for texture mapping.
|
857
|
+
#
|
858
|
+
# @param mode [IMAGE, NORMAL] image coordinate, or normalized coordinate
|
859
|
+
#
|
860
|
+
# @return [nil] nil
|
861
|
+
#
|
862
|
+
# @see https://processing.org/reference/textureMode_.html
|
863
|
+
# @see https://p5js.org/reference/#/p5/textureMode
|
864
|
+
#
|
865
|
+
def textureMode(mode)
|
866
|
+
@painter__.texcoord_mode = mode
|
867
|
+
nil
|
868
|
+
end
|
869
|
+
|
870
|
+
# Sets the texture wrapping mode.
|
871
|
+
#
|
872
|
+
# @param wrap [CLAMP, REPEAT] how texutres behave when go outside of the range
|
873
|
+
#
|
874
|
+
# @return [nil] nil
|
875
|
+
#
|
876
|
+
# @see https://processing.org/reference/textureWrap_.html
|
877
|
+
# @see https://p5js.org/reference/#/p5/textureWrap
|
878
|
+
#
|
879
|
+
def textureWrap(wrap)
|
880
|
+
@painter__.texcoord_wrap = wrap
|
881
|
+
nil
|
738
882
|
end
|
739
883
|
|
740
884
|
# Sets shader.
|
@@ -924,9 +1068,8 @@ module Processing
|
|
924
1068
|
def arc(a, b, c, d, start, stop)
|
925
1069
|
assertDrawing__
|
926
1070
|
x, y, w, h = toXYWH__ @ellipseMode__, a, b, c, d
|
927
|
-
|
928
|
-
|
929
|
-
@painter__.ellipse x, y, w, h, from: start, to: stop
|
1071
|
+
from, to = toDegrees__(-start), toDegrees__(-stop)
|
1072
|
+
@painter__.ellipse x, y, w, h, from: from, to: to
|
930
1073
|
nil
|
931
1074
|
end
|
932
1075
|
|
@@ -1087,13 +1230,196 @@ module Processing
|
|
1087
1230
|
def image(img, a, b, c = nil, d = nil)
|
1088
1231
|
assertDrawing__
|
1089
1232
|
x, y, w, h = toXYWH__ @imageMode__, a, b, c || img.width, d || img.height
|
1090
|
-
|
1091
|
-
img.drawImage__ @painter__, x, y, w, h, fill: tint, stroke: :none
|
1233
|
+
img.drawImage__ @painter__, x, y, w, h, fill: getTint__, stroke: :none
|
1092
1234
|
nil
|
1093
1235
|
end
|
1094
1236
|
|
1095
1237
|
alias drawImage image
|
1096
1238
|
|
1239
|
+
# Draws a shape.
|
1240
|
+
#
|
1241
|
+
# The parameters a, b, c, and d are determined by shapeMode().
|
1242
|
+
#
|
1243
|
+
# @overload shape(img, a, b)
|
1244
|
+
# @overload shape(img, a, b, c, d)
|
1245
|
+
#
|
1246
|
+
# @param shp [Shape] shape to draw
|
1247
|
+
# @param a [Numeric] horizontal position of the shape, by default
|
1248
|
+
# @param b [Numeric] vertical position of the shape, by default
|
1249
|
+
# @param c [Numeric] width of the shape, by default
|
1250
|
+
# @param d [Numeric] height of the shape, by default
|
1251
|
+
#
|
1252
|
+
# @return [nil] nil
|
1253
|
+
#
|
1254
|
+
def shape(shp, a = 0, b = 0, c = nil, d = nil)
|
1255
|
+
assertDrawing__
|
1256
|
+
return nil unless shp.isVisible
|
1257
|
+
|
1258
|
+
drawWithTexture__ do |_|
|
1259
|
+
if c || d || @shapeMode__ != CORNER
|
1260
|
+
x, y, w, h = toXYWH__ @shapeMode__, a, b, c || shp.width, d || shp.height
|
1261
|
+
shp.draw__ @painter__, x, y, w, h
|
1262
|
+
else
|
1263
|
+
shp.draw__ @painter__, a, b
|
1264
|
+
end
|
1265
|
+
end
|
1266
|
+
nil
|
1267
|
+
end
|
1268
|
+
|
1269
|
+
alias drawShape shape
|
1270
|
+
|
1271
|
+
# Begins drawing complex shapes.
|
1272
|
+
#
|
1273
|
+
# @param type [POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, QUAD_STRIP, TESS]
|
1274
|
+
#
|
1275
|
+
# @return [nil] nil
|
1276
|
+
#
|
1277
|
+
# @example
|
1278
|
+
# # Draws polygon
|
1279
|
+
# beginShape
|
1280
|
+
# vertex 10, 10
|
1281
|
+
# vertex 10, 50
|
1282
|
+
# vertex 50, 50
|
1283
|
+
# vertex 90, 10
|
1284
|
+
# endShape CLOSE
|
1285
|
+
#
|
1286
|
+
# # Draws triangles
|
1287
|
+
# beginShape TRIANGLES
|
1288
|
+
# vertex 10, 10
|
1289
|
+
# vertex 10, 50
|
1290
|
+
# vertex 50, 50
|
1291
|
+
# endShape
|
1292
|
+
#
|
1293
|
+
# @see https://processing.org/reference/beginShape_.html
|
1294
|
+
#
|
1295
|
+
def beginShape(type = nil)
|
1296
|
+
raise "beginShape() cannot be called twice" if @drawingShape__
|
1297
|
+
@drawingShape__ = createShape
|
1298
|
+
@drawingShape__.beginShape type
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
# Ends drawing complex shapes.
|
1302
|
+
#
|
1303
|
+
# @overload endShape()
|
1304
|
+
# @overload endShape(CLOSE)
|
1305
|
+
#
|
1306
|
+
# @param mode [CLOSE] Use CLOSE to create looped polygon
|
1307
|
+
#
|
1308
|
+
# @return [nil] nil
|
1309
|
+
#
|
1310
|
+
# @see https://processing.org/reference/endShape_.html
|
1311
|
+
#
|
1312
|
+
def endShape(mode = nil)
|
1313
|
+
s = @drawingShape__ or raise "endShape() must be called after beginShape()"
|
1314
|
+
s.endShape mode
|
1315
|
+
shape s
|
1316
|
+
@drawingShape__ = nil
|
1317
|
+
nil
|
1318
|
+
end
|
1319
|
+
|
1320
|
+
# Begins drawing a hole inside shape.
|
1321
|
+
#
|
1322
|
+
# @return [nil] nil
|
1323
|
+
#
|
1324
|
+
# @example
|
1325
|
+
# beginShape
|
1326
|
+
# vertex 10, 10
|
1327
|
+
# vertex 10, 50
|
1328
|
+
# vertex 50, 50
|
1329
|
+
# vertex 90, 10
|
1330
|
+
# beginContour
|
1331
|
+
# vertex 20, 20
|
1332
|
+
# vertex 30, 20
|
1333
|
+
# vertex 30, 30
|
1334
|
+
# vertex 20, 30
|
1335
|
+
# endContour
|
1336
|
+
# endShape CLOSE
|
1337
|
+
#
|
1338
|
+
# @see https://processing.org/reference/beginContour_.html
|
1339
|
+
# @see https://p5js.org/reference/#/p5/beginContour
|
1340
|
+
#
|
1341
|
+
def beginContour()
|
1342
|
+
(@drawingShape__ or raise "beginContour() must be called after beginShape()")
|
1343
|
+
.beginContour
|
1344
|
+
end
|
1345
|
+
|
1346
|
+
# Ends drawing a hole.
|
1347
|
+
#
|
1348
|
+
# @return [nil] nil
|
1349
|
+
#
|
1350
|
+
# @see https://processing.org/reference/endContour_.html
|
1351
|
+
# @see https://p5js.org/reference/#/p5/endContour
|
1352
|
+
#
|
1353
|
+
def endContour()
|
1354
|
+
(@drawingShape__ or raise "endContour() must be called after beginShape()")
|
1355
|
+
.endContour
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
# Append vertex for shape polygon.
|
1359
|
+
#
|
1360
|
+
# @overload vertex(x, y)
|
1361
|
+
# @overload vertex(x, y, u, v)
|
1362
|
+
#
|
1363
|
+
# @param x [Numeric] x position of vertex
|
1364
|
+
# @param y [Numeric] y position of vertex
|
1365
|
+
# @param u [Numeric] u texture coordinate of vertex
|
1366
|
+
# @param v [Numeric] v texture coordinate of vertex
|
1367
|
+
#
|
1368
|
+
# @return [nil] nil
|
1369
|
+
#
|
1370
|
+
# @see https://processing.org/reference/vertex_.html
|
1371
|
+
# @see https://p5js.org/reference/#/p5/vertex
|
1372
|
+
#
|
1373
|
+
def vertex(x, y, u = nil, v = nil)
|
1374
|
+
(@drawingShape__ or raise "vertex() must be called after beginShape()")
|
1375
|
+
.vertex x, y, u, v
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
# Append curve vertex for shape polygon.
|
1379
|
+
#
|
1380
|
+
# @param x [Numeric] x position of vertex
|
1381
|
+
# @param y [Numeric] y position of vertex
|
1382
|
+
#
|
1383
|
+
# @return [nil] nil
|
1384
|
+
#
|
1385
|
+
# @see https://processing.org/reference/curveVertex_.html
|
1386
|
+
# @see https://p5js.org/reference/#/p5/curveVertex
|
1387
|
+
#
|
1388
|
+
def curveVertex(x, y)
|
1389
|
+
(@drawingShape__ or raise "curveVertex() must be called after beginShape()")
|
1390
|
+
.curveVertex x, y
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
# Append bezier vertex for shape polygon.
|
1394
|
+
#
|
1395
|
+
# @param x [Numeric] x position of vertex
|
1396
|
+
# @param y [Numeric] y position of vertex
|
1397
|
+
#
|
1398
|
+
# @return [nil] nil
|
1399
|
+
#
|
1400
|
+
# @see https://processing.org/reference/bezierVertex_.html
|
1401
|
+
# @see https://p5js.org/reference/#/p5/bezierVertex
|
1402
|
+
#
|
1403
|
+
def bezierVertex(x2, y2, x3, y3, x4, y4)
|
1404
|
+
(@drawingShape__ or raise "bezierVertex() must be called after beginShape()")
|
1405
|
+
.bezierVertex x2, y2, x3, y3, x4, y4
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
# Append quadratic vertex for shape polygon.
|
1409
|
+
#
|
1410
|
+
# @param x [Numeric] x position of vertex
|
1411
|
+
# @param y [Numeric] y position of vertex
|
1412
|
+
#
|
1413
|
+
# @return [nil] nil
|
1414
|
+
#
|
1415
|
+
# @see https://processing.org/reference/quadraticVertex_.html
|
1416
|
+
# @see https://p5js.org/reference/#/p5/quadraticVertex
|
1417
|
+
#
|
1418
|
+
def quadraticVertex(cx, cy, x3, y3)
|
1419
|
+
(@drawingShape__ or raise "quadraticVertex() must be called after beginShape()")
|
1420
|
+
.quadraticVertex cx, cy, x3, y3
|
1421
|
+
end
|
1422
|
+
|
1097
1423
|
# Copies image.
|
1098
1424
|
#
|
1099
1425
|
# @overload copy(sx, sy, sw, sh, dx, dy, dw, dh)
|
@@ -1135,11 +1461,34 @@ module Processing
|
|
1135
1461
|
#
|
1136
1462
|
def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
1137
1463
|
assertDrawing__
|
1138
|
-
|
1139
|
-
img ||= self
|
1140
|
-
img.drawImage__(
|
1464
|
+
(img || self).drawImage__(
|
1141
1465
|
@painter__, sx, sy, sw, sh, dx, dy, dw, dh,
|
1142
|
-
fill:
|
1466
|
+
fill: getTint__, stroke: :none, blend_mode: mode)
|
1467
|
+
end
|
1468
|
+
|
1469
|
+
# Loads all pixels to the 'pixels' array.
|
1470
|
+
#
|
1471
|
+
# @return [nil] nil
|
1472
|
+
#
|
1473
|
+
def loadPixels()
|
1474
|
+
@pixels__ = getInternal__.pixels
|
1475
|
+
end
|
1476
|
+
|
1477
|
+
# Update the image pixels with the 'pixels' array.
|
1478
|
+
#
|
1479
|
+
# @return [nil] nil
|
1480
|
+
#
|
1481
|
+
def updatePixels()
|
1482
|
+
return unless @pixels__
|
1483
|
+
getInternal__.pixels = @pixels__
|
1484
|
+
@pixels__ = nil
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
# An array of all pixels.
|
1488
|
+
# Call loadPixels() before accessing the array.
|
1489
|
+
#
|
1490
|
+
def pixels()
|
1491
|
+
@pixels__
|
1143
1492
|
end
|
1144
1493
|
|
1145
1494
|
# Saves screen image to file.
|
@@ -1149,7 +1498,7 @@ module Processing
|
|
1149
1498
|
# @return [nil] nil
|
1150
1499
|
#
|
1151
1500
|
def save(filename)
|
1152
|
-
|
1501
|
+
getInternal__.save filename
|
1153
1502
|
nil
|
1154
1503
|
end
|
1155
1504
|
|
@@ -1181,9 +1530,9 @@ module Processing
|
|
1181
1530
|
#
|
1182
1531
|
# @return [nil] nil
|
1183
1532
|
#
|
1184
|
-
def scale(x, y)
|
1533
|
+
def scale(x, y = nil, z = 1)
|
1185
1534
|
assertDrawing__
|
1186
|
-
@painter__.scale x, y
|
1535
|
+
@painter__.scale x, (y || x), z
|
1187
1536
|
nil
|
1188
1537
|
end
|
1189
1538
|
|
@@ -1195,7 +1544,7 @@ module Processing
|
|
1195
1544
|
#
|
1196
1545
|
def rotate(angle)
|
1197
1546
|
assertDrawing__
|
1198
|
-
@painter__.rotate
|
1547
|
+
@painter__.rotate toDegrees__ angle
|
1199
1548
|
nil
|
1200
1549
|
end
|
1201
1550
|
|
@@ -1247,6 +1596,9 @@ module Processing
|
|
1247
1596
|
@painter__.clip,
|
1248
1597
|
@painter__.blend_mode,
|
1249
1598
|
@painter__.font,
|
1599
|
+
@painter__.texture,
|
1600
|
+
@painter__.texcoord_mode,
|
1601
|
+
@painter__.texcoord_wrap,
|
1250
1602
|
@painter__.shader,
|
1251
1603
|
@hsbColor__,
|
1252
1604
|
@colorMaxes__,
|
@@ -1254,8 +1606,10 @@ module Processing
|
|
1254
1606
|
@rectMode__,
|
1255
1607
|
@ellipseMode__,
|
1256
1608
|
@imageMode__,
|
1609
|
+
@shapeMode__,
|
1257
1610
|
@textAlignH__,
|
1258
1611
|
@textAlignV__,
|
1612
|
+
@textFont__,
|
1259
1613
|
@tint__,
|
1260
1614
|
]
|
1261
1615
|
block.call if block
|
@@ -1278,6 +1632,9 @@ module Processing
|
|
1278
1632
|
@painter__.clip,
|
1279
1633
|
@painter__.blend_mode,
|
1280
1634
|
@painter__.font,
|
1635
|
+
@painter__.texture,
|
1636
|
+
@painter__.texcoord_mode,
|
1637
|
+
@painter__.texcoord_wrap,
|
1281
1638
|
@painter__.shader,
|
1282
1639
|
@hsbColor__,
|
1283
1640
|
@colorMaxes__,
|
@@ -1285,9 +1642,12 @@ module Processing
|
|
1285
1642
|
@rectMode__,
|
1286
1643
|
@ellipseMode__,
|
1287
1644
|
@imageMode__,
|
1645
|
+
@shapeMode__,
|
1288
1646
|
@textAlignH__,
|
1289
1647
|
@textAlignV__,
|
1648
|
+
@textFont__,
|
1290
1649
|
@tint__ = @styleStack__.pop
|
1650
|
+
@textFont__.setSize__ @painter__.font.size
|
1291
1651
|
nil
|
1292
1652
|
end
|
1293
1653
|
|
@@ -1699,7 +2059,7 @@ module Processing
|
|
1699
2059
|
rand (low || 0).to_f...(high || 1).to_f
|
1700
2060
|
end
|
1701
2061
|
|
1702
|
-
# Creates a new vector.
|
2062
|
+
# Creates a new vector object.
|
1703
2063
|
#
|
1704
2064
|
# @overload createVector()
|
1705
2065
|
# @overload createVector(x, y)
|
@@ -1715,7 +2075,17 @@ module Processing
|
|
1715
2075
|
Vector.new(*args, context: self)
|
1716
2076
|
end
|
1717
2077
|
|
1718
|
-
# Creates a new
|
2078
|
+
# Creates a new font object.
|
2079
|
+
#
|
2080
|
+
# @param name [String] font name
|
2081
|
+
# @param size [Numeric] font size (max 256)
|
2082
|
+
#
|
2083
|
+
def createFont(name, size)
|
2084
|
+
size = FONT_SIZE_MAX__ if size && size > FONT_SIZE_MAX__
|
2085
|
+
Font.new Rays::Font.new(name, size || FONT_SIZE_DEFAULT__)
|
2086
|
+
end
|
2087
|
+
|
2088
|
+
# Creates a new image object.
|
1719
2089
|
#
|
1720
2090
|
# @overload createImage(w, h)
|
1721
2091
|
# @overload createImage(w, h, format)
|
@@ -1732,6 +2102,67 @@ module Processing
|
|
1732
2102
|
Image.new Rays::Image.new(w, h, colorspace).paint {background 0, 0}
|
1733
2103
|
end
|
1734
2104
|
|
2105
|
+
# Creates a new shape object.
|
2106
|
+
#
|
2107
|
+
# @overload createShape()
|
2108
|
+
# @overload createShape(LINE, x1, y1, x2, y2)
|
2109
|
+
# @overload createShape(RECT, a, b, c, d)
|
2110
|
+
# @overload createShape(ELLIPSE, a, b, c, d)
|
2111
|
+
# @overload createShape(ARC, a, b, c, d, start, stop)
|
2112
|
+
# @overload createShape(TRIANGLE, x1, y1, x2, y2, x3, y3)
|
2113
|
+
# @overload createShape(QUAD, x1, y1, x2, y2, x3, y3, x4, y4)
|
2114
|
+
# @overload createShape(GROUP)
|
2115
|
+
#
|
2116
|
+
# @param kind [LINE, RECT, ELLIPSE, ARC, TRIANGLE, QUAD, GROUP]
|
2117
|
+
#
|
2118
|
+
def createShape(kind = nil, *args)
|
2119
|
+
case kind
|
2120
|
+
when LINE then createLineShape__( *args)
|
2121
|
+
when RECT then createRectShape__( *args)
|
2122
|
+
when ELLIPSE then createEllipseShape__( *args)
|
2123
|
+
when ARC then createArcShape__( *args)
|
2124
|
+
when TRIANGLE then createTriangleShape__(*args)
|
2125
|
+
when QUAD then createQuadShape__( *args)
|
2126
|
+
when GROUP then Shape.new nil, [], context: self
|
2127
|
+
when nil then Shape.new context: self
|
2128
|
+
else raise ArgumentError, "Unknown shape kind '#{kind}'"
|
2129
|
+
end
|
2130
|
+
end
|
2131
|
+
|
2132
|
+
# @private
|
2133
|
+
private def createLineShape__(x1, y1, x2, y2)
|
2134
|
+
Shape.new Rays::Polygon.line(x1, y1, x2, y2), context: self
|
2135
|
+
end
|
2136
|
+
|
2137
|
+
# @private
|
2138
|
+
private def createRectShape__(a, b, c, d)
|
2139
|
+
x, y, w, h = toXYWH__ @rectMode__, a, b, c, d
|
2140
|
+
Shape.new Rays::Polygon.rect(x, y, w, h), context: self
|
2141
|
+
end
|
2142
|
+
|
2143
|
+
# @private
|
2144
|
+
private def createEllipseShape__(a, b, c, d)
|
2145
|
+
x, y, w, h = toXYWH__ @ellipseMode__, a, b, c, d
|
2146
|
+
Shape.new Rays::Polygon.ellipse(x, y, w, h), context: self
|
2147
|
+
end
|
2148
|
+
|
2149
|
+
# @private
|
2150
|
+
private def createArcShape__(a, b, c, d, start, stop)
|
2151
|
+
x, y, w, h = toXYWH__ @ellipseMode__, a, b, c, d
|
2152
|
+
from, to = toDegrees__(-start), toDegrees__(-stop)
|
2153
|
+
Shape.new Rays::Polygon.ellipse(x, y, w, h, from: from, to: to), context: self
|
2154
|
+
end
|
2155
|
+
|
2156
|
+
# @private
|
2157
|
+
private def createTriangleShape__(x1, y1, x2, y2, x3, y3)
|
2158
|
+
Shape.new Rays::Polygon.new(x1, y1, x2, y2, x3, y3, loop: true), context: self
|
2159
|
+
end
|
2160
|
+
|
2161
|
+
# @private
|
2162
|
+
private def createQuadShape__(x1, y1, x2, y2, x3, y3, x4, y4)
|
2163
|
+
Shape.new Rays::Polygon.quads(x1, y1, x2, y2, x3, y3, x4, y4), context: self
|
2164
|
+
end
|
2165
|
+
|
1735
2166
|
# Creates a new off-screen graphics context object.
|
1736
2167
|
#
|
1737
2168
|
# @param width [Numeric] width of graphics image
|
@@ -1790,6 +2221,23 @@ module Processing
|
|
1790
2221
|
Capture.new(*args)
|
1791
2222
|
end
|
1792
2223
|
|
2224
|
+
# Loads font from file.
|
2225
|
+
#
|
2226
|
+
# @param filename [String] file name to load font file
|
2227
|
+
#
|
2228
|
+
# @return [Font] loaded font object
|
2229
|
+
#
|
2230
|
+
# @see https://processing.org/reference/loadFont_.html
|
2231
|
+
# @see https://p5js.org/reference/#/p5/loadFont
|
2232
|
+
#
|
2233
|
+
def loadFont(filename)
|
2234
|
+
ext = File.extname filename
|
2235
|
+
raise "unsupported font type -- '#{ext}'" unless ext =~ /^\.?(ttf|otf)$/i
|
2236
|
+
|
2237
|
+
filename = httpGet__ filename, ext if filename =~ %r|^https?://|
|
2238
|
+
Font.new Rays::Font.load p filename
|
2239
|
+
end
|
2240
|
+
|
1793
2241
|
# Loads image.
|
1794
2242
|
#
|
1795
2243
|
# @param filename [String] file name to load image
|
@@ -1797,11 +2245,39 @@ module Processing
|
|
1797
2245
|
#
|
1798
2246
|
# @return [Image] loaded image object
|
1799
2247
|
#
|
2248
|
+
# @see https://processing.org/reference/loadImage_.html
|
2249
|
+
# @see https://p5js.org/reference/#/p5/loadImage
|
2250
|
+
#
|
1800
2251
|
def loadImage(filename, extension = nil)
|
1801
|
-
|
2252
|
+
ext = extension || File.extname(filename)
|
2253
|
+
raise "unsupported image type -- '#{ext}'" unless ext =~ /^\.?(png|jpg|gif)$/i
|
2254
|
+
|
2255
|
+
filename = httpGet__ filename, ext if filename =~ %r|^https?://|
|
1802
2256
|
Image.new Rays::Image.load filename
|
1803
2257
|
end
|
1804
2258
|
|
2259
|
+
# Loads image on a new thread.
|
2260
|
+
# When the image is loading, its width and height will be 0.
|
2261
|
+
# If an error occurs while loading the image, its width and height wil be -1.
|
2262
|
+
#
|
2263
|
+
# @param filename [String] file name to load image
|
2264
|
+
# @param extension [String] type of image to load (ex. 'png')
|
2265
|
+
#
|
2266
|
+
# @return [Image] loading image object
|
2267
|
+
#
|
2268
|
+
# @see https://processing.org/reference/requestImage_.html
|
2269
|
+
#
|
2270
|
+
def requestImage(filename, extension = nil)
|
2271
|
+
img = Image.new nil
|
2272
|
+
Thread.new filename, extension do |fn, ext|
|
2273
|
+
loaded = loadImage(fn, ext) or raise
|
2274
|
+
img.setInternal__ loaded.getInternal__
|
2275
|
+
rescue
|
2276
|
+
img.setInternal__ nil, true
|
2277
|
+
end
|
2278
|
+
img
|
2279
|
+
end
|
2280
|
+
|
1805
2281
|
# Loads shader file.
|
1806
2282
|
#
|
1807
2283
|
# @overload loadShader(fragPath)
|
@@ -1817,10 +2293,7 @@ module Processing
|
|
1817
2293
|
end
|
1818
2294
|
|
1819
2295
|
# @private
|
1820
|
-
private def
|
1821
|
-
ext ||= File.extname uri
|
1822
|
-
raise "unsupported image type -- #{ext}" unless ext =~ /^\.?(png|jpg|gif)$/i
|
1823
|
-
|
2296
|
+
private def httpGet__(uri, ext)
|
1824
2297
|
tmpdir = tmpdir__
|
1825
2298
|
path = tmpdir + Digest::SHA1.hexdigest(uri)
|
1826
2299
|
path = path.sub_ext ext
|