indices, int topIndex) {
+ for (int index = topIndex; index >= 0; index--) {
+ int xIndex = indices.get(index);
+ indices.set(index, xIndex + 1);
+ }
+ }
+
+ // https://www.w3.org/TR/SVG11/text.html#FontSizeProperty
+
+ /**
+ * Get font size from context.
+ *
+ * ‘font-size’ Value: < absolute-size > | < relative-size > | < length > | < percentage > |
+ * inherit Initial: medium Applies to: text content elements Inherited: yes, the computed value is
+ * inherited Percentages: refer to parent element's font size Media: visual Animatable: yes
+ *
+ *
This property refers to the size of the font from baseline to baseline when multiple lines
+ * of text are set solid in a multiline layout environment.
+ *
+ *
For SVG, if a < length > is provided without a unit identifier (e.g., an unqualified number
+ * such as 128), the SVG user agent processes the < length > as a height value in the current user
+ * coordinate system.
+ *
+ *
If a < length > is provided with one of the unit identifiers (e.g., 12pt or 10%), then the
+ * SVG user agent converts the < length > into a corresponding value in the current user
+ * coordinate system by applying the rules described in Units.
+ *
+ *
Except for any additional information provided in this specification, the normative
+ * definition of the property is in CSS2 ([CSS2], section 15.2.4).
+ */
+ double getFontSize() {
+ return mFontSize;
+ }
+
+ double nextX(double advance) {
+ incrementIndices(mXIndices, mXsIndex);
+
+ int nextIndex = mXIndex + 1;
+ if (nextIndex < mXs.length) {
+ mDX = 0;
+ mXIndex = nextIndex;
+ SVGLength string = mXs[nextIndex];
+ mX = PropHelper.fromRelative(string, mWidth, 0, mScale, mFontSize);
}
- private double[] getDoubleArrayFromReadableArray(ArrayList readableArray) {
- int size = readableArray.size();
- double[] doubles = new double[size];
- for (int i = 0; i < size; i++) {
- SVGLength length = readableArray.get(i);
- doubles[i] = length.value;
- }
- return doubles;
+ mX += advance;
+
+ return mX;
+ }
+
+ double nextY() {
+ incrementIndices(mYIndices, mYsIndex);
+
+ int nextIndex = mYIndex + 1;
+ if (nextIndex < mYs.length) {
+ mDY = 0;
+ mYIndex = nextIndex;
+ SVGLength string = mYs[nextIndex];
+ mY = PropHelper.fromRelative(string, mHeight, 0, mScale, mFontSize);
}
- void pushContext(
- boolean reset,
- TextView node,
- @Nullable ReadableMap font,
- @Nullable ArrayList x,
- @Nullable ArrayList y,
- @Nullable ArrayList deltaX,
- @Nullable ArrayList deltaY,
- @Nullable ArrayList rotate
- ) {
- if (reset) {
- this.reset();
- }
+ return mY;
+ }
- pushNodeAndFont(node, font);
+ double nextDeltaX() {
+ incrementIndices(mDXIndices, mDXsIndex);
- if (x != null && x.size() != 0) {
- mXsIndex++;
- mXIndex = -1;
- mXIndices.add(mXIndex);
- mXs = getStringArrayFromReadableArray(x);
- mXsContext.add(mXs);
- }
-
- if (y != null && y.size() != 0) {
- mYsIndex++;
- mYIndex = -1;
- mYIndices.add(mYIndex);
- mYs = getStringArrayFromReadableArray(y);
- mYsContext.add(mYs);
- }
-
- if (deltaX != null && deltaX.size() != 0) {
- mDXsIndex++;
- mDXIndex = -1;
- mDXIndices.add(mDXIndex);
- mDXs = getStringArrayFromReadableArray(deltaX);
- mDXsContext.add(mDXs);
- }
-
- if (deltaY != null && deltaY.size() != 0) {
- mDYsIndex++;
- mDYIndex = -1;
- mDYIndices.add(mDYIndex);
- mDYs = getStringArrayFromReadableArray(deltaY);
- mDYsContext.add(mDYs);
- }
-
- if (rotate != null && rotate.size() != 0) {
- mRsIndex++;
- mRIndex = -1;
- mRIndices.add(mRIndex);
- mRs = getDoubleArrayFromReadableArray(rotate);
- mRsContext.add(mRs);
- }
-
- pushIndices();
+ int nextIndex = mDXIndex + 1;
+ if (nextIndex < mDXs.length) {
+ mDXIndex = nextIndex;
+ SVGLength string = mDXs[nextIndex];
+ double val = PropHelper.fromRelative(string, mWidth, 0, mScale, mFontSize);
+ mDX += val;
}
- void popContext() {
- mFontContext.remove(mTop);
- mXsIndices.remove(mTop);
- mYsIndices.remove(mTop);
- mDXsIndices.remove(mTop);
- mDYsIndices.remove(mTop);
- mRsIndices.remove(mTop);
+ return mDX;
+ }
- mTop--;
+ double nextDeltaY() {
+ incrementIndices(mDYIndices, mDYsIndex);
- int x = mXsIndex;
- int y = mYsIndex;
- int dx = mDXsIndex;
- int dy = mDYsIndex;
- int r = mRsIndex;
-
- topFont = mFontContext.get(mTop);
- mXsIndex = mXsIndices.get(mTop);
- mYsIndex = mYsIndices.get(mTop);
- mDXsIndex = mDXsIndices.get(mTop);
- mDYsIndex = mDYsIndices.get(mTop);
- mRsIndex = mRsIndices.get(mTop);
-
- if (x != mXsIndex) {
- mXsContext.remove(x);
- mXs = mXsContext.get(mXsIndex);
- mXIndex = mXIndices.get(mXsIndex);
- }
- if (y != mYsIndex) {
- mYsContext.remove(y);
- mYs = mYsContext.get(mYsIndex);
- mYIndex = mYIndices.get(mYsIndex);
- }
- if (dx != mDXsIndex) {
- mDXsContext.remove(dx);
- mDXs = mDXsContext.get(mDXsIndex);
- mDXIndex = mDXIndices.get(mDXsIndex);
- }
- if (dy != mDYsIndex) {
- mDYsContext.remove(dy);
- mDYs = mDYsContext.get(mDYsIndex);
- mDYIndex = mDYIndices.get(mDYsIndex);
- }
- if (r != mRsIndex) {
- mRsContext.remove(r);
- mRs = mRsContext.get(mRsIndex);
- mRIndex = mRIndices.get(mRsIndex);
- }
+ int nextIndex = mDYIndex + 1;
+ if (nextIndex < mDYs.length) {
+ mDYIndex = nextIndex;
+ SVGLength string = mDYs[nextIndex];
+ double val = PropHelper.fromRelative(string, mHeight, 0, mScale, mFontSize);
+ mDY += val;
}
- private static void incrementIndices(ArrayList indices, int topIndex) {
- for (int index = topIndex; index >= 0; index--) {
- int xIndex = indices.get(index);
- indices.set(index, xIndex + 1);
- }
- }
+ return mDY;
+ }
- // https://www.w3.org/TR/SVG11/text.html#FontSizeProperty
+ double nextRotation() {
+ incrementIndices(mRIndices, mRsIndex);
- /**
- * Get font size from context.
- *
- * ‘font-size’
- * Value: < absolute-size > | < relative-size > | < length > | < percentage > | inherit
- * Initial: medium
- * Applies to: text content elements
- * Inherited: yes, the computed value is inherited
- * Percentages: refer to parent element's font size
- * Media: visual
- * Animatable: yes
- *
- * This property refers to the size of the font from baseline to
- * baseline when multiple lines of text are set solid in a multiline
- * layout environment.
- *
- * For SVG, if a < length > is provided without a unit identifier
- * (e.g., an unqualified number such as 128), the SVG user agent
- * processes the < length > as a height value in the current user
- * coordinate system.
- *
- * If a < length > is provided with one of the unit identifiers
- * (e.g., 12pt or 10%), then the SVG user agent converts the
- * < length > into a corresponding value in the current user
- * coordinate system by applying the rules described in Units.
- *
- * Except for any additional information provided in this specification,
- * the normative definition of the property is in CSS2 ([CSS2], section 15.2.4).
- */
- double getFontSize() {
- return mFontSize;
- }
+ mRIndex = Math.min(mRIndex + 1, mRs.length - 1);
- double nextX(double advance) {
- incrementIndices(mXIndices, mXsIndex);
+ return mRs[mRIndex];
+ }
- int nextIndex = mXIndex + 1;
- if (nextIndex < mXs.length) {
- mDX = 0;
- mXIndex = nextIndex;
- SVGLength string = mXs[nextIndex];
- mX = PropHelper.fromRelative(string, mWidth, 0, mScale, mFontSize);
- }
+ float getWidth() {
+ return mWidth;
+ }
- mX += advance;
-
- return mX;
- }
-
- double nextY() {
- incrementIndices(mYIndices, mYsIndex);
-
- int nextIndex = mYIndex + 1;
- if (nextIndex < mYs.length) {
- mDY = 0;
- mYIndex = nextIndex;
- SVGLength string = mYs[nextIndex];
- mY = PropHelper.fromRelative(string, mHeight, 0, mScale, mFontSize);
- }
-
- return mY;
- }
-
- double nextDeltaX() {
- incrementIndices(mDXIndices, mDXsIndex);
-
- int nextIndex = mDXIndex + 1;
- if (nextIndex < mDXs.length) {
- mDXIndex = nextIndex;
- SVGLength string = mDXs[nextIndex];
- double val = PropHelper.fromRelative(string, mWidth, 0, mScale, mFontSize);
- mDX += val;
- }
-
- return mDX;
- }
-
- double nextDeltaY() {
- incrementIndices(mDYIndices, mDYsIndex);
-
- int nextIndex = mDYIndex + 1;
- if (nextIndex < mDYs.length) {
- mDYIndex = nextIndex;
- SVGLength string = mDYs[nextIndex];
- double val = PropHelper.fromRelative(string, mHeight, 0, mScale, mFontSize);
- mDY += val;
- }
-
- return mDY;
- }
-
- double nextRotation() {
- incrementIndices(mRIndices, mRsIndex);
-
- mRIndex = Math.min(mRIndex + 1, mRs.length - 1);
-
- return mRs[mRIndex];
- }
-
- float getWidth() {
- return mWidth;
- }
-
- float getHeight() {
- return mHeight;
- }
+ float getHeight() {
+ return mHeight;
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/GlyphPathBag.java b/android/src/main/java/com/horcrux/svg/GlyphPathBag.java
index b520c599..1a8dca34 100644
--- a/android/src/main/java/com/horcrux/svg/GlyphPathBag.java
+++ b/android/src/main/java/com/horcrux/svg/GlyphPathBag.java
@@ -2,47 +2,46 @@ package com.horcrux.svg;
import android.graphics.Paint;
import android.graphics.Path;
-
import java.util.ArrayList;
class GlyphPathBag {
- private final ArrayList paths = new ArrayList<>();
- private final int[][] data = new int[256][];
- private final Paint paint;
+ private final ArrayList paths = new ArrayList<>();
+ private final int[][] data = new int[256][];
+ private final Paint paint;
- GlyphPathBag(Paint paint) {
- this.paint = paint;
- // Make indexed-by-one, to allow zero to represent non-cached
- paths.add(new Path());
+ GlyphPathBag(Paint paint) {
+ this.paint = paint;
+ // Make indexed-by-one, to allow zero to represent non-cached
+ paths.add(new Path());
+ }
+
+ Path getOrCreateAndCache(char ch, String current) {
+ int index = getIndex(ch);
+ Path cached;
+
+ if (index != 0) {
+ cached = paths.get(index);
+ } else {
+ cached = new Path();
+ paint.getTextPath(current, 0, 1, 0, 0, cached);
+
+ int[] bin = data[ch >> 8];
+ if (bin == null) {
+ bin = data[ch >> 8] = new int[256];
+ }
+ bin[ch & 0xFF] = paths.size();
+
+ paths.add(cached);
}
- Path getOrCreateAndCache(char ch, String current) {
- int index = getIndex(ch);
- Path cached;
+ Path glyph = new Path();
+ glyph.addPath(cached);
+ return glyph;
+ }
- if (index != 0) {
- cached = paths.get(index);
- } else {
- cached = new Path();
- paint.getTextPath(current, 0, 1, 0, 0, cached);
-
- int[] bin = data[ch >> 8];
- if (bin == null) {
- bin = data[ch >> 8] = new int[256];
- }
- bin[ch & 0xFF] = paths.size();
-
- paths.add(cached);
- }
-
- Path glyph = new Path();
- glyph.addPath(cached);
- return glyph;
- }
-
- private int getIndex(char ch) {
- int[] bin = data[ch >> 8];
- if (bin == null) return 0;
- return bin[ch & 0xFF];
- }
+ private int getIndex(char ch) {
+ int[] bin = data[ch >> 8];
+ if (bin == null) return 0;
+ return bin[ch & 0xFF];
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/GroupView.java b/android/src/main/java/com/horcrux/svg/GroupView.java
index e7b54f14..b532631c 100644
--- a/android/src/main/java/com/horcrux/svg/GroupView.java
+++ b/android/src/main/java/com/horcrux/svg/GroupView.java
@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -19,268 +18,264 @@ import android.graphics.RectF;
import android.graphics.Region;
import android.os.Build;
import android.view.View;
-
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.annotations.ReactProp;
-import com.facebook.react.views.view.ReactViewGroup;
-
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
class GroupView extends RenderableView {
- @Nullable ReadableMap mFont;
- private GlyphContext mGlyphContext;
+ @Nullable ReadableMap mFont;
+ private GlyphContext mGlyphContext;
- public GroupView(ReactContext reactContext) {
- super(reactContext);
+ public GroupView(ReactContext reactContext) {
+ super(reactContext);
+ }
+
+ @ReactProp(name = "font")
+ public void setFont(@Nullable ReadableMap font) {
+ mFont = font;
+ invalidate();
+ }
+
+ void setupGlyphContext(Canvas canvas) {
+ RectF clipBounds = new RectF(canvas.getClipBounds());
+ if (mMatrix != null) {
+ mMatrix.mapRect(clipBounds);
}
-
- @ReactProp(name = "font")
- public void setFont(@Nullable ReadableMap font) {
- mFont = font;
- invalidate();
+ if (mTransform != null) {
+ mTransform.mapRect(clipBounds);
}
+ mGlyphContext = new GlyphContext(mScale, clipBounds.width(), clipBounds.height());
+ }
- void setupGlyphContext(Canvas canvas) {
- RectF clipBounds = new RectF(canvas.getClipBounds());
- if (mMatrix != null) {
- mMatrix.mapRect(clipBounds);
+ GlyphContext getGlyphContext() {
+ return mGlyphContext;
+ }
+
+ private static T requireNonNull(T obj) {
+ if (obj == null) throw new NullPointerException();
+ return obj;
+ }
+
+ GlyphContext getTextRootGlyphContext() {
+ return requireNonNull(getTextRoot()).getGlyphContext();
+ }
+
+ void pushGlyphContext() {
+ getTextRootGlyphContext().pushContext(this, mFont);
+ }
+
+ void popGlyphContext() {
+ getTextRootGlyphContext().popContext();
+ }
+
+ void draw(final Canvas canvas, final Paint paint, final float opacity) {
+ setupGlyphContext(canvas);
+ clip(canvas, paint);
+ drawGroup(canvas, paint, opacity);
+ }
+
+ void drawGroup(final Canvas canvas, final Paint paint, final float opacity) {
+ pushGlyphContext();
+ final SvgView svg = getSvgView();
+ final GroupView self = this;
+ final RectF groupRect = new RectF();
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child instanceof MaskView) {
+ continue;
+ }
+ if (child instanceof VirtualView) {
+ VirtualView node = ((VirtualView) child);
+ if ("none".equals(node.mDisplay)) {
+ continue;
}
- if (mTransform != null) {
- mTransform.mapRect(clipBounds);
- }
- mGlyphContext = new GlyphContext(mScale, clipBounds.width(), clipBounds.height());
- }
-
- GlyphContext getGlyphContext() {
- return mGlyphContext;
- }
-
- private static T requireNonNull(T obj) {
- if (obj == null)
- throw new NullPointerException();
- return obj;
- }
-
- GlyphContext getTextRootGlyphContext() {
- return requireNonNull(getTextRoot()).getGlyphContext();
- }
-
- void pushGlyphContext() {
- getTextRootGlyphContext().pushContext(this, mFont);
- }
-
- void popGlyphContext() {
- getTextRootGlyphContext().popContext();
- }
-
- void draw(final Canvas canvas, final Paint paint, final float opacity) {
- setupGlyphContext(canvas);
- clip(canvas, paint);
- drawGroup(canvas, paint, opacity);
- }
-
- void drawGroup(final Canvas canvas, final Paint paint, final float opacity) {
- pushGlyphContext();
- final SvgView svg = getSvgView();
- final GroupView self = this;
- final RectF groupRect = new RectF();
- for (int i = 0; i < getChildCount(); i++) {
- View child = getChildAt(i);
- if (child instanceof MaskView) {
- continue;
- }
- if (child instanceof VirtualView) {
- VirtualView node = ((VirtualView)child);
- if ("none".equals(node.mDisplay)) {
- continue;
- }
- if (node instanceof RenderableView) {
- ((RenderableView)node).mergeProperties(self);
- }
-
- int count = node.saveAndSetupCanvas(canvas, mCTM);
- node.render(canvas, paint, opacity * mOpacity);
- RectF r = node.getClientRect();
- if (r != null) {
- groupRect.union(r);
- }
-
- node.restoreCanvas(canvas, count);
-
- if (node instanceof RenderableView) {
- ((RenderableView)node).resetProperties();
- }
-
- if (node.isResponsible()) {
- svg.enableTouchEvents();
- }
- } else if (child instanceof SvgView) {
- SvgView svgView = (SvgView)child;
- svgView.drawChildren(canvas);
- if (svgView.isResponsible()) {
- svg.enableTouchEvents();
- }
- }
- }
- this.setClientRect(groupRect);
- popGlyphContext();
- }
-
- void drawPath(Canvas canvas, Paint paint, float opacity) {
- super.draw(canvas, paint, opacity);
- }
-
- @Override
- Path getPath(final Canvas canvas, final Paint paint) {
- if (mPath != null) {
- return mPath;
- }
- mPath = new Path();
-
- for (int i = 0; i < getChildCount(); i++) {
- View node = getChildAt(i);
- if (node instanceof MaskView) {
- continue;
- }
- if (node instanceof VirtualView) {
- VirtualView n = (VirtualView)node;
- Matrix transform = n.mMatrix;
- mPath.addPath(n.getPath(canvas, paint), transform);
- }
+ if (node instanceof RenderableView) {
+ ((RenderableView) node).mergeProperties(self);
}
- return mPath;
+ int count = node.saveAndSetupCanvas(canvas, mCTM);
+ node.render(canvas, paint, opacity * mOpacity);
+ RectF r = node.getClientRect();
+ if (r != null) {
+ groupRect.union(r);
+ }
+
+ node.restoreCanvas(canvas, count);
+
+ if (node instanceof RenderableView) {
+ ((RenderableView) node).resetProperties();
+ }
+
+ if (node.isResponsible()) {
+ svg.enableTouchEvents();
+ }
+ } else if (child instanceof SvgView) {
+ SvgView svgView = (SvgView) child;
+ svgView.drawChildren(canvas);
+ if (svgView.isResponsible()) {
+ svg.enableTouchEvents();
+ }
+ }
+ }
+ this.setClientRect(groupRect);
+ popGlyphContext();
+ }
+
+ void drawPath(Canvas canvas, Paint paint, float opacity) {
+ super.draw(canvas, paint, opacity);
+ }
+
+ @Override
+ Path getPath(final Canvas canvas, final Paint paint) {
+ if (mPath != null) {
+ return mPath;
+ }
+ mPath = new Path();
+
+ for (int i = 0; i < getChildCount(); i++) {
+ View node = getChildAt(i);
+ if (node instanceof MaskView) {
+ continue;
+ }
+ if (node instanceof VirtualView) {
+ VirtualView n = (VirtualView) node;
+ Matrix transform = n.mMatrix;
+ mPath.addPath(n.getPath(canvas, paint), transform);
+ }
}
- Path getPath(final Canvas canvas, final Paint paint, final Region.Op op) {
- final Path path = new Path();
+ return mPath;
+ }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- final Path.Op pop = Path.Op.valueOf(op.name());
- for (int i = 0; i < getChildCount(); i++) {
- View node = getChildAt(i);
- if (node instanceof MaskView) {
- continue;
- }
- if (node instanceof VirtualView) {
- VirtualView n = (VirtualView)node;
- Matrix transform = n.mMatrix;
- Path p2;
- if (n instanceof GroupView) {
- p2 = ((GroupView)n).getPath(canvas, paint, op);
- } else {
- p2 = n.getPath(canvas, paint);
- }
- p2.transform(transform);
- path.op(p2, pop);
- }
- }
- } else {
- Rect clipBounds = canvas.getClipBounds();
- final Region bounds = new Region(clipBounds);
- final Region r = new Region();
- for (int i = 0; i < getChildCount(); i++) {
- View node = getChildAt(i);
- if (node instanceof MaskView) {
- continue;
- }
- if (node instanceof VirtualView) {
- VirtualView n = (VirtualView)node;
- Matrix transform = n.mMatrix;
- Path p2;
- if (n instanceof GroupView) {
- p2 = ((GroupView)n).getPath(canvas, paint, op);
- } else {
- p2 = n.getPath(canvas, paint);
- }
- if (transform != null) {
- p2.transform(transform);
- }
- Region r2 = new Region();
- r2.setPath(p2, bounds);
- r.op(r2, op);
- }
- }
- path.addPath(r.getBoundaryPath());
+ Path getPath(final Canvas canvas, final Paint paint, final Region.Op op) {
+ final Path path = new Path();
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ final Path.Op pop = Path.Op.valueOf(op.name());
+ for (int i = 0; i < getChildCount(); i++) {
+ View node = getChildAt(i);
+ if (node instanceof MaskView) {
+ continue;
}
-
- return path;
+ if (node instanceof VirtualView) {
+ VirtualView n = (VirtualView) node;
+ Matrix transform = n.mMatrix;
+ Path p2;
+ if (n instanceof GroupView) {
+ p2 = ((GroupView) n).getPath(canvas, paint, op);
+ } else {
+ p2 = n.getPath(canvas, paint);
+ }
+ p2.transform(transform);
+ path.op(p2, pop);
+ }
+ }
+ } else {
+ Rect clipBounds = canvas.getClipBounds();
+ final Region bounds = new Region(clipBounds);
+ final Region r = new Region();
+ for (int i = 0; i < getChildCount(); i++) {
+ View node = getChildAt(i);
+ if (node instanceof MaskView) {
+ continue;
+ }
+ if (node instanceof VirtualView) {
+ VirtualView n = (VirtualView) node;
+ Matrix transform = n.mMatrix;
+ Path p2;
+ if (n instanceof GroupView) {
+ p2 = ((GroupView) n).getPath(canvas, paint, op);
+ } else {
+ p2 = n.getPath(canvas, paint);
+ }
+ if (transform != null) {
+ p2.transform(transform);
+ }
+ Region r2 = new Region();
+ r2.setPath(p2, bounds);
+ r.op(r2, op);
+ }
+ }
+ path.addPath(r.getBoundaryPath());
}
- @Override
- int hitTest(final float[] src) {
- if (!mInvertible || !mTransformInvertible) {
- return -1;
- }
+ return path;
+ }
- float[] dst = new float[2];
- mInvMatrix.mapPoints(dst, src);
- mInvTransform.mapPoints(dst);
+ @Override
+ int hitTest(final float[] src) {
+ if (!mInvertible || !mTransformInvertible) {
+ return -1;
+ }
- int x = Math.round(dst[0]);
- int y = Math.round(dst[1]);
+ float[] dst = new float[2];
+ mInvMatrix.mapPoints(dst, src);
+ mInvTransform.mapPoints(dst);
- Path clipPath = getClipPath();
- if (clipPath != null) {
- if (mClipRegionPath != clipPath) {
- mClipRegionPath = clipPath;
- mClipBounds = new RectF();
- clipPath.computeBounds(mClipBounds, true);
- mClipRegion = getRegion(clipPath, mClipBounds);
- }
- if (!mClipRegion.contains(x, y)) {
- return -1;
- }
- }
-
- for (int i = getChildCount() - 1; i >= 0; i--) {
- View child = getChildAt(i);
- if (child instanceof VirtualView) {
- if (child instanceof MaskView) {
- continue;
- }
-
- VirtualView node = (VirtualView) child;
-
- int hitChild = node.hitTest(dst);
- if (hitChild != -1) {
- return (node.isResponsible() || hitChild != child.getId()) ? hitChild : getId();
- }
- } else if (child instanceof SvgView) {
- SvgView node = (SvgView) child;
-
- int hitChild = node.reactTagForTouch(dst[0], dst[1]);
- if (hitChild != child.getId()) {
- return hitChild;
- }
- }
- }
+ int x = Math.round(dst[0]);
+ int y = Math.round(dst[1]);
+ Path clipPath = getClipPath();
+ if (clipPath != null) {
+ if (mClipRegionPath != clipPath) {
+ mClipRegionPath = clipPath;
+ mClipBounds = new RectF();
+ clipPath.computeBounds(mClipBounds, true);
+ mClipRegion = getRegion(clipPath, mClipBounds);
+ }
+ if (!mClipRegion.contains(x, y)) {
return -1;
+ }
}
- void saveDefinition() {
- if (mName != null) {
- getSvgView().defineTemplate(this, mName);
+ for (int i = getChildCount() - 1; i >= 0; i--) {
+ View child = getChildAt(i);
+ if (child instanceof VirtualView) {
+ if (child instanceof MaskView) {
+ continue;
}
- for (int i = 0; i < getChildCount(); i++) {
- View node = getChildAt(i);
- if (node instanceof VirtualView) {
- ((VirtualView)node).saveDefinition();
- }
+ VirtualView node = (VirtualView) child;
+
+ int hitChild = node.hitTest(dst);
+ if (hitChild != -1) {
+ return (node.isResponsible() || hitChild != child.getId()) ? hitChild : getId();
}
+ } else if (child instanceof SvgView) {
+ SvgView node = (SvgView) child;
+
+ int hitChild = node.reactTagForTouch(dst[0], dst[1]);
+ if (hitChild != child.getId()) {
+ return hitChild;
+ }
+ }
}
- @Override
- void resetProperties() {
- for (int i = 0; i < getChildCount(); i++) {
- View node = getChildAt(i);
- if (node instanceof RenderableView) {
- ((RenderableView)node).resetProperties();
- }
- }
+ return -1;
+ }
+
+ void saveDefinition() {
+ if (mName != null) {
+ getSvgView().defineTemplate(this, mName);
}
+
+ for (int i = 0; i < getChildCount(); i++) {
+ View node = getChildAt(i);
+ if (node instanceof VirtualView) {
+ ((VirtualView) node).saveDefinition();
+ }
+ }
+ }
+
+ @Override
+ void resetProperties() {
+ for (int i = 0; i < getChildCount(); i++) {
+ View node = getChildAt(i);
+ if (node instanceof RenderableView) {
+ ((RenderableView) node).resetProperties();
+ }
+ }
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/ImageView.java b/android/src/main/java/com/horcrux/svg/ImageView.java
index ab049006..4ddd2b9b 100644
--- a/android/src/main/java/com/horcrux/svg/ImageView.java
+++ b/android/src/main/java/com/horcrux/svg/ImageView.java
@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -17,7 +16,6 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.net.Uri;
-
import com.facebook.common.executors.UiThreadImmediateExecutorService;
import com.facebook.common.logging.FLog;
import com.facebook.common.references.CloseableReference;
@@ -35,235 +33,240 @@ import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.imagehelper.ImageSource;
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
-
import java.util.concurrent.atomic.AtomicBoolean;
-
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
class ImageView extends RenderableView {
- private SVGLength mX;
- private SVGLength mY;
- private SVGLength mW;
- private SVGLength mH;
- private String uriString;
- private int mImageWidth;
- private int mImageHeight;
- private String mAlign;
- private int mMeetOrSlice;
- private final AtomicBoolean mLoading = new AtomicBoolean(false);
+ private SVGLength mX;
+ private SVGLength mY;
+ private SVGLength mW;
+ private SVGLength mH;
+ private String uriString;
+ private int mImageWidth;
+ private int mImageHeight;
+ private String mAlign;
+ private int mMeetOrSlice;
+ private final AtomicBoolean mLoading = new AtomicBoolean(false);
- public ImageView(ReactContext reactContext) {
- super(reactContext);
- }
+ public ImageView(ReactContext reactContext) {
+ super(reactContext);
+ }
- @ReactProp(name = "x")
- public void setX(Dynamic x) {
- mX = SVGLength.from(x);
- invalidate();
- }
+ @ReactProp(name = "x")
+ public void setX(Dynamic x) {
+ mX = SVGLength.from(x);
+ invalidate();
+ }
public void setX(String x) {
mX = SVGLength.from(x);
invalidate();
}
- @ReactProp(name = "y")
- public void setY(Dynamic y) {
- mY = SVGLength.from(y);
- invalidate();
- }
+ @ReactProp(name = "y")
+ public void setY(Dynamic y) {
+ mY = SVGLength.from(y);
+ invalidate();
+ }
public void setY(String y) {
mY = SVGLength.from(y);
invalidate();
}
- @ReactProp(name = "width")
- public void setWidth(Dynamic width) {
- mW = SVGLength.from(width);
- invalidate();
- }
+ @ReactProp(name = "width")
+ public void setWidth(Dynamic width) {
+ mW = SVGLength.from(width);
+ invalidate();
+ }
public void setWidth(String width) {
mW = SVGLength.from(width);
invalidate();
}
- @ReactProp(name = "height")
- public void setHeight(Dynamic height) {
- mH = SVGLength.from(height);
- invalidate();
- }
+ @ReactProp(name = "height")
+ public void setHeight(Dynamic height) {
+ mH = SVGLength.from(height);
+ invalidate();
+ }
public void setHeight(String height) {
mH = SVGLength.from(height);
invalidate();
}
+ @ReactProp(name = "src")
+ public void setSrc(@Nullable ReadableMap src) {
+ if (src != null) {
+ uriString = src.getString("uri");
- @ReactProp(name = "src")
- public void setSrc(@Nullable ReadableMap src) {
- if (src != null) {
- uriString = src.getString("uri");
+ if (uriString == null || uriString.isEmpty()) {
+ // TODO: give warning about this
+ return;
+ }
- if (uriString == null || uriString.isEmpty()) {
- //TODO: give warning about this
- return;
- }
-
- if (src.hasKey("width") && src.hasKey("height")) {
- mImageWidth = src.getInt("width");
- mImageHeight = src.getInt("height");
- } else {
- mImageWidth = 0;
- mImageHeight = 0;
- }
- Uri mUri = Uri.parse(uriString);
- if (mUri.getScheme() == null) {
- ResourceDrawableIdHelper.getInstance().getResourceDrawableUri(mContext, uriString);
- }
- }
+ if (src.hasKey("width") && src.hasKey("height")) {
+ mImageWidth = src.getInt("width");
+ mImageHeight = src.getInt("height");
+ } else {
+ mImageWidth = 0;
+ mImageHeight = 0;
+ }
+ Uri mUri = Uri.parse(uriString);
+ if (mUri.getScheme() == null) {
+ ResourceDrawableIdHelper.getInstance().getResourceDrawableUri(mContext, uriString);
+ }
}
+ }
- @ReactProp(name = "align")
- public void setAlign(String align) {
- mAlign = align;
- invalidate();
+ @ReactProp(name = "align")
+ public void setAlign(String align) {
+ mAlign = align;
+ invalidate();
+ }
+
+ @ReactProp(name = "meetOrSlice")
+ public void setMeetOrSlice(int meetOrSlice) {
+ mMeetOrSlice = meetOrSlice;
+ invalidate();
+ }
+
+ @Override
+ void draw(final Canvas canvas, final Paint paint, final float opacity) {
+ if (!mLoading.get()) {
+ ImagePipeline imagePipeline = Fresco.getImagePipeline();
+ ImageSource imageSource = new ImageSource(mContext, uriString);
+ ImageRequest request = ImageRequest.fromUri(imageSource.getUri());
+ boolean inMemoryCache = imagePipeline.isInBitmapMemoryCache(request);
+
+ if (inMemoryCache) {
+ tryRenderFromBitmapCache(imagePipeline, request, canvas, paint, opacity * mOpacity);
+ } else {
+ loadBitmap(imagePipeline, request);
+ }
}
+ }
- @ReactProp(name = "meetOrSlice")
- public void setMeetOrSlice(int meetOrSlice) {
- mMeetOrSlice = meetOrSlice;
- invalidate();
- }
+ @Override
+ Path getPath(Canvas canvas, Paint paint) {
+ mPath = new Path();
+ mPath.addRect(getRect(), Path.Direction.CW);
+ return mPath;
+ }
- @Override
- void draw(final Canvas canvas, final Paint paint, final float opacity) {
- if (!mLoading.get()) {
- ImagePipeline imagePipeline = Fresco.getImagePipeline();
- ImageSource imageSource = new ImageSource(mContext, uriString);
- ImageRequest request = ImageRequest.fromUri(imageSource.getUri());
- boolean inMemoryCache = imagePipeline.isInBitmapMemoryCache(request);
-
- if (inMemoryCache) {
- tryRenderFromBitmapCache(imagePipeline, request, canvas, paint, opacity * mOpacity);
- } else {
- loadBitmap(imagePipeline, request);
+ private void loadBitmap(final ImagePipeline imagePipeline, final ImageRequest request) {
+ mLoading.set(true);
+ final DataSource> dataSource =
+ imagePipeline.fetchDecodedImage(request, mContext);
+ BaseBitmapDataSubscriber subscriber =
+ new BaseBitmapDataSubscriber() {
+ @Override
+ public void onNewResultImpl(Bitmap bitmap) {
+ mLoading.set(false);
+ SvgView view = getSvgView();
+ if (view != null) {
+ view.invalidate();
}
- }
- }
+ }
- @Override
- Path getPath(Canvas canvas, Paint paint) {
- mPath = new Path();
- mPath.addRect(getRect(), Path.Direction.CW);
- return mPath;
- }
-
- private void loadBitmap(final ImagePipeline imagePipeline, final ImageRequest request) {
- mLoading.set(true);
- final DataSource> dataSource
- = imagePipeline.fetchDecodedImage(request, mContext);
- BaseBitmapDataSubscriber subscriber = new BaseBitmapDataSubscriber() {
- @Override
- public void onNewResultImpl(Bitmap bitmap) {
- mLoading.set(false);
- SvgView view = getSvgView();
- if (view != null) {
- view.invalidate();
- }
- }
-
- @Override
- public void onFailureImpl(DataSource dataSource) {
- // No cleanup required here.
- // TODO: more details about this failure
- mLoading.set(false);
- FLog.w(ReactConstants.TAG, dataSource.getFailureCause(), "RNSVG: fetchDecodedImage failed!");
- }
+ @Override
+ public void onFailureImpl(DataSource dataSource) {
+ // No cleanup required here.
+ // TODO: more details about this failure
+ mLoading.set(false);
+ FLog.w(
+ ReactConstants.TAG,
+ dataSource.getFailureCause(),
+ "RNSVG: fetchDecodedImage failed!");
+ }
};
- dataSource.subscribe(subscriber, UiThreadImmediateExecutorService.getInstance());
+ dataSource.subscribe(subscriber, UiThreadImmediateExecutorService.getInstance());
+ }
+
+ @Nonnull
+ private RectF getRect() {
+ double x = relativeOnWidth(mX);
+ double y = relativeOnHeight(mY);
+ double w = relativeOnWidth(mW);
+ double h = relativeOnHeight(mH);
+ if (w == 0) {
+ w = mImageWidth * mScale;
+ }
+ if (h == 0) {
+ h = mImageHeight * mScale;
}
- @Nonnull
- private RectF getRect() {
- double x = relativeOnWidth(mX);
- double y = relativeOnHeight(mY);
- double w = relativeOnWidth(mW);
- double h = relativeOnHeight(mH);
- if (w == 0) {
- w = mImageWidth * mScale;
- }
- if (h == 0) {
- h = mImageHeight * mScale;
- }
+ return new RectF((float) x, (float) y, (float) (x + w), (float) (y + h));
+ }
- return new RectF((float) x, (float) y, (float) (x + w), (float) (y + h));
+ private void doRender(Canvas canvas, Paint paint, Bitmap bitmap, float opacity) {
+ if (mImageWidth == 0 || mImageHeight == 0) {
+ mImageWidth = bitmap.getWidth();
+ mImageHeight = bitmap.getHeight();
}
- private void doRender(Canvas canvas, Paint paint, Bitmap bitmap, float opacity) {
- if (mImageWidth == 0 || mImageHeight == 0) {
- mImageWidth = bitmap.getWidth();
- mImageHeight = bitmap.getHeight();
- }
+ RectF renderRect = getRect();
+ RectF vbRect = new RectF(0, 0, mImageWidth, mImageHeight);
+ Matrix transform = ViewBox.getTransform(vbRect, renderRect, mAlign, mMeetOrSlice);
+ transform.mapRect(vbRect);
- RectF renderRect = getRect();
- RectF vbRect = new RectF(0, 0, mImageWidth, mImageHeight);
- Matrix transform = ViewBox.getTransform(vbRect, renderRect, mAlign, mMeetOrSlice);
- transform.mapRect(vbRect);
+ canvas.clipPath(getPath(canvas, paint));
- canvas.clipPath(getPath(canvas, paint));
-
- Path clipPath = getClipPath(canvas, paint);
- if (clipPath != null) {
- canvas.clipPath(clipPath);
- }
-
- Paint alphaPaint = new Paint();
- alphaPaint.setAlpha((int) (opacity * 255));
- canvas.drawBitmap(bitmap, null, vbRect, alphaPaint);
- mCTM.mapRect(vbRect);
- this.setClientRect(vbRect);
+ Path clipPath = getClipPath(canvas, paint);
+ if (clipPath != null) {
+ canvas.clipPath(clipPath);
}
- private void tryRenderFromBitmapCache(ImagePipeline imagePipeline, ImageRequest request, Canvas canvas, Paint paint, float opacity) {
- final DataSource> dataSource
- = imagePipeline.fetchImageFromBitmapCache(request, mContext);
+ Paint alphaPaint = new Paint();
+ alphaPaint.setAlpha((int) (opacity * 255));
+ canvas.drawBitmap(bitmap, null, vbRect, alphaPaint);
+ mCTM.mapRect(vbRect);
+ this.setClientRect(vbRect);
+ }
- try {
- final CloseableReference imageReference = dataSource.getResult();
- if (imageReference == null) {
- return;
- }
+ private void tryRenderFromBitmapCache(
+ ImagePipeline imagePipeline,
+ ImageRequest request,
+ Canvas canvas,
+ Paint paint,
+ float opacity) {
+ final DataSource> dataSource =
+ imagePipeline.fetchImageFromBitmapCache(request, mContext);
- try {
- CloseableImage closeableImage = imageReference.get();
- if (!(closeableImage instanceof CloseableBitmap)) {
- return;
- }
+ try {
+ final CloseableReference imageReference = dataSource.getResult();
+ if (imageReference == null) {
+ return;
+ }
- CloseableBitmap closeableBitmap = (CloseableBitmap) closeableImage;
- final Bitmap bitmap = closeableBitmap.getUnderlyingBitmap();
-
- if (bitmap == null) {
- return;
- }
-
- doRender(canvas, paint, bitmap, opacity);
-
- } catch (Exception e) {
- throw new IllegalStateException(e);
- } finally {
- CloseableReference.closeSafely(imageReference);
- }
-
- } catch (Exception e) {
- throw new IllegalStateException(e);
- } finally {
- dataSource.close();
+ try {
+ CloseableImage closeableImage = imageReference.get();
+ if (!(closeableImage instanceof CloseableBitmap)) {
+ return;
}
- }
+ CloseableBitmap closeableBitmap = (CloseableBitmap) closeableImage;
+ final Bitmap bitmap = closeableBitmap.getUnderlyingBitmap();
+
+ if (bitmap == null) {
+ return;
+ }
+
+ doRender(canvas, paint, bitmap, opacity);
+
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ } finally {
+ CloseableReference.closeSafely(imageReference);
+ }
+
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ } finally {
+ dataSource.close();
+ }
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/LineView.java b/android/src/main/java/com/horcrux/svg/LineView.java
index a5eb5229..0ab3e65f 100644
--- a/android/src/main/java/com/horcrux/svg/LineView.java
+++ b/android/src/main/java/com/horcrux/svg/LineView.java
@@ -6,83 +6,81 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
-
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@SuppressLint("ViewConstructor")
class LineView extends RenderableView {
- private SVGLength mX1;
- private SVGLength mY1;
- private SVGLength mX2;
- private SVGLength mY2;
+ private SVGLength mX1;
+ private SVGLength mY1;
+ private SVGLength mX2;
+ private SVGLength mY2;
- public LineView(ReactContext reactContext) {
- super(reactContext);
- }
+ public LineView(ReactContext reactContext) {
+ super(reactContext);
+ }
- @ReactProp(name = "x1")
- public void setX1(Dynamic x1) {
- mX1 = SVGLength.from(x1);
- invalidate();
- }
+ @ReactProp(name = "x1")
+ public void setX1(Dynamic x1) {
+ mX1 = SVGLength.from(x1);
+ invalidate();
+ }
public void setX1(String x1) {
mX1 = SVGLength.from(x1);
invalidate();
}
- @ReactProp(name = "y1")
- public void setY1(Dynamic y1) {
- mY1 = SVGLength.from(y1);
- invalidate();
- }
+ @ReactProp(name = "y1")
+ public void setY1(Dynamic y1) {
+ mY1 = SVGLength.from(y1);
+ invalidate();
+ }
public void setY1(String y1) {
mY1 = SVGLength.from(y1);
invalidate();
}
- @ReactProp(name = "x2")
- public void setX2(Dynamic x2) {
- mX2 = SVGLength.from(x2);
- invalidate();
- }
+ @ReactProp(name = "x2")
+ public void setX2(Dynamic x2) {
+ mX2 = SVGLength.from(x2);
+ invalidate();
+ }
public void setX2(String x2) {
mX2 = SVGLength.from(x2);
invalidate();
}
- @ReactProp(name = "y2")
- public void setY2(Dynamic y2) {
- mY2 = SVGLength.from(y2);
- invalidate();
- }
+ @ReactProp(name = "y2")
+ public void setY2(Dynamic y2) {
+ mY2 = SVGLength.from(y2);
+ invalidate();
+ }
public void setY2(String y2) {
mY2 = SVGLength.from(y2);
invalidate();
}
- @Override
- Path getPath(Canvas canvas, Paint paint) {
- Path path = new Path();
- double x1 = relativeOnWidth(mX1);
- double y1 = relativeOnHeight(mY1);
- double x2 = relativeOnWidth(mX2);
- double y2 = relativeOnHeight(mY2);
+ @Override
+ Path getPath(Canvas canvas, Paint paint) {
+ Path path = new Path();
+ double x1 = relativeOnWidth(mX1);
+ double y1 = relativeOnHeight(mY1);
+ double x2 = relativeOnWidth(mX2);
+ double y2 = relativeOnHeight(mY2);
- path.moveTo((float) x1, (float) y1);
- path.lineTo((float) x2, (float) y2);
- return path;
- }
+ path.moveTo((float) x1, (float) y1);
+ path.lineTo((float) x2, (float) y2);
+ return path;
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/LinearGradientView.java b/android/src/main/java/com/horcrux/svg/LinearGradientView.java
index b2c432be..43b9d1a5 100644
--- a/android/src/main/java/com/horcrux/svg/LinearGradientView.java
+++ b/android/src/main/java/com/horcrux/svg/LinearGradientView.java
@@ -6,140 +6,138 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
-
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
-
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
class LinearGradientView extends DefinitionView {
- private SVGLength mX1;
- private SVGLength mY1;
- private SVGLength mX2;
- private SVGLength mY2;
- private ReadableArray mGradient;
- private Brush.BrushUnits mGradientUnits;
+ private SVGLength mX1;
+ private SVGLength mY1;
+ private SVGLength mX2;
+ private SVGLength mY2;
+ private ReadableArray mGradient;
+ private Brush.BrushUnits mGradientUnits;
- private static final float[] sRawMatrix = new float[]{
+ private static final float[] sRawMatrix =
+ new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1
- };
- private Matrix mMatrix = null;
+ };
+ private Matrix mMatrix = null;
- public LinearGradientView(ReactContext reactContext) {
- super(reactContext);
- }
+ public LinearGradientView(ReactContext reactContext) {
+ super(reactContext);
+ }
- @ReactProp(name = "x1")
- public void setX1(Dynamic x1) {
- mX1 = SVGLength.from(x1);
- invalidate();
- }
+ @ReactProp(name = "x1")
+ public void setX1(Dynamic x1) {
+ mX1 = SVGLength.from(x1);
+ invalidate();
+ }
public void setX1(String x1) {
mX1 = SVGLength.from(x1);
invalidate();
}
- @ReactProp(name = "y1")
- public void setY1(Dynamic y1) {
- mY1 = SVGLength.from(y1);
- invalidate();
- }
+ @ReactProp(name = "y1")
+ public void setY1(Dynamic y1) {
+ mY1 = SVGLength.from(y1);
+ invalidate();
+ }
public void setY1(String y1) {
mY1 = SVGLength.from(y1);
invalidate();
}
- @ReactProp(name = "x2")
- public void setX2(Dynamic x2) {
- mX2 = SVGLength.from(x2);
- invalidate();
- }
+ @ReactProp(name = "x2")
+ public void setX2(Dynamic x2) {
+ mX2 = SVGLength.from(x2);
+ invalidate();
+ }
public void setX2(String x2) {
mX2 = SVGLength.from(x2);
invalidate();
}
- @ReactProp(name = "y2")
- public void setY2(Dynamic y2) {
- mY2 = SVGLength.from(y2);
- invalidate();
- }
+ @ReactProp(name = "y2")
+ public void setY2(Dynamic y2) {
+ mY2 = SVGLength.from(y2);
+ invalidate();
+ }
public void setY2(String y2) {
mY2 = SVGLength.from(y2);
invalidate();
}
- @ReactProp(name = "gradient")
- public void setGradient(ReadableArray gradient) {
- mGradient = gradient;
- invalidate();
- }
+ @ReactProp(name = "gradient")
+ public void setGradient(ReadableArray gradient) {
+ mGradient = gradient;
+ invalidate();
+ }
- @ReactProp(name = "gradientUnits")
- public void setGradientUnits(int gradientUnits) {
- switch (gradientUnits) {
- case 0:
- mGradientUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
- break;
- case 1:
- mGradientUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
- break;
+ @ReactProp(name = "gradientUnits")
+ public void setGradientUnits(int gradientUnits) {
+ switch (gradientUnits) {
+ case 0:
+ mGradientUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
+ break;
+ case 1:
+ mGradientUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
+ break;
+ }
+ invalidate();
+ }
+
+ @ReactProp(name = "gradientTransform")
+ public void setGradientTransform(@Nullable ReadableArray matrixArray) {
+ if (matrixArray != null) {
+ int matrixSize = PropHelper.toMatrixData(matrixArray, sRawMatrix, mScale);
+ if (matrixSize == 6) {
+ if (mMatrix == null) {
+ mMatrix = new Matrix();
}
- invalidate();
+ mMatrix.setValues(sRawMatrix);
+ } else if (matrixSize != -1) {
+ FLog.w(ReactConstants.TAG, "RNSVG: Transform matrices must be of size 6");
+ }
+ } else {
+ mMatrix = null;
}
- @ReactProp(name = "gradientTransform")
- public void setGradientTransform(@Nullable ReadableArray matrixArray) {
- if (matrixArray != null) {
- int matrixSize = PropHelper.toMatrixData(matrixArray, sRawMatrix, mScale);
- if (matrixSize == 6) {
- if (mMatrix == null) {
- mMatrix = new Matrix();
- }
- mMatrix.setValues(sRawMatrix);
- } else if (matrixSize != -1) {
- FLog.w(ReactConstants.TAG, "RNSVG: Transform matrices must be of size 6");
- }
- } else {
- mMatrix = null;
- }
+ invalidate();
+ }
- invalidate();
- }
-
- @Override
- void saveDefinition() {
- if (mName != null) {
- SVGLength[] points = new SVGLength[]{mX1, mY1, mX2, mY2};
- Brush brush = new Brush(Brush.BrushType.LINEAR_GRADIENT, points, mGradientUnits);
- brush.setGradientColors(mGradient);
- if (mMatrix != null) {
- brush.setGradientTransform(mMatrix);
- }
-
- SvgView svg = getSvgView();
- if (mGradientUnits == Brush.BrushUnits.USER_SPACE_ON_USE) {
- brush.setUserSpaceBoundingBox(svg.getCanvasBounds());
- }
-
- svg.defineBrush(brush, mName);
- }
+ @Override
+ void saveDefinition() {
+ if (mName != null) {
+ SVGLength[] points = new SVGLength[] {mX1, mY1, mX2, mY2};
+ Brush brush = new Brush(Brush.BrushType.LINEAR_GRADIENT, points, mGradientUnits);
+ brush.setGradientColors(mGradient);
+ if (mMatrix != null) {
+ brush.setGradientTransform(mMatrix);
+ }
+
+ SvgView svg = getSvgView();
+ if (mGradientUnits == Brush.BrushUnits.USER_SPACE_ON_USE) {
+ brush.setUserSpaceBoundingBox(svg.getCanvasBounds());
+ }
+
+ svg.defineBrush(brush, mName);
}
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/MarkerView.java b/android/src/main/java/com/horcrux/svg/MarkerView.java
index cdcc41f7..86d0cb61 100644
--- a/android/src/main/java/com/horcrux/svg/MarkerView.java
+++ b/android/src/main/java/com/horcrux/svg/MarkerView.java
@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -15,7 +14,6 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;
-
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -23,167 +21,173 @@ import com.facebook.react.uimanager.annotations.ReactProp;
@SuppressLint("ViewConstructor")
class MarkerView extends GroupView {
- private SVGLength mRefX;
- private SVGLength mRefY;
- private SVGLength mMarkerWidth;
- private SVGLength mMarkerHeight;
- private String mMarkerUnits;
- private String mOrient;
+ private SVGLength mRefX;
+ private SVGLength mRefY;
+ private SVGLength mMarkerWidth;
+ private SVGLength mMarkerHeight;
+ private String mMarkerUnits;
+ private String mOrient;
- private float mMinX;
- private float mMinY;
- private float mVbWidth;
- private float mVbHeight;
- String mAlign;
- int mMeetOrSlice;
+ private float mMinX;
+ private float mMinY;
+ private float mVbWidth;
+ private float mVbHeight;
+ String mAlign;
+ int mMeetOrSlice;
- Matrix markerTransform = new Matrix();
+ Matrix markerTransform = new Matrix();
- public MarkerView(ReactContext reactContext) {
- super(reactContext);
- }
+ public MarkerView(ReactContext reactContext) {
+ super(reactContext);
+ }
- @ReactProp(name = "refX")
- public void setRefX(Dynamic refX) {
- mRefX = SVGLength.from(refX);
- invalidate();
- }
+ @ReactProp(name = "refX")
+ public void setRefX(Dynamic refX) {
+ mRefX = SVGLength.from(refX);
+ invalidate();
+ }
public void setRefX(String refX) {
mRefX = SVGLength.from(refX);
invalidate();
}
- @ReactProp(name = "refY")
- public void setRefY(Dynamic refY) {
- mRefY = SVGLength.from(refY);
- invalidate();
- }
+ @ReactProp(name = "refY")
+ public void setRefY(Dynamic refY) {
+ mRefY = SVGLength.from(refY);
+ invalidate();
+ }
public void setRefY(String refY) {
mRefY = SVGLength.from(refY);
invalidate();
}
- @ReactProp(name = "markerWidth")
- public void setMarkerWidth(Dynamic markerWidth) {
- mMarkerWidth = SVGLength.from(markerWidth);
- invalidate();
- }
+ @ReactProp(name = "markerWidth")
+ public void setMarkerWidth(Dynamic markerWidth) {
+ mMarkerWidth = SVGLength.from(markerWidth);
+ invalidate();
+ }
public void setMarkerWidth(String markerWidth) {
mMarkerWidth = SVGLength.from(markerWidth);
invalidate();
}
- @ReactProp(name = "markerHeight")
- public void setMarkerHeight(Dynamic markerHeight) {
- mMarkerHeight = SVGLength.from(markerHeight);
- invalidate();
- }
+ @ReactProp(name = "markerHeight")
+ public void setMarkerHeight(Dynamic markerHeight) {
+ mMarkerHeight = SVGLength.from(markerHeight);
+ invalidate();
+ }
public void setMarkerHeight(String markerHeight) {
mMarkerHeight = SVGLength.from(markerHeight);
invalidate();
}
- @ReactProp(name = "markerUnits")
- public void setMarkerUnits(String markerUnits) {
- mMarkerUnits = markerUnits;
- invalidate();
- }
+ @ReactProp(name = "markerUnits")
+ public void setMarkerUnits(String markerUnits) {
+ mMarkerUnits = markerUnits;
+ invalidate();
+ }
- @ReactProp(name = "orient")
- public void setOrient(String orient) {
- mOrient = orient;
- invalidate();
- }
+ @ReactProp(name = "orient")
+ public void setOrient(String orient) {
+ mOrient = orient;
+ invalidate();
+ }
- @ReactProp(name = "minX")
- public void setMinX(float minX) {
- mMinX = minX;
- invalidate();
- }
+ @ReactProp(name = "minX")
+ public void setMinX(float minX) {
+ mMinX = minX;
+ invalidate();
+ }
- @ReactProp(name = "minY")
- public void setMinY(float minY) {
- mMinY = minY;
- invalidate();
- }
+ @ReactProp(name = "minY")
+ public void setMinY(float minY) {
+ mMinY = minY;
+ invalidate();
+ }
- @ReactProp(name = "vbWidth")
- public void setVbWidth(float vbWidth) {
- mVbWidth = vbWidth;
- invalidate();
- }
+ @ReactProp(name = "vbWidth")
+ public void setVbWidth(float vbWidth) {
+ mVbWidth = vbWidth;
+ invalidate();
+ }
- @ReactProp(name = "vbHeight")
- public void setVbHeight(float vbHeight) {
- mVbHeight = vbHeight;
- invalidate();
- }
+ @ReactProp(name = "vbHeight")
+ public void setVbHeight(float vbHeight) {
+ mVbHeight = vbHeight;
+ invalidate();
+ }
- @ReactProp(name = "align")
- public void setAlign(String align) {
- mAlign = align;
- invalidate();
- }
+ @ReactProp(name = "align")
+ public void setAlign(String align) {
+ mAlign = align;
+ invalidate();
+ }
- @ReactProp(name = "meetOrSlice")
- public void setMeetOrSlice(int meetOrSlice) {
- mMeetOrSlice = meetOrSlice;
- invalidate();
- }
+ @ReactProp(name = "meetOrSlice")
+ public void setMeetOrSlice(int meetOrSlice) {
+ mMeetOrSlice = meetOrSlice;
+ invalidate();
+ }
- @Override
- void saveDefinition() {
- if (mName != null) {
- SvgView svg = getSvgView();
- svg.defineMarker(this, mName);
- for (int i = 0; i < getChildCount(); i++) {
- View node = getChildAt(i);
- if (node instanceof VirtualView) {
- ((VirtualView)node).saveDefinition();
- }
- }
+ @Override
+ void saveDefinition() {
+ if (mName != null) {
+ SvgView svg = getSvgView();
+ svg.defineMarker(this, mName);
+ for (int i = 0; i < getChildCount(); i++) {
+ View node = getChildAt(i);
+ if (node instanceof VirtualView) {
+ ((VirtualView) node).saveDefinition();
}
+ }
+ }
+ }
+
+ void renderMarker(
+ Canvas canvas, Paint paint, float opacity, RNSVGMarkerPosition position, float strokeWidth) {
+ int count = saveAndSetupCanvas(canvas, mCTM);
+
+ markerTransform.reset();
+ Point origin = position.origin;
+ markerTransform.setTranslate((float) origin.x * mScale, (float) origin.y * mScale);
+
+ double markerAngle = "auto".equals(mOrient) ? -1 : Double.parseDouble(mOrient);
+ float degrees = 180 + (float) (markerAngle == -1 ? position.angle : markerAngle);
+ markerTransform.preRotate(degrees);
+
+ boolean useStrokeWidth = "strokeWidth".equals(mMarkerUnits);
+ if (useStrokeWidth) {
+ markerTransform.preScale(strokeWidth, strokeWidth);
}
- void renderMarker(Canvas canvas, Paint paint, float opacity, RNSVGMarkerPosition position, float strokeWidth) {
- int count = saveAndSetupCanvas(canvas, mCTM);
-
- markerTransform.reset();
- Point origin = position.origin;
- markerTransform.setTranslate((float)origin.x * mScale, (float)origin.y * mScale);
-
- double markerAngle = "auto".equals(mOrient) ? -1 : Double.parseDouble(mOrient);
- float degrees = 180 + (float) (markerAngle == -1 ? position.angle : markerAngle);
- markerTransform.preRotate(degrees);
-
- boolean useStrokeWidth = "strokeWidth".equals(mMarkerUnits);
- if (useStrokeWidth) {
- markerTransform.preScale(strokeWidth, strokeWidth);
- }
-
- double width = relativeOnWidth(mMarkerWidth) / mScale;
- double height = relativeOnHeight(mMarkerHeight) / mScale;
- RectF eRect = new RectF(0, 0, (float)width, (float)height);
- if (mAlign != null) {
- RectF vbRect = new RectF(mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
- Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice);
- float[] values = new float[9];
- viewBoxMatrix.getValues(values);
- markerTransform.preScale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]);
- }
-
- double x = relativeOnWidth(mRefX);
- double y = relativeOnHeight(mRefY);
- markerTransform.preTranslate((float)-x, (float)-y);
-
- canvas.concat(markerTransform);
-
- drawGroup(canvas, paint, opacity);
-
- restoreCanvas(canvas, count);
+ double width = relativeOnWidth(mMarkerWidth) / mScale;
+ double height = relativeOnHeight(mMarkerHeight) / mScale;
+ RectF eRect = new RectF(0, 0, (float) width, (float) height);
+ if (mAlign != null) {
+ RectF vbRect =
+ new RectF(
+ mMinX * mScale,
+ mMinY * mScale,
+ (mMinX + mVbWidth) * mScale,
+ (mMinY + mVbHeight) * mScale);
+ Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice);
+ float[] values = new float[9];
+ viewBoxMatrix.getValues(values);
+ markerTransform.preScale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]);
}
+
+ double x = relativeOnWidth(mRefX);
+ double y = relativeOnHeight(mRefY);
+ markerTransform.preTranslate((float) -x, (float) -y);
+
+ canvas.concat(markerTransform);
+
+ drawGroup(canvas, paint, opacity);
+
+ restoreCanvas(canvas, count);
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/MaskView.java b/android/src/main/java/com/horcrux/svg/MaskView.java
index 70e99e88..50f982ff 100644
--- a/android/src/main/java/com/horcrux/svg/MaskView.java
+++ b/android/src/main/java/com/horcrux/svg/MaskView.java
@@ -6,140 +6,139 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
-
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
-
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
class MaskView extends GroupView {
- SVGLength mX;
- SVGLength mY;
- SVGLength mW;
- SVGLength mH;
+ SVGLength mX;
+ SVGLength mY;
+ SVGLength mW;
+ SVGLength mH;
- // TODO implement proper support for units
- @SuppressWarnings({"FieldCanBeLocal", "unused"})
- private Brush.BrushUnits mMaskUnits;
- @SuppressWarnings({"FieldCanBeLocal", "unused"})
- private Brush.BrushUnits mMaskContentUnits;
+ // TODO implement proper support for units
+ @SuppressWarnings({"FieldCanBeLocal", "unused"})
+ private Brush.BrushUnits mMaskUnits;
- private static final float[] sRawMatrix = new float[]{
+ @SuppressWarnings({"FieldCanBeLocal", "unused"})
+ private Brush.BrushUnits mMaskContentUnits;
+
+ private static final float[] sRawMatrix =
+ new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1
- };
- private Matrix mMatrix = null;
+ };
+ private Matrix mMatrix = null;
- public MaskView(ReactContext reactContext) {
- super(reactContext);
- }
+ public MaskView(ReactContext reactContext) {
+ super(reactContext);
+ }
- @ReactProp(name = "x")
- public void setX(Dynamic x) {
- mX = SVGLength.from(x);
- invalidate();
- }
+ @ReactProp(name = "x")
+ public void setX(Dynamic x) {
+ mX = SVGLength.from(x);
+ invalidate();
+ }
public void setX(String x) {
mX = SVGLength.from(x);
invalidate();
}
- @ReactProp(name = "y")
- public void setY(Dynamic y) {
- mY = SVGLength.from(y);
- invalidate();
- }
+ @ReactProp(name = "y")
+ public void setY(Dynamic y) {
+ mY = SVGLength.from(y);
+ invalidate();
+ }
public void setY(String y) {
mY = SVGLength.from(y);
invalidate();
}
- @ReactProp(name = "width")
- public void setWidth(Dynamic width) {
- mW = SVGLength.from(width);
- invalidate();
- }
+ @ReactProp(name = "width")
+ public void setWidth(Dynamic width) {
+ mW = SVGLength.from(width);
+ invalidate();
+ }
public void setWidth(String width) {
mW = SVGLength.from(width);
invalidate();
}
- @ReactProp(name = "height")
- public void setHeight(Dynamic height) {
- mH = SVGLength.from(height);
- invalidate();
- }
+ @ReactProp(name = "height")
+ public void setHeight(Dynamic height) {
+ mH = SVGLength.from(height);
+ invalidate();
+ }
public void setHeight(String height) {
mH = SVGLength.from(height);
invalidate();
}
- @ReactProp(name = "maskUnits")
- public void setMaskUnits(int maskUnits) {
- switch (maskUnits) {
- case 0:
- mMaskUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
- break;
- case 1:
- mMaskUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
- break;
+ @ReactProp(name = "maskUnits")
+ public void setMaskUnits(int maskUnits) {
+ switch (maskUnits) {
+ case 0:
+ mMaskUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
+ break;
+ case 1:
+ mMaskUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
+ break;
+ }
+ invalidate();
+ }
+
+ @ReactProp(name = "maskContentUnits")
+ public void setMaskContentUnits(int maskContentUnits) {
+ switch (maskContentUnits) {
+ case 0:
+ mMaskContentUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
+ break;
+ case 1:
+ mMaskContentUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
+ break;
+ }
+ invalidate();
+ }
+
+ @ReactProp(name = "maskTransform")
+ public void setMaskTransform(@Nullable ReadableArray matrixArray) {
+ if (matrixArray != null) {
+ int matrixSize = PropHelper.toMatrixData(matrixArray, sRawMatrix, mScale);
+ if (matrixSize == 6) {
+ if (mMatrix == null) {
+ mMatrix = new Matrix();
}
- invalidate();
+ mMatrix.setValues(sRawMatrix);
+ } else if (matrixSize != -1) {
+ FLog.w(ReactConstants.TAG, "RNSVG: Transform matrices must be of size 6");
+ }
+ } else {
+ mMatrix = null;
}
- @ReactProp(name = "maskContentUnits")
- public void setMaskContentUnits(int maskContentUnits) {
- switch (maskContentUnits) {
- case 0:
- mMaskContentUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
- break;
- case 1:
- mMaskContentUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
- break;
- }
- invalidate();
- }
+ invalidate();
+ }
- @ReactProp(name = "maskTransform")
- public void setMaskTransform(@Nullable ReadableArray matrixArray) {
- if (matrixArray != null) {
- int matrixSize = PropHelper.toMatrixData(matrixArray, sRawMatrix, mScale);
- if (matrixSize == 6) {
- if (mMatrix == null) {
- mMatrix = new Matrix();
- }
- mMatrix.setValues(sRawMatrix);
- } else if (matrixSize != -1) {
- FLog.w(ReactConstants.TAG, "RNSVG: Transform matrices must be of size 6");
- }
- } else {
- mMatrix = null;
- }
-
- invalidate();
- }
-
- @Override
- void saveDefinition() {
- if (mName != null) {
- SvgView svg = getSvgView();
- svg.defineMask(this, mName);
- }
+ @Override
+ void saveDefinition() {
+ if (mName != null) {
+ SvgView svg = getSvgView();
+ svg.defineMask(this, mName);
}
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/PathParser.java b/android/src/main/java/com/horcrux/svg/PathParser.java
index f2546c54..f618030e 100644
--- a/android/src/main/java/com/horcrux/svg/PathParser.java
+++ b/android/src/main/java/com/horcrux/svg/PathParser.java
@@ -2,609 +2,678 @@ package com.horcrux.svg;
import android.graphics.Path;
import android.graphics.RectF;
-
import java.util.ArrayList;
class PathElement {
- ElementType type;
- Point[] points;
- PathElement(ElementType type, Point[] points) {
- this.type = type;
- this.points = points;
- }
+ ElementType type;
+ Point[] points;
+
+ PathElement(ElementType type, Point[] points) {
+ this.type = type;
+ this.points = points;
+ }
}
class PathParser {
- static float mScale;
+ static float mScale;
- private static int i;
- private static int l;
- private static String s;
- private static Path mPath;
- static ArrayList elements;
+ private static int i;
+ private static int l;
+ private static String s;
+ private static Path mPath;
+ static ArrayList elements;
- private static float mPenX;
- private static float mPenY;
- private static float mPivotX;
- private static float mPivotY;
- private static float mPenDownX;
- private static float mPenDownY;
- private static boolean mPenDown;
+ private static float mPenX;
+ private static float mPenY;
+ private static float mPivotX;
+ private static float mPivotY;
+ private static float mPenDownX;
+ private static float mPenDownY;
+ private static boolean mPenDown;
- static Path parse(String d) {
- elements = new ArrayList<>();
- mPath = new Path();
- if(d == null){
- return mPath;
- }
- char prev_cmd = ' ';
- l = d.length();
- s = d;
- i = 0;
+ static Path parse(String d) {
+ elements = new ArrayList<>();
+ mPath = new Path();
+ if (d == null) {
+ return mPath;
+ }
+ char prev_cmd = ' ';
+ l = d.length();
+ s = d;
+ i = 0;
- mPenX = 0f;
- mPenY = 0f;
- mPivotX = 0f;
- mPivotY = 0f;
- mPenDownX = 0f;
- mPenDownY = 0f;
- mPenDown = false;
+ mPenX = 0f;
+ mPenY = 0f;
+ mPivotX = 0f;
+ mPivotY = 0f;
+ mPenDownX = 0f;
+ mPenDownY = 0f;
+ mPenDown = false;
- while (i < l) {
- skip_spaces();
+ while (i < l) {
+ skip_spaces();
- if (i >= l) {
- break;
- }
+ if (i >= l) {
+ break;
+ }
- boolean has_prev_cmd = prev_cmd != ' ';
- char first_char = s.charAt(i);
+ boolean has_prev_cmd = prev_cmd != ' ';
+ char first_char = s.charAt(i);
- if (!has_prev_cmd && first_char != 'M' && first_char != 'm') {
- // The first segment must be a MoveTo.
- throw new Error(String.format("Unexpected character '%c' (i=%d, s=%s)", first_char, i, s));
- }
-
- // TODO: simplify
- boolean is_implicit_move_to;
- char cmd;
- if (is_cmd(first_char)) {
- is_implicit_move_to = false;
- cmd = first_char;
- i += 1;
- } else if (is_number_start(first_char) && has_prev_cmd) {
- if (prev_cmd == 'Z' || prev_cmd == 'z') {
- // ClosePath cannot be followed by a number.
- throw new Error(String.format("Unexpected number after 'z' (s=%s)", s));
- }
-
- if (prev_cmd == 'M' || prev_cmd == 'm') {
- // 'If a moveto is followed by multiple pairs of coordinates,
- // the subsequent pairs are treated as implicit lineto commands.'
- // So we parse them as LineTo.
- is_implicit_move_to = true;
- if (is_absolute(prev_cmd)) {
- cmd = 'L';
- } else {
- cmd = 'l';
- }
- } else {
- is_implicit_move_to = false;
- cmd = prev_cmd;
- }
- } else {
- throw new Error(String.format("Unexpected character '%c' (i=%d, s=%s)", first_char, i, s));
- }
-
- boolean absolute = is_absolute(cmd);
- switch (cmd) {
- case 'm': {
- move(parse_list_number(), parse_list_number());
- break;
- }
- case 'M': {
- moveTo(parse_list_number(), parse_list_number());
- break;
- }
- case 'l': {
- line(parse_list_number(), parse_list_number());
- break;
- }
- case 'L': {
- lineTo(parse_list_number(), parse_list_number());
- break;
- }
- case 'h': {
- line(parse_list_number(), 0);
- break;
- }
- case 'H': {
- lineTo(parse_list_number(), mPenY);
- break;
- }
- case 'v': {
- line(0, parse_list_number());
- break;
- }
- case 'V': {
- lineTo(mPenX, parse_list_number());
- break;
- }
- case 'c': {
- curve(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
- break;
- }
- case 'C': {
- curveTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
- break;
- }
- case 's': {
- smoothCurve(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
- break;
- }
- case 'S': {
- smoothCurveTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
- break;
- }
- case 'q': {
- quadraticBezierCurve(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
- break;
- }
- case 'Q': {
- quadraticBezierCurveTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
- break;
- }
- case 't': {
- smoothQuadraticBezierCurve(parse_list_number(), parse_list_number());
- break;
- }
- case 'T': {
- smoothQuadraticBezierCurveTo(parse_list_number(), parse_list_number());
- break;
- }
- case 'a': {
- arc(parse_list_number(), parse_list_number(), parse_list_number(), parse_flag(), parse_flag(), parse_list_number(), parse_list_number());
- break;
- }
- case 'A': {
- arcTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_flag(), parse_flag(), parse_list_number(), parse_list_number());
- break;
- }
- case 'z':
- case 'Z': {
- close();
- break;
- }
- default: {
- throw new Error(String.format("Unexpected comand '%c' (s=%s)", cmd, s));
- }
- }
-
-
- if (is_implicit_move_to) {
- if (absolute) {
- prev_cmd = 'M';
- } else {
- prev_cmd = 'm';
- }
- } else {
- prev_cmd = cmd;
- }
+ if (!has_prev_cmd && first_char != 'M' && first_char != 'm') {
+ // The first segment must be a MoveTo.
+ throw new Error(String.format("Unexpected character '%c' (i=%d, s=%s)", first_char, i, s));
+ }
+ // TODO: simplify
+ boolean is_implicit_move_to;
+ char cmd;
+ if (is_cmd(first_char)) {
+ is_implicit_move_to = false;
+ cmd = first_char;
+ i += 1;
+ } else if (is_number_start(first_char) && has_prev_cmd) {
+ if (prev_cmd == 'Z' || prev_cmd == 'z') {
+ // ClosePath cannot be followed by a number.
+ throw new Error(String.format("Unexpected number after 'z' (s=%s)", s));
}
- return mPath;
- }
-
- private static void move(float x, float y) {
- moveTo(x + mPenX, y + mPenY);
- }
-
- private static void moveTo(float x, float y) {
- //FLog.w(ReactConstants.TAG, "move x: " + x + " y: " + y);
- mPenDownX = mPivotX = mPenX = x;
- mPenDownY = mPivotY = mPenY = y;
- mPath.moveTo(x * mScale, y * mScale);
- elements.add(new PathElement(ElementType.kCGPathElementMoveToPoint, new Point[]{new Point(x,y)}));
- }
-
- private static void line(float x, float y) {
- lineTo(x + mPenX, y + mPenY);
- }
-
- private static void lineTo(float x, float y) {
- //FLog.w(ReactConstants.TAG, "line x: " + x + " y: " + y);
- setPenDown();
- mPivotX = mPenX = x;
- mPivotY = mPenY = y;
- mPath.lineTo(x * mScale, y * mScale);
- elements.add(new PathElement(ElementType.kCGPathElementAddLineToPoint, new Point[]{new Point(x,y)}));
- }
-
- private static void curve(float c1x, float c1y, float c2x, float c2y, float ex, float ey) {
- curveTo(c1x + mPenX, c1y + mPenY, c2x + mPenX, c2y + mPenY, ex + mPenX, ey + mPenY);
- }
-
- private static void curveTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey) {
- //FLog.w(ReactConstants.TAG, "curve c1x: " + c1x + " c1y: " + c1y + "ex: " + ex + " ey: " + ey);
- mPivotX = c2x;
- mPivotY = c2y;
- cubicTo(c1x, c1y, c2x, c2y, ex, ey);
- }
-
- private static void cubicTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey) {
- setPenDown();
- mPenX = ex;
- mPenY = ey;
- mPath.cubicTo(c1x * mScale, c1y * mScale, c2x * mScale, c2y * mScale, ex * mScale, ey * mScale);
- elements.add(new PathElement(ElementType.kCGPathElementAddCurveToPoint, new Point[]{new Point(c1x, c1y), new Point(c2x, c2y), new Point(ex, ey)}));
- }
-
- private static void smoothCurve(float c1x, float c1y, float ex, float ey) {
- smoothCurveTo(c1x + mPenX, c1y + mPenY, ex + mPenX, ey + mPenY);
- }
-
- private static void smoothCurveTo(float c1x, float c1y, float ex, float ey) {
- //FLog.w(ReactConstants.TAG, "smoothcurve c1x: " + c1x + " c1y: " + c1y + "ex: " + ex + " ey: " + ey);
- float c2x = c1x;
- float c2y = c1y;
- c1x = (mPenX * 2) - mPivotX;
- c1y = (mPenY * 2) - mPivotY;
- mPivotX = c2x;
- mPivotY = c2y;
- cubicTo(c1x, c1y, c2x, c2y, ex, ey);
- }
-
- private static void quadraticBezierCurve(float c1x, float c1y, float c2x, float c2y) {
- quadraticBezierCurveTo(c1x + mPenX, c1y + mPenY, c2x + mPenX, c2y + mPenY);
- }
-
- private static void quadraticBezierCurveTo(float c1x, float c1y, float c2x, float c2y) {
- //FLog.w(ReactConstants.TAG, "quad c1x: " + c1x + " c1y: " + c1y + "c2x: " + c2x + " c2y: " + c2y);
- mPivotX = c1x;
- mPivotY = c1y;
- float ex = c2x;
- float ey = c2y;
- c2x = (ex + c1x * 2) / 3;
- c2y = (ey + c1y * 2) / 3;
- c1x = (mPenX + c1x * 2) / 3;
- c1y = (mPenY + c1y * 2) / 3;
- cubicTo(c1x, c1y, c2x, c2y, ex, ey);
- }
-
- private static void smoothQuadraticBezierCurve(float c1x, float c1y) {
- smoothQuadraticBezierCurveTo(c1x + mPenX, c1y + mPenY);
- }
-
- private static void smoothQuadraticBezierCurveTo(float c1x, float c1y) {
- //FLog.w(ReactConstants.TAG, "smoothquad c1x: " + c1x + " c1y: " + c1y);
- float c2x = c1x;
- float c2y = c1y;
- c1x = (mPenX * 2) - mPivotX;
- c1y = (mPenY * 2) - mPivotY;
- quadraticBezierCurveTo(c1x, c1y, c2x, c2y);
- }
-
- private static void arc(float rx, float ry, float rotation, boolean outer, boolean clockwise, float x, float y) {
- arcTo(rx, ry, rotation, outer, clockwise, x + mPenX, y + mPenY);
- }
-
- private static void arcTo(float rx, float ry, float rotation, boolean outer, boolean clockwise, float x, float y) {
- //FLog.w(ReactConstants.TAG, "arc rx: " + rx + " ry: " + ry + " rotation: " + rotation + " outer: " + outer + " clockwise: " + clockwise + " x: " + x + " y: " + y);
- float tX = mPenX;
- float tY = mPenY;
-
- ry = Math.abs(ry == 0 ? (rx == 0 ? (y - tY) : rx) : ry);
- rx = Math.abs(rx == 0 ? (x - tX) : rx);
-
- if (rx == 0 || ry == 0 || (x == tX && y == tY)) {
- lineTo(x, y);
- return;
- }
-
- float rad = (float) Math.toRadians(rotation);
- float cos = (float) Math.cos(rad);
- float sin = (float) Math.sin(rad);
- x -= tX;
- y -= tY;
-
- // Ellipse Center
- float cx = cos * x / 2 + sin * y / 2;
- float cy = -sin * x / 2 + cos * y / 2;
- float rxry = rx * rx * ry * ry;
- float rycx = ry * ry * cx * cx;
- float rxcy = rx * rx * cy * cy;
- float a = rxry - rxcy - rycx;
-
- if (a < 0) {
- a = (float) Math.sqrt(1 - a / rxry);
- rx *= a;
- ry *= a;
- cx = x / 2;
- cy = y / 2;
+ if (prev_cmd == 'M' || prev_cmd == 'm') {
+ // 'If a moveto is followed by multiple pairs of coordinates,
+ // the subsequent pairs are treated as implicit lineto commands.'
+ // So we parse them as LineTo.
+ is_implicit_move_to = true;
+ if (is_absolute(prev_cmd)) {
+ cmd = 'L';
+ } else {
+ cmd = 'l';
+ }
} else {
- a = (float) Math.sqrt(a / (rxcy + rycx));
-
- if (outer == clockwise) {
- a = -a;
- }
- float cxd = -a * cy * rx / ry;
- float cyd = a * cx * ry / rx;
- cx = cos * cxd - sin * cyd + x / 2;
- cy = sin * cxd + cos * cyd + y / 2;
+ is_implicit_move_to = false;
+ cmd = prev_cmd;
}
+ } else {
+ throw new Error(String.format("Unexpected character '%c' (i=%d, s=%s)", first_char, i, s));
+ }
- // Rotation + Scale Transform
- float xx = cos / rx;
- float yx = sin / rx;
- float xy = -sin / ry;
- float yy = cos / ry;
+ boolean absolute = is_absolute(cmd);
+ switch (cmd) {
+ case 'm':
+ {
+ move(parse_list_number(), parse_list_number());
+ break;
+ }
+ case 'M':
+ {
+ moveTo(parse_list_number(), parse_list_number());
+ break;
+ }
+ case 'l':
+ {
+ line(parse_list_number(), parse_list_number());
+ break;
+ }
+ case 'L':
+ {
+ lineTo(parse_list_number(), parse_list_number());
+ break;
+ }
+ case 'h':
+ {
+ line(parse_list_number(), 0);
+ break;
+ }
+ case 'H':
+ {
+ lineTo(parse_list_number(), mPenY);
+ break;
+ }
+ case 'v':
+ {
+ line(0, parse_list_number());
+ break;
+ }
+ case 'V':
+ {
+ lineTo(mPenX, parse_list_number());
+ break;
+ }
+ case 'c':
+ {
+ curve(
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number());
+ break;
+ }
+ case 'C':
+ {
+ curveTo(
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number());
+ break;
+ }
+ case 's':
+ {
+ smoothCurve(
+ parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
+ break;
+ }
+ case 'S':
+ {
+ smoothCurveTo(
+ parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
+ break;
+ }
+ case 'q':
+ {
+ quadraticBezierCurve(
+ parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
+ break;
+ }
+ case 'Q':
+ {
+ quadraticBezierCurveTo(
+ parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
+ break;
+ }
+ case 't':
+ {
+ smoothQuadraticBezierCurve(parse_list_number(), parse_list_number());
+ break;
+ }
+ case 'T':
+ {
+ smoothQuadraticBezierCurveTo(parse_list_number(), parse_list_number());
+ break;
+ }
+ case 'a':
+ {
+ arc(
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number(),
+ parse_flag(),
+ parse_flag(),
+ parse_list_number(),
+ parse_list_number());
+ break;
+ }
+ case 'A':
+ {
+ arcTo(
+ parse_list_number(),
+ parse_list_number(),
+ parse_list_number(),
+ parse_flag(),
+ parse_flag(),
+ parse_list_number(),
+ parse_list_number());
+ break;
+ }
+ case 'z':
+ case 'Z':
+ {
+ close();
+ break;
+ }
+ default:
+ {
+ throw new Error(String.format("Unexpected comand '%c' (s=%s)", cmd, s));
+ }
+ }
- // Start and End Angle
- float sa = (float) Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy);
- float ea = (float) Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
-
- cx += tX;
- cy += tY;
- x += tX;
- y += tY;
-
- setPenDown();
-
- mPenX = mPivotX = x;
- mPenY = mPivotY = y;
-
- if (rx != ry || rad != 0f) {
- arcToBezier(cx, cy, rx, ry, sa, ea, clockwise, rad);
+ if (is_implicit_move_to) {
+ if (absolute) {
+ prev_cmd = 'M';
} else {
-
- float start = (float) Math.toDegrees(sa);
- float end = (float) Math.toDegrees(ea);
- float sweep = Math.abs((start - end) % 360);
-
- if (outer) {
- if (sweep < 180) {
- sweep = 360 - sweep;
- }
- } else {
- if (sweep > 180) {
- sweep = 360 - sweep;
- }
- }
-
- if (!clockwise) {
- sweep = -sweep;
- }
-
- RectF oval = new RectF(
- (cx - rx) * mScale,
- (cy - rx) * mScale,
- (cx + rx) * mScale,
- (cy + rx) * mScale);
-
- mPath.arcTo(oval, start, sweep);
- elements.add(new PathElement(ElementType.kCGPathElementAddCurveToPoint, new Point[]{new Point(x, y)}));
+ prev_cmd = 'm';
}
+ } else {
+ prev_cmd = cmd;
+ }
}
- private static void close() {
- if (mPenDown) {
- mPenX = mPenDownX;
- mPenY = mPenDownY;
- mPenDown = false;
- mPath.close();
- elements.add(new PathElement(ElementType.kCGPathElementCloseSubpath, new Point[]{new Point(mPenX, mPenY)}));
+ return mPath;
+ }
+
+ private static void move(float x, float y) {
+ moveTo(x + mPenX, y + mPenY);
+ }
+
+ private static void moveTo(float x, float y) {
+ // FLog.w(ReactConstants.TAG, "move x: " + x + " y: " + y);
+ mPenDownX = mPivotX = mPenX = x;
+ mPenDownY = mPivotY = mPenY = y;
+ mPath.moveTo(x * mScale, y * mScale);
+ elements.add(
+ new PathElement(ElementType.kCGPathElementMoveToPoint, new Point[] {new Point(x, y)}));
+ }
+
+ private static void line(float x, float y) {
+ lineTo(x + mPenX, y + mPenY);
+ }
+
+ private static void lineTo(float x, float y) {
+ // FLog.w(ReactConstants.TAG, "line x: " + x + " y: " + y);
+ setPenDown();
+ mPivotX = mPenX = x;
+ mPivotY = mPenY = y;
+ mPath.lineTo(x * mScale, y * mScale);
+ elements.add(
+ new PathElement(ElementType.kCGPathElementAddLineToPoint, new Point[] {new Point(x, y)}));
+ }
+
+ private static void curve(float c1x, float c1y, float c2x, float c2y, float ex, float ey) {
+ curveTo(c1x + mPenX, c1y + mPenY, c2x + mPenX, c2y + mPenY, ex + mPenX, ey + mPenY);
+ }
+
+ private static void curveTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey) {
+ // FLog.w(ReactConstants.TAG, "curve c1x: " + c1x + " c1y: " + c1y + "ex: " + ex + " ey: " +
+ // ey);
+ mPivotX = c2x;
+ mPivotY = c2y;
+ cubicTo(c1x, c1y, c2x, c2y, ex, ey);
+ }
+
+ private static void cubicTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey) {
+ setPenDown();
+ mPenX = ex;
+ mPenY = ey;
+ mPath.cubicTo(c1x * mScale, c1y * mScale, c2x * mScale, c2y * mScale, ex * mScale, ey * mScale);
+ elements.add(
+ new PathElement(
+ ElementType.kCGPathElementAddCurveToPoint,
+ new Point[] {new Point(c1x, c1y), new Point(c2x, c2y), new Point(ex, ey)}));
+ }
+
+ private static void smoothCurve(float c1x, float c1y, float ex, float ey) {
+ smoothCurveTo(c1x + mPenX, c1y + mPenY, ex + mPenX, ey + mPenY);
+ }
+
+ private static void smoothCurveTo(float c1x, float c1y, float ex, float ey) {
+ // FLog.w(ReactConstants.TAG, "smoothcurve c1x: " + c1x + " c1y: " + c1y + "ex: " + ex + " ey: "
+ // + ey);
+ float c2x = c1x;
+ float c2y = c1y;
+ c1x = (mPenX * 2) - mPivotX;
+ c1y = (mPenY * 2) - mPivotY;
+ mPivotX = c2x;
+ mPivotY = c2y;
+ cubicTo(c1x, c1y, c2x, c2y, ex, ey);
+ }
+
+ private static void quadraticBezierCurve(float c1x, float c1y, float c2x, float c2y) {
+ quadraticBezierCurveTo(c1x + mPenX, c1y + mPenY, c2x + mPenX, c2y + mPenY);
+ }
+
+ private static void quadraticBezierCurveTo(float c1x, float c1y, float c2x, float c2y) {
+ // FLog.w(ReactConstants.TAG, "quad c1x: " + c1x + " c1y: " + c1y + "c2x: " + c2x + " c2y: " +
+ // c2y);
+ mPivotX = c1x;
+ mPivotY = c1y;
+ float ex = c2x;
+ float ey = c2y;
+ c2x = (ex + c1x * 2) / 3;
+ c2y = (ey + c1y * 2) / 3;
+ c1x = (mPenX + c1x * 2) / 3;
+ c1y = (mPenY + c1y * 2) / 3;
+ cubicTo(c1x, c1y, c2x, c2y, ex, ey);
+ }
+
+ private static void smoothQuadraticBezierCurve(float c1x, float c1y) {
+ smoothQuadraticBezierCurveTo(c1x + mPenX, c1y + mPenY);
+ }
+
+ private static void smoothQuadraticBezierCurveTo(float c1x, float c1y) {
+ // FLog.w(ReactConstants.TAG, "smoothquad c1x: " + c1x + " c1y: " + c1y);
+ float c2x = c1x;
+ float c2y = c1y;
+ c1x = (mPenX * 2) - mPivotX;
+ c1y = (mPenY * 2) - mPivotY;
+ quadraticBezierCurveTo(c1x, c1y, c2x, c2y);
+ }
+
+ private static void arc(
+ float rx, float ry, float rotation, boolean outer, boolean clockwise, float x, float y) {
+ arcTo(rx, ry, rotation, outer, clockwise, x + mPenX, y + mPenY);
+ }
+
+ private static void arcTo(
+ float rx, float ry, float rotation, boolean outer, boolean clockwise, float x, float y) {
+ // FLog.w(ReactConstants.TAG, "arc rx: " + rx + " ry: " + ry + " rotation: " + rotation + "
+ // outer: " + outer + " clockwise: " + clockwise + " x: " + x + " y: " + y);
+ float tX = mPenX;
+ float tY = mPenY;
+
+ ry = Math.abs(ry == 0 ? (rx == 0 ? (y - tY) : rx) : ry);
+ rx = Math.abs(rx == 0 ? (x - tX) : rx);
+
+ if (rx == 0 || ry == 0 || (x == tX && y == tY)) {
+ lineTo(x, y);
+ return;
+ }
+
+ float rad = (float) Math.toRadians(rotation);
+ float cos = (float) Math.cos(rad);
+ float sin = (float) Math.sin(rad);
+ x -= tX;
+ y -= tY;
+
+ // Ellipse Center
+ float cx = cos * x / 2 + sin * y / 2;
+ float cy = -sin * x / 2 + cos * y / 2;
+ float rxry = rx * rx * ry * ry;
+ float rycx = ry * ry * cx * cx;
+ float rxcy = rx * rx * cy * cy;
+ float a = rxry - rxcy - rycx;
+
+ if (a < 0) {
+ a = (float) Math.sqrt(1 - a / rxry);
+ rx *= a;
+ ry *= a;
+ cx = x / 2;
+ cy = y / 2;
+ } else {
+ a = (float) Math.sqrt(a / (rxcy + rycx));
+
+ if (outer == clockwise) {
+ a = -a;
+ }
+ float cxd = -a * cy * rx / ry;
+ float cyd = a * cx * ry / rx;
+ cx = cos * cxd - sin * cyd + x / 2;
+ cy = sin * cxd + cos * cyd + y / 2;
+ }
+
+ // Rotation + Scale Transform
+ float xx = cos / rx;
+ float yx = sin / rx;
+ float xy = -sin / ry;
+ float yy = cos / ry;
+
+ // Start and End Angle
+ float sa = (float) Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy);
+ float ea = (float) Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
+
+ cx += tX;
+ cy += tY;
+ x += tX;
+ y += tY;
+
+ setPenDown();
+
+ mPenX = mPivotX = x;
+ mPenY = mPivotY = y;
+
+ if (rx != ry || rad != 0f) {
+ arcToBezier(cx, cy, rx, ry, sa, ea, clockwise, rad);
+ } else {
+
+ float start = (float) Math.toDegrees(sa);
+ float end = (float) Math.toDegrees(ea);
+ float sweep = Math.abs((start - end) % 360);
+
+ if (outer) {
+ if (sweep < 180) {
+ sweep = 360 - sweep;
}
- }
-
- private static void arcToBezier(float cx, float cy, float rx, float ry, float sa, float ea, boolean clockwise, float rad) {
- // Inverse Rotation + Scale Transform
- float cos = (float) Math.cos(rad);
- float sin = (float) Math.sin(rad);
- float xx = cos * rx;
- float yx = -sin * ry;
- float xy = sin * rx;
- float yy = cos * ry;
-
- // Bezier Curve Approximation
- float arc = ea - sa;
- if (arc < 0 && clockwise) {
- arc += Math.PI * 2;
- } else if (arc > 0 && !clockwise) {
- arc -= Math.PI * 2;
+ } else {
+ if (sweep > 180) {
+ sweep = 360 - sweep;
}
+ }
- int n = (int) Math.ceil(Math.abs(round(arc / (Math.PI / 2))));
+ if (!clockwise) {
+ sweep = -sweep;
+ }
- float step = arc / n;
- float k = (float) ((4 / 3.0) * Math.tan(step / 4));
+ RectF oval =
+ new RectF((cx - rx) * mScale, (cy - rx) * mScale, (cx + rx) * mScale, (cy + rx) * mScale);
- float x = (float) Math.cos(sa);
- float y = (float) Math.sin(sa);
+ mPath.arcTo(oval, start, sweep);
+ elements.add(
+ new PathElement(
+ ElementType.kCGPathElementAddCurveToPoint, new Point[] {new Point(x, y)}));
+ }
+ }
- for (int i = 0; i < n; i++) {
- float cp1x = x - k * y;
- float cp1y = y + k * x;
+ private static void close() {
+ if (mPenDown) {
+ mPenX = mPenDownX;
+ mPenY = mPenDownY;
+ mPenDown = false;
+ mPath.close();
+ elements.add(
+ new PathElement(
+ ElementType.kCGPathElementCloseSubpath, new Point[] {new Point(mPenX, mPenY)}));
+ }
+ }
- sa += step;
- x = (float) Math.cos(sa);
- y = (float) Math.sin(sa);
+ private static void arcToBezier(
+ float cx, float cy, float rx, float ry, float sa, float ea, boolean clockwise, float rad) {
+ // Inverse Rotation + Scale Transform
+ float cos = (float) Math.cos(rad);
+ float sin = (float) Math.sin(rad);
+ float xx = cos * rx;
+ float yx = -sin * ry;
+ float xy = sin * rx;
+ float yy = cos * ry;
- float cp2x = x + k * y;
- float cp2y = y - k * x;
-
- float c1x = (cx + xx * cp1x + yx * cp1y);
- float c1y = (cy + xy * cp1x + yy * cp1y);
- float c2x = (cx + xx * cp2x + yx * cp2y);
- float c2y = (cy + xy * cp2x + yy * cp2y);
- float ex = (cx + xx * x + yx * y);
- float ey = (cy + xy * x + yy * y);
-
- mPath.cubicTo(c1x * mScale, c1y * mScale, c2x * mScale, c2y * mScale, ex * mScale, ey * mScale);
- elements.add(new PathElement(ElementType.kCGPathElementAddCurveToPoint, new Point[]{new Point(c1x, c1y), new Point(c2x, c2y), new Point(ex, ey)}));
- }
+ // Bezier Curve Approximation
+ float arc = ea - sa;
+ if (arc < 0 && clockwise) {
+ arc += Math.PI * 2;
+ } else if (arc > 0 && !clockwise) {
+ arc -= Math.PI * 2;
}
- private static void setPenDown() {
- if (!mPenDown) {
- mPenDownX = mPenX;
- mPenDownY = mPenY;
- mPenDown = true;
- }
+ int n = (int) Math.ceil(Math.abs(round(arc / (Math.PI / 2))));
+
+ float step = arc / n;
+ float k = (float) ((4 / 3.0) * Math.tan(step / 4));
+
+ float x = (float) Math.cos(sa);
+ float y = (float) Math.sin(sa);
+
+ for (int i = 0; i < n; i++) {
+ float cp1x = x - k * y;
+ float cp1y = y + k * x;
+
+ sa += step;
+ x = (float) Math.cos(sa);
+ y = (float) Math.sin(sa);
+
+ float cp2x = x + k * y;
+ float cp2y = y - k * x;
+
+ float c1x = (cx + xx * cp1x + yx * cp1y);
+ float c1y = (cy + xy * cp1x + yy * cp1y);
+ float c2x = (cx + xx * cp2x + yx * cp2y);
+ float c2y = (cy + xy * cp2x + yy * cp2y);
+ float ex = (cx + xx * x + yx * y);
+ float ey = (cy + xy * x + yy * y);
+
+ mPath.cubicTo(
+ c1x * mScale, c1y * mScale, c2x * mScale, c2y * mScale, ex * mScale, ey * mScale);
+ elements.add(
+ new PathElement(
+ ElementType.kCGPathElementAddCurveToPoint,
+ new Point[] {new Point(c1x, c1y), new Point(c2x, c2y), new Point(ex, ey)}));
}
+ }
- private static double round(double val) {
- double multiplier = Math.pow(10, 4);
- return Math.round(val * multiplier) / multiplier;
+ private static void setPenDown() {
+ if (!mPenDown) {
+ mPenDownX = mPenX;
+ mPenDownY = mPenY;
+ mPenDown = true;
}
+ }
- private static void skip_spaces() {
- while (i < l && Character.isWhitespace(s.charAt(i))) i++;
+ private static double round(double val) {
+ double multiplier = Math.pow(10, 4);
+ return Math.round(val * multiplier) / multiplier;
+ }
+
+ private static void skip_spaces() {
+ while (i < l && Character.isWhitespace(s.charAt(i))) i++;
+ }
+
+ private static boolean is_cmd(char c) {
+ switch (c) {
+ case 'M':
+ case 'm':
+ case 'Z':
+ case 'z':
+ case 'L':
+ case 'l':
+ case 'H':
+ case 'h':
+ case 'V':
+ case 'v':
+ case 'C':
+ case 'c':
+ case 'S':
+ case 's':
+ case 'Q':
+ case 'q':
+ case 'T':
+ case 't':
+ case 'A':
+ case 'a':
+ return true;
}
+ return false;
+ }
- private static boolean is_cmd(char c) {
- switch (c) {
- case 'M':
- case 'm':
- case 'Z':
- case 'z':
- case 'L':
- case 'l':
- case 'H':
- case 'h':
- case 'V':
- case 'v':
- case 'C':
- case 'c':
- case 'S':
- case 's':
- case 'Q':
- case 'q':
- case 'T':
- case 't':
- case 'A':
- case 'a':
- return true;
- }
- return false;
- }
+ private static boolean is_number_start(char c) {
+ return (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+';
+ }
- private static boolean is_number_start(char c) {
- return (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+';
- }
+ private static boolean is_absolute(char c) {
+ return Character.isUpperCase(c);
+ }
- private static boolean is_absolute(char c) {
- return Character.isUpperCase(c);
- }
+ // By the SVG spec 'large-arc' and 'sweep' must contain only one char
+ // and can be written without any separators, e.g.: 10 20 30 01 10 20.
+ private static boolean parse_flag() {
+ skip_spaces();
- // By the SVG spec 'large-arc' and 'sweep' must contain only one char
- // and can be written without any separators, e.g.: 10 20 30 01 10 20.
- private static boolean parse_flag() {
- skip_spaces();
-
- char c = s.charAt(i);
- switch (c) {
- case '0':
- case '1': {
- i += 1;
- if (i < l && s.charAt(i) == ',') {
- i += 1;
- }
- skip_spaces();
- break;
- }
- default:
- throw new Error(String.format("Unexpected flag '%c' (i=%d, s=%s)", c, i, s));
- }
-
- return c == '1';
- }
-
- private static float parse_list_number() {
- if (i == l) {
- throw new Error(String.format("Unexpected end (s=%s)", s));
- }
-
- float n = parse_number();
- skip_spaces();
- parse_list_separator();
-
- return n;
- }
-
- private static float parse_number() {
- // Strip off leading whitespaces.
- skip_spaces();
-
- if (i == l) {
- throw new Error(String.format("Unexpected end (s=%s)", s));
- }
-
- int start = i;
-
- char c = s.charAt(i);
-
- // Consume sign.
- if (c == '-' || c == '+') {
+ char c = s.charAt(i);
+ switch (c) {
+ case '0':
+ case '1':
+ {
+ i += 1;
+ if (i < l && s.charAt(i) == ',') {
i += 1;
- c = s.charAt(i);
+ }
+ skip_spaces();
+ break;
}
-
- // Consume integer.
- if (c >= '0' && c <= '9') {
- skip_digits();
- if (i < l) {
- c = s.charAt(i);
- }
- } else if (c != '.') {
- throw new Error(String.format("Invalid number formating character '%c' (i=%d, s=%s)", c ,i, s));
- }
-
- // Consume fraction.
- if (c == '.') {
- i += 1;
- skip_digits();
- if (i < l) {
- c = s.charAt(i);
- }
- }
-
- if ((c == 'e' || c == 'E') && i + 1 < l) {
- char c2 = s.charAt(i + 1);
- // Check for `em`/`ex`.
- if (c2 != 'm' && c2 != 'x') {
- i += 1;
- c = s.charAt(i);
-
- if (c == '+' || c == '-') {
- i += 1;
- skip_digits();
- } else if (c >= '0' && c <= '9') {
- skip_digits();
- } else {
- throw new Error(String.format("Invalid number formating character '%c' (i=%d, s=%s)", c, i, s));
- }
- }
- }
-
- String num = s.substring(start, i);
- float n = Float.parseFloat(num);
-
- // inf, nan, etc. are an error.
- if (Float.isInfinite(n) || Float.isNaN(n)) {
- throw new Error(String.format("Invalid number '%s' (start=%d, i=%d, s=%s)", num, start, i, s));
- }
-
- return n;
+ default:
+ throw new Error(String.format("Unexpected flag '%c' (i=%d, s=%s)", c, i, s));
}
- private static void parse_list_separator() {
- if (i < l && s.charAt(i) == ',') {
- i += 1;
- }
+ return c == '1';
+ }
+
+ private static float parse_list_number() {
+ if (i == l) {
+ throw new Error(String.format("Unexpected end (s=%s)", s));
}
- private static void skip_digits() {
- while (i < l && Character.isDigit(s.charAt(i))) i++;
+ float n = parse_number();
+ skip_spaces();
+ parse_list_separator();
+
+ return n;
+ }
+
+ private static float parse_number() {
+ // Strip off leading whitespaces.
+ skip_spaces();
+
+ if (i == l) {
+ throw new Error(String.format("Unexpected end (s=%s)", s));
}
+
+ int start = i;
+
+ char c = s.charAt(i);
+
+ // Consume sign.
+ if (c == '-' || c == '+') {
+ i += 1;
+ c = s.charAt(i);
+ }
+
+ // Consume integer.
+ if (c >= '0' && c <= '9') {
+ skip_digits();
+ if (i < l) {
+ c = s.charAt(i);
+ }
+ } else if (c != '.') {
+ throw new Error(
+ String.format("Invalid number formating character '%c' (i=%d, s=%s)", c, i, s));
+ }
+
+ // Consume fraction.
+ if (c == '.') {
+ i += 1;
+ skip_digits();
+ if (i < l) {
+ c = s.charAt(i);
+ }
+ }
+
+ if ((c == 'e' || c == 'E') && i + 1 < l) {
+ char c2 = s.charAt(i + 1);
+ // Check for `em`/`ex`.
+ if (c2 != 'm' && c2 != 'x') {
+ i += 1;
+ c = s.charAt(i);
+
+ if (c == '+' || c == '-') {
+ i += 1;
+ skip_digits();
+ } else if (c >= '0' && c <= '9') {
+ skip_digits();
+ } else {
+ throw new Error(
+ String.format("Invalid number formating character '%c' (i=%d, s=%s)", c, i, s));
+ }
+ }
+ }
+
+ String num = s.substring(start, i);
+ float n = Float.parseFloat(num);
+
+ // inf, nan, etc. are an error.
+ if (Float.isInfinite(n) || Float.isNaN(n)) {
+ throw new Error(
+ String.format("Invalid number '%s' (start=%d, i=%d, s=%s)", num, start, i, s));
+ }
+
+ return n;
+ }
+
+ private static void parse_list_separator() {
+ if (i < l && s.charAt(i) == ',') {
+ i += 1;
+ }
+ }
+
+ private static void skip_digits() {
+ while (i < l && Character.isDigit(s.charAt(i))) i++;
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/PathView.java b/android/src/main/java/com/horcrux/svg/PathView.java
index 20c5fee0..34ac697f 100644
--- a/android/src/main/java/com/horcrux/svg/PathView.java
+++ b/android/src/main/java/com/horcrux/svg/PathView.java
@@ -6,37 +6,34 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
-
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@SuppressLint("ViewConstructor")
class PathView extends RenderableView {
- private Path mPath;
+ private Path mPath;
- public PathView(ReactContext reactContext) {
- super(reactContext);
- PathParser.mScale = mScale;
- mPath = new Path();
- }
+ public PathView(ReactContext reactContext) {
+ super(reactContext);
+ PathParser.mScale = mScale;
+ mPath = new Path();
+ }
- @ReactProp(name = "d")
- public void setD(String d) {
- mPath = PathParser.parse(d);
- elements = PathParser.elements;
- invalidate();
- }
-
- @Override
- Path getPath(Canvas canvas, Paint paint) {
- return mPath;
- }
+ @ReactProp(name = "d")
+ public void setD(String d) {
+ mPath = PathParser.parse(d);
+ elements = PathParser.elements;
+ invalidate();
+ }
+ @Override
+ Path getPath(Canvas canvas, Paint paint) {
+ return mPath;
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/PatternView.java b/android/src/main/java/com/horcrux/svg/PatternView.java
index d4fd40a6..b448abcc 100644
--- a/android/src/main/java/com/horcrux/svg/PatternView.java
+++ b/android/src/main/java/com/horcrux/svg/PatternView.java
@@ -6,197 +6,197 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
import android.graphics.RectF;
-
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
-
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
class PatternView extends GroupView {
- private SVGLength mX;
- private SVGLength mY;
- private SVGLength mW;
- private SVGLength mH;
- private Brush.BrushUnits mPatternUnits;
- private Brush.BrushUnits mPatternContentUnits;
+ private SVGLength mX;
+ private SVGLength mY;
+ private SVGLength mW;
+ private SVGLength mH;
+ private Brush.BrushUnits mPatternUnits;
+ private Brush.BrushUnits mPatternContentUnits;
- private float mMinX;
- private float mMinY;
- private float mVbWidth;
- private float mVbHeight;
- String mAlign;
- int mMeetOrSlice;
+ private float mMinX;
+ private float mMinY;
+ private float mVbWidth;
+ private float mVbHeight;
+ String mAlign;
+ int mMeetOrSlice;
- private static final float[] sRawMatrix = new float[]{
+ private static final float[] sRawMatrix =
+ new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1
- };
- private Matrix mMatrix = null;
+ };
+ private Matrix mMatrix = null;
- public PatternView(ReactContext reactContext) {
- super(reactContext);
- }
+ public PatternView(ReactContext reactContext) {
+ super(reactContext);
+ }
- @ReactProp(name = "x")
- public void setX(Dynamic x) {
- mX = SVGLength.from(x);
- invalidate();
- }
+ @ReactProp(name = "x")
+ public void setX(Dynamic x) {
+ mX = SVGLength.from(x);
+ invalidate();
+ }
public void setX(String x) {
mX = SVGLength.from(x);
invalidate();
}
- @ReactProp(name = "y")
- public void setY(Dynamic y) {
- mY = SVGLength.from(y);
- invalidate();
- }
+ @ReactProp(name = "y")
+ public void setY(Dynamic y) {
+ mY = SVGLength.from(y);
+ invalidate();
+ }
public void setY(String y) {
mY = SVGLength.from(y);
invalidate();
}
- @ReactProp(name = "width")
- public void setWidth(Dynamic width) {
- mW = SVGLength.from(width);
- invalidate();
- }
+ @ReactProp(name = "width")
+ public void setWidth(Dynamic width) {
+ mW = SVGLength.from(width);
+ invalidate();
+ }
public void setWidth(String width) {
mW = SVGLength.from(width);
invalidate();
}
- @ReactProp(name = "height")
- public void setHeight(Dynamic height) {
- mH = SVGLength.from(height);
- invalidate();
- }
+
+ @ReactProp(name = "height")
+ public void setHeight(Dynamic height) {
+ mH = SVGLength.from(height);
+ invalidate();
+ }
public void setHeight(String height) {
mH = SVGLength.from(height);
invalidate();
}
- @ReactProp(name = "patternUnits")
- public void setPatternUnits(int patternUnits) {
- switch (patternUnits) {
- case 0:
- mPatternUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
- break;
- case 1:
- mPatternUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
- break;
+ @ReactProp(name = "patternUnits")
+ public void setPatternUnits(int patternUnits) {
+ switch (patternUnits) {
+ case 0:
+ mPatternUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
+ break;
+ case 1:
+ mPatternUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
+ break;
+ }
+ invalidate();
+ }
+
+ @ReactProp(name = "patternContentUnits")
+ public void setPatternContentUnits(int patternContentUnits) {
+ switch (patternContentUnits) {
+ case 0:
+ mPatternContentUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
+ break;
+ case 1:
+ mPatternContentUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
+ break;
+ }
+ invalidate();
+ }
+
+ @ReactProp(name = "patternTransform")
+ public void setPatternTransform(@Nullable ReadableArray matrixArray) {
+ if (matrixArray != null) {
+ int matrixSize = PropHelper.toMatrixData(matrixArray, sRawMatrix, mScale);
+ if (matrixSize == 6) {
+ if (mMatrix == null) {
+ mMatrix = new Matrix();
}
- invalidate();
+ mMatrix.setValues(sRawMatrix);
+ } else if (matrixSize != -1) {
+ FLog.w(ReactConstants.TAG, "RNSVG: Transform matrices must be of size 6");
+ }
+ } else {
+ mMatrix = null;
}
- @ReactProp(name = "patternContentUnits")
- public void setPatternContentUnits(int patternContentUnits) {
- switch (patternContentUnits) {
- case 0:
- mPatternContentUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
- break;
- case 1:
- mPatternContentUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
- break;
- }
- invalidate();
- }
-
- @ReactProp(name = "patternTransform")
- public void setPatternTransform(@Nullable ReadableArray matrixArray) {
- if (matrixArray != null) {
- int matrixSize = PropHelper.toMatrixData(matrixArray, sRawMatrix, mScale);
- if (matrixSize == 6) {
- if (mMatrix == null) {
- mMatrix = new Matrix();
- }
- mMatrix.setValues(sRawMatrix);
- } else if (matrixSize != -1) {
- FLog.w(ReactConstants.TAG, "RNSVG: Transform matrices must be of size 6");
- }
- } else {
- mMatrix = null;
- }
-
- invalidate();
- }
-
- @ReactProp(name = "minX")
- public void setMinX(float minX) {
- mMinX = minX;
- invalidate();
- }
-
- @ReactProp(name = "minY")
- public void setMinY(float minY) {
- mMinY = minY;
- invalidate();
- }
-
- @ReactProp(name = "vbWidth")
- public void setVbWidth(float vbWidth) {
- mVbWidth = vbWidth;
- invalidate();
- }
-
- @ReactProp(name = "vbHeight")
- public void setVbHeight(float vbHeight) {
- mVbHeight = vbHeight;
- invalidate();
- }
-
- @ReactProp(name = "align")
- public void setAlign(String align) {
- mAlign = align;
- invalidate();
- }
-
- @ReactProp(name = "meetOrSlice")
- public void setMeetOrSlice(int meetOrSlice) {
- mMeetOrSlice = meetOrSlice;
- invalidate();
- }
-
-
- RectF getViewBox() {
- return new RectF(mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
- }
-
- @Override
- void saveDefinition() {
- if (mName != null) {
- SVGLength[] points = new SVGLength[]{mX,mY,mW,mH};
- Brush brush = new Brush(Brush.BrushType.PATTERN, points, mPatternUnits);
- brush.setContentUnits(mPatternContentUnits);
- brush.setPattern(this);
-
- if (mMatrix != null) {
- brush.setGradientTransform(mMatrix);
- }
-
- SvgView svg = getSvgView();
- if (mPatternUnits == Brush.BrushUnits.USER_SPACE_ON_USE || mPatternContentUnits == Brush.BrushUnits.USER_SPACE_ON_USE) {
- brush.setUserSpaceBoundingBox(svg.getCanvasBounds());
- }
-
- svg.defineBrush(brush, mName);
- }
+ invalidate();
+ }
+
+ @ReactProp(name = "minX")
+ public void setMinX(float minX) {
+ mMinX = minX;
+ invalidate();
+ }
+
+ @ReactProp(name = "minY")
+ public void setMinY(float minY) {
+ mMinY = minY;
+ invalidate();
+ }
+
+ @ReactProp(name = "vbWidth")
+ public void setVbWidth(float vbWidth) {
+ mVbWidth = vbWidth;
+ invalidate();
+ }
+
+ @ReactProp(name = "vbHeight")
+ public void setVbHeight(float vbHeight) {
+ mVbHeight = vbHeight;
+ invalidate();
+ }
+
+ @ReactProp(name = "align")
+ public void setAlign(String align) {
+ mAlign = align;
+ invalidate();
+ }
+
+ @ReactProp(name = "meetOrSlice")
+ public void setMeetOrSlice(int meetOrSlice) {
+ mMeetOrSlice = meetOrSlice;
+ invalidate();
+ }
+
+ RectF getViewBox() {
+ return new RectF(
+ mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
+ }
+
+ @Override
+ void saveDefinition() {
+ if (mName != null) {
+ SVGLength[] points = new SVGLength[] {mX, mY, mW, mH};
+ Brush brush = new Brush(Brush.BrushType.PATTERN, points, mPatternUnits);
+ brush.setContentUnits(mPatternContentUnits);
+ brush.setPattern(this);
+
+ if (mMatrix != null) {
+ brush.setGradientTransform(mMatrix);
+ }
+
+ SvgView svg = getSvgView();
+ if (mPatternUnits == Brush.BrushUnits.USER_SPACE_ON_USE
+ || mPatternContentUnits == Brush.BrushUnits.USER_SPACE_ON_USE) {
+ brush.setUserSpaceBoundingBox(svg.getCanvasBounds());
+ }
+
+ svg.defineBrush(brush, mName);
}
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/PropHelper.java b/android/src/main/java/com/horcrux/svg/PropHelper.java
index 3b4edab6..c56e98e9 100644
--- a/android/src/main/java/com/horcrux/svg/PropHelper.java
+++ b/android/src/main/java/com/horcrux/svg/PropHelper.java
@@ -6,215 +6,211 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import com.facebook.react.bridge.ReadableArray;
-/**
- * Contains static helper methods for accessing props.
- */
+/** Contains static helper methods for accessing props. */
class PropHelper {
- private static final int inputMatrixDataSize = 6;
+ private static final int inputMatrixDataSize = 6;
- /**
- * Converts given {@link ReadableArray} to a matrix data array, {@code float[6]}.
- * Writes result to the array passed in {@param into}.
- * This method will write exactly six items to the output array from the input array.
- *
- * If the input array has a different size, then only the size is returned;
- * Does not check output array size. Ensure space for at least six elements.
- *
- * @param value input array
- * @param sRawMatrix output matrix
- * @param mScale current resolution scaling
- * @return size of input array
- */
- static int toMatrixData(ReadableArray value, float[] sRawMatrix, float mScale) {
- int fromSize = value.size();
- if (fromSize != inputMatrixDataSize) {
- return fromSize;
- }
-
- sRawMatrix[0] = (float) value.getDouble(0);
- sRawMatrix[1] = (float) value.getDouble(2);
- sRawMatrix[2] = (float) value.getDouble(4) * mScale;
- sRawMatrix[3] = (float) value.getDouble(1);
- sRawMatrix[4] = (float) value.getDouble(3);
- sRawMatrix[5] = (float) value.getDouble(5) * mScale;
-
- return inputMatrixDataSize;
+ /**
+ * Converts given {@link ReadableArray} to a matrix data array, {@code float[6]}. Writes result to
+ * the array passed in {@param into}. This method will write exactly six items to the output array
+ * from the input array.
+ *
+ * If the input array has a different size, then only the size is returned; Does not check
+ * output array size. Ensure space for at least six elements.
+ *
+ * @param value input array
+ * @param sRawMatrix output matrix
+ * @param mScale current resolution scaling
+ * @return size of input array
+ */
+ static int toMatrixData(ReadableArray value, float[] sRawMatrix, float mScale) {
+ int fromSize = value.size();
+ if (fromSize != inputMatrixDataSize) {
+ return fromSize;
}
- /**
- * Converts length string into px / user units
- * in the current user coordinate system
- *
- * @param length length string
- * @param relative relative size for percentages
- * @param scale scaling parameter
- * @param fontSize current font size
- * @return value in the current user coordinate system
- */
- static double fromRelative(String length, double relative, double scale, double fontSize) {
- /*
- TODO list
+ sRawMatrix[0] = (float) value.getDouble(0);
+ sRawMatrix[1] = (float) value.getDouble(2);
+ sRawMatrix[2] = (float) value.getDouble(4) * mScale;
+ sRawMatrix[3] = (float) value.getDouble(1);
+ sRawMatrix[4] = (float) value.getDouble(3);
+ sRawMatrix[5] = (float) value.getDouble(5) * mScale;
- unit relative to
- em font size of the element
- ex x-height of the element’s font
- ch width of the "0" (ZERO, U+0030) glyph in the element’s font
- rem font size of the root element
- vw 1% of viewport’s width
- vh 1% of viewport’s height
- vmin 1% of viewport’s smaller dimension
- vmax 1% of viewport’s larger dimension
+ return inputMatrixDataSize;
+ }
- relative-size [ larger | smaller ]
- absolute-size: [ xx-small | x-small | small | medium | large | x-large | xx-large ]
+ /**
+ * Converts length string into px / user units in the current user coordinate system
+ *
+ * @param length length string
+ * @param relative relative size for percentages
+ * @param scale scaling parameter
+ * @param fontSize current font size
+ * @return value in the current user coordinate system
+ */
+ static double fromRelative(String length, double relative, double scale, double fontSize) {
+ /*
+ TODO list
- https://www.w3.org/TR/css3-values/#relative-lengths
- https://www.w3.org/TR/css3-values/#absolute-lengths
- https://drafts.csswg.org/css-cascade-4/#computed-value
- https://drafts.csswg.org/css-fonts-3/#propdef-font-size
- https://drafts.csswg.org/css2/fonts.html#propdef-font-size
- */
- length = length.trim();
- int stringLength = length.length();
- int percentIndex = stringLength - 1;
- if (stringLength == 0 || length.equals("normal")) {
- return 0d;
- } else if (length.codePointAt(percentIndex) == '%') {
- return Double.valueOf(length.substring(0, percentIndex)) / 100 * relative;
- } else {
- int twoLetterUnitIndex = stringLength - 2;
- if (twoLetterUnitIndex > 0) {
- String lastTwo = length.substring(twoLetterUnitIndex);
- int end = twoLetterUnitIndex;
- double unit = 1;
+ unit relative to
+ em font size of the element
+ ex x-height of the element’s font
+ ch width of the "0" (ZERO, U+0030) glyph in the element’s font
+ rem font size of the root element
+ vw 1% of viewport’s width
+ vh 1% of viewport’s height
+ vmin 1% of viewport’s smaller dimension
+ vmax 1% of viewport’s larger dimension
- switch (lastTwo) {
- case "px":
- break;
+ relative-size [ larger | smaller ]
+ absolute-size: [ xx-small | x-small | small | medium | large | x-large | xx-large ]
- case "em":
- unit = fontSize;
- break;
-
- /*
- "1pt" equals "1.25px" (and therefore 1.25 user units)
- "1pc" equals "15px" (and therefore 15 user units)
- "1mm" would be "3.543307px" (3.543307 user units)
- "1cm" equals "35.43307px" (and therefore 35.43307 user units)
- "1in" equals "90px" (and therefore 90 user units)
- */
-
- case "pt":
- unit = 1.25d;
- break;
-
- case "pc":
- unit = 15;
- break;
-
- case "mm":
- unit = 3.543307d;
- break;
-
- case "cm":
- unit = 35.43307d;
- break;
-
- case "in":
- unit = 90;
- break;
-
- default:
- end = stringLength;
- }
-
- return Double.valueOf(length.substring(0, end)) * unit * scale;
- } else {
- return Double.valueOf(length) * scale;
- }
- }
- }
- /**
- * Converts SVGLength into px / user units
- * in the current user coordinate system
- *
- * @param length length string
- * @param relative relative size for percentages
- * @param offset offset for all units
- * @param scale scaling parameter
- * @param fontSize current font size
- * @return value in the current user coordinate system
- */
- static double fromRelative(SVGLength length, double relative, double offset, double scale, double fontSize) {
- /*
- TODO list
-
- unit relative to
- em font size of the element
- ex x-height of the element’s font
- ch width of the "0" (ZERO, U+0030) glyph in the element’s font
- rem font size of the root element
- vw 1% of viewport’s width
- vh 1% of viewport’s height
- vmin 1% of viewport’s smaller dimension
- vmax 1% of viewport’s larger dimension
-
- relative-size [ larger | smaller ]
- absolute-size: [ xx-small | x-small | small | medium | large | x-large | xx-large ]
-
- https://www.w3.org/TR/css3-values/#relative-lengths
- https://www.w3.org/TR/css3-values/#absolute-lengths
- https://drafts.csswg.org/css-cascade-4/#computed-value
- https://drafts.csswg.org/css-fonts-3/#propdef-font-size
- https://drafts.csswg.org/css2/fonts.html#propdef-font-size
- */
- if (length == null) {
- return offset;
- }
- SVGLength.UnitType unitType = length.unit;
- double value = length.value;
+ https://www.w3.org/TR/css3-values/#relative-lengths
+ https://www.w3.org/TR/css3-values/#absolute-lengths
+ https://drafts.csswg.org/css-cascade-4/#computed-value
+ https://drafts.csswg.org/css-fonts-3/#propdef-font-size
+ https://drafts.csswg.org/css2/fonts.html#propdef-font-size
+ */
+ length = length.trim();
+ int stringLength = length.length();
+ int percentIndex = stringLength - 1;
+ if (stringLength == 0 || length.equals("normal")) {
+ return 0d;
+ } else if (length.codePointAt(percentIndex) == '%') {
+ return Double.valueOf(length.substring(0, percentIndex)) / 100 * relative;
+ } else {
+ int twoLetterUnitIndex = stringLength - 2;
+ if (twoLetterUnitIndex > 0) {
+ String lastTwo = length.substring(twoLetterUnitIndex);
+ int end = twoLetterUnitIndex;
double unit = 1;
- switch (unitType) {
- case NUMBER:
- case PX:
- break;
- case PERCENTAGE:
- return value / 100 * relative + offset;
+ switch (lastTwo) {
+ case "px":
+ break;
- case EMS:
- unit = fontSize;
- break;
- case EXS:
- unit = fontSize / 2;
- break;
+ case "em":
+ unit = fontSize;
+ break;
- case CM:
- unit = 35.43307;
- break;
- case MM:
- unit = 3.543307;
- break;
- case IN:
- unit = 90;
- break;
- case PT:
- unit = 1.25;
- break;
- case PC:
- unit = 15;
- break;
+ /*
+ "1pt" equals "1.25px" (and therefore 1.25 user units)
+ "1pc" equals "15px" (and therefore 15 user units)
+ "1mm" would be "3.543307px" (3.543307 user units)
+ "1cm" equals "35.43307px" (and therefore 35.43307 user units)
+ "1in" equals "90px" (and therefore 90 user units)
+ */
- default:
- case UNKNOWN:
- return value * scale + offset;
+ case "pt":
+ unit = 1.25d;
+ break;
+
+ case "pc":
+ unit = 15;
+ break;
+
+ case "mm":
+ unit = 3.543307d;
+ break;
+
+ case "cm":
+ unit = 35.43307d;
+ break;
+
+ case "in":
+ unit = 90;
+ break;
+
+ default:
+ end = stringLength;
}
- return value * unit * scale + offset;
+
+ return Double.valueOf(length.substring(0, end)) * unit * scale;
+ } else {
+ return Double.valueOf(length) * scale;
+ }
}
+ }
+ /**
+ * Converts SVGLength into px / user units in the current user coordinate system
+ *
+ * @param length length string
+ * @param relative relative size for percentages
+ * @param offset offset for all units
+ * @param scale scaling parameter
+ * @param fontSize current font size
+ * @return value in the current user coordinate system
+ */
+ static double fromRelative(
+ SVGLength length, double relative, double offset, double scale, double fontSize) {
+ /*
+ TODO list
+
+ unit relative to
+ em font size of the element
+ ex x-height of the element’s font
+ ch width of the "0" (ZERO, U+0030) glyph in the element’s font
+ rem font size of the root element
+ vw 1% of viewport’s width
+ vh 1% of viewport’s height
+ vmin 1% of viewport’s smaller dimension
+ vmax 1% of viewport’s larger dimension
+
+ relative-size [ larger | smaller ]
+ absolute-size: [ xx-small | x-small | small | medium | large | x-large | xx-large ]
+
+ https://www.w3.org/TR/css3-values/#relative-lengths
+ https://www.w3.org/TR/css3-values/#absolute-lengths
+ https://drafts.csswg.org/css-cascade-4/#computed-value
+ https://drafts.csswg.org/css-fonts-3/#propdef-font-size
+ https://drafts.csswg.org/css2/fonts.html#propdef-font-size
+ */
+ if (length == null) {
+ return offset;
+ }
+ SVGLength.UnitType unitType = length.unit;
+ double value = length.value;
+ double unit = 1;
+ switch (unitType) {
+ case NUMBER:
+ case PX:
+ break;
+
+ case PERCENTAGE:
+ return value / 100 * relative + offset;
+
+ case EMS:
+ unit = fontSize;
+ break;
+ case EXS:
+ unit = fontSize / 2;
+ break;
+
+ case CM:
+ unit = 35.43307;
+ break;
+ case MM:
+ unit = 3.543307;
+ break;
+ case IN:
+ unit = 90;
+ break;
+ case PT:
+ unit = 1.25;
+ break;
+ case PC:
+ unit = 15;
+ break;
+
+ default:
+ case UNKNOWN:
+ return value * scale + offset;
+ }
+ return value * unit * scale + offset;
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/RNSVGMarkerPosition.java b/android/src/main/java/com/horcrux/svg/RNSVGMarkerPosition.java
index 66cf1276..83ae08cd 100644
--- a/android/src/main/java/com/horcrux/svg/RNSVGMarkerPosition.java
+++ b/android/src/main/java/com/horcrux/svg/RNSVGMarkerPosition.java
@@ -3,178 +3,170 @@ package com.horcrux.svg;
import java.util.ArrayList;
enum RNSVGMarkerType {
- kStartMarker,
- kMidMarker,
- kEndMarker
+ kStartMarker,
+ kMidMarker,
+ kEndMarker
}
enum ElementType {
- kCGPathElementAddCurveToPoint,
- kCGPathElementAddQuadCurveToPoint,
- kCGPathElementMoveToPoint,
- kCGPathElementAddLineToPoint,
- kCGPathElementCloseSubpath
+ kCGPathElementAddCurveToPoint,
+ kCGPathElementAddQuadCurveToPoint,
+ kCGPathElementMoveToPoint,
+ kCGPathElementAddLineToPoint,
+ kCGPathElementCloseSubpath
}
class Point {
- double x;
- double y;
- Point(double x, double y){
- this.x = x;
- this.y = y;
- }
+ double x;
+ double y;
+
+ Point(double x, double y) {
+ this.x = x;
+ this.y = y;
+ }
}
class SegmentData {
- Point start_tangent; // Tangent in the start point of the segment.
- Point end_tangent; // Tangent in the end point of the segment.
- Point position; // The end point of the segment.
+ Point start_tangent; // Tangent in the start point of the segment.
+ Point end_tangent; // Tangent in the end point of the segment.
+ Point position; // The end point of the segment.
}
class RNSVGMarkerPosition {
- static private ArrayList positions_;
- static private int element_index_;
- static private Point origin_;
- static private Point subpath_start_;
- static private Point in_slope_;
- static private Point out_slope_;
- @SuppressWarnings("unused")
- static private boolean auto_start_reverse_; // TODO
+ private static ArrayList positions_;
+ private static int element_index_;
+ private static Point origin_;
+ private static Point subpath_start_;
+ private static Point in_slope_;
+ private static Point out_slope_;
- RNSVGMarkerType type;
- Point origin;
- double angle;
+ @SuppressWarnings("unused")
+ private static boolean auto_start_reverse_; // TODO
- private RNSVGMarkerPosition(RNSVGMarkerType type, Point origin, double angle) {
- this.type = type;
- this.origin = origin;
- this.angle = angle;
+ RNSVGMarkerType type;
+ Point origin;
+ double angle;
+
+ private RNSVGMarkerPosition(RNSVGMarkerType type, Point origin, double angle) {
+ this.type = type;
+ this.origin = origin;
+ this.angle = angle;
+ }
+
+ static ArrayList fromPath(ArrayList elements) {
+ positions_ = new ArrayList<>();
+ element_index_ = 0;
+ origin_ = new Point(0, 0);
+ subpath_start_ = new Point(0, 0);
+ for (PathElement e : elements) {
+ UpdateFromPathElement(e);
}
+ PathIsDone();
+ return positions_;
+ }
- static ArrayList fromPath(ArrayList elements) {
- positions_ = new ArrayList<>();
- element_index_ = 0;
- origin_ = new Point(0, 0);
- subpath_start_ = new Point(0, 0);
- for (PathElement e : elements) {
- UpdateFromPathElement(e);
- }
- PathIsDone();
- return positions_;
- }
+ private static void PathIsDone() {
+ double angle = CurrentAngle(RNSVGMarkerType.kEndMarker);
+ positions_.add(new RNSVGMarkerPosition(RNSVGMarkerType.kEndMarker, origin_, angle));
+ }
- private static void PathIsDone() {
- double angle = CurrentAngle(RNSVGMarkerType.kEndMarker);
- positions_.add(new RNSVGMarkerPosition(RNSVGMarkerType.kEndMarker, origin_, angle));
- }
+ private static double BisectingAngle(double in_angle, double out_angle) {
+ // WK193015: Prevent bugs due to angles being non-continuous.
+ if (Math.abs(in_angle - out_angle) > 180) in_angle += 360;
+ return (in_angle + out_angle) / 2;
+ }
- private static double BisectingAngle(double in_angle, double out_angle) {
- // WK193015: Prevent bugs due to angles being non-continuous.
- if (Math.abs(in_angle - out_angle) > 180)
- in_angle += 360;
- return (in_angle + out_angle) / 2;
- }
+ private static double rad2deg(double rad) {
+ double RNSVG_radToDeg = 180 / Math.PI;
+ return rad * RNSVG_radToDeg;
+ }
- private static double rad2deg(double rad) {
- double RNSVG_radToDeg = 180 / Math.PI;
- return rad * RNSVG_radToDeg;
- }
+ private static double SlopeAngleRadians(Point p) {
+ return Math.atan2(p.y, p.x);
+ }
- private static double SlopeAngleRadians(Point p) {
- return Math.atan2(p.y, p.x);
+ private static double CurrentAngle(RNSVGMarkerType type) {
+ // For details of this calculation, see:
+ // http://www.w3.org/TR/SVG/single-page.html#painting-MarkerElement
+ double in_angle = rad2deg(SlopeAngleRadians(in_slope_));
+ double out_angle = rad2deg(SlopeAngleRadians(out_slope_));
+ switch (type) {
+ case kStartMarker:
+ if (auto_start_reverse_) out_angle += 180;
+ return out_angle;
+ case kMidMarker:
+ return BisectingAngle(in_angle, out_angle);
+ case kEndMarker:
+ return in_angle;
}
+ return 0;
+ }
- private static double CurrentAngle(RNSVGMarkerType type) {
- // For details of this calculation, see:
- // http://www.w3.org/TR/SVG/single-page.html#painting-MarkerElement
- double in_angle = rad2deg(SlopeAngleRadians(in_slope_));
- double out_angle = rad2deg(SlopeAngleRadians(out_slope_));
- switch (type) {
- case kStartMarker:
- if (auto_start_reverse_)
- out_angle += 180;
- return out_angle;
- case kMidMarker:
- return BisectingAngle(in_angle, out_angle);
- case kEndMarker:
- return in_angle;
- }
- return 0;
- }
+ private static Point subtract(Point p1, Point p2) {
+ return new Point(p2.x - p1.x, p2.y - p1.y);
+ }
- private static Point subtract(Point p1, Point p2) {
- return new Point(p2.x - p1.x, p2.y - p1.y);
- }
+ private static boolean isZero(Point p) {
+ return p.x == 0 && p.y == 0;
+ }
- private static boolean isZero(Point p) {
- return p.x == 0 && p.y == 0;
- }
+ private static void ComputeQuadTangents(SegmentData data, Point start, Point control, Point end) {
+ data.start_tangent = subtract(control, start);
+ data.end_tangent = subtract(end, control);
+ if (isZero(data.start_tangent)) data.start_tangent = data.end_tangent;
+ else if (isZero(data.end_tangent)) data.end_tangent = data.start_tangent;
+ }
- private static void ComputeQuadTangents(SegmentData data,
- Point start,
- Point control,
- Point end) {
- data.start_tangent = subtract(control, start);
- data.end_tangent = subtract(end, control);
- if (isZero(data.start_tangent))
- data.start_tangent = data.end_tangent;
- else if (isZero(data.end_tangent))
- data.end_tangent = data.start_tangent;
+ private static SegmentData ExtractPathElementFeatures(PathElement element) {
+ SegmentData data = new SegmentData();
+ Point[] points = element.points;
+ switch (element.type) {
+ case kCGPathElementAddCurveToPoint:
+ data.position = points[2];
+ data.start_tangent = subtract(points[0], origin_);
+ data.end_tangent = subtract(points[2], points[1]);
+ if (isZero(data.start_tangent)) ComputeQuadTangents(data, points[0], points[1], points[2]);
+ else if (isZero(data.end_tangent)) ComputeQuadTangents(data, origin_, points[0], points[1]);
+ break;
+ case kCGPathElementAddQuadCurveToPoint:
+ data.position = points[1];
+ ComputeQuadTangents(data, origin_, points[0], points[1]);
+ break;
+ case kCGPathElementMoveToPoint:
+ case kCGPathElementAddLineToPoint:
+ data.position = points[0];
+ data.start_tangent = subtract(data.position, origin_);
+ data.end_tangent = subtract(data.position, origin_);
+ break;
+ case kCGPathElementCloseSubpath:
+ data.position = subpath_start_;
+ data.start_tangent = subtract(data.position, origin_);
+ data.end_tangent = subtract(data.position, origin_);
+ break;
}
+ return data;
+ }
- private static SegmentData ExtractPathElementFeatures(PathElement element) {
- SegmentData data = new SegmentData();
- Point[] points = element.points;
- switch (element.type) {
- case kCGPathElementAddCurveToPoint:
- data.position = points[2];
- data.start_tangent = subtract(points[0], origin_);
- data.end_tangent = subtract(points[2], points[1]);
- if (isZero(data.start_tangent))
- ComputeQuadTangents(data, points[0], points[1], points[2]);
- else if (isZero(data.end_tangent))
- ComputeQuadTangents(data, origin_, points[0], points[1]);
- break;
- case kCGPathElementAddQuadCurveToPoint:
- data.position = points[1];
- ComputeQuadTangents(data, origin_, points[0], points[1]);
- break;
- case kCGPathElementMoveToPoint:
- case kCGPathElementAddLineToPoint:
- data.position = points[0];
- data.start_tangent = subtract(data.position, origin_);
- data.end_tangent = subtract(data.position, origin_);
- break;
- case kCGPathElementCloseSubpath:
- data.position = subpath_start_;
- data.start_tangent = subtract(data.position, origin_);
- data.end_tangent = subtract(data.position, origin_);
- break;
- }
- return data;
- }
-
- private static void UpdateFromPathElement(PathElement element) {
- SegmentData segment_data = ExtractPathElementFeatures(element);
- // First update the outgoing slope for the previous element.
- out_slope_ = segment_data.start_tangent;
- // Record the marker for the previous element.
- if (element_index_ > 0) {
- RNSVGMarkerType marker_type =
- element_index_ == 1 ? RNSVGMarkerType.kStartMarker : RNSVGMarkerType.kMidMarker;
- double angle = CurrentAngle(marker_type);
- positions_.add(new RNSVGMarkerPosition(marker_type, origin_, angle));
- }
- // Update the incoming slope for this marker position.
- in_slope_ = segment_data.end_tangent;
- // Update marker position.
- origin_ = segment_data.position;
- // If this is a 'move to' segment, save the point for use with 'close'.
- if (element.type == ElementType.kCGPathElementMoveToPoint)
- subpath_start_ = element.points[0];
- else if (element.type == ElementType.kCGPathElementCloseSubpath)
- subpath_start_ = new Point(0, 0);
- ++element_index_;
+ private static void UpdateFromPathElement(PathElement element) {
+ SegmentData segment_data = ExtractPathElementFeatures(element);
+ // First update the outgoing slope for the previous element.
+ out_slope_ = segment_data.start_tangent;
+ // Record the marker for the previous element.
+ if (element_index_ > 0) {
+ RNSVGMarkerType marker_type =
+ element_index_ == 1 ? RNSVGMarkerType.kStartMarker : RNSVGMarkerType.kMidMarker;
+ double angle = CurrentAngle(marker_type);
+ positions_.add(new RNSVGMarkerPosition(marker_type, origin_, angle));
}
+ // Update the incoming slope for this marker position.
+ in_slope_ = segment_data.end_tangent;
+ // Update marker position.
+ origin_ = segment_data.position;
+ // If this is a 'move to' segment, save the point for use with 'close'.
+ if (element.type == ElementType.kCGPathElementMoveToPoint) subpath_start_ = element.points[0];
+ else if (element.type == ElementType.kCGPathElementCloseSubpath)
+ subpath_start_ = new Point(0, 0);
+ ++element_index_;
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/RNSVGRenderableManager.java b/android/src/main/java/com/horcrux/svg/RNSVGRenderableManager.java
index 71856fd0..1d08408d 100644
--- a/android/src/main/java/com/horcrux/svg/RNSVGRenderableManager.java
+++ b/android/src/main/java/com/horcrux/svg/RNSVGRenderableManager.java
@@ -6,16 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
+import static com.facebook.react.common.StandardCharsets.UTF_8;
+
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.graphics.Region;
-
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
@@ -23,251 +23,247 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
-
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-
import javax.annotation.Nonnull;
-import static com.facebook.react.common.StandardCharsets.UTF_8;
-
class RNSVGRenderableManager extends ReactContextBaseJavaModule {
- RNSVGRenderableManager(ReactApplicationContext reactContext) {
- super(reactContext);
+ RNSVGRenderableManager(ReactApplicationContext reactContext) {
+ super(reactContext);
+ }
+
+ @Nonnull
+ @Override
+ public String getName() {
+ return "RNSVGRenderableManager";
+ }
+
+ @SuppressWarnings("unused")
+ @ReactMethod(isBlockingSynchronousMethod = true)
+ public boolean isPointInFill(int tag, ReadableMap options) {
+ RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
+ if (svg == null) {
+ return false;
}
- @Nonnull
- @Override
- public String getName() {
- return "RNSVGRenderableManager";
+ float scale = svg.mScale;
+ float x = (float) options.getDouble("x") * scale;
+ float y = (float) options.getDouble("y") * scale;
+
+ int i = svg.hitTest(new float[] {x, y});
+ return i != -1;
+ }
+
+ @SuppressWarnings("unused")
+ @ReactMethod(isBlockingSynchronousMethod = true)
+ public boolean isPointInStroke(int tag, ReadableMap options) {
+ RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
+ if (svg == null) {
+ return false;
}
- @SuppressWarnings("unused")
- @ReactMethod(isBlockingSynchronousMethod = true)
- public boolean isPointInFill(int tag, ReadableMap options) {
- RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
- if (svg == null) {
- return false;
+ try {
+ svg.getPath(null, null);
+ } catch (NullPointerException e) {
+ svg.invalidate();
+ return false;
+ }
+
+ svg.initBounds();
+
+ float scale = svg.mScale;
+ int x = (int) (options.getDouble("x") * scale);
+ int y = (int) (options.getDouble("y") * scale);
+
+ Region strokeRegion = svg.mStrokeRegion;
+ return strokeRegion != null && strokeRegion.contains(x, y);
+ }
+
+ @SuppressWarnings("unused")
+ @ReactMethod(isBlockingSynchronousMethod = true)
+ public float getTotalLength(int tag) {
+ RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
+ if (svg == null) {
+ return 0;
+ }
+
+ Path path;
+
+ try {
+ path = svg.getPath(null, null);
+ } catch (NullPointerException e) {
+ svg.invalidate();
+ return -1;
+ }
+
+ PathMeasure pm = new PathMeasure(path, false);
+ return pm.getLength() / svg.mScale;
+ }
+
+ @SuppressWarnings("unused")
+ @ReactMethod(isBlockingSynchronousMethod = true)
+ public WritableMap getPointAtLength(int tag, ReadableMap options) {
+ RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
+ if (svg == null) {
+ return Arguments.createMap();
+ }
+
+ Path path;
+
+ try {
+ path = svg.getPath(null, null);
+ } catch (NullPointerException e) {
+ svg.invalidate();
+ return Arguments.createMap();
+ }
+
+ PathMeasure pm = new PathMeasure(path, false);
+ float length = (float) options.getDouble("length");
+ float scale = svg.mScale;
+
+ float[] pos = new float[2];
+ float[] tan = new float[2];
+ float distance = Math.max(0, Math.min(length, pm.getLength()));
+ pm.getPosTan(distance, pos, tan);
+
+ double angle = Math.atan2(tan[1], tan[0]);
+ WritableMap result = Arguments.createMap();
+ result.putDouble("x", pos[0] / scale);
+ result.putDouble("y", pos[1] / scale);
+ result.putDouble("angle", angle);
+ return result;
+ }
+
+ @SuppressWarnings("unused")
+ @ReactMethod(isBlockingSynchronousMethod = true)
+ public WritableMap getBBox(int tag, ReadableMap options) {
+ RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
+ if (svg == null) {
+ return Arguments.createMap();
+ }
+
+ boolean fill = options.getBoolean("fill");
+ boolean stroke = options.getBoolean("stroke");
+ boolean markers = options.getBoolean("markers");
+ boolean clipped = options.getBoolean("clipped");
+
+ try {
+ svg.getPath(null, null);
+ } catch (NullPointerException e) {
+ svg.invalidate();
+ return Arguments.createMap();
+ }
+
+ float scale = svg.mScale;
+ svg.initBounds();
+
+ RectF bounds = new RectF();
+ RectF fillBounds = svg.mFillBounds;
+ RectF strokeBounds = svg.mStrokeBounds;
+ RectF markerBounds = svg.mMarkerBounds;
+ RectF clipBounds = svg.mClipBounds;
+
+ if (fill && fillBounds != null) {
+ bounds.union(fillBounds);
+ }
+ if (stroke && strokeBounds != null) {
+ bounds.union(strokeBounds);
+ }
+ if (markers && markerBounds != null) {
+ bounds.union(markerBounds);
+ }
+ if (clipped && clipBounds != null) {
+ bounds.intersect(clipBounds);
+ }
+
+ WritableMap result = Arguments.createMap();
+ result.putDouble("x", bounds.left / scale);
+ result.putDouble("y", bounds.top / scale);
+ result.putDouble("width", bounds.width() / scale);
+ result.putDouble("height", bounds.height() / scale);
+ return result;
+ }
+
+ @SuppressWarnings("unused")
+ @ReactMethod(isBlockingSynchronousMethod = true)
+ public WritableMap getCTM(int tag) {
+ RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
+ if (svg == null) {
+ return Arguments.createMap();
+ }
+
+ float scale = svg.mScale;
+ Matrix ctm = new Matrix(svg.mCTM);
+ Matrix invViewBoxMatrix = svg.getSvgView().mInvViewBoxMatrix;
+ ctm.preConcat(invViewBoxMatrix);
+
+ float[] values = new float[9];
+ ctm.getValues(values);
+
+ WritableMap result = Arguments.createMap();
+ result.putDouble("a", values[Matrix.MSCALE_X]);
+ result.putDouble("b", values[Matrix.MSKEW_Y]);
+ result.putDouble("c", values[Matrix.MSKEW_X]);
+ result.putDouble("d", values[Matrix.MSCALE_Y]);
+ result.putDouble("e", values[Matrix.MTRANS_X] / scale);
+ result.putDouble("f", values[Matrix.MTRANS_Y] / scale);
+ return result;
+ }
+
+ @SuppressWarnings("unused")
+ @ReactMethod(isBlockingSynchronousMethod = true)
+ public WritableMap getScreenCTM(int tag) {
+ RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
+ if (svg == null) {
+ return Arguments.createMap();
+ }
+
+ float[] values = new float[9];
+ svg.mCTM.getValues(values);
+ float scale = svg.mScale;
+
+ WritableMap result = Arguments.createMap();
+ result.putDouble("a", values[Matrix.MSCALE_X]);
+ result.putDouble("b", values[Matrix.MSKEW_Y]);
+ result.putDouble("c", values[Matrix.MSKEW_X]);
+ result.putDouble("d", values[Matrix.MSCALE_Y]);
+ result.putDouble("e", values[Matrix.MTRANS_X] / scale);
+ result.putDouble("f", values[Matrix.MTRANS_Y] / scale);
+ return result;
+ }
+
+ @ReactMethod
+ public void getRawResource(String name, Promise promise) {
+ try {
+ ReactApplicationContext context = getReactApplicationContext();
+ Resources resources = context.getResources();
+ String packageName = context.getPackageName();
+ int id = resources.getIdentifier(name, "raw", packageName);
+ InputStream stream = resources.openRawResource(id);
+ try {
+ InputStreamReader reader = new InputStreamReader(stream, UTF_8);
+ char[] buffer = new char[DEFAULT_BUFFER_SIZE];
+ StringBuilder builder = new StringBuilder();
+ int n;
+ while ((n = reader.read(buffer, 0, DEFAULT_BUFFER_SIZE)) != EOF) {
+ builder.append(buffer, 0, n);
}
-
- float scale = svg.mScale;
- float x = (float) options.getDouble("x") * scale;
- float y = (float) options.getDouble("y") * scale;
-
- int i = svg.hitTest(new float[]{x, y});
- return i != -1;
- }
-
- @SuppressWarnings("unused")
- @ReactMethod(isBlockingSynchronousMethod = true)
- public boolean isPointInStroke(int tag, ReadableMap options) {
- RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
- if (svg == null) {
- return false;
- }
-
+ String result = builder.toString();
+ promise.resolve(result);
+ } finally {
try {
- svg.getPath(null, null);
- } catch (NullPointerException e) {
- svg.invalidate();
- return false;
+ stream.close();
+ } catch (IOException ioe) {
+ // ignore
}
-
- svg.initBounds();
-
- float scale = svg.mScale;
- int x = (int) (options.getDouble("x") * scale);
- int y = (int) (options.getDouble("y") * scale);
-
- Region strokeRegion = svg.mStrokeRegion;
- return strokeRegion != null && strokeRegion.contains(x, y);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ promise.reject(e);
}
+ }
- @SuppressWarnings("unused")
- @ReactMethod(isBlockingSynchronousMethod = true)
- public float getTotalLength(int tag) {
- RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
- if (svg == null) {
- return 0;
- }
-
- Path path;
-
- try {
- path = svg.getPath(null, null);
- } catch (NullPointerException e) {
- svg.invalidate();
- return -1;
- }
-
- PathMeasure pm = new PathMeasure(path, false);
- return pm.getLength() / svg.mScale;
- }
-
- @SuppressWarnings("unused")
- @ReactMethod(isBlockingSynchronousMethod = true)
- public WritableMap getPointAtLength(int tag, ReadableMap options) {
- RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
- if (svg == null) {
- return Arguments.createMap();
- }
-
- Path path;
-
- try {
- path = svg.getPath(null, null);
- } catch (NullPointerException e) {
- svg.invalidate();
- return Arguments.createMap();
- }
-
- PathMeasure pm = new PathMeasure(path, false);
- float length = (float) options.getDouble("length");
- float scale = svg.mScale;
-
- float[] pos = new float[2];
- float[] tan = new float[2];
- float distance = Math.max(0, Math.min(length, pm.getLength()));
- pm.getPosTan(distance, pos, tan);
-
- double angle = Math.atan2(tan[1], tan[0]);
- WritableMap result = Arguments.createMap();
- result.putDouble("x", pos[0] / scale);
- result.putDouble("y", pos[1] / scale);
- result.putDouble("angle", angle);
- return result;
- }
-
- @SuppressWarnings("unused")
- @ReactMethod(isBlockingSynchronousMethod = true)
- public WritableMap getBBox(int tag, ReadableMap options) {
- RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
- if (svg == null) {
- return Arguments.createMap();
- }
-
- boolean fill = options.getBoolean("fill");
- boolean stroke = options.getBoolean("stroke");
- boolean markers = options.getBoolean("markers");
- boolean clipped = options.getBoolean("clipped");
-
- try {
- svg.getPath(null, null);
- } catch (NullPointerException e) {
- svg.invalidate();
- return Arguments.createMap();
- }
-
- float scale = svg.mScale;
- svg.initBounds();
-
- RectF bounds = new RectF();
- RectF fillBounds = svg.mFillBounds;
- RectF strokeBounds = svg.mStrokeBounds;
- RectF markerBounds = svg.mMarkerBounds;
- RectF clipBounds = svg.mClipBounds;
-
- if (fill && fillBounds != null) {
- bounds.union(fillBounds);
- }
- if (stroke && strokeBounds != null) {
- bounds.union(strokeBounds);
- }
- if (markers && markerBounds != null) {
- bounds.union(markerBounds);
- }
- if (clipped && clipBounds != null) {
- bounds.intersect(clipBounds);
- }
-
- WritableMap result = Arguments.createMap();
- result.putDouble("x", bounds.left / scale);
- result.putDouble("y", bounds.top / scale);
- result.putDouble("width", bounds.width() / scale);
- result.putDouble("height", bounds.height() / scale);
- return result;
- }
-
- @SuppressWarnings("unused")
- @ReactMethod(isBlockingSynchronousMethod = true)
- public WritableMap getCTM(int tag) {
- RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
- if (svg == null) {
- return Arguments.createMap();
- }
-
- float scale = svg.mScale;
- Matrix ctm = new Matrix(svg.mCTM);
- Matrix invViewBoxMatrix = svg.getSvgView().mInvViewBoxMatrix;
- ctm.preConcat(invViewBoxMatrix);
-
- float[] values = new float[9];
- ctm.getValues(values);
-
- WritableMap result = Arguments.createMap();
- result.putDouble("a", values[Matrix.MSCALE_X]);
- result.putDouble("b", values[Matrix.MSKEW_Y]);
- result.putDouble("c", values[Matrix.MSKEW_X]);
- result.putDouble("d", values[Matrix.MSCALE_Y]);
- result.putDouble("e", values[Matrix.MTRANS_X] / scale);
- result.putDouble("f", values[Matrix.MTRANS_Y] / scale);
- return result;
- }
-
- @SuppressWarnings("unused")
- @ReactMethod(isBlockingSynchronousMethod = true)
- public WritableMap getScreenCTM(int tag) {
- RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
- if (svg == null) {
- return Arguments.createMap();
- }
-
- float[] values = new float[9];
- svg.mCTM.getValues(values);
- float scale = svg.mScale;
-
- WritableMap result = Arguments.createMap();
- result.putDouble("a", values[Matrix.MSCALE_X]);
- result.putDouble("b", values[Matrix.MSKEW_Y]);
- result.putDouble("c", values[Matrix.MSKEW_X]);
- result.putDouble("d", values[Matrix.MSCALE_Y]);
- result.putDouble("e", values[Matrix.MTRANS_X] / scale);
- result.putDouble("f", values[Matrix.MTRANS_Y] / scale);
- return result;
- }
-
- @ReactMethod
- public void getRawResource(String name, Promise promise) {
- try {
- ReactApplicationContext context = getReactApplicationContext();
- Resources resources = context.getResources();
- String packageName = context.getPackageName();
- int id = resources.getIdentifier(name, "raw", packageName);
- InputStream stream = resources.openRawResource(id);
- try {
- InputStreamReader reader = new InputStreamReader(stream, UTF_8);
- char[] buffer = new char[DEFAULT_BUFFER_SIZE];
- StringBuilder builder = new StringBuilder();
- int n;
- while ((n = reader.read(buffer, 0, DEFAULT_BUFFER_SIZE)) != EOF) {
- builder.append(buffer, 0, n);
- }
- String result = builder.toString();
- promise.resolve(result);
- } finally {
- try {
- stream.close();
- } catch (IOException ioe) {
- // ignore
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- promise.reject(e);
- }
- }
-
- private static final int EOF = -1;
- private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+ private static final int EOF = -1;
+ private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
}
diff --git a/android/src/main/java/com/horcrux/svg/RadialGradientView.java b/android/src/main/java/com/horcrux/svg/RadialGradientView.java
index ac6cbb0a..ae20fa39 100644
--- a/android/src/main/java/com/horcrux/svg/RadialGradientView.java
+++ b/android/src/main/java/com/horcrux/svg/RadialGradientView.java
@@ -6,163 +6,161 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
-
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
-
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
class RadialGradientView extends DefinitionView {
- private SVGLength mFx;
- private SVGLength mFy;
- private SVGLength mRx;
- private SVGLength mRy;
- private SVGLength mCx;
- private SVGLength mCy;
- private ReadableArray mGradient;
- private Brush.BrushUnits mGradientUnits;
+ private SVGLength mFx;
+ private SVGLength mFy;
+ private SVGLength mRx;
+ private SVGLength mRy;
+ private SVGLength mCx;
+ private SVGLength mCy;
+ private ReadableArray mGradient;
+ private Brush.BrushUnits mGradientUnits;
- private static final float[] sRawMatrix = new float[]{
+ private static final float[] sRawMatrix =
+ new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1
- };
- private Matrix mMatrix = null;
+ };
+ private Matrix mMatrix = null;
- public RadialGradientView(ReactContext reactContext) {
- super(reactContext);
- }
+ public RadialGradientView(ReactContext reactContext) {
+ super(reactContext);
+ }
- @ReactProp(name = "fx")
- public void setFx(Dynamic fx) {
- mFx = SVGLength.from(fx);
- invalidate();
- }
+ @ReactProp(name = "fx")
+ public void setFx(Dynamic fx) {
+ mFx = SVGLength.from(fx);
+ invalidate();
+ }
public void setFx(String fx) {
mFx = SVGLength.from(fx);
invalidate();
}
- @ReactProp(name = "fy")
- public void setFy(Dynamic fy) {
- mFy = SVGLength.from(fy);
- invalidate();
- }
+ @ReactProp(name = "fy")
+ public void setFy(Dynamic fy) {
+ mFy = SVGLength.from(fy);
+ invalidate();
+ }
public void setFy(String fy) {
mFy = SVGLength.from(fy);
invalidate();
}
- @ReactProp(name = "rx")
- public void setRx(Dynamic rx) {
- mRx = SVGLength.from(rx);
- invalidate();
- }
+ @ReactProp(name = "rx")
+ public void setRx(Dynamic rx) {
+ mRx = SVGLength.from(rx);
+ invalidate();
+ }
public void setRx(String rx) {
mRx = SVGLength.from(rx);
invalidate();
}
- @ReactProp(name = "ry")
- public void setRy(Dynamic ry) {
- mRy = SVGLength.from(ry);
- invalidate();
- }
+ @ReactProp(name = "ry")
+ public void setRy(Dynamic ry) {
+ mRy = SVGLength.from(ry);
+ invalidate();
+ }
public void setRy(String ry) {
mRy = SVGLength.from(ry);
invalidate();
}
- @ReactProp(name = "cx")
- public void setCx(Dynamic cx) {
- mCx = SVGLength.from(cx);
- invalidate();
- }
+ @ReactProp(name = "cx")
+ public void setCx(Dynamic cx) {
+ mCx = SVGLength.from(cx);
+ invalidate();
+ }
public void setCx(String cx) {
mCx = SVGLength.from(cx);
invalidate();
}
- @ReactProp(name = "cy")
- public void setCy(Dynamic cy) {
- mCy = SVGLength.from(cy);
- invalidate();
- }
+ @ReactProp(name = "cy")
+ public void setCy(Dynamic cy) {
+ mCy = SVGLength.from(cy);
+ invalidate();
+ }
public void setCy(String cy) {
mCy = SVGLength.from(cy);
invalidate();
}
- @ReactProp(name = "gradient")
- public void setGradient(ReadableArray gradient) {
- mGradient = gradient;
- invalidate();
- }
+ @ReactProp(name = "gradient")
+ public void setGradient(ReadableArray gradient) {
+ mGradient = gradient;
+ invalidate();
+ }
- @ReactProp(name = "gradientUnits")
- public void setGradientUnits(int gradientUnits) {
- switch (gradientUnits) {
- case 0:
- mGradientUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
- break;
- case 1:
- mGradientUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
- break;
+ @ReactProp(name = "gradientUnits")
+ public void setGradientUnits(int gradientUnits) {
+ switch (gradientUnits) {
+ case 0:
+ mGradientUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
+ break;
+ case 1:
+ mGradientUnits = Brush.BrushUnits.USER_SPACE_ON_USE;
+ break;
+ }
+ invalidate();
+ }
+
+ @ReactProp(name = "gradientTransform")
+ public void setGradientTransform(@Nullable ReadableArray matrixArray) {
+ if (matrixArray != null) {
+ int matrixSize = PropHelper.toMatrixData(matrixArray, sRawMatrix, mScale);
+ if (matrixSize == 6) {
+ if (mMatrix == null) {
+ mMatrix = new Matrix();
}
- invalidate();
+ mMatrix.setValues(sRawMatrix);
+ } else if (matrixSize != -1) {
+ FLog.w(ReactConstants.TAG, "RNSVG: Transform matrices must be of size 6");
+ }
+ } else {
+ mMatrix = null;
}
- @ReactProp(name = "gradientTransform")
- public void setGradientTransform(@Nullable ReadableArray matrixArray) {
- if (matrixArray != null) {
- int matrixSize = PropHelper.toMatrixData(matrixArray, sRawMatrix, mScale);
- if (matrixSize == 6) {
- if (mMatrix == null) {
- mMatrix = new Matrix();
- }
- mMatrix.setValues(sRawMatrix);
- } else if (matrixSize != -1) {
- FLog.w(ReactConstants.TAG, "RNSVG: Transform matrices must be of size 6");
- }
- } else {
- mMatrix = null;
- }
+ invalidate();
+ }
- invalidate();
- }
-
- @Override
- void saveDefinition() {
- if (mName != null) {
- SVGLength[] points = new SVGLength[]{mFx,mFy,mRx,mRy,mCx,mCy};
- Brush brush = new Brush(Brush.BrushType.RADIAL_GRADIENT, points, mGradientUnits);
- brush.setGradientColors(mGradient);
- if (mMatrix != null) {
- brush.setGradientTransform(mMatrix);
- }
-
- SvgView svg = getSvgView();
- if (mGradientUnits == Brush.BrushUnits.USER_SPACE_ON_USE) {
- brush.setUserSpaceBoundingBox(svg.getCanvasBounds());
- }
-
- svg.defineBrush(brush, mName);
- }
+ @Override
+ void saveDefinition() {
+ if (mName != null) {
+ SVGLength[] points = new SVGLength[] {mFx, mFy, mRx, mRy, mCx, mCy};
+ Brush brush = new Brush(Brush.BrushType.RADIAL_GRADIENT, points, mGradientUnits);
+ brush.setGradientColors(mGradient);
+ if (mMatrix != null) {
+ brush.setGradientTransform(mMatrix);
+ }
+
+ SvgView svg = getSvgView();
+ if (mGradientUnits == Brush.BrushUnits.USER_SPACE_ON_USE) {
+ brush.setUserSpaceBoundingBox(svg.getCanvasBounds());
+ }
+
+ svg.defineBrush(brush, mName);
}
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/RectView.java b/android/src/main/java/com/horcrux/svg/RectView.java
index 0de262ff..e57169aa 100644
--- a/android/src/main/java/com/horcrux/svg/RectView.java
+++ b/android/src/main/java/com/horcrux/svg/RectView.java
@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -15,128 +14,139 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Build;
-
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@SuppressLint("ViewConstructor")
class RectView extends RenderableView {
- private SVGLength mX;
- private SVGLength mY;
- private SVGLength mW;
- private SVGLength mH;
- private SVGLength mRx;
- private SVGLength mRy;
+ private SVGLength mX;
+ private SVGLength mY;
+ private SVGLength mW;
+ private SVGLength mH;
+ private SVGLength mRx;
+ private SVGLength mRy;
- public RectView(ReactContext reactContext) {
- super(reactContext);
- }
+ public RectView(ReactContext reactContext) {
+ super(reactContext);
+ }
- @ReactProp(name = "x")
- public void setX(Dynamic x) {
- mX = SVGLength.from(x);
- invalidate();
- }
+ @ReactProp(name = "x")
+ public void setX(Dynamic x) {
+ mX = SVGLength.from(x);
+ invalidate();
+ }
public void setX(String x) {
mX = SVGLength.from(x);
invalidate();
}
- @ReactProp(name = "y")
- public void setY(Dynamic y) {
- mY = SVGLength.from(y);
- invalidate();
- }
+ @ReactProp(name = "y")
+ public void setY(Dynamic y) {
+ mY = SVGLength.from(y);
+ invalidate();
+ }
public void setY(String y) {
mY = SVGLength.from(y);
invalidate();
}
- @ReactProp(name = "width")
- public void setWidth(Dynamic width) {
- mW = SVGLength.from(width);
- invalidate();
- }
+ @ReactProp(name = "width")
+ public void setWidth(Dynamic width) {
+ mW = SVGLength.from(width);
+ invalidate();
+ }
public void setWidth(String width) {
mW = SVGLength.from(width);
invalidate();
}
- @ReactProp(name = "height")
- public void setHeight(Dynamic height) {
- mH = SVGLength.from(height);
- invalidate();
- }
+ @ReactProp(name = "height")
+ public void setHeight(Dynamic height) {
+ mH = SVGLength.from(height);
+ invalidate();
+ }
public void setHeight(String height) {
mH = SVGLength.from(height);
invalidate();
}
- @ReactProp(name = "rx")
- public void setRx(Dynamic rx) {
- mRx = SVGLength.from(rx);
- invalidate();
- }
+ @ReactProp(name = "rx")
+ public void setRx(Dynamic rx) {
+ mRx = SVGLength.from(rx);
+ invalidate();
+ }
public void setRx(String rx) {
mRx = SVGLength.from(rx);
invalidate();
}
- @ReactProp(name = "ry")
- public void setRy(Dynamic ry) {
- mRy = SVGLength.from(ry);
- invalidate();
- }
+ @ReactProp(name = "ry")
+ public void setRy(Dynamic ry) {
+ mRy = SVGLength.from(ry);
+ invalidate();
+ }
public void setRy(String ry) {
mRy = SVGLength.from(ry);
invalidate();
}
- @Override
- Path getPath(Canvas canvas, Paint paint) {
- Path path = new Path();
- double x = relativeOnWidth(mX);
- double y = relativeOnHeight(mY);
- double w = relativeOnWidth(mW);
- double h = relativeOnHeight(mH);
+ @Override
+ Path getPath(Canvas canvas, Paint paint) {
+ Path path = new Path();
+ double x = relativeOnWidth(mX);
+ double y = relativeOnHeight(mY);
+ double w = relativeOnWidth(mW);
+ double h = relativeOnHeight(mH);
- if (mRx != null || mRy != null) {
- double rx = 0d;
- double ry = 0d;
- if (mRx == null) {
- ry = relativeOnHeight(mRy);
- rx = ry;
- } else if (mRy == null) {
- rx = relativeOnWidth(mRx);
- ry = rx;
- } else {
- rx = relativeOnWidth(mRx);
- ry = relativeOnHeight(mRy);
- }
+ if (mRx != null || mRy != null) {
+ double rx = 0d;
+ double ry = 0d;
+ if (mRx == null) {
+ ry = relativeOnHeight(mRy);
+ rx = ry;
+ } else if (mRy == null) {
+ rx = relativeOnWidth(mRx);
+ ry = rx;
+ } else {
+ rx = relativeOnWidth(mRx);
+ ry = relativeOnHeight(mRy);
+ }
- if (rx > w / 2) {
- rx = w / 2;
- }
+ if (rx > w / 2) {
+ rx = w / 2;
+ }
- if (ry > h / 2) {
- ry = h / 2;
- }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- path.addRoundRect((float) x, (float) y, (float) (x + w), (float) (y + h), (float) rx, (float) ry, Path.Direction.CW);
- } else {
- path.addRoundRect(new RectF((float) x, (float) y, (float) (x + w), (float) (y + h)), (float) rx, (float) ry, Path.Direction.CW);
- }
- } else {
- path.addRect((float) x, (float) y, (float) (x + w), (float) (y + h), Path.Direction.CW);
- path.close(); // Ensure isSimplePath = false such that rect doesn't become represented using integers
- }
- return path;
+ if (ry > h / 2) {
+ ry = h / 2;
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ path.addRoundRect(
+ (float) x,
+ (float) y,
+ (float) (x + w),
+ (float) (y + h),
+ (float) rx,
+ (float) ry,
+ Path.Direction.CW);
+ } else {
+ path.addRoundRect(
+ new RectF((float) x, (float) y, (float) (x + w), (float) (y + h)),
+ (float) rx,
+ (float) ry,
+ Path.Direction.CW);
+ }
+ } else {
+ path.addRect((float) x, (float) y, (float) (x + w), (float) (y + h), Path.Direction.CW);
+ path.close(); // Ensure isSimplePath = false such that rect doesn't become represented using
+ // integers
}
+ return path;
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/RenderableView.java b/android/src/main/java/com/horcrux/svg/RenderableView.java
index edfb788b..11d8e381 100644
--- a/android/src/main/java/com/horcrux/svg/RenderableView.java
+++ b/android/src/main/java/com/horcrux/svg/RenderableView.java
@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
import android.graphics.Bitmap;
@@ -20,7 +19,7 @@ import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
-
+import com.facebook.react.bridge.ColorPropConverter;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.JavaOnlyArray;
@@ -28,122 +27,118 @@ import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
-import com.facebook.react.bridge.ColorPropConverter;
import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.annotations.ReactProp;
-
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-
import javax.annotation.Nullable;
@SuppressWarnings({"WeakerAccess", "RedundantSuppression"})
-abstract public class RenderableView extends VirtualView {
+public abstract class RenderableView extends VirtualView {
- RenderableView(ReactContext reactContext) {
- super(reactContext);
- setPivotX(0);
- setPivotY(0);
+ RenderableView(ReactContext reactContext) {
+ super(reactContext);
+ setPivotX(0);
+ setPivotY(0);
+ }
+
+ static RenderableView contextElement;
+ // strokeLinecap
+ private static final int CAP_BUTT = 0;
+ static final int CAP_ROUND = 1;
+ private static final int CAP_SQUARE = 2;
+
+ // strokeLinejoin
+ private static final int JOIN_BEVEL = 2;
+ private static final int JOIN_MITER = 0;
+ static final int JOIN_ROUND = 1;
+
+ // fillRule
+ private static final int FILL_RULE_EVENODD = 0;
+ static final int FILL_RULE_NONZERO = 1;
+
+ // vectorEffect
+ private static final int VECTOR_EFFECT_DEFAULT = 0;
+ private static final int VECTOR_EFFECT_NON_SCALING_STROKE = 1;
+ // static final int VECTOR_EFFECT_INHERIT = 2;
+ // static final int VECTOR_EFFECT_URI = 3;
+
+ /*
+ Used in mergeProperties, keep public
+ */
+
+ public int vectorEffect = VECTOR_EFFECT_DEFAULT;
+ public @Nullable ReadableArray stroke;
+ public @Nullable SVGLength[] strokeDasharray;
+
+ public SVGLength strokeWidth = new SVGLength(1);
+ public float strokeOpacity = 1;
+ public float strokeMiterlimit = 4;
+ public float strokeDashoffset = 0;
+
+ public Paint.Cap strokeLinecap = Paint.Cap.BUTT;
+ public Paint.Join strokeLinejoin = Paint.Join.MITER;
+
+ public @Nullable ReadableArray fill;
+ public float fillOpacity = 1;
+ public Path.FillType fillRule = Path.FillType.WINDING;
+
+ /*
+ End merged properties
+ */
+ private @Nullable ArrayList mLastMergedList;
+ private @Nullable ArrayList mOriginProperties;
+ private @Nullable ArrayList mPropList;
+ private @Nullable ArrayList mAttributeList;
+
+ private static final Pattern regex = Pattern.compile("[0-9.-]+");
+
+ @Override
+ public void setId(int id) {
+ super.setId(id);
+ RenderableViewManager.setRenderableView(id, this);
+ }
+
+ @ReactProp(name = "vectorEffect")
+ public void setVectorEffect(int vectorEffect) {
+ this.vectorEffect = vectorEffect;
+ invalidate();
+ }
+
+ @ReactProp(name = "fill")
+ public void setFill(@Nullable Dynamic fill) {
+ if (fill == null || fill.isNull()) {
+ this.fill = null;
+ invalidate();
+ return;
}
- static RenderableView contextElement;
- // strokeLinecap
- private static final int CAP_BUTT = 0;
- static final int CAP_ROUND = 1;
- private static final int CAP_SQUARE = 2;
-
- // strokeLinejoin
- private static final int JOIN_BEVEL = 2;
- private static final int JOIN_MITER = 0;
- static final int JOIN_ROUND = 1;
-
- // fillRule
- private static final int FILL_RULE_EVENODD = 0;
- static final int FILL_RULE_NONZERO = 1;
-
- // vectorEffect
- private static final int VECTOR_EFFECT_DEFAULT = 0;
- private static final int VECTOR_EFFECT_NON_SCALING_STROKE = 1;
- //static final int VECTOR_EFFECT_INHERIT = 2;
- //static final int VECTOR_EFFECT_URI = 3;
-
- /*
- Used in mergeProperties, keep public
- */
-
- public int vectorEffect = VECTOR_EFFECT_DEFAULT;
- public @Nullable ReadableArray stroke;
- public @Nullable SVGLength[] strokeDasharray;
-
- public SVGLength strokeWidth = new SVGLength(1);
- public float strokeOpacity = 1;
- public float strokeMiterlimit = 4;
- public float strokeDashoffset = 0;
-
- public Paint.Cap strokeLinecap = Paint.Cap.BUTT;
- public Paint.Join strokeLinejoin = Paint.Join.MITER;
-
- public @Nullable ReadableArray fill;
- public float fillOpacity = 1;
- public Path.FillType fillRule = Path.FillType.WINDING;
-
- /*
- End merged properties
- */
- private @Nullable ArrayList mLastMergedList;
- private @Nullable ArrayList mOriginProperties;
- private @Nullable ArrayList mPropList;
- private @Nullable ArrayList mAttributeList;
-
- private static final Pattern regex = Pattern.compile("[0-9.-]+");
-
- @Override
- public void setId(int id) {
- super.setId(id);
- RenderableViewManager.setRenderableView(id, this);
+ ReadableType fillType = fill.getType();
+ if (fillType.equals(ReadableType.Map)) {
+ ReadableMap fillMap = fill.asMap();
+ setFill(fillMap);
}
- @ReactProp(name = "vectorEffect")
- public void setVectorEffect(int vectorEffect) {
- this.vectorEffect = vectorEffect;
- invalidate();
- }
-
- @ReactProp(name = "fill")
- public void setFill(@Nullable Dynamic fill) {
- if (fill == null || fill.isNull()) {
- this.fill = null;
- invalidate();
- return;
- }
-
- ReadableType fillType = fill.getType();
- if (fillType.equals(ReadableType.Map)) {
- ReadableMap fillMap = fill.asMap();
- setFill(fillMap);
- }
-
-
- // This code will probably never be reached with current changes
- if (fillType.equals(ReadableType.Number)) {
- this.fill = JavaOnlyArray.of(0, fill.asInt());
- } else if (fillType.equals(ReadableType.Array)) {
- this.fill = fill.asArray();
- } else {
- JavaOnlyArray arr = new JavaOnlyArray();
- arr.pushInt(0);
- Matcher m = regex.matcher(fill.asString());
- int i = 0;
- while (m.find()) {
- double parsed = Double.parseDouble(m.group());
- arr.pushDouble(i++ < 3 ? parsed / 255 : parsed);
- }
- this.fill = arr;
- }
- invalidate();
+ // This code will probably never be reached with current changes
+ if (fillType.equals(ReadableType.Number)) {
+ this.fill = JavaOnlyArray.of(0, fill.asInt());
+ } else if (fillType.equals(ReadableType.Array)) {
+ this.fill = fill.asArray();
+ } else {
+ JavaOnlyArray arr = new JavaOnlyArray();
+ arr.pushInt(0);
+ Matcher m = regex.matcher(fill.asString());
+ int i = 0;
+ while (m.find()) {
+ double parsed = Double.parseDouble(m.group());
+ arr.pushDouble(i++ < 3 ? parsed / 255 : parsed);
+ }
+ this.fill = arr;
}
+ invalidate();
+ }
public void setFill(ReadableMap fill) {
if (fill == null) {
@@ -167,53 +162,52 @@ abstract public class RenderableView extends VirtualView {
invalidate();
}
- @ReactProp(name = "fillOpacity", defaultFloat = 1f)
- public void setFillOpacity(float fillOpacity) {
- this.fillOpacity = fillOpacity;
- invalidate();
+ @ReactProp(name = "fillOpacity", defaultFloat = 1f)
+ public void setFillOpacity(float fillOpacity) {
+ this.fillOpacity = fillOpacity;
+ invalidate();
+ }
+
+ @ReactProp(name = "fillRule", defaultInt = FILL_RULE_NONZERO)
+ public void setFillRule(int fillRule) {
+ switch (fillRule) {
+ case FILL_RULE_EVENODD:
+ this.fillRule = Path.FillType.EVEN_ODD;
+ break;
+ case FILL_RULE_NONZERO:
+ break;
+ default:
+ throw new JSApplicationIllegalArgumentException("fillRule " + fillRule + " unrecognized");
}
- @ReactProp(name = "fillRule", defaultInt = FILL_RULE_NONZERO)
- public void setFillRule(int fillRule) {
- switch (fillRule) {
- case FILL_RULE_EVENODD:
- this.fillRule = Path.FillType.EVEN_ODD;
- break;
- case FILL_RULE_NONZERO:
- break;
- default:
- throw new JSApplicationIllegalArgumentException(
- "fillRule " + fillRule + " unrecognized");
- }
+ invalidate();
+ }
- invalidate();
+ @ReactProp(name = "stroke")
+ public void setStroke(@Nullable Dynamic strokeColors) {
+ if (strokeColors == null || strokeColors.isNull()) {
+ stroke = null;
+ invalidate();
+ return;
}
-
- @ReactProp(name = "stroke")
- public void setStroke(@Nullable Dynamic strokeColors) {
- if (strokeColors == null || strokeColors.isNull()) {
- stroke = null;
- invalidate();
- return;
- }
- ReadableType type = strokeColors.getType();
- if (type.equals(ReadableType.Number)) {
- stroke = JavaOnlyArray.of(0, strokeColors.asInt());
- } else if (type.equals(ReadableType.Array)) {
- stroke = strokeColors.asArray();
- } else {
- JavaOnlyArray arr = new JavaOnlyArray();
- arr.pushInt(0);
- Matcher m = regex.matcher(strokeColors.asString());
- int i = 0;
- while (m.find()) {
- double parsed = Double.parseDouble(m.group());
- arr.pushDouble(i++ < 3 ? parsed / 255 : parsed);
- }
- stroke = arr;
- }
- invalidate();
+ ReadableType type = strokeColors.getType();
+ if (type.equals(ReadableType.Number)) {
+ stroke = JavaOnlyArray.of(0, strokeColors.asInt());
+ } else if (type.equals(ReadableType.Array)) {
+ stroke = strokeColors.asArray();
+ } else {
+ JavaOnlyArray arr = new JavaOnlyArray();
+ arr.pushInt(0);
+ Matcher m = regex.matcher(strokeColors.asString());
+ int i = 0;
+ while (m.find()) {
+ double parsed = Double.parseDouble(m.group());
+ arr.pushDouble(i++ < 3 ? parsed / 255 : parsed);
+ }
+ stroke = arr;
}
+ invalidate();
+ }
public void setStroke(@Nullable ReadableMap stroke) {
if (stroke == null) {
@@ -237,484 +231,485 @@ abstract public class RenderableView extends VirtualView {
invalidate();
}
- @ReactProp(name = "strokeOpacity", defaultFloat = 1f)
- public void setStrokeOpacity(float strokeOpacity) {
- this.strokeOpacity = strokeOpacity;
- invalidate();
- }
+ @ReactProp(name = "strokeOpacity", defaultFloat = 1f)
+ public void setStrokeOpacity(float strokeOpacity) {
+ this.strokeOpacity = strokeOpacity;
+ invalidate();
+ }
- @ReactProp(name = "strokeDasharray")
- public void setStrokeDasharray(@Nullable ReadableArray strokeDasharray) {
- if (strokeDasharray != null) {
- int fromSize = strokeDasharray.size();
- this.strokeDasharray = new SVGLength[fromSize];
- for (int i = 0; i < fromSize; i++) {
- this.strokeDasharray[i] = SVGLength.from(strokeDasharray.getDynamic(i));
- }
- } else {
- this.strokeDasharray = null;
- }
- invalidate();
+ @ReactProp(name = "strokeDasharray")
+ public void setStrokeDasharray(@Nullable ReadableArray strokeDasharray) {
+ if (strokeDasharray != null) {
+ int fromSize = strokeDasharray.size();
+ this.strokeDasharray = new SVGLength[fromSize];
+ for (int i = 0; i < fromSize; i++) {
+ this.strokeDasharray[i] = SVGLength.from(strokeDasharray.getDynamic(i));
+ }
+ } else {
+ this.strokeDasharray = null;
}
+ invalidate();
+ }
- @ReactProp(name = "strokeDashoffset")
- public void setStrokeDashoffset(float strokeDashoffset) {
- this.strokeDashoffset = strokeDashoffset * mScale;
- invalidate();
- }
+ @ReactProp(name = "strokeDashoffset")
+ public void setStrokeDashoffset(float strokeDashoffset) {
+ this.strokeDashoffset = strokeDashoffset * mScale;
+ invalidate();
+ }
- @ReactProp(name = "strokeWidth")
- public void setStrokeWidth(Dynamic strokeWidth) {
- this.strokeWidth = SVGLength.from(strokeWidth);
- invalidate();
- }
+ @ReactProp(name = "strokeWidth")
+ public void setStrokeWidth(Dynamic strokeWidth) {
+ this.strokeWidth = SVGLength.from(strokeWidth);
+ invalidate();
+ }
public void setStrokeWidth(String strokeWidth) {
this.strokeWidth = SVGLength.from(strokeWidth);
invalidate();
}
- @ReactProp(name = "strokeMiterlimit", defaultFloat = 4f)
- public void setStrokeMiterlimit(float strokeMiterlimit) {
- this.strokeMiterlimit = strokeMiterlimit;
- invalidate();
+ @ReactProp(name = "strokeMiterlimit", defaultFloat = 4f)
+ public void setStrokeMiterlimit(float strokeMiterlimit) {
+ this.strokeMiterlimit = strokeMiterlimit;
+ invalidate();
+ }
+
+ @ReactProp(name = "strokeLinecap", defaultInt = CAP_ROUND)
+ public void setStrokeLinecap(int strokeLinecap) {
+ switch (strokeLinecap) {
+ case CAP_BUTT:
+ this.strokeLinecap = Paint.Cap.BUTT;
+ break;
+ case CAP_SQUARE:
+ this.strokeLinecap = Paint.Cap.SQUARE;
+ break;
+ case CAP_ROUND:
+ this.strokeLinecap = Paint.Cap.ROUND;
+ break;
+ default:
+ throw new JSApplicationIllegalArgumentException(
+ "strokeLinecap " + strokeLinecap + " unrecognized");
+ }
+ invalidate();
+ }
+
+ @ReactProp(name = "strokeLinejoin", defaultInt = JOIN_ROUND)
+ public void setStrokeLinejoin(int strokeLinejoin) {
+ switch (strokeLinejoin) {
+ case JOIN_MITER:
+ this.strokeLinejoin = Paint.Join.MITER;
+ break;
+ case JOIN_BEVEL:
+ this.strokeLinejoin = Paint.Join.BEVEL;
+ break;
+ case JOIN_ROUND:
+ this.strokeLinejoin = Paint.Join.ROUND;
+ break;
+ default:
+ throw new JSApplicationIllegalArgumentException(
+ "strokeLinejoin " + strokeLinejoin + " unrecognized");
+ }
+ invalidate();
+ }
+
+ @ReactProp(name = "propList")
+ public void setPropList(@Nullable ReadableArray propList) {
+ if (propList != null) {
+ mPropList = mAttributeList = new ArrayList<>();
+ for (int i = 0; i < propList.size(); i++) {
+ mPropList.add(propList.getString(i));
+ }
}
- @ReactProp(name = "strokeLinecap", defaultInt = CAP_ROUND)
- public void setStrokeLinecap(int strokeLinecap) {
- switch (strokeLinecap) {
- case CAP_BUTT:
- this.strokeLinecap = Paint.Cap.BUTT;
- break;
- case CAP_SQUARE:
- this.strokeLinecap = Paint.Cap.SQUARE;
- break;
- case CAP_ROUND:
- this.strokeLinecap = Paint.Cap.ROUND;
- break;
- default:
- throw new JSApplicationIllegalArgumentException(
- "strokeLinecap " + strokeLinecap + " unrecognized");
+ invalidate();
+ }
+
+ private static double saturate(double v) {
+ return v <= 0 ? 0 : (v >= 1 ? 1 : v);
+ }
+
+ void render(Canvas canvas, Paint paint, float opacity) {
+ MaskView mask = null;
+ if (mMask != null) {
+ SvgView root = getSvgView();
+ mask = (MaskView) root.getDefinedMask(mMask);
+ }
+ if (mask != null) {
+ Rect clipBounds = canvas.getClipBounds();
+ int height = clipBounds.height();
+ int width = clipBounds.width();
+
+ Bitmap maskBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Bitmap original = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+
+ Canvas originalCanvas = new Canvas(original);
+ Canvas maskCanvas = new Canvas(maskBitmap);
+ Canvas resultCanvas = new Canvas(result);
+
+ // Clip to mask bounds and render the mask
+ float maskX = (float) relativeOnWidth(mask.mX);
+ float maskY = (float) relativeOnHeight(mask.mY);
+ float maskWidth = (float) relativeOnWidth(mask.mW);
+ float maskHeight = (float) relativeOnHeight(mask.mH);
+ maskCanvas.clipRect(maskX, maskY, maskWidth, maskHeight);
+
+ Paint maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mask.draw(maskCanvas, maskPaint, 1);
+
+ // Apply luminanceToAlpha filter primitive
+ // https://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement
+ int nPixels = width * height;
+ int[] pixels = new int[nPixels];
+ maskBitmap.getPixels(pixels, 0, width, 0, 0, width, height);
+
+ for (int i = 0; i < nPixels; i++) {
+ int color = pixels[i];
+
+ int r = (color >> 16) & 0xFF;
+ int g = (color >> 8) & 0xFF;
+ int b = color & 0xFF;
+ int a = color >>> 24;
+
+ double luminance = saturate(((0.299 * r) + (0.587 * g) + (0.144 * b)) / 255);
+ int alpha = (int) (a * luminance);
+ int pixel = (alpha << 24);
+ pixels[i] = pixel;
+ }
+
+ maskBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
+
+ // Render content of current SVG Renderable to image
+ draw(originalCanvas, paint, opacity);
+
+ // Blend current element and mask
+ maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
+ resultCanvas.drawBitmap(original, 0, 0, null);
+ resultCanvas.drawBitmap(maskBitmap, 0, 0, maskPaint);
+
+ // Render composited result into current render context
+ canvas.drawBitmap(result, 0, 0, paint);
+ } else {
+ draw(canvas, paint, opacity);
+ }
+ }
+
+ @Override
+ void draw(Canvas canvas, Paint paint, float opacity) {
+ opacity *= mOpacity;
+
+ boolean computePaths = mPath == null;
+ if (computePaths) {
+ mPath = getPath(canvas, paint);
+ mPath.setFillType(fillRule);
+ }
+ boolean nonScalingStroke = vectorEffect == VECTOR_EFFECT_NON_SCALING_STROKE;
+ Path path = mPath;
+ if (nonScalingStroke) {
+ Path scaled = new Path();
+ //noinspection deprecation
+ mPath.transform(mCTM, scaled);
+ canvas.setMatrix(null);
+ path = scaled;
+ }
+
+ if (computePaths || path != mPath) {
+ mBox = new RectF();
+ path.computeBounds(mBox, true);
+ }
+
+ RectF clientRect = new RectF(mBox);
+ mCTM.mapRect(clientRect);
+ this.setClientRect(clientRect);
+
+ clip(canvas, paint);
+
+ if (setupFillPaint(paint, opacity * fillOpacity)) {
+ if (computePaths) {
+ mFillPath = new Path();
+ paint.getFillPath(path, mFillPath);
+ }
+ canvas.drawPath(path, paint);
+ }
+ if (setupStrokePaint(paint, opacity * strokeOpacity)) {
+ if (computePaths) {
+ mStrokePath = new Path();
+ paint.getFillPath(path, mStrokePath);
+ }
+ canvas.drawPath(path, paint);
+ }
+ renderMarkers(canvas, paint, opacity);
+ }
+
+ void renderMarkers(Canvas canvas, Paint paint, float opacity) {
+ MarkerView markerStart = (MarkerView) getSvgView().getDefinedMarker(mMarkerStart);
+ MarkerView markerMid = (MarkerView) getSvgView().getDefinedMarker(mMarkerMid);
+ MarkerView markerEnd = (MarkerView) getSvgView().getDefinedMarker(mMarkerEnd);
+ if (elements != null && (markerStart != null || markerMid != null || markerEnd != null)) {
+ contextElement = this;
+ ArrayList positions = RNSVGMarkerPosition.fromPath(elements);
+ float width = (float) (this.strokeWidth != null ? relativeOnOther(this.strokeWidth) : 1);
+ mMarkerPath = new Path();
+ for (RNSVGMarkerPosition position : positions) {
+ RNSVGMarkerType type = position.type;
+ MarkerView marker = null;
+ switch (type) {
+ case kStartMarker:
+ marker = markerStart;
+ break;
+
+ case kMidMarker:
+ marker = markerMid;
+ break;
+
+ case kEndMarker:
+ marker = markerEnd;
+ break;
}
- invalidate();
- }
-
- @ReactProp(name = "strokeLinejoin", defaultInt = JOIN_ROUND)
- public void setStrokeLinejoin(int strokeLinejoin) {
- switch (strokeLinejoin) {
- case JOIN_MITER:
- this.strokeLinejoin = Paint.Join.MITER;
- break;
- case JOIN_BEVEL:
- this.strokeLinejoin = Paint.Join.BEVEL;
- break;
- case JOIN_ROUND:
- this.strokeLinejoin = Paint.Join.ROUND;
- break;
- default:
- throw new JSApplicationIllegalArgumentException(
- "strokeLinejoin " + strokeLinejoin + " unrecognized");
+ if (marker == null) {
+ continue;
}
- invalidate();
+ marker.renderMarker(canvas, paint, opacity, position, width);
+ Matrix transform = marker.markerTransform;
+ mMarkerPath.addPath(marker.getPath(canvas, paint), transform);
+ }
+ contextElement = null;
+ }
+ }
+
+ /**
+ * Sets up paint according to the props set on a view. Returns {@code true} if the fill should be
+ * drawn, {@code false} if not.
+ */
+ boolean setupFillPaint(Paint paint, float opacity) {
+ if (fill != null && fill.size() > 0) {
+ paint.reset();
+ paint.setFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG | Paint.SUBPIXEL_TEXT_FLAG);
+ paint.setStyle(Paint.Style.FILL);
+ setupPaint(paint, opacity, fill);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Sets up paint according to the props set on a view. Returns {@code true} if the stroke should
+ * be drawn, {@code false} if not.
+ */
+ boolean setupStrokePaint(Paint paint, float opacity) {
+ paint.reset();
+ double strokeWidth = relativeOnOther(this.strokeWidth);
+ if (strokeWidth == 0 || stroke == null || stroke.size() == 0) {
+ return false;
}
- @ReactProp(name = "propList")
- public void setPropList(@Nullable ReadableArray propList) {
- if (propList != null) {
- mPropList = mAttributeList = new ArrayList<>();
- for (int i = 0; i < propList.size(); i++) {
- mPropList.add(propList.getString(i));
- }
- }
+ paint.setFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG | Paint.SUBPIXEL_TEXT_FLAG);
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setStrokeCap(strokeLinecap);
+ paint.setStrokeJoin(strokeLinejoin);
+ paint.setStrokeMiter(strokeMiterlimit * mScale);
+ paint.setStrokeWidth((float) strokeWidth);
+ setupPaint(paint, opacity, stroke);
- invalidate();
+ if (strokeDasharray != null) {
+ int length = strokeDasharray.length;
+ float[] intervals = new float[length];
+ for (int i = 0; i < length; i++) {
+ intervals[i] = (float) relativeOnOther(strokeDasharray[i]);
+ }
+ paint.setPathEffect(new DashPathEffect(intervals, strokeDashoffset));
}
- private static double saturate(double v) {
- return v <= 0 ? 0 : (v >= 1 ? 1 : v);
- }
+ return true;
+ }
- void render(Canvas canvas, Paint paint, float opacity) {
- MaskView mask = null;
- if (mMask != null) {
- SvgView root = getSvgView();
- mask = (MaskView) root.getDefinedMask(mMask);
- }
- if (mask != null) {
- Rect clipBounds = canvas.getClipBounds();
- int height = clipBounds.height();
- int width = clipBounds.width();
-
- Bitmap maskBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Bitmap original = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-
- Canvas originalCanvas = new Canvas(original);
- Canvas maskCanvas = new Canvas(maskBitmap);
- Canvas resultCanvas = new Canvas(result);
-
- // Clip to mask bounds and render the mask
- float maskX = (float) relativeOnWidth(mask.mX);
- float maskY = (float) relativeOnHeight(mask.mY);
- float maskWidth = (float) relativeOnWidth(mask.mW);
- float maskHeight = (float) relativeOnHeight(mask.mH);
- maskCanvas.clipRect(maskX, maskY, maskWidth, maskHeight);
-
- Paint maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mask.draw(maskCanvas, maskPaint, 1);
-
- // Apply luminanceToAlpha filter primitive https://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement
- int nPixels = width * height;
- int[] pixels = new int[nPixels];
- maskBitmap.getPixels(pixels, 0, width, 0, 0, width, height);
-
- for (int i = 0; i < nPixels; i++) {
- int color = pixels[i];
-
- int r = (color >> 16) & 0xFF;
- int g = (color >> 8) & 0xFF;
- int b = color & 0xFF;
- int a = color >>> 24;
-
- double luminance = saturate(((0.299 * r) + (0.587 * g) + (0.144 * b)) / 255);
- int alpha = (int) (a * luminance);
- int pixel = (alpha << 24);
- pixels[i] = pixel;
- }
-
- maskBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
-
- // Render content of current SVG Renderable to image
- draw(originalCanvas, paint, opacity);
-
- // Blend current element and mask
- maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
- resultCanvas.drawBitmap(original, 0, 0, null);
- resultCanvas.drawBitmap(maskBitmap, 0, 0, maskPaint);
-
- // Render composited result into current render context
- canvas.drawBitmap(result, 0, 0, paint);
+ private void setupPaint(Paint paint, float opacity, ReadableArray colors) {
+ int colorType = colors.getInt(0);
+ switch (colorType) {
+ case 0:
+ if (colors.size() == 2) {
+ int color;
+ if (colors.getType(1) == ReadableType.Map) {
+ color = ColorPropConverter.getColor(colors.getMap(1), getContext());
+ } else {
+ color = colors.getInt(1);
+ }
+ int alpha = color >>> 24;
+ int combined = Math.round((float) alpha * opacity);
+ paint.setColor(combined << 24 | (color & 0x00ffffff));
} else {
- draw(canvas, paint, opacity);
+ // solid color
+ paint.setARGB(
+ (int) (colors.size() > 4 ? colors.getDouble(4) * opacity * 255 : opacity * 255),
+ (int) (colors.getDouble(1) * 255),
+ (int) (colors.getDouble(2) * 255),
+ (int) (colors.getDouble(3) * 255));
+ }
+ break;
+ case 1:
+ {
+ Brush brush = getSvgView().getDefinedBrush(colors.getString(1));
+ if (brush != null) {
+ brush.setupPaint(paint, mBox, mScale, opacity);
+ }
+ break;
+ }
+ case 2:
+ {
+ int brush = getSvgView().mTintColor;
+ paint.setColor(brush);
+ break;
+ }
+ case 3:
+ {
+ if (contextElement != null && contextElement.fill != null) {
+ setupPaint(paint, opacity, contextElement.fill);
+ }
+ break;
+ }
+ case 4:
+ {
+ if (contextElement != null && contextElement.stroke != null) {
+ setupPaint(paint, opacity, contextElement.stroke);
+ }
+ break;
}
}
+ }
- @Override
- void draw(Canvas canvas, Paint paint, float opacity) {
- opacity *= mOpacity;
+ abstract Path getPath(Canvas canvas, Paint paint);
- boolean computePaths = mPath == null;
- if (computePaths) {
- mPath = getPath(canvas, paint);
- mPath.setFillType(fillRule);
- }
- boolean nonScalingStroke = vectorEffect == VECTOR_EFFECT_NON_SCALING_STROKE;
- Path path = mPath;
- if (nonScalingStroke) {
- Path scaled = new Path();
- //noinspection deprecation
- mPath.transform(mCTM, scaled);
- canvas.setMatrix(null);
- path = scaled;
- }
-
- if (computePaths || path != mPath) {
- mBox = new RectF();
- path.computeBounds(mBox, true);
- }
-
- RectF clientRect = new RectF(mBox);
- mCTM.mapRect(clientRect);
- this.setClientRect(clientRect);
-
- clip(canvas, paint);
-
- if (setupFillPaint(paint, opacity * fillOpacity)) {
- if (computePaths) {
- mFillPath = new Path();
- paint.getFillPath(path, mFillPath);
- }
- canvas.drawPath(path, paint);
- }
- if (setupStrokePaint(paint, opacity * strokeOpacity)) {
- if (computePaths) {
- mStrokePath = new Path();
- paint.getFillPath(path, mStrokePath);
- }
- canvas.drawPath(path, paint);
- }
- renderMarkers(canvas, paint, opacity);
+ @Override
+ int hitTest(final float[] src) {
+ if (mPath == null || !mInvertible || !mTransformInvertible) {
+ return -1;
}
- void renderMarkers(Canvas canvas, Paint paint, float opacity) {
- MarkerView markerStart = (MarkerView)getSvgView().getDefinedMarker(mMarkerStart);
- MarkerView markerMid = (MarkerView)getSvgView().getDefinedMarker(mMarkerMid);
- MarkerView markerEnd = (MarkerView)getSvgView().getDefinedMarker(mMarkerEnd);
- if (elements != null && (markerStart != null || markerMid != null || markerEnd != null)) {
- contextElement = this;
- ArrayList positions = RNSVGMarkerPosition.fromPath(elements);
- float width = (float)(this.strokeWidth != null ? relativeOnOther(this.strokeWidth) : 1);
- mMarkerPath = new Path();
- for (RNSVGMarkerPosition position : positions) {
- RNSVGMarkerType type = position.type;
- MarkerView marker = null;
- switch (type) {
- case kStartMarker:
- marker = markerStart;
- break;
-
- case kMidMarker:
- marker = markerMid;
- break;
-
- case kEndMarker:
- marker = markerEnd;
- break;
- }
- if (marker == null) {
- continue;
- }
- marker.renderMarker(canvas, paint, opacity, position, width);
- Matrix transform = marker.markerTransform;
- mMarkerPath.addPath(marker.getPath(canvas, paint), transform);
- }
- contextElement = null;
- }
+ if (mPointerEvents == PointerEvents.NONE) {
+ return -1;
}
- /**
- * Sets up paint according to the props set on a view. Returns {@code true}
- * if the fill should be drawn, {@code false} if not.
- */
- boolean setupFillPaint(Paint paint, float opacity) {
- if (fill != null && fill.size() > 0) {
- paint.reset();
- paint.setFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG | Paint.SUBPIXEL_TEXT_FLAG);
- paint.setStyle(Paint.Style.FILL);
- setupPaint(paint, opacity, fill);
- return true;
- }
- return false;
+ float[] dst = new float[2];
+ mInvMatrix.mapPoints(dst, src);
+ mInvTransform.mapPoints(dst);
+ int x = Math.round(dst[0]);
+ int y = Math.round(dst[1]);
+
+ initBounds();
+
+ if ((mRegion == null || !mRegion.contains(x, y))
+ && (mStrokeRegion == null
+ || !mStrokeRegion.contains(x, y)
+ && (mMarkerRegion == null || !mMarkerRegion.contains(x, y)))) {
+ return -1;
}
- /**
- * Sets up paint according to the props set on a view. Returns {@code true}
- * if the stroke should be drawn, {@code false} if not.
- */
- boolean setupStrokePaint(Paint paint, float opacity) {
- paint.reset();
- double strokeWidth = relativeOnOther(this.strokeWidth);
- if (strokeWidth == 0 || stroke == null || stroke.size() == 0) {
- return false;
- }
-
- paint.setFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG | Paint.SUBPIXEL_TEXT_FLAG);
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeCap(strokeLinecap);
- paint.setStrokeJoin(strokeLinejoin);
- paint.setStrokeMiter(strokeMiterlimit * mScale);
- paint.setStrokeWidth((float) strokeWidth);
- setupPaint(paint, opacity, stroke);
-
- if (strokeDasharray != null) {
- int length = strokeDasharray.length;
- float[] intervals = new float[length];
- for (int i = 0; i < length; i++) {
- intervals[i] = (float)relativeOnOther(strokeDasharray[i]);
- }
- paint.setPathEffect(new DashPathEffect(intervals, strokeDashoffset));
- }
-
- return true;
+ Path clipPath = getClipPath();
+ if (clipPath != null) {
+ if (!mClipRegion.contains(x, y)) {
+ return -1;
+ }
}
- private void setupPaint(Paint paint, float opacity, ReadableArray colors) {
- int colorType = colors.getInt(0);
- switch (colorType) {
- case 0:
- if (colors.size() == 2) {
- int color;
- if (colors.getType(1) == ReadableType.Map) {
- color = ColorPropConverter.getColor(colors.getMap(1), getContext());
- } else {
- color = colors.getInt(1);
- }
- int alpha = color >>> 24;
- int combined = Math.round((float)alpha * opacity);
- paint.setColor(combined << 24 | (color & 0x00ffffff));
- } else {
- // solid color
- paint.setARGB(
- (int) (colors.size() > 4 ? colors.getDouble(4) * opacity * 255 : opacity * 255),
- (int) (colors.getDouble(1) * 255),
- (int) (colors.getDouble(2) * 255),
- (int) (colors.getDouble(3) * 255));
- }
- break;
- case 1: {
- Brush brush = getSvgView().getDefinedBrush(colors.getString(1));
- if (brush != null) {
- brush.setupPaint(paint, mBox, mScale, opacity);
- }
- break;
- }
- case 2: {
- int brush = getSvgView().mTintColor;
- paint.setColor(brush);
- break;
- }
- case 3: {
- if (contextElement != null && contextElement.fill != null) {
- setupPaint(paint, opacity, contextElement.fill);
- }
- break;
- }
- case 4: {
- if (contextElement != null && contextElement.stroke != null) {
- setupPaint(paint, opacity, contextElement.stroke);
- }
- break;
- }
- }
+ return getId();
+ }
+ void initBounds() {
+ if (mRegion == null && mFillPath != null) {
+ mFillBounds = new RectF();
+ mFillPath.computeBounds(mFillBounds, true);
+ mRegion = getRegion(mFillPath, mFillBounds);
+ }
+ if (mRegion == null && mPath != null) {
+ mFillBounds = new RectF();
+ mPath.computeBounds(mFillBounds, true);
+ mRegion = getRegion(mPath, mFillBounds);
+ }
+ if (mStrokeRegion == null && mStrokePath != null) {
+ mStrokeBounds = new RectF();
+ mStrokePath.computeBounds(mStrokeBounds, true);
+ mStrokeRegion = getRegion(mStrokePath, mStrokeBounds);
+ }
+ if (mMarkerRegion == null && mMarkerPath != null) {
+ mMarkerBounds = new RectF();
+ mMarkerPath.computeBounds(mMarkerBounds, true);
+ mMarkerRegion = getRegion(mMarkerPath, mMarkerBounds);
+ }
+ Path clipPath = getClipPath();
+ if (clipPath != null) {
+ if (mClipRegionPath != clipPath) {
+ mClipRegionPath = clipPath;
+ mClipBounds = new RectF();
+ clipPath.computeBounds(mClipBounds, true);
+ mClipRegion = getRegion(clipPath, mClipBounds);
+ }
+ }
+ }
+
+ Region getRegion(Path path, RectF rectF) {
+ Region region = new Region();
+ region.setPath(
+ path,
+ new Region(
+ (int) Math.floor(rectF.left),
+ (int) Math.floor(rectF.top),
+ (int) Math.ceil(rectF.right),
+ (int) Math.ceil(rectF.bottom)));
+
+ return region;
+ }
+
+ private ArrayList getAttributeList() {
+ return mAttributeList;
+ }
+
+ void mergeProperties(RenderableView target) {
+ ArrayList targetAttributeList = target.getAttributeList();
+
+ if (targetAttributeList == null || targetAttributeList.size() == 0) {
+ return;
}
- abstract Path getPath(Canvas canvas, Paint paint);
+ mOriginProperties = new ArrayList<>();
+ mAttributeList = mPropList == null ? new ArrayList() : new ArrayList<>(mPropList);
- @Override
- int hitTest(final float[] src) {
- if (mPath == null || !mInvertible || !mTransformInvertible) {
- return -1;
+ for (int i = 0, size = targetAttributeList.size(); i < size; i++) {
+ try {
+ String fieldName = targetAttributeList.get(i);
+ Field field = getClass().getField(fieldName);
+ Object value = field.get(target);
+ mOriginProperties.add(field.get(this));
+
+ if (!hasOwnProperty(fieldName)) {
+ mAttributeList.add(fieldName);
+ field.set(this, value);
}
-
- if (mPointerEvents == PointerEvents.NONE) {
- return -1;
- }
-
- float[] dst = new float[2];
- mInvMatrix.mapPoints(dst, src);
- mInvTransform.mapPoints(dst);
- int x = Math.round(dst[0]);
- int y = Math.round(dst[1]);
-
- initBounds();
-
- if (
- (mRegion == null || !mRegion.contains(x, y)) &&
- (mStrokeRegion == null || !mStrokeRegion.contains(x, y) &&
- (mMarkerRegion == null || !mMarkerRegion.contains(x, y)))
- ) {
- return -1;
- }
-
- Path clipPath = getClipPath();
- if (clipPath != null) {
- if (!mClipRegion.contains(x, y)) {
- return -1;
- }
- }
-
- return getId();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
}
- void initBounds() {
- if (mRegion == null && mFillPath != null) {
- mFillBounds = new RectF();
- mFillPath.computeBounds(mFillBounds, true);
- mRegion = getRegion(mFillPath, mFillBounds);
- }
- if (mRegion == null && mPath != null) {
- mFillBounds = new RectF();
- mPath.computeBounds(mFillBounds, true);
- mRegion = getRegion(mPath, mFillBounds);
- }
- if (mStrokeRegion == null && mStrokePath != null) {
- mStrokeBounds = new RectF();
- mStrokePath.computeBounds(mStrokeBounds, true);
- mStrokeRegion = getRegion(mStrokePath, mStrokeBounds);
- }
- if (mMarkerRegion == null && mMarkerPath != null) {
- mMarkerBounds = new RectF();
- mMarkerPath.computeBounds(mMarkerBounds, true);
- mMarkerRegion = getRegion(mMarkerPath, mMarkerBounds);
- }
- Path clipPath = getClipPath();
- if (clipPath != null) {
- if (mClipRegionPath != clipPath) {
- mClipRegionPath = clipPath;
- mClipBounds = new RectF();
- clipPath.computeBounds(mClipBounds, true);
- mClipRegion = getRegion(clipPath, mClipBounds);
- }
+ mLastMergedList = targetAttributeList;
+ }
+
+ void resetProperties() {
+ if (mLastMergedList != null && mOriginProperties != null) {
+ try {
+ for (int i = mLastMergedList.size() - 1; i >= 0; i--) {
+ Field field = getClass().getField(mLastMergedList.get(i));
+ field.set(this, mOriginProperties.get(i));
}
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+
+ mLastMergedList = null;
+ mOriginProperties = null;
+ mAttributeList = mPropList;
}
+ }
- Region getRegion(Path path, RectF rectF) {
- Region region = new Region();
- region.setPath(path,
- new Region(
- (int) Math.floor(rectF.left),
- (int) Math.floor(rectF.top),
- (int) Math.ceil(rectF.right),
- (int) Math.ceil(rectF.bottom)
- )
- );
-
- return region;
- }
-
- private ArrayList getAttributeList() {
- return mAttributeList;
- }
-
- void mergeProperties(RenderableView target) {
- ArrayList targetAttributeList = target.getAttributeList();
-
- if (targetAttributeList == null ||
- targetAttributeList.size() == 0) {
- return;
- }
-
- mOriginProperties = new ArrayList<>();
- mAttributeList = mPropList == null ? new ArrayList() : new ArrayList<>(mPropList);
-
- for (int i = 0, size = targetAttributeList.size(); i < size; i++) {
- try {
- String fieldName = targetAttributeList.get(i);
- Field field = getClass().getField(fieldName);
- Object value = field.get(target);
- mOriginProperties.add(field.get(this));
-
- if (!hasOwnProperty(fieldName)) {
- mAttributeList.add(fieldName);
- field.set(this, value);
- }
- } catch (Exception e) {
- throw new IllegalStateException(e);
- }
- }
-
- mLastMergedList = targetAttributeList;
- }
-
- void resetProperties() {
- if (mLastMergedList != null && mOriginProperties != null) {
- try {
- for (int i = mLastMergedList.size() - 1; i >= 0; i--) {
- Field field = getClass().getField(mLastMergedList.get(i));
- field.set(this, mOriginProperties.get(i));
- }
- } catch (Exception e) {
- throw new IllegalStateException(e);
- }
-
- mLastMergedList = null;
- mOriginProperties = null;
- mAttributeList = mPropList;
- }
- }
-
- private boolean hasOwnProperty(String propName) {
- return mAttributeList != null && mAttributeList.contains(propName);
- }
+ private boolean hasOwnProperty(String propName) {
+ return mAttributeList != null && mAttributeList.contains(propName);
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/RenderableViewManager.java b/android/src/main/java/com/horcrux/svg/RenderableViewManager.java
index 833c9a20..c5f6d764 100644
--- a/android/src/main/java/com/horcrux/svg/RenderableViewManager.java
+++ b/android/src/main/java/com/horcrux/svg/RenderableViewManager.java
@@ -6,77 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/
-
package com.horcrux.svg;
-import android.graphics.Matrix;
-import android.util.SparseArray;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.facebook.react.bridge.Dynamic;
-import com.facebook.react.bridge.JavaOnlyMap;
-import com.facebook.react.bridge.ReadableArray;
-import com.facebook.react.bridge.ReadableMap;
-import com.facebook.react.bridge.ReadableType;
-import com.facebook.react.uimanager.DisplayMetricsHolder;
-import com.facebook.react.uimanager.LayoutShadowNode;
-import com.facebook.react.uimanager.MatrixMathHelper;
-import com.facebook.react.uimanager.PixelUtil;
-import com.facebook.react.uimanager.PointerEvents;
-import com.facebook.react.uimanager.ThemedReactContext;
-import com.facebook.react.uimanager.TransformHelper;
-import com.facebook.react.uimanager.ViewGroupManager;
-import com.facebook.react.uimanager.ViewManagerDelegate;
-import com.facebook.react.uimanager.ViewProps;
-import com.facebook.react.uimanager.annotations.ReactProp;
-import com.facebook.react.uimanager.annotations.ReactPropGroup;
-import com.facebook.react.viewmanagers.RNSVGCircleManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGCircleManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGClipPathManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGClipPathManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGDefsManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGDefsManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGEllipseManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGEllipseManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGForeignObjectManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGForeignObjectManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGGroupManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGGroupManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGImageManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGImageManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGLineManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGLineManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGLinearGradientManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGLinearGradientManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGMarkerManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGMarkerManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGMaskManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGMaskManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGPathManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGPathManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGPatternManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGPatternManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGRadialGradientManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGRadialGradientManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGRectManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGRectManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGSymbolManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGSymbolManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGTSpanManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGTSpanManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGTextManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGTextManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGTextPathManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGTextPathManagerInterface;
-import com.facebook.react.viewmanagers.RNSVGUseManagerDelegate;
-import com.facebook.react.viewmanagers.RNSVGUseManagerInterface;
-
-import java.util.Locale;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
import static com.facebook.react.uimanager.MatrixMathHelper.determinant;
import static com.facebook.react.uimanager.MatrixMathHelper.inverse;
import static com.facebook.react.uimanager.MatrixMathHelper.multiplyVectorByMatrix;
@@ -142,9 +73,72 @@ import static com.horcrux.svg.RenderableView.CAP_ROUND;
import static com.horcrux.svg.RenderableView.FILL_RULE_NONZERO;
import static com.horcrux.svg.RenderableView.JOIN_ROUND;
-/**
- * ViewManager for DefinitionView RNSVG views
- */
+import android.graphics.Matrix;
+import android.util.SparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+import com.facebook.react.bridge.Dynamic;
+import com.facebook.react.bridge.JavaOnlyMap;
+import com.facebook.react.bridge.ReadableArray;
+import com.facebook.react.bridge.ReadableMap;
+import com.facebook.react.bridge.ReadableType;
+import com.facebook.react.uimanager.DisplayMetricsHolder;
+import com.facebook.react.uimanager.LayoutShadowNode;
+import com.facebook.react.uimanager.MatrixMathHelper;
+import com.facebook.react.uimanager.PixelUtil;
+import com.facebook.react.uimanager.PointerEvents;
+import com.facebook.react.uimanager.ThemedReactContext;
+import com.facebook.react.uimanager.TransformHelper;
+import com.facebook.react.uimanager.ViewGroupManager;
+import com.facebook.react.uimanager.ViewManagerDelegate;
+import com.facebook.react.uimanager.ViewProps;
+import com.facebook.react.uimanager.annotations.ReactProp;
+import com.facebook.react.uimanager.annotations.ReactPropGroup;
+import com.facebook.react.viewmanagers.RNSVGCircleManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGCircleManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGClipPathManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGClipPathManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGDefsManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGDefsManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGEllipseManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGEllipseManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGForeignObjectManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGForeignObjectManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGGroupManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGGroupManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGImageManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGImageManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGLineManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGLineManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGLinearGradientManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGLinearGradientManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGMarkerManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGMarkerManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGMaskManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGMaskManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGPathManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGPathManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGPatternManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGPatternManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGRadialGradientManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGRadialGradientManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGRectManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGRectManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGSymbolManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGSymbolManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGTSpanManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGTSpanManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGTextManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGTextManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGTextPathManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGTextPathManagerInterface;
+import com.facebook.react.viewmanagers.RNSVGUseManagerDelegate;
+import com.facebook.react.viewmanagers.RNSVGUseManagerInterface;
+import java.util.Locale;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/** ViewManager for DefinitionView RNSVG views */
class VirtualViewManager extends ViewGroupManager {
protected final SVGClass svgClass;
@@ -159,69 +153,67 @@ class VirtualViewManager extends ViewGroupManager extends ViewGroupManager extends ViewGroupManager extends ViewGroupManager extends ViewGroupManager extends ViewGroupManager PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX) {
- float invertedCameraDistance = (float) perspectiveArray[PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX];
+ float invertedCameraDistance =
+ (float) perspectiveArray[PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX];
if (invertedCameraDistance == 0) {
// Default camera distance, before scale multiplier (1280)
invertedCameraDistance = 0.00078125f;
@@ -399,9 +391,9 @@ class VirtualViewManager extends ViewGroupManager extends ViewGroupManager extends ViewGroupManager extends ViewGroupManager extends ViewGroupManager mTagToRenderableView = new SparseArray<>();
private static final SparseArray mTagToRunnable = new SparseArray<>();
@@ -652,86 +644,85 @@ class VirtualViewManager extends ViewGroupManager extends VirtualViewManager {
RenderableViewManager(SVGClass svgclass) {
super(svgclass);
}
- static class GroupViewManagerAbstract extends RenderableViewManager {
- GroupViewManagerAbstract(SVGClass svgClass) {
- super(svgClass);
- }
- @ReactProp(name = "font")
- public void setFont(U node, @Nullable ReadableMap font) {
- node.setFont(font);
- }
-
- @ReactProp(name = "fontSize")
- public void setFontSize(U node, Dynamic fontSize) {
- JavaOnlyMap map = new JavaOnlyMap();
- switch (fontSize.getType()) {
- case Number:
- map.putDouble("fontSize", fontSize.asDouble());
- break;
- case String:
- map.putString("fontSize", fontSize.asString());
- break;
- default:
- return;
- }
- node.setFont(map);
- }
-
- public void setFontSize(U view, @Nullable String value) {
- JavaOnlyMap map = new JavaOnlyMap();
- map.putString("fontSize", value);
- view.setFont(map);
- }
-
- @ReactProp(name = "fontWeight")
- public void setFontWeight(U node, Dynamic fontWeight) {
- JavaOnlyMap map = new JavaOnlyMap();
- switch (fontWeight.getType()) {
- case Number:
- map.putDouble("fontWeight", fontWeight.asDouble());
- break;
- case String:
- map.putString("fontWeight", fontWeight.asString());
- break;
- default:
- return;
- }
- node.setFont(map);
- }
-
- public void setFontWeight(U view, @Nullable String value) {
- JavaOnlyMap map = new JavaOnlyMap();
- map.putString("fontWeight", value);
- view.setFont(map);
- }
+ static class GroupViewManagerAbstract extends RenderableViewManager {
+ GroupViewManagerAbstract(SVGClass svgClass) {
+ super(svgClass);
}
- static class GroupViewManager extends GroupViewManagerAbstract implements RNSVGGroupManagerInterface {
- GroupViewManager() {
- super(SVGClass.RNSVGGroup);
- mDelegate = new RNSVGGroupManagerDelegate(this);
- }
-
- private final ViewManagerDelegate mDelegate;
-
- protected ViewManagerDelegate getDelegate(){
- return mDelegate;
- }
-
+ @ReactProp(name = "font")
+ public void setFont(U node, @Nullable ReadableMap font) {
+ node.setFont(font);
}
- static class PathViewManager extends RenderableViewManager implements RNSVGPathManagerInterface {
+ @ReactProp(name = "fontSize")
+ public void setFontSize(U node, Dynamic fontSize) {
+ JavaOnlyMap map = new JavaOnlyMap();
+ switch (fontSize.getType()) {
+ case Number:
+ map.putDouble("fontSize", fontSize.asDouble());
+ break;
+ case String:
+ map.putString("fontSize", fontSize.asString());
+ break;
+ default:
+ return;
+ }
+ node.setFont(map);
+ }
+
+ public void setFontSize(U view, @Nullable String value) {
+ JavaOnlyMap map = new JavaOnlyMap();
+ map.putString("fontSize", value);
+ view.setFont(map);
+ }
+
+ @ReactProp(name = "fontWeight")
+ public void setFontWeight(U node, Dynamic fontWeight) {
+ JavaOnlyMap map = new JavaOnlyMap();
+ switch (fontWeight.getType()) {
+ case Number:
+ map.putDouble("fontWeight", fontWeight.asDouble());
+ break;
+ case String:
+ map.putString("fontWeight", fontWeight.asString());
+ break;
+ default:
+ return;
+ }
+ node.setFont(map);
+ }
+
+ public void setFontWeight(U view, @Nullable String value) {
+ JavaOnlyMap map = new JavaOnlyMap();
+ map.putString("fontWeight", value);
+ view.setFont(map);
+ }
+ }
+
+ static class GroupViewManager extends GroupViewManagerAbstract
+ implements RNSVGGroupManagerInterface {
+ GroupViewManager() {
+ super(SVGClass.RNSVGGroup);
+ mDelegate = new RNSVGGroupManagerDelegate(this);
+ }
+
+ private final ViewManagerDelegate mDelegate;
+
+ protected ViewManagerDelegate getDelegate() {
+ return mDelegate;
+ }
+ }
+
+ static class PathViewManager extends RenderableViewManager
+ implements RNSVGPathManagerInterface {
PathViewManager() {
super(SVGClass.RNSVGPath);
mDelegate = new RNSVGPathManagerDelegate(this);
@@ -739,15 +730,15 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "d")
- public void setD(PathView node, String d) {
- node.setD(d);
- }
+ @ReactProp(name = "d")
+ public void setD(PathView node, String d) {
+ node.setD(d);
}
+ }
static class TextViewManagerAbstract extends GroupViewManagerAbstract {
TextViewManagerAbstract(SVGClass svgClass) {
@@ -863,7 +854,8 @@ class RenderableViewManager extends VirtualViewManager
}
}
- static class TextViewManager extends TextViewManagerAbstract implements RNSVGTextManagerInterface {
+ static class TextViewManager extends TextViewManagerAbstract
+ implements RNSVGTextManagerInterface {
TextViewManager() {
super(SVGClass.RNSVGText);
mDelegate = new RNSVGTextManagerDelegate(this);
@@ -871,18 +863,18 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- TextViewManager(SVGClass svgClass) {
- super(svgClass);
- mDelegate = new RNSVGTextManagerDelegate(this);
- }
-
+ TextViewManager(SVGClass svgClass) {
+ super(svgClass);
+ mDelegate = new RNSVGTextManagerDelegate(this);
+ }
}
- static class TSpanViewManager extends TextViewManagerAbstract implements RNSVGTSpanManagerInterface {
+ static class TSpanViewManager extends TextViewManagerAbstract
+ implements RNSVGTSpanManagerInterface {
TSpanViewManager() {
super(SVGClass.RNSVGTSpan);
mDelegate = new RNSVGTSpanManagerDelegate(this);
@@ -895,18 +887,18 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "content")
- public void setContent(TSpanView node, @Nullable String content) {
- node.setContent(content);
- }
-
+ @ReactProp(name = "content")
+ public void setContent(TSpanView node, @Nullable String content) {
+ node.setContent(content);
+ }
}
- static class TextPathViewManager extends TextViewManagerAbstract implements RNSVGTextPathManagerInterface {
+ static class TextPathViewManager extends TextViewManagerAbstract
+ implements RNSVGTextPathManagerInterface {
TextPathViewManager() {
super(SVGClass.RNSVGTextPath);
mDelegate = new RNSVGTextPathManagerDelegate(this);
@@ -914,29 +906,29 @@ class RenderableViewManager extends VirtualViewManager
TextPathViewManager(SVGClass svgClass) {
super(svgClass);
- mDelegate = new RNSVGTextPathManagerDelegate (this);
+ mDelegate = new RNSVGTextPathManagerDelegate(this);
}
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "href")
- public void setHref(TextPathView node, String href) {
- node.setHref(href);
- }
+ @ReactProp(name = "href")
+ public void setHref(TextPathView node, String href) {
+ node.setHref(href);
+ }
- @ReactProp(name = "startOffset")
- public void setStartOffset(TextPathView node, Dynamic startOffset) {
- node.setStartOffset(startOffset);
- }
+ @ReactProp(name = "startOffset")
+ public void setStartOffset(TextPathView node, Dynamic startOffset) {
+ node.setStartOffset(startOffset);
+ }
- @ReactProp(name = "method")
- public void setMethod(TextPathView node, @Nullable String method) {
- node.setMethod(method);
- }
+ @ReactProp(name = "method")
+ public void setMethod(TextPathView node, @Nullable String method) {
+ node.setMethod(method);
+ }
@Override
public void setMidLine(TextPathView view, @Nullable String value) {
@@ -944,9 +936,9 @@ class RenderableViewManager extends VirtualViewManager
}
@ReactProp(name = "spacing")
- public void setSpacing(TextPathView node, @Nullable String spacing) {
- node.setSpacing(spacing);
- }
+ public void setSpacing(TextPathView node, @Nullable String spacing) {
+ node.setSpacing(spacing);
+ }
@Override
public void setStartOffset(TextPathView view, @Nullable String value) {
@@ -954,17 +946,18 @@ class RenderableViewManager extends VirtualViewManager
}
@ReactProp(name = "side")
- public void setSide(TextPathView node, @Nullable String side) {
- node.setSide(side);
- }
-
- @ReactProp(name = "midLine")
- public void setSharp(TextPathView node, @Nullable String midLine) {
- node.setSharp(midLine);
- }
+ public void setSide(TextPathView node, @Nullable String side) {
+ node.setSide(side);
}
- static class ImageViewManager extends RenderableViewManager implements RNSVGImageManagerInterface {
+ @ReactProp(name = "midLine")
+ public void setSharp(TextPathView node, @Nullable String midLine) {
+ node.setSharp(midLine);
+ }
+ }
+
+ static class ImageViewManager extends RenderableViewManager
+ implements RNSVGImageManagerInterface {
ImageViewManager() {
super(SVGClass.RNSVGImage);
mDelegate = new RNSVGImageManagerDelegate(this);
@@ -972,29 +965,29 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "x")
- public void setX(ImageView node, Dynamic x) {
- node.setX(x);
- }
+ @ReactProp(name = "x")
+ public void setX(ImageView node, Dynamic x) {
+ node.setX(x);
+ }
- @ReactProp(name = "y")
- public void setY(ImageView node, Dynamic y) {
- node.setY(y);
- }
+ @ReactProp(name = "y")
+ public void setY(ImageView node, Dynamic y) {
+ node.setY(y);
+ }
- @ReactProp(name = "width")
- public void setWidth(ImageView node, Dynamic width) {
- node.setWidth(width);
- }
+ @ReactProp(name = "width")
+ public void setWidth(ImageView node, Dynamic width) {
+ node.setWidth(width);
+ }
- @ReactProp(name = "height")
- public void setHeight(ImageView node, Dynamic height) {
- node.setHeight(height);
- }
+ @ReactProp(name = "height")
+ public void setHeight(ImageView node, Dynamic height) {
+ node.setHeight(height);
+ }
@Override
public void setX(ImageView view, @Nullable String value) {
@@ -1027,119 +1020,121 @@ class RenderableViewManager extends VirtualViewManager
}
@ReactProp(name = "src")
- public void setSrc(ImageView node, @Nullable ReadableMap src) {
- node.setSrc(src);
- }
-
-
- @ReactProp(name = "align")
- public void setAlign(ImageView node, String align) {
- node.setAlign(align);
- }
-
- @ReactProp(name = "meetOrSlice")
- public void setMeetOrSlice(ImageView node, int meetOrSlice) {
- node.setMeetOrSlice(meetOrSlice);
- }
+ public void setSrc(ImageView node, @Nullable ReadableMap src) {
+ node.setSrc(src);
}
- static class CircleViewManager extends RenderableViewManager implements RNSVGCircleManagerInterface {
- CircleViewManager() {
- super(SVGClass.RNSVGCircle);
- mDelegate = new RNSVGCircleManagerDelegate(this);
- }
-
- private final ViewManagerDelegate mDelegate;
-
- protected ViewManagerDelegate getDelegate(){
- return mDelegate;
- }
-
- @ReactProp(name = "cx")
- public void setCx(CircleView node, Dynamic cx) {
- node.setCx(cx);
- }
-
- @ReactProp(name = "cy")
- public void setCy(CircleView node, Dynamic cy) {
- node.setCy(cy);
- }
-
- @ReactProp(name = "r")
- public void setR(CircleView node, Dynamic r) {
- node.setR(r);
- }
-
- @Override
- public void setCx(CircleView view, String value) {
- view.setCx(value);
- }
-
- @Override
- public void setCy(CircleView view, String value) {
- view.setCy(value);
- }
-
- @Override
- public void setR(CircleView view, String value) {
- view.setR(value);
- }
+ @ReactProp(name = "align")
+ public void setAlign(ImageView node, String align) {
+ node.setAlign(align);
}
- static class EllipseViewManager extends RenderableViewManager implements RNSVGEllipseManagerInterface {
- EllipseViewManager() {
- super(SVGClass.RNSVGEllipse);
- mDelegate = new RNSVGEllipseManagerDelegate(this);
- }
+ @ReactProp(name = "meetOrSlice")
+ public void setMeetOrSlice(ImageView node, int meetOrSlice) {
+ node.setMeetOrSlice(meetOrSlice);
+ }
+ }
- private final ViewManagerDelegate mDelegate;
-
- protected ViewManagerDelegate getDelegate(){
- return mDelegate;
- }
-
- @ReactProp(name = "cx")
- public void setCx(EllipseView node, Dynamic cx) {
- node.setCx(cx);
- }
-
- @ReactProp(name = "cy")
- public void setCy(EllipseView node, Dynamic cy) {
- node.setCy(cy);
- }
-
- @ReactProp(name = "rx")
- public void setRx(EllipseView node, Dynamic rx) {
- node.setRx(rx);
- }
-
- @ReactProp(name = "ry")
- public void setRy(EllipseView node, Dynamic ry) {
- node.setRy(ry);
- }
-
- @Override
- public void setCx(EllipseView view, @Nullable String value) {
- view.setCx(value);
- }
-
- @Override
- public void setCy(EllipseView view, @Nullable String value) {
- view.setCy(value);
- }
-
- @Override
- public void setRx(EllipseView view, @Nullable String value) {
- view.setRx(value);
- }
-
- @Override
- public void setRy(EllipseView view, @Nullable String value) {
- view.setRy(value);
- }
+ static class CircleViewManager extends RenderableViewManager
+ implements RNSVGCircleManagerInterface {
+ CircleViewManager() {
+ super(SVGClass.RNSVGCircle);
+ mDelegate = new RNSVGCircleManagerDelegate(this);
}
- static class LineViewManager extends RenderableViewManager implements RNSVGLineManagerInterface {
+ private final ViewManagerDelegate mDelegate;
+
+ protected ViewManagerDelegate getDelegate() {
+ return mDelegate;
+ }
+
+ @ReactProp(name = "cx")
+ public void setCx(CircleView node, Dynamic cx) {
+ node.setCx(cx);
+ }
+
+ @ReactProp(name = "cy")
+ public void setCy(CircleView node, Dynamic cy) {
+ node.setCy(cy);
+ }
+
+ @ReactProp(name = "r")
+ public void setR(CircleView node, Dynamic r) {
+ node.setR(r);
+ }
+
+ @Override
+ public void setCx(CircleView view, String value) {
+ view.setCx(value);
+ }
+
+ @Override
+ public void setCy(CircleView view, String value) {
+ view.setCy(value);
+ }
+
+ @Override
+ public void setR(CircleView view, String value) {
+ view.setR(value);
+ }
+ }
+
+ static class EllipseViewManager extends RenderableViewManager
+ implements RNSVGEllipseManagerInterface {
+ EllipseViewManager() {
+ super(SVGClass.RNSVGEllipse);
+ mDelegate = new RNSVGEllipseManagerDelegate(this);
+ }
+
+ private final ViewManagerDelegate mDelegate;
+
+ protected ViewManagerDelegate getDelegate() {
+ return mDelegate;
+ }
+
+ @ReactProp(name = "cx")
+ public void setCx(EllipseView node, Dynamic cx) {
+ node.setCx(cx);
+ }
+
+ @ReactProp(name = "cy")
+ public void setCy(EllipseView node, Dynamic cy) {
+ node.setCy(cy);
+ }
+
+ @ReactProp(name = "rx")
+ public void setRx(EllipseView node, Dynamic rx) {
+ node.setRx(rx);
+ }
+
+ @ReactProp(name = "ry")
+ public void setRy(EllipseView node, Dynamic ry) {
+ node.setRy(ry);
+ }
+
+ @Override
+ public void setCx(EllipseView view, @Nullable String value) {
+ view.setCx(value);
+ }
+
+ @Override
+ public void setCy(EllipseView view, @Nullable String value) {
+ view.setCy(value);
+ }
+
+ @Override
+ public void setRx(EllipseView view, @Nullable String value) {
+ view.setRx(value);
+ }
+
+ @Override
+ public void setRy(EllipseView view, @Nullable String value) {
+ view.setRy(value);
+ }
+ }
+
+ static class LineViewManager extends RenderableViewManager
+ implements RNSVGLineManagerInterface {
LineViewManager() {
super(SVGClass.RNSVGLine);
@@ -1148,29 +1143,29 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "x1")
- public void setX1(LineView node, Dynamic x1) {
- node.setX1(x1);
- }
+ @ReactProp(name = "x1")
+ public void setX1(LineView node, Dynamic x1) {
+ node.setX1(x1);
+ }
- @ReactProp(name = "y1")
- public void setY1(LineView node, Dynamic y1) {
- node.setY1(y1);
- }
+ @ReactProp(name = "y1")
+ public void setY1(LineView node, Dynamic y1) {
+ node.setY1(y1);
+ }
- @ReactProp(name = "x2")
- public void setX2(LineView node, Dynamic x2) {
- node.setX2(x2);
- }
+ @ReactProp(name = "x2")
+ public void setX2(LineView node, Dynamic x2) {
+ node.setX2(x2);
+ }
- @ReactProp(name = "y2")
- public void setY2(LineView node, Dynamic y2) {
- node.setY2(y2);
- }
+ @ReactProp(name = "y2")
+ public void setY2(LineView node, Dynamic y2) {
+ node.setY2(y2);
+ }
@Override
public void setX1(LineView view, @Nullable String value) {
@@ -1193,7 +1188,8 @@ class RenderableViewManager extends VirtualViewManager
}
}
- static class RectViewManager extends RenderableViewManager implements RNSVGRectManagerInterface {
+ static class RectViewManager extends RenderableViewManager
+ implements RNSVGRectManagerInterface {
RectViewManager() {
super(SVGClass.RNSVGRect);
@@ -1202,39 +1198,39 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "x")
- public void setX(RectView node, Dynamic x) {
- node.setX(x);
- }
+ @ReactProp(name = "x")
+ public void setX(RectView node, Dynamic x) {
+ node.setX(x);
+ }
- @ReactProp(name = "y")
- public void setY(RectView node, Dynamic y) {
- node.setY(y);
- }
+ @ReactProp(name = "y")
+ public void setY(RectView node, Dynamic y) {
+ node.setY(y);
+ }
- @ReactProp(name = "width")
- public void setWidth(RectView node, Dynamic width) {
- node.setWidth(width);
- }
+ @ReactProp(name = "width")
+ public void setWidth(RectView node, Dynamic width) {
+ node.setWidth(width);
+ }
- @ReactProp(name = "height")
- public void setHeight(RectView node, Dynamic height) {
- node.setHeight(height);
- }
+ @ReactProp(name = "height")
+ public void setHeight(RectView node, Dynamic height) {
+ node.setHeight(height);
+ }
- @ReactProp(name = "rx")
- public void setRx(RectView node, Dynamic rx) {
- node.setRx(rx);
- }
+ @ReactProp(name = "rx")
+ public void setRx(RectView node, Dynamic rx) {
+ node.setRx(rx);
+ }
- @ReactProp(name = "ry")
- public void setRy(RectView node, Dynamic ry) {
- node.setRy(ry);
- }
+ @ReactProp(name = "ry")
+ public void setRy(RectView node, Dynamic ry) {
+ node.setRy(ry);
+ }
@Override
public void setX(RectView view, @Nullable String value) {
@@ -1244,60 +1240,55 @@ class RenderableViewManager extends VirtualViewManager
@Override
public void setY(RectView view, @Nullable String value) {
view.setY(value);
-
}
@Override
public void setRectheight(RectView view, @Nullable String value) {
view.setHeight(value);
-
}
@Override
public void setRectwidth(RectView view, @Nullable String value) {
view.setWidth(value);
-
}
@Override
public void setHeight(RectView view, @Nullable String value) {
view.setHeight(value);
-
}
@Override
public void setWidth(RectView view, @Nullable String value) {
view.setWidth(value);
-
}
@Override
public void setRx(RectView view, @Nullable String value) {
view.setRx(value);
-
}
@Override
public void setRy(RectView view, @Nullable String value) {
view.setRy(value);
-
}
}
- static class ClipPathViewManager extends GroupViewManagerAbstract implements RNSVGClipPathManagerInterface{
- ClipPathViewManager() {
- super(SVGClass.RNSVGClipPath);
- mDelegate = new RNSVGClipPathManagerDelegate(this);
- }
-
- private final ViewManagerDelegate mDelegate;
-
- protected ViewManagerDelegate getDelegate(){
- return mDelegate;
- }
+ static class ClipPathViewManager extends GroupViewManagerAbstract
+ implements RNSVGClipPathManagerInterface {
+ ClipPathViewManager() {
+ super(SVGClass.RNSVGClipPath);
+ mDelegate = new RNSVGClipPathManagerDelegate(this);
}
- static class DefsViewManager extends VirtualViewManager implements RNSVGDefsManagerInterface {
+ private final ViewManagerDelegate mDelegate;
+
+ protected ViewManagerDelegate getDelegate() {
+ return mDelegate;
+ }
+ }
+
+ static class DefsViewManager extends VirtualViewManager
+ implements RNSVGDefsManagerInterface {
DefsViewManager() {
super(SVGClass.RNSVGDefs);
@@ -1306,12 +1297,13 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- }
+ }
- static class UseViewManager extends RenderableViewManager implements RNSVGUseManagerInterface {
+ static class UseViewManager extends RenderableViewManager
+ implements RNSVGUseManagerInterface {
UseViewManager() {
super(SVGClass.RNSVGUse);
@@ -1320,14 +1312,14 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "href")
- public void setHref(UseView node, String href) {
- node.setHref(href);
- }
+ @ReactProp(name = "href")
+ public void setHref(UseView node, String href) {
+ node.setHref(href);
+ }
@Override
public void setX(UseView view, @Nullable String value) {
@@ -1360,27 +1352,28 @@ class RenderableViewManager extends VirtualViewManager
}
@ReactProp(name = "x")
- public void setX(UseView node, Dynamic x) {
- node.setX(x);
- }
-
- @ReactProp(name = "y")
- public void setY(UseView node, Dynamic y) {
- node.setY(y);
- }
-
- @ReactProp(name = "width")
- public void setWidth(UseView node, Dynamic width) {
- node.setWidth(width);
- }
-
- @ReactProp(name = "height")
- public void setHeight(UseView node, Dynamic height) {
- node.setHeight(height);
- }
+ public void setX(UseView node, Dynamic x) {
+ node.setX(x);
}
- static class SymbolManager extends GroupViewManagerAbstract implements RNSVGSymbolManagerInterface {
+ @ReactProp(name = "y")
+ public void setY(UseView node, Dynamic y) {
+ node.setY(y);
+ }
+
+ @ReactProp(name = "width")
+ public void setWidth(UseView node, Dynamic width) {
+ node.setWidth(width);
+ }
+
+ @ReactProp(name = "height")
+ public void setHeight(UseView node, Dynamic height) {
+ node.setHeight(height);
+ }
+ }
+
+ static class SymbolManager extends GroupViewManagerAbstract
+ implements RNSVGSymbolManagerInterface {
SymbolManager() {
super(SVGClass.RNSVGSymbol);
mDelegate = new RNSVGSymbolManagerDelegate(this);
@@ -1388,42 +1381,43 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "minX")
- public void setMinX(SymbolView node, float minX) {
- node.setMinX(minX);
- }
-
- @ReactProp(name = "minY")
- public void setMinY(SymbolView node, float minY) {
- node.setMinY(minY);
- }
-
- @ReactProp(name = "vbWidth")
- public void setVbWidth(SymbolView node, float vbWidth) {
- node.setVbWidth(vbWidth);
- }
-
- @ReactProp(name = "vbHeight")
- public void setVbHeight(SymbolView node, float vbHeight) {
- node.setVbHeight(vbHeight);
- }
-
- @ReactProp(name = "align")
- public void setAlign(SymbolView node, String align) {
- node.setAlign(align);
- }
-
- @ReactProp(name = "meetOrSlice")
- public void setMeetOrSlice(SymbolView node, int meetOrSlice) {
- node.setMeetOrSlice(meetOrSlice);
- }
+ @ReactProp(name = "minX")
+ public void setMinX(SymbolView node, float minX) {
+ node.setMinX(minX);
}
- static class PatternManager extends GroupViewManagerAbstract implements RNSVGPatternManagerInterface {
+ @ReactProp(name = "minY")
+ public void setMinY(SymbolView node, float minY) {
+ node.setMinY(minY);
+ }
+
+ @ReactProp(name = "vbWidth")
+ public void setVbWidth(SymbolView node, float vbWidth) {
+ node.setVbWidth(vbWidth);
+ }
+
+ @ReactProp(name = "vbHeight")
+ public void setVbHeight(SymbolView node, float vbHeight) {
+ node.setVbHeight(vbHeight);
+ }
+
+ @ReactProp(name = "align")
+ public void setAlign(SymbolView node, String align) {
+ node.setAlign(align);
+ }
+
+ @ReactProp(name = "meetOrSlice")
+ public void setMeetOrSlice(SymbolView node, int meetOrSlice) {
+ node.setMeetOrSlice(meetOrSlice);
+ }
+ }
+
+ static class PatternManager extends GroupViewManagerAbstract
+ implements RNSVGPatternManagerInterface {
PatternManager() {
super(SVGClass.RNSVGPattern);
mDelegate = new RNSVGPatternManagerDelegate(this);
@@ -1431,33 +1425,33 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "x")
- public void setX(PatternView node, Dynamic x) {
- node.setX(x);
- }
+ @ReactProp(name = "x")
+ public void setX(PatternView node, Dynamic x) {
+ node.setX(x);
+ }
- @ReactProp(name = "y")
- public void setY(PatternView node, Dynamic y) {
- node.setY(y);
- }
+ @ReactProp(name = "y")
+ public void setY(PatternView node, Dynamic y) {
+ node.setY(y);
+ }
- @ReactProp(name = "width")
- public void setWidth(PatternView node, Dynamic width) {
- node.setWidth(width);
- }
+ @ReactProp(name = "width")
+ public void setWidth(PatternView node, Dynamic width) {
+ node.setWidth(width);
+ }
- @ReactProp(name = "height")
- public void setHeight(PatternView node, Dynamic height) {
- node.setHeight(height);
- }
+ @ReactProp(name = "height")
+ public void setHeight(PatternView node, Dynamic height) {
+ node.setHeight(height);
+ }
@Override
public void setX(PatternView view, @Nullable String value) {
- view.setX(value);
+ view.setX(value);
}
@Override
@@ -1486,52 +1480,53 @@ class RenderableViewManager extends VirtualViewManager
}
@ReactProp(name = "patternUnits")
- public void setPatternUnits(PatternView node, int patternUnits) {
- node.setPatternUnits(patternUnits);
- }
-
- @ReactProp(name = "patternContentUnits")
- public void setPatternContentUnits(PatternView node, int patternContentUnits) {
- node.setPatternContentUnits(patternContentUnits);
- }
-
- @ReactProp(name = "patternTransform")
- public void setPatternTransform(PatternView node, @Nullable ReadableArray matrixArray) {
- node.setPatternTransform(matrixArray);
- }
-
- @ReactProp(name = "minX")
- public void setMinX(PatternView node, float minX) {
- node.setMinX(minX);
- }
-
- @ReactProp(name = "minY")
- public void setMinY(PatternView node, float minY) {
- node.setMinY(minY);
- }
-
- @ReactProp(name = "vbWidth")
- public void setVbWidth(PatternView node, float vbWidth) {
- node.setVbWidth(vbWidth);
- }
-
- @ReactProp(name = "vbHeight")
- public void setVbHeight(PatternView node, float vbHeight) {
- node.setVbHeight(vbHeight);
- }
-
- @ReactProp(name = "align")
- public void setAlign(PatternView node, String align) {
- node.setAlign(align);
- }
-
- @ReactProp(name = "meetOrSlice")
- public void setMeetOrSlice(PatternView node, int meetOrSlice) {
- node.setMeetOrSlice(meetOrSlice);
- }
+ public void setPatternUnits(PatternView node, int patternUnits) {
+ node.setPatternUnits(patternUnits);
}
- static class MaskManager extends GroupViewManagerAbstract implements RNSVGMaskManagerInterface {
+ @ReactProp(name = "patternContentUnits")
+ public void setPatternContentUnits(PatternView node, int patternContentUnits) {
+ node.setPatternContentUnits(patternContentUnits);
+ }
+
+ @ReactProp(name = "patternTransform")
+ public void setPatternTransform(PatternView node, @Nullable ReadableArray matrixArray) {
+ node.setPatternTransform(matrixArray);
+ }
+
+ @ReactProp(name = "minX")
+ public void setMinX(PatternView node, float minX) {
+ node.setMinX(minX);
+ }
+
+ @ReactProp(name = "minY")
+ public void setMinY(PatternView node, float minY) {
+ node.setMinY(minY);
+ }
+
+ @ReactProp(name = "vbWidth")
+ public void setVbWidth(PatternView node, float vbWidth) {
+ node.setVbWidth(vbWidth);
+ }
+
+ @ReactProp(name = "vbHeight")
+ public void setVbHeight(PatternView node, float vbHeight) {
+ node.setVbHeight(vbHeight);
+ }
+
+ @ReactProp(name = "align")
+ public void setAlign(PatternView node, String align) {
+ node.setAlign(align);
+ }
+
+ @ReactProp(name = "meetOrSlice")
+ public void setMeetOrSlice(PatternView node, int meetOrSlice) {
+ node.setMeetOrSlice(meetOrSlice);
+ }
+ }
+
+ static class MaskManager extends GroupViewManagerAbstract
+ implements RNSVGMaskManagerInterface {
MaskManager() {
super(SVGClass.RNSVGMask);
mDelegate = new RNSVGMaskManagerDelegate(this);
@@ -1539,29 +1534,29 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "x")
- public void setX(MaskView node, Dynamic x) {
- node.setX(x);
- }
+ @ReactProp(name = "x")
+ public void setX(MaskView node, Dynamic x) {
+ node.setX(x);
+ }
- @ReactProp(name = "y")
- public void setY(MaskView node, Dynamic y) {
- node.setY(y);
- }
+ @ReactProp(name = "y")
+ public void setY(MaskView node, Dynamic y) {
+ node.setY(y);
+ }
- @ReactProp(name = "width")
- public void setWidth(MaskView node, Dynamic width) {
- node.setWidth(width);
- }
+ @ReactProp(name = "width")
+ public void setWidth(MaskView node, Dynamic width) {
+ node.setWidth(width);
+ }
- @ReactProp(name = "height")
- public void setHeight(MaskView node, Dynamic height) {
- node.setHeight(height);
- }
+ @ReactProp(name = "height")
+ public void setHeight(MaskView node, Dynamic height) {
+ node.setHeight(height);
+ }
@Override
public void setX(MaskView view, @Nullable String value) {
@@ -1594,84 +1589,87 @@ class RenderableViewManager extends VirtualViewManager
}
@ReactProp(name = "maskUnits")
- public void setMaskUnits(MaskView node, int maskUnits) {
- node.setMaskUnits(maskUnits);
- }
-
- @ReactProp(name = "maskContentUnits")
- public void setMaskContentUnits(MaskView node, int maskContentUnits) {
- node.setMaskContentUnits(maskContentUnits);
- }
-
- @ReactProp(name = "maskTransform")
- public void setMaskTransform(MaskView node, @Nullable ReadableArray matrixArray) {
- node.setMaskTransform(matrixArray);
- }
+ public void setMaskUnits(MaskView node, int maskUnits) {
+ node.setMaskUnits(maskUnits);
}
- static class ForeignObjectManager extends GroupViewManagerAbstract implements RNSVGForeignObjectManagerInterface {
- ForeignObjectManager() {
- super(SVGClass.RNSVGForeignObject);
- mDelegate = new RNSVGForeignObjectManagerDelegate(this);
- }
+ @ReactProp(name = "maskContentUnits")
+ public void setMaskContentUnits(MaskView node, int maskContentUnits) {
+ node.setMaskContentUnits(maskContentUnits);
+ }
- private final ViewManagerDelegate mDelegate;
+ @ReactProp(name = "maskTransform")
+ public void setMaskTransform(MaskView node, @Nullable ReadableArray matrixArray) {
+ node.setMaskTransform(matrixArray);
+ }
+ }
- protected ViewManagerDelegate getDelegate(){
- return mDelegate;
- }
- @ReactProp(name = "x")
- public void setX(ForeignObjectView node, Dynamic x) {
- node.setX(x);
- }
+ static class ForeignObjectManager extends GroupViewManagerAbstract
+ implements RNSVGForeignObjectManagerInterface {
+ ForeignObjectManager() {
+ super(SVGClass.RNSVGForeignObject);
+ mDelegate = new RNSVGForeignObjectManagerDelegate(this);
+ }
- @ReactProp(name = "y")
- public void setY(ForeignObjectView node, Dynamic y) {
- node.setY(y);
- }
+ private final ViewManagerDelegate mDelegate;
- @ReactProp(name = "width")
- public void setWidth(ForeignObjectView node, Dynamic width) {
- node.setWidth(width);
- }
+ protected ViewManagerDelegate getDelegate() {
+ return mDelegate;
+ }
- @ReactProp(name = "height")
- public void setHeight(ForeignObjectView node, Dynamic height) {
- node.setHeight(height);
- }
+ @ReactProp(name = "x")
+ public void setX(ForeignObjectView node, Dynamic x) {
+ node.setX(x);
+ }
- @Override
- public void setX(ForeignObjectView view, @Nullable String value) {
- view.setX(value);
- }
+ @ReactProp(name = "y")
+ public void setY(ForeignObjectView node, Dynamic y) {
+ node.setY(y);
+ }
- @Override
- public void setY(ForeignObjectView view, @Nullable String value) {
- view.setY(value);
- }
+ @ReactProp(name = "width")
+ public void setWidth(ForeignObjectView node, Dynamic width) {
+ node.setWidth(width);
+ }
- @Override
- public void setForeignObjectheight(ForeignObjectView view, @Nullable String value) {
- view.setHeight(value);
- }
+ @ReactProp(name = "height")
+ public void setHeight(ForeignObjectView node, Dynamic height) {
+ node.setHeight(height);
+ }
- @Override
- public void setForeignObjectwidth(ForeignObjectView view, @Nullable String value) {
- view.setWidth(value);
- }
+ @Override
+ public void setX(ForeignObjectView view, @Nullable String value) {
+ view.setX(value);
+ }
- @Override
- public void setHeight(ForeignObjectView view, @Nullable String value) {
- view.setHeight(value);
- }
+ @Override
+ public void setY(ForeignObjectView view, @Nullable String value) {
+ view.setY(value);
+ }
- @Override
- public void setWidth(ForeignObjectView view, @Nullable String value) {
- view.setWidth(value);
- }
- }
+ @Override
+ public void setForeignObjectheight(ForeignObjectView view, @Nullable String value) {
+ view.setHeight(value);
+ }
- static class MarkerManager extends GroupViewManagerAbstract implements RNSVGMarkerManagerInterface {
+ @Override
+ public void setForeignObjectwidth(ForeignObjectView view, @Nullable String value) {
+ view.setWidth(value);
+ }
+
+ @Override
+ public void setHeight(ForeignObjectView view, @Nullable String value) {
+ view.setHeight(value);
+ }
+
+ @Override
+ public void setWidth(ForeignObjectView view, @Nullable String value) {
+ view.setWidth(value);
+ }
+ }
+
+ static class MarkerManager extends GroupViewManagerAbstract
+ implements RNSVGMarkerManagerInterface {
MarkerManager() {
super(SVGClass.RNSVGMarker);
mDelegate = new RNSVGMarkerManagerDelegate(this);
@@ -1679,29 +1677,29 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "refX")
- public void setRefX(MarkerView node, Dynamic refX) {
- node.setRefX(refX);
- }
+ @ReactProp(name = "refX")
+ public void setRefX(MarkerView node, Dynamic refX) {
+ node.setRefX(refX);
+ }
- @ReactProp(name = "refY")
- public void setRefY(MarkerView node, Dynamic refY) {
- node.setRefY(refY);
- }
+ @ReactProp(name = "refY")
+ public void setRefY(MarkerView node, Dynamic refY) {
+ node.setRefY(refY);
+ }
- @ReactProp(name = "markerWidth")
- public void setMarkerWidth(MarkerView node, Dynamic markerWidth) {
- node.setMarkerWidth(markerWidth);
- }
+ @ReactProp(name = "markerWidth")
+ public void setMarkerWidth(MarkerView node, Dynamic markerWidth) {
+ node.setMarkerWidth(markerWidth);
+ }
- @ReactProp(name = "markerHeight")
- public void setMarkerHeight(MarkerView node, Dynamic markerHeight) {
- node.setMarkerHeight(markerHeight);
- }
+ @ReactProp(name = "markerHeight")
+ public void setMarkerHeight(MarkerView node, Dynamic markerHeight) {
+ node.setMarkerHeight(markerHeight);
+ }
@Override
public void setRefX(MarkerView view, @Nullable String value) {
@@ -1724,47 +1722,48 @@ class RenderableViewManager extends VirtualViewManager
}
@ReactProp(name = "markerUnits")
- public void setMarkerUnits(MarkerView node, String markerUnits) {
- node.setMarkerUnits(markerUnits);
- }
-
- @ReactProp(name = "orient")
- public void setOrient(MarkerView node, String orient) {
- node.setOrient(orient);
- }
-
- @ReactProp(name = "minX")
- public void setMinX(MarkerView node, float minX) {
- node.setMinX(minX);
- }
-
- @ReactProp(name = "minY")
- public void setMinY(MarkerView node, float minY) {
- node.setMinY(minY);
- }
-
- @ReactProp(name = "vbWidth")
- public void setVbWidth(MarkerView node, float vbWidth) {
- node.setVbWidth(vbWidth);
- }
-
- @ReactProp(name = "vbHeight")
- public void setVbHeight(MarkerView node, float vbHeight) {
- node.setVbHeight(vbHeight);
- }
-
- @ReactProp(name = "align")
- public void setAlign(MarkerView node, String align) {
- node.setAlign(align);
- }
-
- @ReactProp(name = "meetOrSlice")
- public void setMeetOrSlice(MarkerView node, int meetOrSlice) {
- node.setMeetOrSlice(meetOrSlice);
- }
+ public void setMarkerUnits(MarkerView node, String markerUnits) {
+ node.setMarkerUnits(markerUnits);
}
- static class LinearGradientManager extends VirtualViewManager implements RNSVGLinearGradientManagerInterface {
+ @ReactProp(name = "orient")
+ public void setOrient(MarkerView node, String orient) {
+ node.setOrient(orient);
+ }
+
+ @ReactProp(name = "minX")
+ public void setMinX(MarkerView node, float minX) {
+ node.setMinX(minX);
+ }
+
+ @ReactProp(name = "minY")
+ public void setMinY(MarkerView node, float minY) {
+ node.setMinY(minY);
+ }
+
+ @ReactProp(name = "vbWidth")
+ public void setVbWidth(MarkerView node, float vbWidth) {
+ node.setVbWidth(vbWidth);
+ }
+
+ @ReactProp(name = "vbHeight")
+ public void setVbHeight(MarkerView node, float vbHeight) {
+ node.setVbHeight(vbHeight);
+ }
+
+ @ReactProp(name = "align")
+ public void setAlign(MarkerView node, String align) {
+ node.setAlign(align);
+ }
+
+ @ReactProp(name = "meetOrSlice")
+ public void setMeetOrSlice(MarkerView node, int meetOrSlice) {
+ node.setMeetOrSlice(meetOrSlice);
+ }
+ }
+
+ static class LinearGradientManager extends VirtualViewManager
+ implements RNSVGLinearGradientManagerInterface {
LinearGradientManager() {
super(SVGClass.RNSVGLinearGradient);
@@ -1773,30 +1772,29 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
+ @ReactProp(name = "x1")
+ public void setX1(LinearGradientView node, Dynamic x1) {
+ node.setX1(x1);
+ }
- @ReactProp(name = "x1")
- public void setX1(LinearGradientView node, Dynamic x1) {
- node.setX1(x1);
- }
+ @ReactProp(name = "y1")
+ public void setY1(LinearGradientView node, Dynamic y1) {
+ node.setY1(y1);
+ }
- @ReactProp(name = "y1")
- public void setY1(LinearGradientView node, Dynamic y1) {
- node.setY1(y1);
- }
+ @ReactProp(name = "x2")
+ public void setX2(LinearGradientView node, Dynamic x2) {
+ node.setX2(x2);
+ }
- @ReactProp(name = "x2")
- public void setX2(LinearGradientView node, Dynamic x2) {
- node.setX2(x2);
- }
-
- @ReactProp(name = "y2")
- public void setY2(LinearGradientView node, Dynamic y2) {
- node.setY2(y2);
- }
+ @ReactProp(name = "y2")
+ public void setY2(LinearGradientView node, Dynamic y2) {
+ node.setY2(y2);
+ }
@Override
public void setX1(LinearGradientView view, @Nullable String value) {
@@ -1819,22 +1817,23 @@ class RenderableViewManager extends VirtualViewManager
}
@ReactProp(name = "gradient")
- public void setGradient(LinearGradientView node, ReadableArray gradient) {
- node.setGradient(gradient);
- }
-
- @ReactProp(name = "gradientUnits")
- public void setGradientUnits(LinearGradientView node, int gradientUnits) {
- node.setGradientUnits(gradientUnits);
- }
-
- @ReactProp(name = "gradientTransform")
- public void setGradientTransform(LinearGradientView node, @Nullable ReadableArray matrixArray) {
- node.setGradientTransform(matrixArray);
- }
+ public void setGradient(LinearGradientView node, ReadableArray gradient) {
+ node.setGradient(gradient);
}
- static class RadialGradientManager extends VirtualViewManager implements RNSVGRadialGradientManagerInterface {
+ @ReactProp(name = "gradientUnits")
+ public void setGradientUnits(LinearGradientView node, int gradientUnits) {
+ node.setGradientUnits(gradientUnits);
+ }
+
+ @ReactProp(name = "gradientTransform")
+ public void setGradientTransform(LinearGradientView node, @Nullable ReadableArray matrixArray) {
+ node.setGradientTransform(matrixArray);
+ }
+ }
+
+ static class RadialGradientManager extends VirtualViewManager
+ implements RNSVGRadialGradientManagerInterface {
RadialGradientManager() {
super(SVGClass.RNSVGRadialGradient);
@@ -1843,39 +1842,39 @@ class RenderableViewManager extends VirtualViewManager
private final ViewManagerDelegate mDelegate;
- protected ViewManagerDelegate getDelegate(){
+ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
- @ReactProp(name = "fx")
- public void setFx(RadialGradientView node, Dynamic fx) {
- node.setFx(fx);
- }
+ @ReactProp(name = "fx")
+ public void setFx(RadialGradientView node, Dynamic fx) {
+ node.setFx(fx);
+ }
- @ReactProp(name = "fy")
- public void setFy(RadialGradientView node, Dynamic fy) {
- node.setFy(fy);
- }
+ @ReactProp(name = "fy")
+ public void setFy(RadialGradientView node, Dynamic fy) {
+ node.setFy(fy);
+ }
- @ReactProp(name = "rx")
- public void setRx(RadialGradientView node, Dynamic rx) {
- node.setRx(rx);
- }
+ @ReactProp(name = "rx")
+ public void setRx(RadialGradientView node, Dynamic rx) {
+ node.setRx(rx);
+ }
- @ReactProp(name = "ry")
- public void setRy(RadialGradientView node, Dynamic ry) {
- node.setRy(ry);
- }
+ @ReactProp(name = "ry")
+ public void setRy(RadialGradientView node, Dynamic ry) {
+ node.setRy(ry);
+ }
- @ReactProp(name = "cx")
- public void setCx(RadialGradientView node, Dynamic cx) {
- node.setCx(cx);
- }
+ @ReactProp(name = "cx")
+ public void setCx(RadialGradientView node, Dynamic cx) {
+ node.setCx(cx);
+ }
- @ReactProp(name = "cy")
- public void setCy(RadialGradientView node, Dynamic cy) {
- node.setCy(cy);
- }
+ @ReactProp(name = "cy")
+ public void setCy(RadialGradientView node, Dynamic cy) {
+ node.setCy(cy);
+ }
@Override
public void setFx(RadialGradientView view, @Nullable String value) {
@@ -1908,97 +1907,95 @@ class RenderableViewManager extends VirtualViewManager
}
@ReactProp(name = "gradient")
- public void setGradient(RadialGradientView node, ReadableArray gradient) {
- node.setGradient(gradient);
- }
-
- @ReactProp(name = "gradientUnits")
- public void setGradientUnits(RadialGradientView node, int gradientUnits) {
- node.setGradientUnits(gradientUnits);
- }
-
- @ReactProp(name = "gradientTransform")
- public void setGradientTransform(RadialGradientView node, @Nullable ReadableArray matrixArray) {
- node.setGradientTransform(matrixArray);
- }
+ public void setGradient(RadialGradientView node, ReadableArray gradient) {
+ node.setGradient(gradient);
}
+ @ReactProp(name = "gradientUnits")
+ public void setGradientUnits(RadialGradientView node, int gradientUnits) {
+ node.setGradientUnits(gradientUnits);
+ }
+
+ @ReactProp(name = "gradientTransform")
+ public void setGradientTransform(RadialGradientView node, @Nullable ReadableArray matrixArray) {
+ node.setGradientTransform(matrixArray);
+ }
+ }
+
@ReactProp(name = "fill")
- public void setFill(T node, @Nullable Dynamic fill) {
- node.setFill(fill);
- }
+ public void setFill(T node, @Nullable Dynamic fill) {
+ node.setFill(fill);
+ }
public void setFill(T view, @Nullable ReadableMap value) {
view.setFill(value);
}
- @ReactProp(name = "fillOpacity", defaultFloat = 1f)
- public void setFillOpacity(T node, float fillOpacity) {
- node.setFillOpacity(fillOpacity);
- }
-
- @ReactProp(name = "fillRule", defaultInt = FILL_RULE_NONZERO)
- public void setFillRule(T node, int fillRule) {
- node.setFillRule(fillRule);
- }
-
-
- @ReactProp(name = "stroke")
- public void setStroke(T node, @Nullable Dynamic strokeColors) {
- node.setStroke(strokeColors);
- }
-
- public void setStroke(T view, @Nullable ReadableMap value) {
- view.setStroke(value);
+ @ReactProp(name = "fillOpacity", defaultFloat = 1f)
+ public void setFillOpacity(T node, float fillOpacity) {
+ node.setFillOpacity(fillOpacity);
}
- @ReactProp(name = "strokeOpacity", defaultFloat = 1f)
- public void setStrokeOpacity(T node, float strokeOpacity) {
- node.setStrokeOpacity(strokeOpacity);
- }
+ @ReactProp(name = "fillRule", defaultInt = FILL_RULE_NONZERO)
+ public void setFillRule(T node, int fillRule) {
+ node.setFillRule(fillRule);
+ }
- @ReactProp(name = "strokeDasharray")
- public void setStrokeDasharray(T node, @Nullable ReadableArray strokeDasharray) {
- node.setStrokeDasharray(strokeDasharray);
- }
+ @ReactProp(name = "stroke")
+ public void setStroke(T node, @Nullable Dynamic strokeColors) {
+ node.setStroke(strokeColors);
+ }
- @ReactProp(name = "strokeDashoffset")
- public void setStrokeDashoffset(T node, float strokeDashoffset) {
- node.setStrokeDashoffset(strokeDashoffset);
- }
+ public void setStroke(T view, @Nullable ReadableMap value) {
+ view.setStroke(value);
+ }
- @ReactProp(name = "strokeWidth")
- public void setStrokeWidth(T node, Dynamic strokeWidth) {
- node.setStrokeWidth(strokeWidth);
- }
+ @ReactProp(name = "strokeOpacity", defaultFloat = 1f)
+ public void setStrokeOpacity(T node, float strokeOpacity) {
+ node.setStrokeOpacity(strokeOpacity);
+ }
+
+ @ReactProp(name = "strokeDasharray")
+ public void setStrokeDasharray(T node, @Nullable ReadableArray strokeDasharray) {
+ node.setStrokeDasharray(strokeDasharray);
+ }
+
+ @ReactProp(name = "strokeDashoffset")
+ public void setStrokeDashoffset(T node, float strokeDashoffset) {
+ node.setStrokeDashoffset(strokeDashoffset);
+ }
+
+ @ReactProp(name = "strokeWidth")
+ public void setStrokeWidth(T node, Dynamic strokeWidth) {
+ node.setStrokeWidth(strokeWidth);
+ }
public void setStrokeWidth(T view, @Nullable String value) {
view.setStrokeWidth(value);
}
- @ReactProp(name = "strokeMiterlimit", defaultFloat = 4f)
- public void setStrokeMiterlimit(T node, float strokeMiterlimit) {
- node.setStrokeMiterlimit(strokeMiterlimit);
- }
+ @ReactProp(name = "strokeMiterlimit", defaultFloat = 4f)
+ public void setStrokeMiterlimit(T node, float strokeMiterlimit) {
+ node.setStrokeMiterlimit(strokeMiterlimit);
+ }
- @ReactProp(name = "strokeLinecap", defaultInt = CAP_ROUND)
- public void setStrokeLinecap(T node, int strokeLinecap) {
- node.setStrokeLinecap(strokeLinecap);
- }
+ @ReactProp(name = "strokeLinecap", defaultInt = CAP_ROUND)
+ public void setStrokeLinecap(T node, int strokeLinecap) {
+ node.setStrokeLinecap(strokeLinecap);
+ }
- @ReactProp(name = "strokeLinejoin", defaultInt = JOIN_ROUND)
- public void setStrokeLinejoin(T node, int strokeLinejoin) {
- node.setStrokeLinejoin(strokeLinejoin);
- }
+ @ReactProp(name = "strokeLinejoin", defaultInt = JOIN_ROUND)
+ public void setStrokeLinejoin(T node, int strokeLinejoin) {
+ node.setStrokeLinejoin(strokeLinejoin);
+ }
- @ReactProp(name = "vectorEffect")
- public void setVectorEffect(T node, int vectorEffect) {
- node.setVectorEffect(vectorEffect);
- }
-
- @ReactProp(name = "propList")
- public void setPropList(T node, @Nullable ReadableArray propList) {
- node.setPropList(propList);
- }
+ @ReactProp(name = "vectorEffect")
+ public void setVectorEffect(T node, int vectorEffect) {
+ node.setVectorEffect(vectorEffect);
+ }
+ @ReactProp(name = "propList")
+ public void setPropList(T node, @Nullable ReadableArray propList) {
+ node.setPropList(propList);
+ }
}
diff --git a/android/src/main/java/com/horcrux/svg/SVGLength.java b/android/src/main/java/com/horcrux/svg/SVGLength.java
index b2203bc6..85ad120b 100644
--- a/android/src/main/java/com/horcrux/svg/SVGLength.java
+++ b/android/src/main/java/com/horcrux/svg/SVGLength.java
@@ -2,7 +2,6 @@ package com.horcrux.svg;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReadableArray;
-
import java.util.ArrayList;
class SVGLength {
@@ -121,26 +120,29 @@ class SVGLength {
static ArrayList arrayFrom(Dynamic dynamic) {
switch (dynamic.getType()) {
- case Number: {
- ArrayList