mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-20 05:55:10 +00:00
refactor gradients on Android merge #86 into branch
This commit is contained in:
@@ -48,6 +48,7 @@ class ClipImage extends Component{
|
|||||||
width="90%"
|
width="90%"
|
||||||
height="90%"
|
height="90%"
|
||||||
href={require('../image.jpg')}
|
href={require('../image.jpg')}
|
||||||
|
opacity="0.6"
|
||||||
clipPath="url(#clip)"
|
clipPath="url(#clip)"
|
||||||
/>
|
/>
|
||||||
<Text
|
<Text
|
||||||
|
|||||||
@@ -9,6 +9,13 @@
|
|||||||
|
|
||||||
package com.horcrux.svg;
|
package com.horcrux.svg;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RadialGradient;
|
||||||
|
import android.graphics.LinearGradient;
|
||||||
|
import android.graphics.Shader;
|
||||||
|
import android.graphics.Matrix;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -29,7 +36,10 @@ import java.util.regex.Pattern;
|
|||||||
* @return a {@code float[]} if converted successfully, or {@code null} if {@param value} was
|
* @return a {@code float[]} if converted successfully, or {@code null} if {@param value} was
|
||||||
* {@code null}.
|
* {@code null}.
|
||||||
*/
|
*/
|
||||||
/*package*/ static @Nullable float[] toFloatArray(@Nullable ReadableArray value) {
|
/*package*/
|
||||||
|
static
|
||||||
|
@Nullable
|
||||||
|
float[] toFloatArray(@Nullable ReadableArray value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
float[] result = new float[value.size()];
|
float[] result = new float[value.size()];
|
||||||
toFloatArray(value, result);
|
toFloatArray(value, result);
|
||||||
@@ -48,7 +58,8 @@ import java.util.regex.Pattern;
|
|||||||
* @param into output array
|
* @param into output array
|
||||||
* @return number of items copied from input to the output array
|
* @return number of items copied from input to the output array
|
||||||
*/
|
*/
|
||||||
/*package*/ static int toFloatArray(ReadableArray value, float[] into) {
|
/*package*/
|
||||||
|
static int toFloatArray(ReadableArray value, float[] into) {
|
||||||
int length = value.size() > into.length ? into.length : value.size();
|
int length = value.size() > into.length ? into.length : value.size();
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
into[i] = (float) value.getDouble(i);
|
into[i] = (float) value.getDouble(i);
|
||||||
@@ -66,7 +77,8 @@ import java.util.regex.Pattern;
|
|||||||
* @param offset offset number
|
* @param offset offset number
|
||||||
* @return actual float based on relative number
|
* @return actual float based on relative number
|
||||||
*/
|
*/
|
||||||
/*package*/ static float fromPercentageToFloat(String percentage, float relative, float offset, float scale) {
|
/*package*/
|
||||||
|
static float fromPercentageToFloat(String percentage, float relative, float offset, float scale) {
|
||||||
Matcher matched = Pattern.compile("^(\\-?\\d+(?:\\.\\d+)?)%$").matcher(percentage);
|
Matcher matched = Pattern.compile("^(\\-?\\d+(?:\\.\\d+)?)%$").matcher(percentage);
|
||||||
if (matched.matches()) {
|
if (matched.matches()) {
|
||||||
return Float.valueOf(matched.group(1)) / 100 * relative + offset;
|
return Float.valueOf(matched.group(1)) / 100 * relative + offset;
|
||||||
@@ -74,6 +86,7 @@ import java.util.regex.Pattern;
|
|||||||
return Float.valueOf(percentage) * scale;
|
return Float.valueOf(percentage) * scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Judge given string is a percentage-like string or not.
|
* Judge given string is a percentage-like string or not.
|
||||||
*
|
*
|
||||||
@@ -81,8 +94,101 @@ import java.util.regex.Pattern;
|
|||||||
* @return string is percentage-like or not.
|
* @return string is percentage-like or not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*package*/ static boolean isPercentage(String string) {
|
/*package*/
|
||||||
|
static boolean isPercentage(String string) {
|
||||||
Pattern pattern = Pattern.compile("^(\\-?\\d+(?:\\.\\d+)?)%$");
|
Pattern pattern = Pattern.compile("^(\\-?\\d+(?:\\.\\d+)?)%$");
|
||||||
return pattern.matcher(string).matches();
|
return pattern.matcher(string).matches();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*package*/ static class RNSVGBrush {
|
||||||
|
|
||||||
|
private GradientType mType = GradientType.LINEAR_GRADIENT;
|
||||||
|
private ReadableArray mPoints;
|
||||||
|
private ReadableArray mColors;
|
||||||
|
|
||||||
|
public RNSVGBrush(GradientType type, ReadableArray points, ReadableArray colors) {
|
||||||
|
mType = type;
|
||||||
|
mPoints = points;
|
||||||
|
mColors = colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GradientType {
|
||||||
|
LINEAR_GRADIENT(0),
|
||||||
|
RADIAL_GRADIENT(1);
|
||||||
|
|
||||||
|
GradientType(int ni) {
|
||||||
|
nativeInt = ni;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int nativeInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseGradientStops(ReadableArray value, int stopsCount, float[] stops, int[] stopsColors) {
|
||||||
|
int startStops = value.size() - stopsCount;
|
||||||
|
for (int i = 0; i < stopsCount; i++) {
|
||||||
|
stops[i] = (float) value.getDouble(startStops + i);
|
||||||
|
stopsColors[i] = Color.argb(
|
||||||
|
(int) (value.getDouble(i * 4 + 3) * 255),
|
||||||
|
(int) (value.getDouble(i * 4) * 255),
|
||||||
|
(int) (value.getDouble(i * 4 + 1) * 255),
|
||||||
|
(int) (value.getDouble(i * 4 + 2) * 255));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setupPaint(Paint paint, RectF box, float mScale) {
|
||||||
|
float height = box.height();
|
||||||
|
float width = box.width();
|
||||||
|
float midX = box.centerX();
|
||||||
|
float midY = box.centerY();
|
||||||
|
float offsetX = (midX - width / 2);
|
||||||
|
float offsetY = (midY - height / 2);
|
||||||
|
|
||||||
|
|
||||||
|
int stopsCount = mColors.size() / 5;
|
||||||
|
int[] stopsColors = new int[stopsCount];
|
||||||
|
float[] stops = new float[stopsCount];
|
||||||
|
parseGradientStops(mColors, stopsCount, stops, stopsColors);
|
||||||
|
|
||||||
|
if (mType == GradientType.LINEAR_GRADIENT) {
|
||||||
|
float x1 = PropHelper.fromPercentageToFloat(mPoints.getString(0), width, offsetX, mScale);
|
||||||
|
float y1 = PropHelper.fromPercentageToFloat(mPoints.getString(1), height, offsetY, mScale);
|
||||||
|
float x2 = PropHelper.fromPercentageToFloat(mPoints.getString(2), width, offsetX, mScale);
|
||||||
|
float y2 = PropHelper.fromPercentageToFloat(mPoints.getString(3), height, offsetY, mScale);
|
||||||
|
paint.setShader(
|
||||||
|
new LinearGradient(
|
||||||
|
x1,
|
||||||
|
y1,
|
||||||
|
x2,
|
||||||
|
y2,
|
||||||
|
stopsColors,
|
||||||
|
stops,
|
||||||
|
Shader.TileMode.CLAMP));
|
||||||
|
} else {
|
||||||
|
float rx = PropHelper.fromPercentageToFloat(mPoints.getString(2), width, 0f, mScale);
|
||||||
|
float ry = PropHelper.fromPercentageToFloat(mPoints.getString(3), height, 0f, mScale);
|
||||||
|
float cx = PropHelper.fromPercentageToFloat(mPoints.getString(4), width, offsetX, mScale);
|
||||||
|
float cy = PropHelper.fromPercentageToFloat(mPoints.getString(5), height, offsetY, mScale) / (ry / rx);
|
||||||
|
// TODO: support focus point.
|
||||||
|
//float fx = PropHelper.fromPercentageToFloat(mPoints.getString(0), width, offsetX) * mScale;
|
||||||
|
//float fy = PropHelper.fromPercentageToFloat(mPoints.getString(1), height, offsetY) * mScale / (ry / rx);
|
||||||
|
Shader radialGradient = new RadialGradient(
|
||||||
|
cx,
|
||||||
|
cy,
|
||||||
|
rx,
|
||||||
|
stopsColors,
|
||||||
|
stops,
|
||||||
|
Shader.TileMode.CLAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
Matrix radialMatrix = new Matrix();
|
||||||
|
radialMatrix.preScale(1f, ry / rx);
|
||||||
|
radialGradient.setLocalMatrix(radialMatrix);
|
||||||
|
paint.setShader(radialGradient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,8 @@
|
|||||||
|
|
||||||
package com.horcrux.svg;
|
package com.horcrux.svg;
|
||||||
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Path;
|
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shadow node for virtual RNSVGClipPath view
|
* Shadow node for virtual RNSVGClipPath view
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Horcrux.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package com.horcrux.svg;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shadow node for virtual Definition type views
|
||||||
|
*/
|
||||||
|
public class RNSVGDefinitionShadowNode extends RNSVGVirtualNode {
|
||||||
|
|
||||||
|
public void draw(Canvas canvas, Paint paint, float opacity) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResponsible() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Path getPath(Canvas canvas, Paint paint) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hitTest(Point point, View view) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList, boolean inherited) {}
|
||||||
|
|
||||||
|
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList) {}
|
||||||
|
|
||||||
|
public void resetProperties() {}
|
||||||
|
}
|
||||||
@@ -11,20 +11,11 @@ package com.horcrux.svg;
|
|||||||
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
|
||||||
import android.graphics.Point;
|
|
||||||
import android.view.View;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shadow node for virtual RNSVGPath view
|
* Shadow node for virtual RNSVGPath view
|
||||||
*/
|
*/
|
||||||
public class RNSVGDefsShadowNode extends RNSVGVirtualNode {
|
public class RNSVGDefsShadowNode extends RNSVGDefinitionShadowNode {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas, Paint paint, float opacity) {
|
public void draw(Canvas canvas, Paint paint, float opacity) {
|
||||||
@@ -38,27 +29,4 @@ public class RNSVGDefsShadowNode extends RNSVGVirtualNode {
|
|||||||
|
|
||||||
restoreCanvas(canvas, count);
|
restoreCanvas(canvas, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isResponsible() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Path getPath(Canvas canvas, Paint paint) {
|
|
||||||
return new Path();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hitTest(Point point, View view) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList, boolean inherited) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resetProperties() {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,8 @@ import com.facebook.react.uimanager.annotations.ReactProp;
|
|||||||
public class RNSVGEllipseShadowNode extends RNSVGPathShadowNode {
|
public class RNSVGEllipseShadowNode extends RNSVGPathShadowNode {
|
||||||
|
|
||||||
private String mCx;
|
private String mCx;
|
||||||
|
|
||||||
private String mCy;
|
private String mCy;
|
||||||
|
|
||||||
private String mRx;
|
private String mRx;
|
||||||
|
|
||||||
private String mRy;
|
private String mRy;
|
||||||
|
|
||||||
@ReactProp(name = "cx")
|
@ReactProp(name = "cx")
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shadow node for virtual RNSVGGroup view
|
* Shadow node for virtual RNSVGGroup view
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ import android.graphics.PorterDuff;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import com.facebook.common.executors.UiThreadImmediateExecutorService;
|
||||||
|
import com.facebook.common.logging.FLog;
|
||||||
import com.facebook.common.executors.CallerThreadExecutor;
|
import com.facebook.common.executors.CallerThreadExecutor;
|
||||||
import com.facebook.common.references.CloseableReference;
|
import com.facebook.common.references.CloseableReference;
|
||||||
import com.facebook.datasource.DataSource;
|
import com.facebook.datasource.DataSource;
|
||||||
@@ -25,12 +26,14 @@ import com.facebook.common.logging.FLog;
|
|||||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||||
import com.facebook.imagepipeline.core.ImagePipeline;
|
import com.facebook.imagepipeline.core.ImagePipeline;
|
||||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
||||||
|
import com.facebook.imagepipeline.image.CloseableBitmap;
|
||||||
import com.facebook.imagepipeline.image.CloseableImage;
|
import com.facebook.imagepipeline.image.CloseableImage;
|
||||||
import com.facebook.imagepipeline.request.ImageRequest;
|
import com.facebook.imagepipeline.request.ImageRequest;
|
||||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
import com.facebook.react.bridge.ReadableMap;
|
||||||
import com.facebook.react.common.ReactConstants;
|
import com.facebook.react.common.ReactConstants;
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,7 +46,6 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
|
|||||||
private String mW;
|
private String mW;
|
||||||
private String mH;
|
private String mH;
|
||||||
private Uri mUri;
|
private Uri mUri;
|
||||||
private Bitmap mBitmap;
|
|
||||||
private boolean mLoading;
|
private boolean mLoading;
|
||||||
|
|
||||||
@ReactProp(name = "x")
|
@ReactProp(name = "x")
|
||||||
@@ -85,40 +87,30 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas, Paint paint, float opacity) {
|
public void draw(final Canvas canvas, final Paint paint, final float opacity) {
|
||||||
RNSVGSvgViewShadowNode node = getSvgShadowNode();
|
final ImageRequest request = ImageRequestBuilder.newBuilderWithSource(mUri).build();
|
||||||
if (mBitmap != null) {
|
final boolean inMemoryCache = Fresco.getImagePipeline().isInBitmapMemoryCache(request);
|
||||||
int count = saveAndSetupCanvas(canvas);
|
|
||||||
|
|
||||||
clip(canvas, paint);
|
|
||||||
float x = PropHelper.fromPercentageToFloat(mX, mCanvasWidth, 0, mScale);
|
|
||||||
float y = PropHelper.fromPercentageToFloat(mY, mCanvasHeight, 0, mScale);
|
|
||||||
float w = PropHelper.fromPercentageToFloat(mW, mCanvasWidth, 0, mScale);
|
|
||||||
float h = PropHelper.fromPercentageToFloat(mH, mCanvasHeight, 0, mScale);
|
|
||||||
canvas.drawBitmap(mBitmap, null, new Rect((int) x, (int) y, (int) (x + w), (int)(y + h)), null);
|
|
||||||
|
|
||||||
restoreCanvas(canvas, count);
|
if (inMemoryCache) {
|
||||||
markUpdateSeen();
|
tryRender(request, canvas, paint, opacity * mOpacity);
|
||||||
} else if (!mLoading) {
|
} else if (!mLoading) {
|
||||||
mLoading = true;
|
loadBitmap(request, canvas, paint);
|
||||||
loadBitmap(canvas, paint, node);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadBitmap(final Canvas canvas, final Paint paint, final RNSVGSvgViewShadowNode node) {
|
private void loadBitmap(@Nonnull final ImageRequest request, @Nonnull final Canvas canvas, @Nonnull final Paint paint) {
|
||||||
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(mUri).build();
|
final DataSource<CloseableReference<CloseableImage>> dataSource
|
||||||
|
= Fresco.getImagePipeline().fetchDecodedImage(request, getThemedContext());
|
||||||
|
|
||||||
ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
|
||||||
DataSource<CloseableReference<CloseableImage>>
|
|
||||||
dataSource = imagePipeline.fetchDecodedImage(request, getThemedContext());
|
|
||||||
dataSource.subscribe(new BaseBitmapDataSubscriber() {
|
dataSource.subscribe(new BaseBitmapDataSubscriber() {
|
||||||
@Override
|
@Override
|
||||||
public void onNewResultImpl(@Nullable Bitmap bitmap) {
|
public void onNewResultImpl(@Nullable Bitmap bitmap) {
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
mBitmap = bitmap;
|
|
||||||
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
||||||
paint.reset();
|
paint.reset();
|
||||||
node.drawChildren(canvas, paint);
|
mLoading = false;
|
||||||
|
getSvgShadowNode().drawChildren(canvas, paint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,9 +118,51 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
|
|||||||
public void onFailureImpl(DataSource dataSource) {
|
public void onFailureImpl(DataSource dataSource) {
|
||||||
// No cleanup required here.
|
// No cleanup required here.
|
||||||
// TODO: more details about this failure
|
// TODO: more details about this failure
|
||||||
FLog.w(ReactConstants.TAG, "RNSVG: load Image load failed!:");
|
mLoading = false;
|
||||||
|
FLog.w(ReactConstants.TAG, dataSource.getFailureCause(), "RNSVG: fetchDecodedImage failed!");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CallerThreadExecutor.getInstance());
|
UiThreadImmediateExecutorService.getInstance()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doRender(@Nonnull final Canvas canvas, @Nonnull final Paint paint, @Nonnull final Bitmap bitmap, final float opacity) {
|
||||||
|
final int count = saveAndSetupCanvas(canvas);
|
||||||
|
|
||||||
|
clip(canvas, paint);
|
||||||
|
float x = PropHelper.fromPercentageToFloat(mX, mCanvasWidth, 0, mScale);
|
||||||
|
float y = PropHelper.fromPercentageToFloat(mY, mCanvasHeight, 0, mScale);
|
||||||
|
float w = PropHelper.fromPercentageToFloat(mW, mCanvasWidth, 0, mScale);
|
||||||
|
float h = PropHelper.fromPercentageToFloat(mH, mCanvasHeight, 0, mScale);
|
||||||
|
Paint alphaPaint = new Paint();
|
||||||
|
|
||||||
|
alphaPaint.setAlpha((int) (opacity * 255));
|
||||||
|
canvas.drawBitmap(bitmap, null, new Rect((int) x, (int) y, (int) (x + w), (int) (y + h)), alphaPaint);
|
||||||
|
|
||||||
|
restoreCanvas(canvas, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryRender(@Nonnull final ImageRequest request, @Nonnull final Canvas canvas, @Nonnull final Paint paint, final float opacity) {
|
||||||
|
final DataSource<CloseableReference<CloseableImage>> dataSource
|
||||||
|
= Fresco.getImagePipeline().fetchImageFromBitmapCache(request, getThemedContext());
|
||||||
|
|
||||||
|
try {
|
||||||
|
final CloseableReference<CloseableImage> imageReference = dataSource.getResult();
|
||||||
|
if (imageReference != null) {
|
||||||
|
try {
|
||||||
|
if (imageReference.get() instanceof CloseableBitmap) {
|
||||||
|
final Bitmap bitmap = ((CloseableBitmap) imageReference.get()).getUnderlyingBitmap();
|
||||||
|
|
||||||
|
if (bitmap != null) {
|
||||||
|
doRender(canvas, paint, bitmap, opacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
CloseableReference.closeSafely(imageReference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
dataSource.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,6 @@ package com.horcrux.svg;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
|
|
||||||
import com.facebook.common.logging.FLog;
|
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
|
||||||
import com.facebook.react.common.ReactConstants;
|
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Horcrux.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package com.horcrux.svg;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.JavaOnlyArray;
|
||||||
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
|
import com.facebook.react.bridge.WritableArray;
|
||||||
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shadow node for virtual LinearGradient definition view
|
||||||
|
*/
|
||||||
|
public class RNSVGLinearGradientShadowNode extends RNSVGDefinitionShadowNode {
|
||||||
|
|
||||||
|
private String mX1;
|
||||||
|
private String mY1;
|
||||||
|
private String mX2;
|
||||||
|
private String mY2;
|
||||||
|
private ReadableArray mGradient;
|
||||||
|
|
||||||
|
@ReactProp(name = "x1")
|
||||||
|
public void setX1(String x1) {
|
||||||
|
mX1 = x1;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "y1")
|
||||||
|
public void setCx(String y1) {
|
||||||
|
mY1 = y1;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "x2")
|
||||||
|
public void setX2(String x2) {
|
||||||
|
mX2 = x2;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "y2")
|
||||||
|
public void setY2(String y2) {
|
||||||
|
mY2 = y2;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "gradient")
|
||||||
|
public void setGradient(ReadableArray gradient) {
|
||||||
|
mGradient = gradient;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void saveDefinition() {
|
||||||
|
if (mName != null) {
|
||||||
|
WritableArray points = new JavaOnlyArray();
|
||||||
|
points.pushString(mX1);
|
||||||
|
points.pushString(mY1);
|
||||||
|
points.pushString(mX2);
|
||||||
|
points.pushString(mY2);
|
||||||
|
|
||||||
|
PropHelper.RNSVGBrush brush = new PropHelper.RNSVGBrush(PropHelper.RNSVGBrush.GradientType.LINEAR_GRADIENT, points, mGradient);
|
||||||
|
getSvgShadowNode().defineBrush(brush, mName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void removeDefinition() {
|
||||||
|
if (mName != null) {
|
||||||
|
getSvgShadowNode().removeBrush(mName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,18 +17,11 @@ import android.graphics.DashPathEffect;
|
|||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.RadialGradient;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.LinearGradient;
|
|
||||||
import android.graphics.Region;
|
|
||||||
import android.graphics.Shader;
|
|
||||||
import android.graphics.Matrix;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import com.facebook.common.logging.FLog;
|
import com.facebook.common.logging.FLog;
|
||||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||||
@@ -78,7 +71,7 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
|
|||||||
|
|
||||||
private ArrayList<String> mChangedList;
|
private ArrayList<String> mChangedList;
|
||||||
private ArrayList<Object> mOriginProperties;
|
private ArrayList<Object> mOriginProperties;
|
||||||
protected ReadableArray mPropList = new JavaOnlyArray();;
|
protected ReadableArray mPropList = new JavaOnlyArray();
|
||||||
|
|
||||||
@ReactProp(name = "d")
|
@ReactProp(name = "d")
|
||||||
public void setPath(@Nullable ReadableArray shapePath) {
|
public void setPath(@Nullable ReadableArray shapePath) {
|
||||||
@@ -281,10 +274,11 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
|
|||||||
* if the stroke should be drawn, {@code false} if not.
|
* if the stroke should be drawn, {@code false} if not.
|
||||||
*/
|
*/
|
||||||
protected boolean setupStrokePaint(Paint paint, float opacity, @Nullable RectF box) {
|
protected boolean setupStrokePaint(Paint paint, float opacity, @Nullable RectF box) {
|
||||||
|
paint.reset();
|
||||||
if (mStrokeWidth == 0 || mStroke == null || mStroke.size() == 0) {
|
if (mStrokeWidth == 0 || mStroke == null || mStroke.size() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
paint.reset();
|
|
||||||
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
|
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
paint.setStrokeCap(mStrokeLinecap);
|
paint.setStrokeCap(mStrokeLinecap);
|
||||||
@@ -310,62 +304,13 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
|
|||||||
(int) (colors.getDouble(1) * 255),
|
(int) (colors.getDouble(1) * 255),
|
||||||
(int) (colors.getDouble(2) * 255),
|
(int) (colors.getDouble(2) * 255),
|
||||||
(int) (colors.getDouble(3) * 255));
|
(int) (colors.getDouble(3) * 255));
|
||||||
} else if (colorType == 1 || colorType == 2) {
|
} else if (colorType == 1) {
|
||||||
if (box == null) {
|
if (box == null) {
|
||||||
box = new RectF();
|
box = new RectF();
|
||||||
mPath.computeBounds(box, true);
|
mPath.computeBounds(box, true);
|
||||||
}
|
}
|
||||||
|
PropHelper.RNSVGBrush brush = getSvgShadowNode().getDefinedBrush(colors.getString(1));
|
||||||
int startColorsPosition = colorType == 1 ? 5 : 7;
|
brush.setupPaint(paint, box, mScale);
|
||||||
|
|
||||||
int stopsCount = (colors.size() - startColorsPosition) / 5;
|
|
||||||
int [] stopsColors = new int [stopsCount];
|
|
||||||
float [] stops = new float[stopsCount];
|
|
||||||
float height = box.height();
|
|
||||||
float width = box.width();
|
|
||||||
float midX = box.centerX();
|
|
||||||
float midY = box.centerY();
|
|
||||||
float offsetX = (midX - width / 2);
|
|
||||||
float offsetY = (midY - height / 2);
|
|
||||||
|
|
||||||
parseGradientStops(colors, stopsCount, stops, stopsColors, startColorsPosition);
|
|
||||||
|
|
||||||
if (colorType == 1) {
|
|
||||||
float x1 = PropHelper.fromPercentageToFloat(colors.getString(1), width, offsetX, mScale);
|
|
||||||
float y1 = PropHelper.fromPercentageToFloat(colors.getString(2), height, offsetY, mScale);
|
|
||||||
float x2 = PropHelper.fromPercentageToFloat(colors.getString(3), width, offsetX, mScale);
|
|
||||||
float y2 = PropHelper.fromPercentageToFloat(colors.getString(4), height, offsetY, mScale);
|
|
||||||
paint.setShader(
|
|
||||||
new LinearGradient(
|
|
||||||
x1,
|
|
||||||
y1,
|
|
||||||
x2,
|
|
||||||
y2,
|
|
||||||
stopsColors,
|
|
||||||
stops,
|
|
||||||
Shader.TileMode.CLAMP));
|
|
||||||
} else {
|
|
||||||
float rx = PropHelper.fromPercentageToFloat(colors.getString(3), width, 0f, mScale);
|
|
||||||
float ry = PropHelper.fromPercentageToFloat(colors.getString(4), height, 0f, mScale);
|
|
||||||
float cx = PropHelper.fromPercentageToFloat(colors.getString(5), width, offsetX, mScale);
|
|
||||||
float cy = PropHelper.fromPercentageToFloat(colors.getString(6), height, offsetY, mScale) / (ry / rx);
|
|
||||||
// TODO: do not support focus point.
|
|
||||||
//float fx = PropHelper.fromPercentageToFloat(colors.getString(1), width, offsetX) * mScale;
|
|
||||||
//float fy = PropHelper.fromPercentageToFloat(colors.getString(2), height, offsetY) * mScale / (ry / rx);
|
|
||||||
Shader radialGradient = new RadialGradient(
|
|
||||||
cx,
|
|
||||||
cy,
|
|
||||||
rx,
|
|
||||||
stopsColors,
|
|
||||||
stops,
|
|
||||||
Shader.TileMode.CLAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
Matrix radialMatrix = new Matrix();
|
|
||||||
radialMatrix.preScale(1f, ry / rx);
|
|
||||||
radialGradient.setLocalMatrix(radialMatrix);
|
|
||||||
paint.setShader(radialGradient);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: Support pattern.
|
// TODO: Support pattern.
|
||||||
FLog.w(ReactConstants.TAG, "RNSVG: Color type " + colorType + " not supported!");
|
FLog.w(ReactConstants.TAG, "RNSVG: Color type " + colorType + " not supported!");
|
||||||
@@ -455,7 +400,7 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
|
|||||||
for (int i = 0, size = mergeList.size(); i < size; i++) {
|
for (int i = 0, size = mergeList.size(); i < size; i++) {
|
||||||
try {
|
try {
|
||||||
String fieldName = mergeList.getString(i);
|
String fieldName = mergeList.getString(i);
|
||||||
Field field = target.getClass().getField(fieldName);
|
Field field = getClass().getField(fieldName);
|
||||||
Object value = field.get(target);
|
Object value = field.get(target);
|
||||||
|
|
||||||
if (inherited) {
|
if (inherited) {
|
||||||
@@ -464,9 +409,9 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
|
|||||||
propList.pushString(fieldName);
|
propList.pushString(fieldName);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
field.set(this, value);
|
mOriginProperties.add(field.get(this));
|
||||||
mOriginProperties.add(value);
|
|
||||||
mChangedList.add(fieldName);
|
mChangedList.add(fieldName);
|
||||||
|
field.set(this, value);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
@@ -497,6 +442,7 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mChangedList = null;
|
mChangedList = null;
|
||||||
|
mOriginProperties = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Horcrux.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package com.horcrux.svg;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.JavaOnlyArray;
|
||||||
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
|
import com.facebook.react.bridge.WritableArray;
|
||||||
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shadow node for virtual LinearGradient definition view
|
||||||
|
*/
|
||||||
|
public class RNSVGRadialGradientShadowNode extends RNSVGDefinitionShadowNode {
|
||||||
|
private String mFx;
|
||||||
|
private String mFy;
|
||||||
|
private String mRx;
|
||||||
|
private String mRy;
|
||||||
|
private String mCx;
|
||||||
|
private String mCy;
|
||||||
|
private ReadableArray mGradient;
|
||||||
|
|
||||||
|
@ReactProp(name = "fx")
|
||||||
|
public void setFX(String fx) {
|
||||||
|
mFx = fx;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "fy")
|
||||||
|
public void setFy(String fy) {
|
||||||
|
mFy = fy;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "rx")
|
||||||
|
public void setRx(String rx) {
|
||||||
|
mRx = rx;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "ry")
|
||||||
|
public void setRy(String ry) {
|
||||||
|
mRy = ry;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "cx")
|
||||||
|
public void setCx(String cx) {
|
||||||
|
mCx = cx;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "cy")
|
||||||
|
public void setCy(String cy) {
|
||||||
|
mCy = cy;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "gradient")
|
||||||
|
public void setGradient(ReadableArray gradient) {
|
||||||
|
mGradient = gradient;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void saveDefinition() {
|
||||||
|
if (mName != null) {
|
||||||
|
WritableArray points = new JavaOnlyArray();
|
||||||
|
points.pushString(mFx);
|
||||||
|
points.pushString(mFy);
|
||||||
|
points.pushString(mRx);
|
||||||
|
points.pushString(mRy);
|
||||||
|
points.pushString(mCx);
|
||||||
|
points.pushString(mCy);
|
||||||
|
|
||||||
|
PropHelper.RNSVGBrush brush = new PropHelper.RNSVGBrush(PropHelper.RNSVGBrush.GradientType.RADIAL_GRADIENT, points, mGradient);
|
||||||
|
getSvgShadowNode().defineBrush(brush, mName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void removeDefinition() {
|
||||||
|
if (mName != null) {
|
||||||
|
getSvgShadowNode().removeBrush(mName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,12 +12,7 @@ package com.horcrux.svg;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
|
|
||||||
import com.facebook.common.logging.FLog;
|
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
|
||||||
import com.facebook.react.common.ReactConstants;
|
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|||||||
@@ -10,24 +10,9 @@
|
|||||||
package com.horcrux.svg;
|
package com.horcrux.svg;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Point;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.facebook.infer.annotation.Assertions;
|
|
||||||
import com.facebook.react.common.SystemClock;
|
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
|
||||||
import com.facebook.react.uimanager.UIManagerModule;
|
|
||||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
||||||
import com.facebook.react.uimanager.events.TouchEvent;
|
|
||||||
import com.facebook.react.uimanager.events.TouchEventType;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
// NativeGestureUtil.notifyNativeGestureStarted
|
// NativeGestureUtil.notifyNativeGestureStarted
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ package com.horcrux.svg;
|
|||||||
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
//import com.facebook.react.uimanager.ReactStylesDiffMap;
|
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
import com.facebook.react.uimanager.ViewGroupManager;
|
import com.facebook.react.uimanager.ViewGroupManager;
|
||||||
|
|
||||||
@@ -34,6 +33,8 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
|
|||||||
/* package */ static final String CLASS_DEFS = "RNSVGDefs";
|
/* package */ static final String CLASS_DEFS = "RNSVGDefs";
|
||||||
/* package */ static final String CLASS_USE = "RNSVGUse";
|
/* package */ static final String CLASS_USE = "RNSVGUse";
|
||||||
/* package */ static final String CLASS_VIEW_BOX = "RNSVGViewBox";
|
/* package */ static final String CLASS_VIEW_BOX = "RNSVGViewBox";
|
||||||
|
/* package */ static final String CLASS_LINEAR_GRADIENT = "RNSVGLinearGradient";
|
||||||
|
/* package */ static final String CLASS_RADIAL_GRADIENT = "RNSVGRadialGradient";
|
||||||
|
|
||||||
private final String mClassName;
|
private final String mClassName;
|
||||||
|
|
||||||
@@ -87,6 +88,14 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
|
|||||||
return new RNSVGRenderableViewManager(CLASS_VIEW_BOX);
|
return new RNSVGRenderableViewManager(CLASS_VIEW_BOX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RNSVGRenderableViewManager createRNSVGLinearGradientManager() {
|
||||||
|
return new RNSVGRenderableViewManager(CLASS_LINEAR_GRADIENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RNSVGRenderableViewManager createRNSVGRadialGradientManager() {
|
||||||
|
return new RNSVGRenderableViewManager(CLASS_RADIAL_GRADIENT);
|
||||||
|
}
|
||||||
|
|
||||||
private RNSVGRenderableViewManager(String className) {
|
private RNSVGRenderableViewManager(String className) {
|
||||||
mClassName = className;
|
mClassName = className;
|
||||||
}
|
}
|
||||||
@@ -135,6 +144,12 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
|
|||||||
case CLASS_VIEW_BOX:
|
case CLASS_VIEW_BOX:
|
||||||
mVirtualNode = new RNSVGViewBoxShadowNode();
|
mVirtualNode = new RNSVGViewBoxShadowNode();
|
||||||
break;
|
break;
|
||||||
|
case CLASS_LINEAR_GRADIENT:
|
||||||
|
mVirtualNode = new RNSVGLinearGradientShadowNode();
|
||||||
|
break;
|
||||||
|
case CLASS_RADIAL_GRADIENT:
|
||||||
|
mVirtualNode = new RNSVGRadialGradientShadowNode();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unexpected type " + mClassName);
|
throw new IllegalStateException("Unexpected type " + mClassName);
|
||||||
}
|
}
|
||||||
@@ -170,6 +185,10 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
|
|||||||
return RNSVGUseShadowNode.class;
|
return RNSVGUseShadowNode.class;
|
||||||
case CLASS_VIEW_BOX:
|
case CLASS_VIEW_BOX:
|
||||||
return RNSVGViewBoxShadowNode.class;
|
return RNSVGViewBoxShadowNode.class;
|
||||||
|
case CLASS_LINEAR_GRADIENT:
|
||||||
|
return RNSVGLinearGradientShadowNode.class;
|
||||||
|
case CLASS_RADIAL_GRADIENT:
|
||||||
|
return RNSVGRadialGradientShadowNode.class;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unexpected type " + mClassName);
|
throw new IllegalStateException("Unexpected type " + mClassName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,21 +19,15 @@ import android.util.Log;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
|
||||||
|
|
||||||
import com.facebook.infer.annotation.Assertions;
|
import com.facebook.infer.annotation.Assertions;
|
||||||
import com.facebook.react.common.SystemClock;
|
import com.facebook.react.common.SystemClock;
|
||||||
import com.facebook.react.touch.OnInterceptTouchEventListener;
|
|
||||||
import com.facebook.react.touch.ReactInterceptingViewGroup;
|
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
import com.facebook.react.uimanager.TouchTargetHelper;
|
|
||||||
import com.facebook.react.uimanager.UIManagerModule;
|
import com.facebook.react.uimanager.UIManagerModule;
|
||||||
import com.facebook.react.uimanager.events.TouchEvent;
|
import com.facebook.react.uimanager.events.TouchEvent;
|
||||||
import com.facebook.react.uimanager.events.TouchEventCoalescingKeyHelper;
|
import com.facebook.react.uimanager.events.TouchEventCoalescingKeyHelper;
|
||||||
import com.facebook.react.uimanager.events.TouchEventType;
|
import com.facebook.react.uimanager.events.TouchEventType;
|
||||||
import com.facebook.react.views.view.ReactClippingViewGroup;
|
|
||||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||||
import com.facebook.react.uimanager.events.NativeGestureUtil;
|
|
||||||
|
|
||||||
// NativeGestureUtil.notifyNativeGestureStarted
|
// NativeGestureUtil.notifyNativeGestureStarted
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ package com.horcrux.svg;
|
|||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -30,10 +28,9 @@ import java.util.Map;
|
|||||||
public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
|
public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
|
||||||
|
|
||||||
private boolean mResponsible = false;
|
private boolean mResponsible = false;
|
||||||
|
|
||||||
private static final Map<String, RNSVGVirtualNode> mDefinedClipPaths = new HashMap<>();
|
private static final Map<String, RNSVGVirtualNode> mDefinedClipPaths = new HashMap<>();
|
||||||
|
|
||||||
private static final Map<String, RNSVGVirtualNode> mDefinedTemplates = new HashMap<>();
|
private static final Map<String, RNSVGVirtualNode> mDefinedTemplates = new HashMap<>();
|
||||||
|
private static final Map<String, PropHelper.RNSVGBrush> mDefinedBrushes = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) {
|
public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) {
|
||||||
@@ -54,7 +51,17 @@ public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
|
|||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawChildren(Canvas canvas, Paint paint) {
|
/**
|
||||||
|
* Draw all of the child nodes of this root node
|
||||||
|
*
|
||||||
|
* This method is synchronized since
|
||||||
|
* {@link com.horcrux.svg.RNSVGImageShadowNode#loadImage(ImageRequest, Canvas, Paint)} calls it
|
||||||
|
* asynchronously after images have loaded and are ready to be drawn.
|
||||||
|
*
|
||||||
|
* @param canvas
|
||||||
|
* @param paint
|
||||||
|
*/
|
||||||
|
public synchronized void drawChildren(Canvas canvas, Paint paint) {
|
||||||
for (int i = 0; i < getChildCount(); i++) {
|
for (int i = 0; i < getChildCount(); i++) {
|
||||||
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
|
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
|
||||||
child.setupDimensions(canvas);
|
child.setupDimensions(canvas);
|
||||||
@@ -114,4 +121,15 @@ public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
|
|||||||
return mDefinedTemplates.get(templateRef);
|
return mDefinedTemplates.get(templateRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void defineBrush(PropHelper.RNSVGBrush brush, String brushRef) {
|
||||||
|
mDefinedBrushes.put(brushRef, brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeBrush(String brushRef) {
|
||||||
|
mDefinedBrushes.remove(brushRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropHelper.RNSVGBrush getDefinedBrush(String brushRef) {
|
||||||
|
return mDefinedBrushes.get(brushRef);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
@@ -22,7 +23,6 @@ import android.graphics.Typeface;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
import com.facebook.react.bridge.ReadableMap;
|
||||||
@@ -102,6 +102,9 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
|
|||||||
if (mPath == null) {
|
if (mPath == null) {
|
||||||
canvas.drawText(text, 0, -paint.ascent(), paint);
|
canvas.drawText(text, 0, -paint.ascent(), paint);
|
||||||
} else {
|
} else {
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.setTranslate(0, -paint.getTextSize() * 1.1f);
|
||||||
|
mPath.transform(matrix);
|
||||||
canvas.drawTextOnPath(text, mPath, 0, -paint.ascent(), paint);
|
canvas.drawTextOnPath(text, mPath, 0, -paint.ascent(), paint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,6 +189,7 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
|
|||||||
if (setupFillPaint(paint, 1.0f, getBox(paint, text))) {
|
if (setupFillPaint(paint, 1.0f, getBox(paint, text))) {
|
||||||
applyTextPropertiesToPaint(paint);
|
applyTextPropertiesToPaint(paint);
|
||||||
paint.getTextPath(text, 0, text.length(), 0, -paint.ascent(), path);
|
paint.getTextPath(text, 0, text.length(), 0, -paint.ascent(), path);
|
||||||
|
path.transform(mMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
|
|||||||
@@ -11,15 +11,12 @@ package com.horcrux.svg;
|
|||||||
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.facebook.common.logging.FLog;
|
import com.facebook.common.logging.FLog;
|
||||||
import com.facebook.react.common.ReactConstants;
|
import com.facebook.react.common.ReactConstants;
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shadow node for virtual RNSVGPath view
|
* Shadow node for virtual RNSVGPath view
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -10,9 +10,7 @@
|
|||||||
package com.horcrux.svg;
|
package com.horcrux.svg;
|
||||||
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Matrix;
|
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
|
|||||||
@@ -11,33 +11,23 @@ package com.horcrux.svg;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
import com.facebook.react.uimanager.DisplayMetricsHolder;
|
import com.facebook.react.uimanager.DisplayMetricsHolder;
|
||||||
import com.facebook.react.uimanager.LayoutShadowNode;
|
import com.facebook.react.uimanager.LayoutShadowNode;
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
import com.facebook.react.uimanager.ReactShadowNode;
|
import com.facebook.react.uimanager.ReactShadowNode;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for RNSVGView virtual nodes: {@link RNSVGGroupShadowNode}, {@link RNSVGPathShadowNode} and
|
* Base class for RNSVGView virtual nodes: {@link RNSVGGroupShadowNode}, {@link RNSVGPathShadowNode} and
|
||||||
@@ -76,7 +66,7 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
|
|||||||
private RNSVGSvgViewShadowNode mSvgShadowNode;
|
private RNSVGSvgViewShadowNode mSvgShadowNode;
|
||||||
|
|
||||||
public RNSVGVirtualNode() {
|
public RNSVGVirtualNode() {
|
||||||
mScale = DisplayMetricsHolder.getWindowDisplayMetrics().density;
|
mScale = DisplayMetricsHolder.getScreenDisplayMetrics().density;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void draw(Canvas canvas, Paint paint, float opacity);
|
public abstract void draw(Canvas canvas, Paint paint, float opacity);
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ public class RNSvgPackage implements ReactPackage {
|
|||||||
RNSVGRenderableViewManager.createRNSVGDefsViewManager(),
|
RNSVGRenderableViewManager.createRNSVGDefsViewManager(),
|
||||||
RNSVGRenderableViewManager.createRNSVGUseViewManager(),
|
RNSVGRenderableViewManager.createRNSVGUseViewManager(),
|
||||||
RNSVGRenderableViewManager.createRNSVGViewBoxViewManager(),
|
RNSVGRenderableViewManager.createRNSVGViewBoxViewManager(),
|
||||||
|
RNSVGRenderableViewManager.createRNSVGLinearGradientManager(),
|
||||||
|
RNSVGRenderableViewManager.createRNSVGRadialGradientManager(),
|
||||||
new RNSVGSvgViewManager());
|
new RNSVGSvgViewManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -313,10 +313,10 @@
|
|||||||
10ABC7381D43982B006CCF6E /* RNSVGVBMOS.h */,
|
10ABC7381D43982B006CCF6E /* RNSVGVBMOS.h */,
|
||||||
10ABC7371D439779006CCF6E /* RNSVGCGFCRule.h */,
|
10ABC7371D439779006CCF6E /* RNSVGCGFCRule.h */,
|
||||||
1039D2AE1CE72F27001E90A8 /* RNSVGPercentageConverter.h */,
|
1039D2AE1CE72F27001E90A8 /* RNSVGPercentageConverter.h */,
|
||||||
|
1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */,
|
||||||
1039D29B1CE72177001E90A8 /* RCTConvert+RNSVG.h */,
|
1039D29B1CE72177001E90A8 /* RCTConvert+RNSVG.h */,
|
||||||
1039D29C1CE72177001E90A8 /* RCTConvert+RNSVG.m */,
|
1039D29C1CE72177001E90A8 /* RCTConvert+RNSVG.m */,
|
||||||
1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */,
|
1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */,
|
||||||
1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */,
|
|
||||||
);
|
);
|
||||||
name = Utils;
|
name = Utils;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|||||||
Reference in New Issue
Block a user