20
20
21
21
'use strict' ;
22
22
23
+ // This global variable is used to minimize the memory usage when patterns are
24
+ // used.
25
+ var temporaryPatternCanvas = null ;
26
+
23
27
var PatternType = {
24
28
AXIAL : 2 ,
25
29
RADIAL : 3
@@ -268,68 +272,24 @@ var TilingPattern = (function TilingPatternClosure() {
268
272
COLORED : 1 ,
269
273
UNCOLORED : 2
270
274
};
271
- var MAX_PATTERN_SIZE = 4096 ;
275
+
276
+ var MAX_PATTERN_SIZE = 8192 ;
272
277
273
278
function TilingPattern (IR , color , ctx , objs , commonObjs ) {
274
- var operatorList = IR [2 ];
279
+ this .name = IR [1 ][0 ].name ;
280
+ this .operatorList = IR [2 ];
275
281
this .matrix = IR [3 ] || [1 , 0 , 0 , 1 , 0 , 0 ];
276
- var bbox = IR [4 ];
277
- var xstep = IR [5 ];
278
- var ystep = IR [6 ];
279
- var paintType = IR [7 ];
280
- var tilingType = IR [8 ];
281
-
282
- TODO ( 'TilingType: ' + tilingType ) ;
283
-
282
+ this . bbox = IR [4 ];
283
+ this . xstep = IR [5 ];
284
+ this . ystep = IR [6 ];
285
+ this . paintType = IR [7 ];
286
+ this . tilingType = IR [8 ];
287
+ this . color = color ;
288
+ this . objs = objs ;
289
+ this . commonObjs = commonObjs ;
284
290
this .curMatrix = ctx .mozCurrentTransform ;
285
- this .ctx = ctx ;
286
291
this .type = 'Pattern' ;
287
-
288
- var x0 = bbox [0 ], y0 = bbox [1 ], x1 = bbox [2 ], y1 = bbox [3 ];
289
-
290
- var topLeft = [x0 , y0 ];
291
- // we want the canvas to be as large as the step size
292
- var botRight = [x0 + xstep , y0 + ystep ];
293
-
294
- var width = botRight [0 ] - topLeft [0 ];
295
- var height = botRight [1 ] - topLeft [1 ];
296
-
297
- // Obtain scale from matrix and current transformation matrix.
298
- var matrixScale = Util .singularValueDecompose2dScale (this .matrix );
299
- var curMatrixScale = Util .singularValueDecompose2dScale (this .curMatrix );
300
- var combinedScale = [matrixScale [0 ] * curMatrixScale [0 ],
301
- matrixScale [1 ] * curMatrixScale [1 ]];
302
-
303
- // MAX_PATTERN_SIZE is used to avoid OOM situation.
304
- // Use width and height values that are as close as possible to the end
305
- // result when the pattern is used. Too low value makes the pattern look
306
- // blurry. Too large value makes it look too crispy.
307
- width = Math .min (Math .ceil (Math .abs (width * combinedScale [0 ])),
308
- MAX_PATTERN_SIZE );
309
-
310
- height = Math .min (Math .ceil (Math .abs (height * combinedScale [1 ])),
311
- MAX_PATTERN_SIZE );
312
-
313
- var tmpCanvas = createScratchCanvas (width , height );
314
-
315
- // set the new canvas element context as the graphics context
316
- var tmpCtx = tmpCanvas .getContext ('2d' );
317
- var graphics = new CanvasGraphics (tmpCtx , commonObjs , objs );
318
-
319
- this .setFillAndStrokeStyleToContext (tmpCtx , paintType , color );
320
-
321
- this .setScale (width , height , xstep , ystep );
322
- this .transformToScale (graphics );
323
-
324
- // transform coordinates to pattern space
325
- var tmpTranslate = [1 , 0 , 0 , 1 , -topLeft [0 ], -topLeft [1 ]];
326
- graphics .transform .apply (graphics , tmpTranslate );
327
-
328
- this .clipBbox (graphics , bbox , x0 , y0 , x1 , y1 );
329
-
330
- graphics .executeOperatorList (operatorList );
331
-
332
- this .canvas = tmpCanvas ;
292
+ this .ctx = ctx ;
333
293
}
334
294
335
295
TilingPattern .getIR = function TilingPattern_getIR (operatorList , dict , args ) {
@@ -347,6 +307,66 @@ var TilingPattern = (function TilingPatternClosure() {
347
307
};
348
308
349
309
TilingPattern .prototype = {
310
+ createPatternCanvas : function TilinPattern_createPatternCanvas (tmpCanvas ) {
311
+ var operatorList = this .operatorList ;
312
+ var bbox = this .bbox ;
313
+ var xstep = this .xstep ;
314
+ var ystep = this .ystep ;
315
+ var paintType = this .paintType ;
316
+ var tilingType = this .tilingType ;
317
+ var color = this .color ;
318
+ var objs = this .objs ;
319
+ var commonObjs = this .commonObjs ;
320
+ var ctx = this .ctx ;
321
+
322
+ TODO ('TilingType: ' + tilingType );
323
+
324
+ var x0 = bbox [0 ], y0 = bbox [1 ], x1 = bbox [2 ], y1 = bbox [3 ];
325
+
326
+ var topLeft = [x0 , y0 ];
327
+ // we want the canvas to be as large as the step size
328
+ var botRight = [x0 + xstep , y0 + ystep ];
329
+
330
+ var width = botRight [0 ] - topLeft [0 ];
331
+ var height = botRight [1 ] - topLeft [1 ];
332
+
333
+ // Obtain scale from matrix and current transformation matrix.
334
+ var matrixScale = Util .singularValueDecompose2dScale (this .matrix );
335
+ var curMatrixScale = Util .singularValueDecompose2dScale (this .curMatrix );
336
+ var combinedScale = [matrixScale [0 ] * curMatrixScale [0 ],
337
+ matrixScale [1 ] * curMatrixScale [1 ]];
338
+
339
+ // MAX_PATTERN_SIZE is used to avoid OOM situation.
340
+ // Use width and height values that are as close as possible to the end
341
+ // result when the pattern is used. Too low value makes the pattern look
342
+ // blurry. Too large value makes it look too crispy.
343
+ width = Math .min (Math .ceil (Math .abs (width * combinedScale [0 ])),
344
+ MAX_PATTERN_SIZE );
345
+
346
+ height = Math .min (Math .ceil (Math .abs (height * combinedScale [1 ])),
347
+ MAX_PATTERN_SIZE );
348
+
349
+ tmpCanvas .width = width ;
350
+ tmpCanvas .height = height ;
351
+
352
+ // set the new canvas element context as the graphics context
353
+ var tmpCtx = tmpCanvas .getContext ('2d' );
354
+ var graphics = new CanvasGraphics (tmpCtx , commonObjs , objs );
355
+
356
+ this .setFillAndStrokeStyleToContext (tmpCtx , paintType , color );
357
+
358
+ this .setScale (width , height , xstep , ystep );
359
+ this .transformToScale (graphics );
360
+
361
+ // transform coordinates to pattern space
362
+ var tmpTranslate = [1 , 0 , 0 , 1 , -topLeft [0 ], -topLeft [1 ]];
363
+ graphics .transform .apply (graphics , tmpTranslate );
364
+
365
+ this .clipBbox (graphics , bbox , x0 , y0 , x1 , y1 );
366
+
367
+ graphics .executeOperatorList (operatorList );
368
+ },
369
+
350
370
setScale : function TilingPattern_setScale (width , height , xstep , ystep ) {
351
371
this .scale = [width / xstep , height / ystep ];
352
372
},
@@ -392,15 +412,19 @@ var TilingPattern = (function TilingPatternClosure() {
392
412
},
393
413
394
414
getPattern : function TilingPattern_getPattern () {
395
- var matrix = this .matrix ;
396
- var curMatrix = this .curMatrix ;
397
- var ctx = this .ctx ;
415
+ // The temporary canvas is created only because the memory is released
416
+ // more quickly than creating multiple temporary canvases.
417
+ if (temporaryPatternCanvas === null ) {
418
+ temporaryPatternCanvas = createScratchCanvas (0 , 0 );
419
+ }
420
+ this .createPatternCanvas (temporaryPatternCanvas );
398
421
399
- ctx .setTransform .apply (ctx , curMatrix );
400
- ctx .transform .apply (ctx , matrix );
422
+ var ctx = this .ctx ;
423
+ ctx .setTransform .apply (ctx , this .curMatrix );
424
+ ctx .transform .apply (ctx , this .matrix );
401
425
this .scaleToContext ();
402
426
403
- return ctx .createPattern (this . canvas , 'repeat' );
427
+ return ctx .createPattern (temporaryPatternCanvas , 'repeat' );
404
428
}
405
429
};
406
430
0 commit comments