processing 0.5.30 → 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/.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
|