3232
3333import java .util .HashSet ;
3434import java .util .Map ;
35+ import java .util .Objects ;
3536import java .util .Set ;
3637
3738public class Canvas implements ICanvas
3839{
3940
4041 private static final Style DEFAULT_SVG_STYLE = new Style ();
4142
42- @ NonNull
43- private final android .graphics .Canvas canvas ;
43+ @ Nullable
44+ private android .graphics .Canvas canvas ;
4445
4546 @ NonNull
4647 private final Paint strokePaint ;
@@ -77,6 +78,8 @@ public class Canvas implements ICanvas
7778 private final ImageLoader imageLoader ;
7879 private final OfflineSurfaceManager offlineSurfaceManager ;
7980
81+ private boolean clearOnStartDraw = true ;
82+
8083 private final Set <String > clips ;
8184
8285 private final Map <String , Typeface > typefaceMap ;
@@ -92,7 +95,7 @@ public class Canvas implements ICanvas
9295 @ NonNull
9396 private final Matrix pointScaleMatrix ;
9497
95- public Canvas (@ NonNull android .graphics .Canvas canvas , Map <String , Typeface > typefaceMap , ImageLoader imageLoader , @ Nullable OfflineSurfaceManager offlineSurfaceManager , float xdpi , float ydpi )
98+ public Canvas (@ Nullable android .graphics .Canvas canvas , Map <String , Typeface > typefaceMap , ImageLoader imageLoader , @ Nullable OfflineSurfaceManager offlineSurfaceManager , float xdpi , float ydpi )
9699 {
97100 this .canvas = canvas ;
98101 this .typefaceMap = typefaceMap ;
@@ -135,11 +138,21 @@ public Canvas(@NonNull android.graphics.Canvas canvas, Map<String, Typeface> typ
135138 applyStyle (DEFAULT_SVG_STYLE );
136139 }
137140
138- public Canvas (@ NonNull android .graphics .Canvas canvas , Map <String , Typeface > typefaceMap , ImageLoader imageLoader , float xdpi , float ydpi )
141+ public Canvas (@ Nullable android .graphics .Canvas canvas , Map <String , Typeface > typefaceMap , ImageLoader imageLoader , float xdpi , float ydpi )
139142 {
140143 this (canvas , typefaceMap , imageLoader , null , xdpi , ydpi );
141144 }
142145
146+ public void setCanvas (@ NonNull android .graphics .Canvas canvas )
147+ {
148+ this .canvas = canvas ;
149+ }
150+
151+ public void setClearOnStartDraw (boolean clearOnStartDraw )
152+ {
153+ this .clearOnStartDraw = clearOnStartDraw ;
154+ }
155+
143156 private void applyStyle (@ NonNull Style style )
144157 {
145158 setStrokeColor (style .getStrokeColor ());
@@ -174,6 +187,7 @@ public void setTransform(@NonNull Transform transform)
174187 transformValues [Matrix .MSCALE_Y ] = (float ) transform .yy ;
175188 transformValues [Matrix .MTRANS_Y ] = (float ) transform .ty ;
176189
190+ Objects .requireNonNull (canvas );
177191 transformMatrix .setValues (transformValues );
178192 canvas .setMatrix (transformMatrix );
179193
@@ -313,6 +327,7 @@ public final void setFontProperties(@NonNull String fontFamily, float fontLineHe
313327 @ Override
314328 public void startDraw (int x , int y , int width , int height )
315329 {
330+ Objects .requireNonNull (canvas );
316331 canvas .save ();
317332
318333 pointsCache [0 ] = x ;
@@ -322,7 +337,7 @@ public void startDraw(int x, int y, int width, int height)
322337
323338 // When offscreen rendering is supported, clear the destination
324339 // Otherwise, do not clear the destination (e.g. when exporting image, we want a white background)
325- if (offlineSurfaceManager != null )
340+ if (offlineSurfaceManager != null && clearOnStartDraw )
326341 canvas .drawRect (pointsCache [0 ], pointsCache [1 ], pointsCache [2 ], pointsCache [3 ], clearPaint );
327342
328343 // Hardware canvas does not support PorterDuffXfermode
@@ -332,6 +347,7 @@ public void startDraw(int x, int y, int width, int height)
332347 @ Override
333348 public void endDraw ()
334349 {
350+ Objects .requireNonNull (canvas );
335351 canvas .restore ();
336352 }
337353
@@ -340,6 +356,7 @@ public void startGroup(@NonNull String id, float x, float y, float width, float
340356 {
341357 if (clipContent )
342358 {
359+ Objects .requireNonNull (canvas );
343360 clips .add (id );
344361 canvas .save ();
345362
@@ -352,6 +369,7 @@ public void endGroup(@NonNull String id)
352369 {
353370 if (clips .remove (id ))
354371 {
372+ Objects .requireNonNull (canvas );
355373 canvas .restore ();
356374 }
357375 }
@@ -378,6 +396,7 @@ public final IPath createPath()
378396 @ Override
379397 public void drawPath (@ NonNull IPath ipath )
380398 {
399+ Objects .requireNonNull (canvas );
381400 Path path = (Path ) ipath ;
382401
383402 if (android .graphics .Color .alpha (fillPaint .getColor ()) != 0 )
@@ -394,6 +413,7 @@ public void drawPath(@NonNull IPath ipath)
394413 @ Override
395414 public void drawRectangle (float x , float y , float width , float height )
396415 {
416+ Objects .requireNonNull (canvas );
397417 if (android .graphics .Color .alpha (fillPaint .getColor ()) != 0 )
398418 {
399419 canvas .drawRect (x , y , x + width , y + height , fillPaint );
@@ -407,6 +427,7 @@ public void drawRectangle(float x, float y, float width, float height)
407427 @ Override
408428 public void drawLine (float x1 , float y1 , float x2 , float y2 )
409429 {
430+ Objects .requireNonNull (canvas );
410431 canvas .drawLine (x1 , y1 , x2 , y2 , strokePaint );
411432 }
412433
@@ -416,16 +437,16 @@ public void drawObject(@NonNull String url, @NonNull String mimeType, float x, f
416437 if (imageLoader == null )
417438 return ;
418439
419- Point screenMin = new Point ( x , y );
420- transform . apply ( screenMin );
421- Point screenMax = new Point ( x + width , y + height );
422- transform . apply ( screenMax );
440+ Objects . requireNonNull ( canvas );
441+
442+ RectF pixelSize = new RectF ( x , y , x + width , y + height );
443+ transformMatrix . mapRect ( pixelSize );
423444
424445 final Rect targetRect = new Rect (
425- (int ) Math .floor (screenMin . x ),
426- (int ) Math .floor (screenMin . y ),
427- (int ) (Math .ceil (screenMax . x ) - x ),
428- (int ) (Math .ceil (screenMax . y ) - y ));
446+ (int ) Math .floor (pixelSize . left ),
447+ (int ) Math .floor (pixelSize . top ),
448+ (int ) (Math .ceil (pixelSize . right ) ),
449+ (int ) (Math .ceil (pixelSize . bottom ) ));
429450
430451 synchronized (imageLoader )
431452 {
@@ -441,22 +462,6 @@ public void drawObject(@NonNull String url, @NonNull String mimeType, float x, f
441462 }
442463 else
443464 {
444- // adjust rectangle so that the image gets fit into original rectangle
445- float fx = width / image .getWidth ();
446- float fy = height / image .getHeight ();
447- if (fx > fy )
448- {
449- float w = image .getWidth () * fy ;
450- x += (width - w ) / 2 ;
451- width = w ;
452- }
453- else
454- {
455- float h = image .getHeight () * fx ;
456- y += (height - h ) / 2 ;
457- height = h ;
458- }
459-
460465 // draw the image
461466 Rect srcRect = new Rect (0 , 0 , image .getWidth (), image .getHeight ());
462467 RectF dstRect = new RectF (x , y , x + width , y + height );
@@ -471,6 +476,7 @@ public void drawObject(@NonNull String url, @NonNull String mimeType, float x, f
471476 @ Override
472477 public void drawText (@ NonNull String label , float x , float y , float xmin , float ymin , float xmax , float ymax )
473478 {
479+ Objects .requireNonNull (canvas );
474480 // transform the insertion point so that it is not impacted by text scale
475481 pointsCache [0 ] = x ;
476482 pointsCache [1 ] = y ;
@@ -496,6 +502,7 @@ public void blendOffscreen(int id, float srcX, float srcY, float srcWidth, float
496502
497503 if (bitmap != null )
498504 {
505+ Objects .requireNonNull (canvas );
499506 floatRectCache .set (destX , destY , destX + destWidth , destY + destHeight );
500507 simpleRectCache .set (Math .round (srcX ), Math .round (srcY ),
501508 Math .round (srcX + srcWidth ), Math .round (srcY + srcHeight ));
0 commit comments