@@ -9,6 +9,7 @@ import * as constants from '../core/constants';
9
9
import { Image } from '../image/p5.Image' ;
10
10
import { Vector } from '../math/p5.Vector' ;
11
11
import { Shape } from '../shape/custom_shapes' ;
12
+ import { States } from './States' ;
12
13
13
14
class ClonableObject {
14
15
constructor ( obj = { } ) {
@@ -70,15 +71,7 @@ class Renderer {
70
71
}
71
72
72
73
// Renderer state machine
73
- this . states = Object . assign ( { } , Renderer . states ) ;
74
- // Clone properties that support it
75
- for ( const key in this . states ) {
76
- if ( this . states [ key ] instanceof Array ) {
77
- this . states [ key ] = this . states [ key ] . slice ( ) ;
78
- } else if ( this . states [ key ] && this . states [ key ] . clone instanceof Function ) {
79
- this . states [ key ] = this . states [ key ] . clone ( ) ;
80
- }
81
- }
74
+ this . states = new States ( Renderer . states ) ;
82
75
83
76
this . states . strokeColor = new Color ( [ 0 , 0 , 0 ] ) ;
84
77
this . states . fillColor = new Color ( [ 255 , 255 , 255 ] ) ;
@@ -122,33 +115,25 @@ class Renderer {
122
115
// and push it into the push pop stack
123
116
push ( ) {
124
117
this . _pushPopDepth ++ ;
125
- const currentStates = Object . assign ( { } , this . states ) ;
126
- // Clone properties that support it
127
- for ( const key in currentStates ) {
128
- if ( currentStates [ key ] instanceof Array ) {
129
- currentStates [ key ] = currentStates [ key ] . slice ( ) ;
130
- } else if ( currentStates [ key ] && currentStates [ key ] . clone instanceof Function ) {
131
- currentStates [ key ] = currentStates [ key ] . clone ( ) ;
132
- }
133
- }
134
- this . _pushPopStack . push ( currentStates ) ;
135
- return currentStates ;
118
+ this . _pushPopStack . push ( this . states . getDiff ( ) ) ;
136
119
}
137
120
138
121
// Pop the previous states out of the push pop stack and
139
122
// assign it back to the current state
140
123
pop ( ) {
141
124
this . _pushPopDepth -- ;
142
- Object . assign ( this . states , this . _pushPopStack . pop ( ) ) ;
143
- this . updateShapeVertexProperties ( ) ;
144
- this . updateShapeProperties ( ) ;
125
+ const diff = this . _pushPopStack . pop ( ) || { } ;
126
+ const modified = this . states . getModified ( ) ;
127
+ this . states . applyDiff ( diff ) ;
128
+ this . updateShapeVertexProperties ( modified ) ;
129
+ this . updateShapeProperties ( modified ) ;
145
130
}
146
131
147
132
bezierOrder ( order ) {
148
133
if ( order === undefined ) {
149
134
return this . states . bezierOrder ;
150
135
} else {
151
- this . states . bezierOrder = order ;
136
+ this . states . setValue ( ' bezierOrder' , order ) ;
152
137
this . updateShapeProperties ( ) ;
153
138
}
154
139
}
@@ -165,11 +150,22 @@ class Renderer {
165
150
if ( value === undefined ) {
166
151
return this . states . splineProperties [ key ] ;
167
152
} else {
153
+ this . states . setValue ( 'splineProperties' , this . states . splineProperties . clone ( ) ) ;
168
154
this . states . splineProperties [ key ] = value ;
169
155
}
170
156
this . updateShapeProperties ( ) ;
171
157
}
172
158
159
+ splineProperties ( values ) {
160
+ if ( values ) {
161
+ for ( const key in values ) {
162
+ this . splineProperty ( key , values [ key ] ) ;
163
+ }
164
+ } else {
165
+ return { ...this . states . splineProperties } ;
166
+ }
167
+ }
168
+
173
169
splineVertex ( x , y , z = 0 , u = 0 , v = 0 ) {
174
170
const position = new Vector ( x , y , z ) ;
175
171
const textureCoordinates = this . getSupportedIndividualVertexProperties ( ) . textureCoordinates
@@ -182,7 +178,7 @@ class Renderer {
182
178
if ( d === undefined ) {
183
179
return this . states . curveDetail ;
184
180
} else {
185
- this . states . curveDetail = d ;
181
+ this . states . setValue ( ' curveDetail' , d ) ;
186
182
}
187
183
}
188
184
@@ -277,31 +273,31 @@ class Renderer {
277
273
}
278
274
279
275
fill ( ...args ) {
280
- this . states . fillSet = true ;
281
- this . states . fillColor = this . _pInst . color ( ...args ) ;
276
+ this . states . setValue ( ' fillSet' , true ) ;
277
+ this . states . setValue ( ' fillColor' , this . _pInst . color ( ...args ) ) ;
282
278
this . updateShapeVertexProperties ( ) ;
283
279
}
284
280
285
281
noFill ( ) {
286
- this . states . fillColor = null ;
282
+ this . states . setValue ( ' fillColor' , null ) ;
287
283
}
288
284
289
285
strokeWeight ( w ) {
290
286
if ( w === undefined ) {
291
287
return this . states . strokeWeight ;
292
288
} else {
293
- this . states . strokeWeight = w ;
289
+ this . states . setValue ( ' strokeWeight' , w ) ;
294
290
}
295
291
}
296
292
297
293
stroke ( ...args ) {
298
- this . states . strokeSet = true ;
299
- this . states . strokeColor = this . _pInst . color ( ...args ) ;
294
+ this . states . setValue ( ' strokeSet' , true ) ;
295
+ this . states . setValue ( ' strokeColor' , this . _pInst . color ( ...args ) ) ;
300
296
this . updateShapeVertexProperties ( ) ;
301
297
}
302
298
303
299
noStroke ( ) {
304
- this . states . strokeColor = null ;
300
+ this . states . setValue ( ' strokeColor' , null ) ;
305
301
}
306
302
307
303
getCommonVertexProperties ( ) {
@@ -314,25 +310,31 @@ class Renderer {
314
310
}
315
311
}
316
312
317
- updateShapeProperties ( ) {
318
- this . currentShape . bezierOrder ( this . states . bezierOrder ) ;
319
- this . currentShape . splineProperty ( 'ends' , this . states . splineProperties . ends ) ;
320
- this . currentShape . splineProperty ( 'tightness' , this . states . splineProperties . tightness ) ;
313
+ updateShapeProperties ( modified ) {
314
+ if ( ! modified || modified . bezierOrder || modified . splineProperties ) {
315
+ const shape = this . currentShape ;
316
+ shape . bezierOrder ( this . states . bezierOrder ) ;
317
+ shape . splineProperty ( 'ends' , this . states . splineProperties . ends ) ;
318
+ shape . splineProperty ( 'tightness' , this . states . splineProperties . tightness ) ;
319
+ }
321
320
}
322
321
323
- updateShapeVertexProperties ( ) {
322
+ updateShapeVertexProperties ( modified ) {
324
323
const props = this . getCommonVertexProperties ( ) ;
325
- for ( const key in props ) {
326
- this . currentShape [ key ] ( props [ key ] ) ;
324
+ if ( ! modified || Object . keys ( modified ) . some ( ( k ) => k in props ) ) {
325
+ const shape = this . currentShape ;
326
+ for ( const key in props ) {
327
+ shape [ key ] ( props [ key ] ) ;
328
+ }
327
329
}
328
330
}
329
331
330
332
textSize ( s ) {
331
333
if ( typeof s === 'number' ) {
332
- this . states . textSize = s ;
334
+ this . states . setValue ( ' textSize' , s ) ;
333
335
if ( ! this . states . leadingSet ) {
334
336
// only use a default value if not previously set (#5181)
335
- this . states . textLeading = s * constants . _DEFAULT_LEADMULT ;
337
+ this . states . setValue ( ' textLeading' , s * constants . _DEFAULT_LEADMULT ) ;
336
338
}
337
339
return this . _applyTextProperties ( ) ;
338
340
}
@@ -342,8 +344,8 @@ class Renderer {
342
344
343
345
textLeading ( l ) {
344
346
if ( typeof l === 'number' ) {
345
- this . states . leadingSet = true ;
346
- this . states . textLeading = l ;
347
+ this . states . setValue ( ' leadingSet' , true ) ;
348
+ this . states . setValue ( ' textLeading' , l ) ;
347
349
return this . _pInst ;
348
350
}
349
351
@@ -358,7 +360,7 @@ class Renderer {
358
360
s === constants . BOLD ||
359
361
s === constants . BOLDITALIC
360
362
) {
361
- this . states . fontStyle = s ;
363
+ this . states . setValue ( ' fontStyle' , s ) ;
362
364
}
363
365
364
366
return this . _applyTextProperties ( ) ;
@@ -383,10 +385,10 @@ class Renderer {
383
385
384
386
textAlign ( h , v ) {
385
387
if ( typeof h !== 'undefined' ) {
386
- this . states . textAlign = h ;
388
+ this . states . setValue ( ' textAlign' , h ) ;
387
389
388
390
if ( typeof v !== 'undefined' ) {
389
- this . states . textBaseline = v ;
391
+ this . states . setValue ( ' textBaseline' , v ) ;
390
392
}
391
393
392
394
return this . _applyTextProperties ( ) ;
@@ -399,7 +401,7 @@ class Renderer {
399
401
}
400
402
401
403
textWrap ( wrapStyle ) {
402
- this . states . textWrap = wrapStyle ;
404
+ this . states . setValue ( ' textWrap' , wrapStyle ) ;
403
405
return this . states . textWrap ;
404
406
}
405
407
@@ -647,8 +649,8 @@ class Renderer {
647
649
648
650
_updateTextMetrics ( ) {
649
651
if ( this . _isOpenType ( ) ) {
650
- this . states . textAscent = this . states . textFont . _textAscent ( ) ;
651
- this . states . textDescent = this . states . textFont . _textDescent ( ) ;
652
+ this . states . setValue ( ' textAscent' , this . states . textFont . _textAscent ( ) ) ;
653
+ this . states . setValue ( ' textDescent' , this . states . textFont . _textDescent ( ) ) ;
652
654
return this ;
653
655
}
654
656
@@ -684,8 +686,8 @@ class Renderer {
684
686
685
687
document . body . removeChild ( container ) ;
686
688
687
- this . states . textAscent = ascent ;
688
- this . states . textDescent = descent ;
689
+ this . states . setValue ( ' textAscent' , ascent ) ;
690
+ this . states . setValue ( ' textDescent' , descent ) ;
689
691
690
692
return this ;
691
693
}
0 commit comments