diff --git a/android/src/main/java/com/horcrux/svg/GroupView.java b/android/src/main/java/com/horcrux/svg/GroupView.java index 44089d557..db20fd2ec 100644 --- a/android/src/main/java/com/horcrux/svg/GroupView.java +++ b/android/src/main/java/com/horcrux/svg/GroupView.java @@ -9,6 +9,7 @@ package com.horcrux.svg; import android.annotation.SuppressLint; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; @@ -29,9 +30,13 @@ class GroupView extends RenderableView { @Nullable ReadableMap mFont; private GlyphContext mGlyphContext; + private Bitmap mLayerBitmap; + private Canvas mLayerCanvas; + private final Paint mLayerPaint; public GroupView(ReactContext reactContext) { super(reactContext); + mLayerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); } public void setFont(Dynamic dynamic) { @@ -92,6 +97,20 @@ void drawGroup(final Canvas canvas, final Paint paint, final float opacity) { final SvgView svg = getSvgView(); final GroupView self = this; final RectF groupRect = new RectF(); + if (mLayerBitmap == null) { + mLayerBitmap = + Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888); + mLayerCanvas = new Canvas(mLayerBitmap); + } else { + mLayerBitmap.recycle(); + mLayerBitmap = + Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888); + mLayerCanvas.setBitmap(mLayerBitmap); + } + // Copy current matrix from original canvas + int saveCount = mLayerCanvas.save(); + mLayerCanvas.setMatrix(canvas.getMatrix()); + elements = new ArrayList<>(); for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); @@ -107,15 +126,15 @@ void drawGroup(final Canvas canvas, final Paint paint, final float opacity) { ((RenderableView) node).mergeProperties(self); } - int count = node.saveAndSetupCanvas(canvas, mCTM); - node.render(canvas, paint, opacity * mOpacity); + int count = node.saveAndSetupCanvas(mLayerCanvas, mCTM); + node.render(mLayerCanvas, paint, opacity); RectF r = node.getClientRect(); if (r != null) { groupRect.union(r); } - node.restoreCanvas(canvas, count); + node.restoreCanvas(mLayerCanvas, count); if (node instanceof RenderableView) { ((RenderableView) node).resetProperties(); @@ -137,6 +156,14 @@ void drawGroup(final Canvas canvas, final Paint paint, final float opacity) { } } } + + // Restore copied canvas and temporary reset original canvas matrix to draw bitmap 1:1 + mLayerCanvas.restoreToCount(saveCount); + saveCount = canvas.save(); + canvas.setMatrix(null); + mLayerPaint.setAlpha((int) (mOpacity * 255)); + canvas.drawBitmap(mLayerBitmap, 0, 0, mLayerPaint); + canvas.restoreToCount(saveCount); this.setClientRect(groupRect); popGlyphContext(); } diff --git a/apps/test-examples/index.tsx b/apps/test-examples/index.tsx index 20997ac8e..14a79e1cb 100644 --- a/apps/test-examples/index.tsx +++ b/apps/test-examples/index.tsx @@ -29,6 +29,7 @@ import Test2366 from './src/Test2366'; import Test2397 from './src/Test2397'; import Test2403 from './src/Test2403'; import Test2407 from './src/Test2407'; +import Test2417 from './src/Test2417'; export default function App() { return ; diff --git a/apps/test-examples/src/Test2417.tsx b/apps/test-examples/src/Test2417.tsx new file mode 100644 index 000000000..f9e9c460d --- /dev/null +++ b/apps/test-examples/src/Test2417.tsx @@ -0,0 +1,20 @@ +import {View} from 'react-native'; +import {G, Rect, Svg} from 'react-native-svg'; + +export default function App() { + return ( + + + + + + + + + + + + + + ); +}