From 7c288b0005195b82938924be802ddb9da25057df Mon Sep 17 00:00:00 2001 From: Horcrux Date: Wed, 20 Apr 2016 12:52:35 +0800 Subject: [PATCH] Android get rid of ART dependency --- Example/android/app/build.gradle | 2 + .../java/com/artsvgexample/MainActivity.java | 2 + Example/android/settings.gradle | 3 + android/build.gradle | 34 ++ android/src/main/AndroidManifest.xml | 3 + android/src/main/java/com/horcrux/svg/BUCK | 22 ++ .../main/java/com/horcrux/svg/PropHelper.java | 54 +++ .../com/horcrux/svg/RNSVGGroupShadowNode.java | 39 ++ .../svg/RNSVGRenderableViewManager.java | 88 +++++ .../com/horcrux/svg/RNSVGShapeShadowNode.java | 251 ++++++++++++ .../com/horcrux/svg/RNSVGSurfaceView.java | 45 +++ .../horcrux/svg/RNSVGSurfaceViewManager.java | 61 +++ .../svg/RNSVGSurfaceViewShadowNode.java | 56 +++ .../com/horcrux/svg/RNSVGTextShadowNode.java | 141 +++++++ .../com/horcrux/svg/RNSVGVirtualNode.java | 113 ++++++ ios/ART.xcodeproj/project.pbxproj | 371 ------------------ 16 files changed, 914 insertions(+), 371 deletions(-) create mode 100644 android/build.gradle create mode 100644 android/src/main/AndroidManifest.xml create mode 100644 android/src/main/java/com/horcrux/svg/BUCK create mode 100644 android/src/main/java/com/horcrux/svg/PropHelper.java create mode 100644 android/src/main/java/com/horcrux/svg/RNSVGGroupShadowNode.java create mode 100644 android/src/main/java/com/horcrux/svg/RNSVGRenderableViewManager.java create mode 100644 android/src/main/java/com/horcrux/svg/RNSVGShapeShadowNode.java create mode 100644 android/src/main/java/com/horcrux/svg/RNSVGSurfaceView.java create mode 100644 android/src/main/java/com/horcrux/svg/RNSVGSurfaceViewManager.java create mode 100644 android/src/main/java/com/horcrux/svg/RNSVGSurfaceViewShadowNode.java create mode 100644 android/src/main/java/com/horcrux/svg/RNSVGTextShadowNode.java create mode 100644 android/src/main/java/com/horcrux/svg/RNSVGVirtualNode.java delete mode 100644 ios/ART.xcodeproj/project.pbxproj diff --git a/Example/android/app/build.gradle b/Example/android/app/build.gradle index 74b52283..e2aa7962 100644 --- a/Example/android/app/build.gradle +++ b/Example/android/app/build.gradle @@ -122,4 +122,6 @@ dependencies { compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:23.0.1" compile "com.facebook.react:react-native:0.20.+" + + compile project(':react-native-svg') } diff --git a/Example/android/app/src/main/java/com/artsvgexample/MainActivity.java b/Example/android/app/src/main/java/com/artsvgexample/MainActivity.java index e2950901..35faddcc 100644 --- a/Example/android/app/src/main/java/com/artsvgexample/MainActivity.java +++ b/Example/android/app/src/main/java/com/artsvgexample/MainActivity.java @@ -6,6 +6,7 @@ import com.facebook.react.shell.MainReactPackage; import java.util.Arrays; import java.util.List; +import com.horcrux.svg.RNSvgPackage; public class MainActivity extends ReactActivity { @@ -34,6 +35,7 @@ public class MainActivity extends ReactActivity { @Override protected List getPackages() { return Arrays.asList( + new RNSvgPackage(), new MainReactPackage() ); } diff --git a/Example/android/settings.gradle b/Example/android/settings.gradle index ce581d4f..0ff10ad1 100644 --- a/Example/android/settings.gradle +++ b/Example/android/settings.gradle @@ -1,3 +1,6 @@ rootProject.name = 'ArtSvgExample' include ':app' + +include ':react-native-svg' +project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-art-svg/android') diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 00000000..c17b2d84 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,34 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:1.1.3' + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + lintOptions { + abortOnError false + } +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'com.facebook.react:react-native:0.24.+' +} diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..ab5e09d9 --- /dev/null +++ b/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/android/src/main/java/com/horcrux/svg/BUCK b/android/src/main/java/com/horcrux/svg/BUCK new file mode 100644 index 00000000..9ea5979a --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/BUCK @@ -0,0 +1,22 @@ +include_defs('//ReactAndroid/DEFS') + +android_library( + name = 'RNSVG', + srcs = glob(['*.java']), + deps = [ + react_native_target('java/com/facebook/react/bridge:bridge'), + react_native_target('java/com/facebook/react/common:common'), + react_native_target('java/com/facebook/csslayout:csslayout'), + react_native_target('java/com/facebook/react/uimanager:uimanager'), + react_native_target('java/com/facebook/react/uimanager/annotations:annotations'), + react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'), + react_native_dep('third-party/java/jsr-305:jsr-305'), + ], + visibility = [ + 'PUBLIC', + ], +) + +project_config( + src_target = ':RNSVG', +) diff --git a/android/src/main/java/com/horcrux/svg/PropHelper.java b/android/src/main/java/com/horcrux/svg/PropHelper.java new file mode 100644 index 00000000..634f9565 --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/PropHelper.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.horcrux.svg; + +import javax.annotation.Nullable; + +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.uimanager.ReactStylesDiffMap; + +/** + * Contains static helper methods for accessing props. + */ +/* package */ class PropHelper { + + /** + * Converts {@link ReadableArray} to an array of {@code float}. Returns newly created array. + * + * @return a {@code float[]} if converted successfully, or {@code null} if {@param value} was + * {@code null}. + */ + /*package*/ static @Nullable float[] toFloatArray(@Nullable ReadableArray value) { + if (value != null) { + float[] result = new float[value.size()]; + toFloatArray(value, result); + return result; + } + return null; + } + + /** + * Converts given {@link ReadableArray} to an array of {@code float}. Writes result to the array + * passed in {@param into}. This method will write to the output array up to the number of items + * from the input array. If the input array is longer than output the remaining part of the input + * will not be converted. + * + * @param value input array + * @param into output array + * @return number of items copied from input to the output array + */ + /*package*/ static int toFloatArray(ReadableArray value, float[] into) { + int length = value.size() > into.length ? into.length : value.size(); + for (int i = 0; i < length; i++) { + into[i] = (float) value.getDouble(i); + } + return value.size(); + } +} diff --git a/android/src/main/java/com/horcrux/svg/RNSVGGroupShadowNode.java b/android/src/main/java/com/horcrux/svg/RNSVGGroupShadowNode.java new file mode 100644 index 00000000..fa848b23 --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/RNSVGGroupShadowNode.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.horcrux.svg; + +import android.graphics.Canvas; +import android.graphics.Paint; + +/** + * Shadow node for virtual RNSVGGroup view + */ +public class RNSVGGroupShadowNode extends RNSVGVirtualNode { + + @Override + public boolean isVirtual() { + return true; + } + + public void draw(Canvas canvas, Paint paint, float opacity) { + opacity *= mOpacity; + if (opacity > MIN_OPACITY_FOR_DRAW) { + saveAndSetupCanvas(canvas); + // TODO(6352006): apply clipping (iOS doesn't do it yet, it seems to cause issues) + for (int i = 0; i < getChildCount(); i++) { + RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i); + child.draw(canvas, paint, opacity); + child.markUpdateSeen(); + } + + restoreCanvas(canvas); + } + } +} diff --git a/android/src/main/java/com/horcrux/svg/RNSVGRenderableViewManager.java b/android/src/main/java/com/horcrux/svg/RNSVGRenderableViewManager.java new file mode 100644 index 00000000..488d99f1 --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/RNSVGRenderableViewManager.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.horcrux.svg; + +import android.view.View; + +import com.facebook.react.uimanager.ReactStylesDiffMap; +import com.facebook.react.uimanager.ReactShadowNode; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.ViewManager; + +/** + * ViewManager for all shadowed RNSVG views: Group, Shape and Text. Since these never get rendered + * into native views and don't need any logic (all the logic is in {@link RNSVGSurfaceView}), this + * "stubbed" ViewManager is used for all of them. + */ +public class RNSVGRenderableViewManager extends ViewManager { + + /* package */ static final String CLASS_GROUP = "RNSVGGroup"; + /* package */ static final String CLASS_SHAPE = "RNSVGShape"; + /* package */ static final String CLASS_TEXT = "RNSVGText"; + + private final String mClassName; + + public static RNSVGRenderableViewManager createRNSVGGroupViewManager() { + return new RNSVGRenderableViewManager(CLASS_GROUP); + } + + public static RNSVGRenderableViewManager createRNSVGShapeViewManager() { + return new RNSVGRenderableViewManager(CLASS_SHAPE); + } + + public static RNSVGRenderableViewManager createRNSVGTextViewManager() { + return new RNSVGRenderableViewManager(CLASS_TEXT); + } + + private RNSVGRenderableViewManager(String className) { + mClassName = className; + } + + @Override + public String getName() { + return mClassName; + } + + @Override + public ReactShadowNode createShadowNodeInstance() { + if (mClassName == CLASS_GROUP) { + return new RNSVGGroupShadowNode(); + } else if (mClassName == CLASS_SHAPE) { + return new RNSVGShapeShadowNode(); + } else if (mClassName == CLASS_TEXT) { + return new RNSVGTextShadowNode(); + } else { + throw new IllegalStateException("Unexpected type " + mClassName); + } + } + + @Override + public Class getShadowNodeClass() { + if (mClassName == CLASS_GROUP) { + return RNSVGGroupShadowNode.class; + } else if (mClassName == CLASS_SHAPE) { + return RNSVGShapeShadowNode.class; + } else if (mClassName == CLASS_TEXT) { + return RNSVGTextShadowNode.class; + } else { + throw new IllegalStateException("Unexpected type " + mClassName); + } + } + + @Override + protected View createViewInstance(ThemedReactContext reactContext) { + throw new IllegalStateException("RNSVGShape does not map into a native view"); + } + + @Override + public void updateExtraData(View root, Object extraData) { + throw new IllegalStateException("RNSVGShape does not map into a native view"); + } +} diff --git a/android/src/main/java/com/horcrux/svg/RNSVGShapeShadowNode.java b/android/src/main/java/com/horcrux/svg/RNSVGShapeShadowNode.java new file mode 100644 index 00000000..1c2c8e72 --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/RNSVGShapeShadowNode.java @@ -0,0 +1,251 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.horcrux.svg; + +import javax.annotation.Nullable; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RectF; + +import com.facebook.common.logging.FLog; +import com.facebook.react.bridge.JSApplicationIllegalArgumentException; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.common.ReactConstants; +import com.facebook.react.uimanager.annotations.ReactProp; + +/** + * Shadow node for virtual RNSVGShape view + */ +public class RNSVGShapeShadowNode extends RNSVGVirtualNode { + + private static final int CAP_BUTT = 0; + private static final int CAP_ROUND = 1; + private static final int CAP_SQUARE = 2; + + private static final int JOIN_BEVEL = 2; + private static final int JOIN_MITER = 0; + private static final int JOIN_ROUND = 1; + + private static final int PATH_TYPE_ARC = 4; + private static final int PATH_TYPE_CLOSE = 1; + private static final int PATH_TYPE_CURVETO = 3; + private static final int PATH_TYPE_LINETO = 2; + private static final int PATH_TYPE_MOVETO = 0; + + protected @Nullable Path mPath; + private @Nullable float[] mStrokeColor; + private @Nullable float[] mFillColor; + private @Nullable float[] mStrokeDash; + private float mStrokeWidth = 1; + private int mStrokeCap = CAP_ROUND; + private int mStrokeJoin = JOIN_ROUND; + + @ReactProp(name = "d") + public void setShapePath(@Nullable ReadableArray shapePath) { + float[] pathData = PropHelper.toFloatArray(shapePath); + mPath = createPath(pathData); + markUpdated(); + } + + @ReactProp(name = "stroke") + public void setStroke(@Nullable ReadableArray strokeColors) { + mStrokeColor = PropHelper.toFloatArray(strokeColors); + markUpdated(); + } + + @ReactProp(name = "strokeDash") + public void setStrokeDash(@Nullable ReadableArray strokeDash) { + mStrokeDash = PropHelper.toFloatArray(strokeDash); + markUpdated(); + } + + @ReactProp(name = "fill") + public void setFill(@Nullable ReadableArray fillColors) { + mFillColor = PropHelper.toFloatArray(fillColors); + markUpdated(); + } + + @ReactProp(name = "strokeWidth", defaultFloat = 1f) + public void setStrokeWidth(float strokeWidth) { + mStrokeWidth = strokeWidth; + markUpdated(); + } + + @ReactProp(name = "strokeCap", defaultInt = CAP_ROUND) + public void setStrokeCap(int strokeCap) { + mStrokeCap = strokeCap; + markUpdated(); + } + + @ReactProp(name = "strokeJoin", defaultInt = JOIN_ROUND) + public void setStrokeJoin(int strokeJoin) { + mStrokeJoin = strokeJoin; + markUpdated(); + } + + @Override + public void draw(Canvas canvas, Paint paint, float opacity) { + opacity *= mOpacity; + if (opacity > MIN_OPACITY_FOR_DRAW) { + saveAndSetupCanvas(canvas); + if (mPath == null) { + throw new JSApplicationIllegalArgumentException( + "Shapes should have a valid path (d) prop"); + } + if (setupStrokePaint(paint, opacity)) { + canvas.drawPath(mPath, paint); + } + if (setupFillPaint(paint, opacity)) { + canvas.drawPath(mPath, paint); + } + restoreCanvas(canvas); + } + markUpdateSeen(); + } + + /** + * Sets up {@link #mPaint} according to the props set on a shadow view. Returns {@code true} + * if the stroke should be drawn, {@code false} if not. + */ + protected boolean setupStrokePaint(Paint paint, float opacity) { + if (mStrokeWidth == 0 || mStrokeColor == null || mStrokeColor.length == 0) { + return false; + } + paint.reset(); + paint.setFlags(Paint.ANTI_ALIAS_FLAG); + paint.setStyle(Paint.Style.STROKE); + switch (mStrokeCap) { + case CAP_BUTT: + paint.setStrokeCap(Paint.Cap.BUTT); + break; + case CAP_SQUARE: + paint.setStrokeCap(Paint.Cap.SQUARE); + break; + case CAP_ROUND: + paint.setStrokeCap(Paint.Cap.ROUND); + break; + default: + throw new JSApplicationIllegalArgumentException( + "strokeCap " + mStrokeCap + " unrecognized"); + } + switch (mStrokeJoin) { + case JOIN_MITER: + paint.setStrokeJoin(Paint.Join.MITER); + break; + case JOIN_BEVEL: + paint.setStrokeJoin(Paint.Join.BEVEL); + break; + case JOIN_ROUND: + paint.setStrokeJoin(Paint.Join.ROUND); + break; + default: + throw new JSApplicationIllegalArgumentException( + "strokeJoin " + mStrokeJoin + " unrecognized"); + } + paint.setStrokeWidth(mStrokeWidth * mScale); + paint.setARGB( + (int) (mStrokeColor.length > 3 ? mStrokeColor[3] * opacity * 255 : opacity * 255), + (int) (mStrokeColor[0] * 255), + (int) (mStrokeColor[1] * 255), + (int) (mStrokeColor[2] * 255)); + if (mStrokeDash != null && mStrokeDash.length > 0) { + // TODO(6352067): Support dashes + FLog.w(ReactConstants.TAG, "RNSVG: Dashes are not supported yet!"); + } + return true; + } + + /** + * Sets up {@link #mPaint} according to the props set on a shadow view. Returns {@code true} + * if the fill should be drawn, {@code false} if not. + */ + protected boolean setupFillPaint(Paint paint, float opacity) { + if (mFillColor != null && mFillColor.length > 0) { + paint.reset(); + paint.setFlags(Paint.ANTI_ALIAS_FLAG); + paint.setStyle(Paint.Style.FILL); + int colorType = (int) mFillColor[0]; + switch (colorType) { + case 0: + paint.setARGB( + (int) (mFillColor.length > 4 ? mFillColor[4] * opacity * 255 : opacity * 255), + (int) (mFillColor[1] * 255), + (int) (mFillColor[2] * 255), + (int) (mFillColor[3] * 255)); + break; + default: + // TODO(6352048): Support gradients etc. + FLog.w(ReactConstants.TAG, "RNSVG: Color type " + colorType + " not supported!"); + } + return true; + } + return false; + } + + /** + * Creates a {@link Path} from an array of instructions constructed by JS + * (see RNSVGSerializablePath.js). Each instruction starts with a type (see PATH_TYPE_*) followed + * by arguments for that instruction. For example, to create a line the instruction will be + * 2 (PATH_LINE_TO), x, y. This will draw a line from the last draw point (or 0,0) to x,y. + * + * @param data the array of instructions + * @return the {@link Path} that can be drawn to a canvas + */ + private Path createPath(float[] data) { + Path path = new Path(); + path.moveTo(0, 0); + int i = 0; + while (i < data.length) { + int type = (int) data[i++]; + switch (type) { + case PATH_TYPE_MOVETO: + path.moveTo(data[i++] * mScale, data[i++] * mScale); + break; + case PATH_TYPE_CLOSE: + path.close(); + break; + case PATH_TYPE_LINETO: + path.lineTo(data[i++] * mScale, data[i++] * mScale); + break; + case PATH_TYPE_CURVETO: + path.cubicTo( + data[i++] * mScale, + data[i++] * mScale, + data[i++] * mScale, + data[i++] * mScale, + data[i++] * mScale, + data[i++] * mScale); + break; + case PATH_TYPE_ARC: + { + float x = data[i++] * mScale; + float y = data[i++] * mScale; + float r = data[i++] * mScale; + float start = (float) Math.toDegrees(data[i++]); + float end = (float) Math.toDegrees(data[i++]); + boolean clockwise = data[i++] == 0f; + if (!clockwise) { + end = 360 - end; + } + float sweep = start - end; + RectF oval = new RectF(x - r, y - r, x + r, y + r); + path.addArc(oval, start, sweep); + break; + } + default: + throw new JSApplicationIllegalArgumentException( + "Unrecognized drawing instruction " + type); + } + } + return path; + } +} diff --git a/android/src/main/java/com/horcrux/svg/RNSVGSurfaceView.java b/android/src/main/java/com/horcrux/svg/RNSVGSurfaceView.java new file mode 100644 index 00000000..1f07f624 --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/RNSVGSurfaceView.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.horcrux.svg; + +import javax.annotation.Nullable; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.view.View; + +/** + * Custom {@link View} implementation that draws an RNSVGSurface React view and its children. + */ +public class RNSVGSurfaceView extends View { + + private @Nullable Bitmap mBitmap; + + public RNSVGSurfaceView(Context context) { + super(context); + } + + public void setBitmap(Bitmap bitmap) { + if (mBitmap != null) { + mBitmap.recycle(); + } + mBitmap = bitmap; + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (mBitmap != null) { + canvas.drawBitmap(mBitmap, 0, 0, null); + } + } +} diff --git a/android/src/main/java/com/horcrux/svg/RNSVGSurfaceViewManager.java b/android/src/main/java/com/horcrux/svg/RNSVGSurfaceViewManager.java new file mode 100644 index 00000000..5571a84d --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/RNSVGSurfaceViewManager.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.horcrux.svg; + +import android.graphics.Bitmap; + +import com.facebook.csslayout.CSSNode; +import com.facebook.csslayout.MeasureOutput; +import com.facebook.react.uimanager.BaseViewManager; +import com.facebook.react.uimanager.ThemedReactContext; + +/** + * ViewManager for RNSVGSurfaceView React views. Renders as a {@link RNSVGSurfaceView} and handles + * invalidating the native view on shadow view updates happening in the underlying tree. + */ +public class RNSVGSurfaceViewManager extends + BaseViewManager { + + private static final String REACT_CLASS = "RNSVGSurfaceView"; + + private static final CSSNode.MeasureFunction MEASURE_FUNCTION = new CSSNode.MeasureFunction() { + @Override + public void measure(CSSNode node, float width, float height, MeasureOutput measureOutput) { + throw new IllegalStateException("SurfaceView should have explicit width and height set"); + } + }; + + @Override + public String getName() { + return REACT_CLASS; + } + + @Override + public RNSVGSurfaceViewShadowNode createShadowNodeInstance() { + RNSVGSurfaceViewShadowNode node = new RNSVGSurfaceViewShadowNode(); + node.setMeasureFunction(MEASURE_FUNCTION); + return node; + } + + @Override + public Class getShadowNodeClass() { + return RNSVGSurfaceViewShadowNode.class; + } + + @Override + protected RNSVGSurfaceView createViewInstance(ThemedReactContext reactContext) { + return new RNSVGSurfaceView(reactContext); + } + + @Override + public void updateExtraData(RNSVGSurfaceView root, Object extraData) { + root.setBitmap((Bitmap) extraData); + } +} diff --git a/android/src/main/java/com/horcrux/svg/RNSVGSurfaceViewShadowNode.java b/android/src/main/java/com/horcrux/svg/RNSVGSurfaceViewShadowNode.java new file mode 100644 index 00000000..1ee1335c --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/RNSVGSurfaceViewShadowNode.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.horcrux.svg; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; + +import com.facebook.react.uimanager.LayoutShadowNode; +import com.facebook.react.uimanager.UIViewOperationQueue; + +/** + * Shadow node for RNSVG virtual tree root - RNSVGSurfaceView + */ +public class RNSVGSurfaceViewShadowNode extends LayoutShadowNode { + + @Override + public boolean isVirtual() { + return false; + } + + @Override + public boolean isVirtualAnchor() { + return true; + } + + @Override + public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) { + super.onCollectExtraUpdates(uiUpdater); + uiUpdater.enqueueUpdateExtraData(getReactTag(), drawOutput()); + } + + private Object drawOutput() { + // TODO(7255985): Use TextureView and pass Surface from the view to draw on it asynchronously + // instead of passing the bitmap (which is inefficient especially in terms of memory usage) + Bitmap bitmap = Bitmap.createBitmap( + (int) getLayoutWidth(), + (int) getLayoutHeight(), + Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + Paint paint = new Paint(); + for (int i = 0; i < getChildCount(); i++) { + RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i); + child.draw(canvas, paint, 1f); + child.markUpdateSeen(); + } + return bitmap; + } +} diff --git a/android/src/main/java/com/horcrux/svg/RNSVGTextShadowNode.java b/android/src/main/java/com/horcrux/svg/RNSVGTextShadowNode.java new file mode 100644 index 00000000..c154f4bb --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/RNSVGTextShadowNode.java @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.horcrux.svg; + +import javax.annotation.Nullable; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Typeface; +import android.text.TextUtils; + +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.uimanager.annotations.ReactProp; + +/** + * Shadow node for virtual RNSVGText view + */ +public class RNSVGTextShadowNode extends RNSVGShapeShadowNode { + + private static final String PROP_LINES = "lines"; + + private static final String PROP_FONT = "font"; + private static final String PROP_FONT_FAMILY = "fontFamily"; + private static final String PROP_FONT_SIZE = "fontSize"; + private static final String PROP_FONT_STYLE = "fontStyle"; + private static final String PROP_FONT_WEIGHT = "fontWeight"; + + private static final int DEFAULT_FONT_SIZE = 12; + + private static final int TEXT_ALIGNMENT_CENTER = 2; + private static final int TEXT_ALIGNMENT_LEFT = 0; + private static final int TEXT_ALIGNMENT_RIGHT = 1; + + private @Nullable ReadableMap mFrame; + private int mTextAlignment = TEXT_ALIGNMENT_LEFT; + + @ReactProp(name = "frame") + public void setFrame(@Nullable ReadableMap frame) { + mFrame = frame; + } + + @ReactProp(name = "alignment", defaultInt = TEXT_ALIGNMENT_LEFT) + public void setAlignment(int alignment) { + mTextAlignment = alignment; + } + + @Override + public void draw(Canvas canvas, Paint paint, float opacity) { + if (mFrame == null) { + return; + } + opacity *= mOpacity; + if (opacity <= MIN_OPACITY_FOR_DRAW) { + return; + } + if (!mFrame.hasKey(PROP_LINES)) { + return; + } + ReadableArray linesProp = mFrame.getArray(PROP_LINES); + if (linesProp == null || linesProp.size() == 0) { + return; + } + + // only set up the canvas if we have something to draw + saveAndSetupCanvas(canvas); + String[] lines = new String[linesProp.size()]; + for (int i = 0; i < lines.length; i++) { + lines[i] = linesProp.getString(i); + } + String text = TextUtils.join("\n", lines); + if (setupStrokePaint(paint, opacity)) { + applyTextPropertiesToPaint(paint); + if (mPath == null) { + canvas.drawText(text, 0, -paint.ascent(), paint); + } else { + canvas.drawTextOnPath(text, mPath, 0, 0, paint); + } + } + if (setupFillPaint(paint, opacity)) { + applyTextPropertiesToPaint(paint); + if (mPath == null) { + canvas.drawText(text, 0, -paint.ascent(), paint); + } else { + canvas.drawTextOnPath(text, mPath, 0, 0, paint); + } + } + restoreCanvas(canvas); + markUpdateSeen(); + } + + private void applyTextPropertiesToPaint(Paint paint) { + int alignment = mTextAlignment; + switch (alignment) { + case TEXT_ALIGNMENT_LEFT: + paint.setTextAlign(Paint.Align.LEFT); + break; + case TEXT_ALIGNMENT_RIGHT: + paint.setTextAlign(Paint.Align.RIGHT); + break; + case TEXT_ALIGNMENT_CENTER: + paint.setTextAlign(Paint.Align.CENTER); + break; + } + if (mFrame != null) { + if (mFrame.hasKey(PROP_FONT)) { + ReadableMap font = mFrame.getMap(PROP_FONT); + if (font != null) { + float fontSize = DEFAULT_FONT_SIZE; + if (font.hasKey(PROP_FONT_SIZE)) { + fontSize = (float) font.getDouble(PROP_FONT_SIZE); + } + paint.setTextSize(fontSize * mScale); + boolean isBold = + font.hasKey(PROP_FONT_WEIGHT) && "bold".equals(font.getString(PROP_FONT_WEIGHT)); + boolean isItalic = + font.hasKey(PROP_FONT_STYLE) && "italic".equals(font.getString(PROP_FONT_STYLE)); + int fontStyle; + if (isBold && isItalic) { + fontStyle = Typeface.BOLD_ITALIC; + } else if (isBold) { + fontStyle = Typeface.BOLD; + } else if (isItalic) { + fontStyle = Typeface.ITALIC; + } else { + fontStyle = Typeface.NORMAL; + } + // NB: if the font family is null / unsupported, the default one will be used + paint.setTypeface(Typeface.create(font.getString(PROP_FONT_FAMILY), fontStyle)); + } + } + } + } +} diff --git a/android/src/main/java/com/horcrux/svg/RNSVGVirtualNode.java b/android/src/main/java/com/horcrux/svg/RNSVGVirtualNode.java new file mode 100644 index 00000000..8532079c --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/RNSVGVirtualNode.java @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.horcrux.svg; + +import javax.annotation.Nullable; + +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; + +import com.facebook.react.bridge.JSApplicationIllegalArgumentException; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.uimanager.DisplayMetricsHolder; +import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.uimanager.ReactShadowNode; + +/** + * Base class for RNSVGView virtual nodes: {@link RNSVGGroupShadowNode}, {@link RNSVGShapeShadowNode} and + * indirectly for {@link RNSVGTextShadowNode}. + */ +public abstract class RNSVGVirtualNode extends ReactShadowNode { + + protected static final float MIN_OPACITY_FOR_DRAW = 0.01f; + + private static final float[] sMatrixData = new float[9]; + private static final float[] sRawMatrix = new float[9]; + + protected float mOpacity = 1f; + private @Nullable Matrix mMatrix = new Matrix(); + + protected final float mScale; + + public RNSVGVirtualNode() { + mScale = DisplayMetricsHolder.getWindowDisplayMetrics().density; + } + + @Override + public boolean isVirtual() { + return true; + } + + public abstract void draw(Canvas canvas, Paint paint, float opacity); + + /** + * Sets up the transform matrix on the canvas before an element is drawn. + * + * NB: for perf reasons this does not apply opacity, as that would mean creating a new canvas + * layer (which allocates an offscreen bitmap) and having it composited afterwards. Instead, the + * drawing code should apply opacity recursively. + * + * @param canvas the canvas to set up + */ + protected final void saveAndSetupCanvas(Canvas canvas) { + canvas.save(); + if (mMatrix != null) { + canvas.concat(mMatrix); + } + } + + /** + * Restore the canvas after an element was drawn. This is always called in mirror with + * {@link #saveAndSetupCanvas}. + * + * @param canvas the canvas to restore + */ + protected void restoreCanvas(Canvas canvas) { + canvas.restore(); + } + + @ReactProp(name = "opacity", defaultFloat = 1f) + public void setOpacity(float opacity) { + mOpacity = opacity; + markUpdated(); + } + + @ReactProp(name = "transform") + public void setTransform(@Nullable ReadableArray transformArray) { + if (transformArray != null) { + int matrixSize = PropHelper.toFloatArray(transformArray, sMatrixData); + if (matrixSize == 6) { + setupMatrix(); + } else if (matrixSize != -1) { + throw new JSApplicationIllegalArgumentException("Transform matrices must be of size 6"); + } + } else { + mMatrix = null; + } + markUpdated(); + } + + protected void setupMatrix() { + sRawMatrix[0] = sMatrixData[0]; + sRawMatrix[1] = sMatrixData[2]; + sRawMatrix[2] = sMatrixData[4] * mScale; + sRawMatrix[3] = sMatrixData[1]; + sRawMatrix[4] = sMatrixData[3]; + sRawMatrix[5] = sMatrixData[5] * mScale; + sRawMatrix[6] = 0; + sRawMatrix[7] = 0; + sRawMatrix[8] = 1; + if (mMatrix == null) { + mMatrix = new Matrix(); + } + mMatrix.setValues(sRawMatrix); + } +} diff --git a/ios/ART.xcodeproj/project.pbxproj b/ios/ART.xcodeproj/project.pbxproj deleted file mode 100644 index 1f98a615..00000000 --- a/ios/ART.xcodeproj/project.pbxproj +++ /dev/null @@ -1,371 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 0CF68B051AF0549300FF9E5C /* ARTGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68ADE1AF0549300FF9E5C /* ARTGroup.m */; }; - 0CF68B061AF0549300FF9E5C /* ARTNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE01AF0549300FF9E5C /* ARTNode.m */; }; - 0CF68B071AF0549300FF9E5C /* ARTRenderable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE21AF0549300FF9E5C /* ARTRenderable.m */; }; - 0CF68B081AF0549300FF9E5C /* ARTShape.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE41AF0549300FF9E5C /* ARTShape.m */; }; - 0CF68B091AF0549300FF9E5C /* ARTSurfaceView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE61AF0549300FF9E5C /* ARTSurfaceView.m */; }; - 0CF68B0A1AF0549300FF9E5C /* ARTText.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE81AF0549300FF9E5C /* ARTText.m */; }; - 0CF68B0B1AF0549300FF9E5C /* ARTBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEC1AF0549300FF9E5C /* ARTBrush.m */; }; - 0CF68B0C1AF0549300FF9E5C /* ARTLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEE1AF0549300FF9E5C /* ARTLinearGradient.m */; }; - 0CF68B0D1AF0549300FF9E5C /* ARTPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF01AF0549300FF9E5C /* ARTPattern.m */; }; - 0CF68B0E1AF0549300FF9E5C /* ARTRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF21AF0549300FF9E5C /* ARTRadialGradient.m */; }; - 0CF68B0F1AF0549300FF9E5C /* ARTSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* ARTSolidColor.m */; }; - 0CF68B101AF0549300FF9E5C /* RCTConvert+ART.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */; }; - 0CF68B111AF0549300FF9E5C /* ARTGroupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFA1AF0549300FF9E5C /* ARTGroupManager.m */; }; - 0CF68B121AF0549300FF9E5C /* ARTNodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFC1AF0549300FF9E5C /* ARTNodeManager.m */; }; - 0CF68B131AF0549300FF9E5C /* ARTRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFE1AF0549300FF9E5C /* ARTRenderableManager.m */; }; - 0CF68B141AF0549300FF9E5C /* ARTShapeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */; }; - 0CF68B151AF0549300FF9E5C /* ARTSurfaceViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */; }; - 0CF68B161AF0549300FF9E5C /* ARTTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B041AF0549300FF9E5C /* ARTTextManager.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 0CF68ABF1AF0540F00FF9E5C /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 0CF68AC11AF0540F00FF9E5C /* libART.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libART.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 0CF68ADB1AF0549300FF9E5C /* ARTCGFloatArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTCGFloatArray.h; sourceTree = ""; }; - 0CF68ADC1AF0549300FF9E5C /* ARTContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTContainer.h; sourceTree = ""; }; - 0CF68ADD1AF0549300FF9E5C /* ARTGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTGroup.h; sourceTree = ""; }; - 0CF68ADE1AF0549300FF9E5C /* ARTGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTGroup.m; sourceTree = ""; }; - 0CF68ADF1AF0549300FF9E5C /* ARTNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTNode.h; sourceTree = ""; }; - 0CF68AE01AF0549300FF9E5C /* ARTNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTNode.m; sourceTree = ""; }; - 0CF68AE11AF0549300FF9E5C /* ARTRenderable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTRenderable.h; sourceTree = ""; }; - 0CF68AE21AF0549300FF9E5C /* ARTRenderable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTRenderable.m; sourceTree = ""; }; - 0CF68AE31AF0549300FF9E5C /* ARTShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTShape.h; sourceTree = ""; }; - 0CF68AE41AF0549300FF9E5C /* ARTShape.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTShape.m; sourceTree = ""; }; - 0CF68AE51AF0549300FF9E5C /* ARTSurfaceView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTSurfaceView.h; sourceTree = ""; }; - 0CF68AE61AF0549300FF9E5C /* ARTSurfaceView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSurfaceView.m; sourceTree = ""; }; - 0CF68AE71AF0549300FF9E5C /* ARTText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTText.h; sourceTree = ""; }; - 0CF68AE81AF0549300FF9E5C /* ARTText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTText.m; sourceTree = ""; }; - 0CF68AE91AF0549300FF9E5C /* ARTTextFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTTextFrame.h; sourceTree = ""; }; - 0CF68AEB1AF0549300FF9E5C /* ARTBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTBrush.h; sourceTree = ""; }; - 0CF68AEC1AF0549300FF9E5C /* ARTBrush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTBrush.m; sourceTree = ""; }; - 0CF68AED1AF0549300FF9E5C /* ARTLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTLinearGradient.h; sourceTree = ""; }; - 0CF68AEE1AF0549300FF9E5C /* ARTLinearGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTLinearGradient.m; sourceTree = ""; }; - 0CF68AEF1AF0549300FF9E5C /* ARTPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTPattern.h; sourceTree = ""; }; - 0CF68AF01AF0549300FF9E5C /* ARTPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTPattern.m; sourceTree = ""; }; - 0CF68AF11AF0549300FF9E5C /* ARTRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTRadialGradient.h; sourceTree = ""; }; - 0CF68AF21AF0549300FF9E5C /* ARTRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTRadialGradient.m; sourceTree = ""; }; - 0CF68AF31AF0549300FF9E5C /* ARTSolidColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTSolidColor.h; sourceTree = ""; }; - 0CF68AF41AF0549300FF9E5C /* ARTSolidColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSolidColor.m; sourceTree = ""; }; - 0CF68AF61AF0549300FF9E5C /* RCTConvert+ART.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+ART.h"; sourceTree = ""; }; - 0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+ART.m"; sourceTree = ""; }; - 0CF68AF91AF0549300FF9E5C /* ARTGroupManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTGroupManager.h; sourceTree = ""; }; - 0CF68AFA1AF0549300FF9E5C /* ARTGroupManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTGroupManager.m; sourceTree = ""; }; - 0CF68AFB1AF0549300FF9E5C /* ARTNodeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTNodeManager.h; sourceTree = ""; }; - 0CF68AFC1AF0549300FF9E5C /* ARTNodeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTNodeManager.m; sourceTree = ""; }; - 0CF68AFD1AF0549300FF9E5C /* ARTRenderableManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTRenderableManager.h; sourceTree = ""; }; - 0CF68AFE1AF0549300FF9E5C /* ARTRenderableManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTRenderableManager.m; sourceTree = ""; }; - 0CF68AFF1AF0549300FF9E5C /* ARTShapeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTShapeManager.h; sourceTree = ""; }; - 0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTShapeManager.m; sourceTree = ""; }; - 0CF68B011AF0549300FF9E5C /* ARTSurfaceViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTSurfaceViewManager.h; sourceTree = ""; }; - 0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSurfaceViewManager.m; sourceTree = ""; }; - 0CF68B031AF0549300FF9E5C /* ARTTextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTTextManager.h; sourceTree = ""; }; - 0CF68B041AF0549300FF9E5C /* ARTTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTTextManager.m; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 0CF68ABE1AF0540F00FF9E5C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 0CF68AB81AF0540F00FF9E5C = { - isa = PBXGroup; - children = ( - 0CF68AEA1AF0549300FF9E5C /* Brushes */, - 0CF68AF81AF0549300FF9E5C /* ViewManagers */, - 0CF68ADB1AF0549300FF9E5C /* ARTCGFloatArray.h */, - 0CF68ADC1AF0549300FF9E5C /* ARTContainer.h */, - 0CF68ADD1AF0549300FF9E5C /* ARTGroup.h */, - 0CF68ADE1AF0549300FF9E5C /* ARTGroup.m */, - 0CF68ADF1AF0549300FF9E5C /* ARTNode.h */, - 0CF68AE01AF0549300FF9E5C /* ARTNode.m */, - 0CF68AE11AF0549300FF9E5C /* ARTRenderable.h */, - 0CF68AE21AF0549300FF9E5C /* ARTRenderable.m */, - 0CF68AE31AF0549300FF9E5C /* ARTShape.h */, - 0CF68AE41AF0549300FF9E5C /* ARTShape.m */, - 0CF68AE51AF0549300FF9E5C /* ARTSurfaceView.h */, - 0CF68AE61AF0549300FF9E5C /* ARTSurfaceView.m */, - 0CF68AE71AF0549300FF9E5C /* ARTText.h */, - 0CF68AE81AF0549300FF9E5C /* ARTText.m */, - 0CF68AE91AF0549300FF9E5C /* ARTTextFrame.h */, - 0CF68AF61AF0549300FF9E5C /* RCTConvert+ART.h */, - 0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */, - 0CF68AC21AF0540F00FF9E5C /* Products */, - ); - sourceTree = ""; - }; - 0CF68AC21AF0540F00FF9E5C /* Products */ = { - isa = PBXGroup; - children = ( - 0CF68AC11AF0540F00FF9E5C /* libART.a */, - ); - name = Products; - sourceTree = ""; - }; - 0CF68AEA1AF0549300FF9E5C /* Brushes */ = { - isa = PBXGroup; - children = ( - 0CF68AEB1AF0549300FF9E5C /* ARTBrush.h */, - 0CF68AEC1AF0549300FF9E5C /* ARTBrush.m */, - 0CF68AED1AF0549300FF9E5C /* ARTLinearGradient.h */, - 0CF68AEE1AF0549300FF9E5C /* ARTLinearGradient.m */, - 0CF68AEF1AF0549300FF9E5C /* ARTPattern.h */, - 0CF68AF01AF0549300FF9E5C /* ARTPattern.m */, - 0CF68AF11AF0549300FF9E5C /* ARTRadialGradient.h */, - 0CF68AF21AF0549300FF9E5C /* ARTRadialGradient.m */, - 0CF68AF31AF0549300FF9E5C /* ARTSolidColor.h */, - 0CF68AF41AF0549300FF9E5C /* ARTSolidColor.m */, - ); - path = Brushes; - sourceTree = ""; - }; - 0CF68AF81AF0549300FF9E5C /* ViewManagers */ = { - isa = PBXGroup; - children = ( - 0CF68AF91AF0549300FF9E5C /* ARTGroupManager.h */, - 0CF68AFA1AF0549300FF9E5C /* ARTGroupManager.m */, - 0CF68AFB1AF0549300FF9E5C /* ARTNodeManager.h */, - 0CF68AFC1AF0549300FF9E5C /* ARTNodeManager.m */, - 0CF68AFD1AF0549300FF9E5C /* ARTRenderableManager.h */, - 0CF68AFE1AF0549300FF9E5C /* ARTRenderableManager.m */, - 0CF68AFF1AF0549300FF9E5C /* ARTShapeManager.h */, - 0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */, - 0CF68B011AF0549300FF9E5C /* ARTSurfaceViewManager.h */, - 0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */, - 0CF68B031AF0549300FF9E5C /* ARTTextManager.h */, - 0CF68B041AF0549300FF9E5C /* ARTTextManager.m */, - ); - path = ViewManagers; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 0CF68AC01AF0540F00FF9E5C /* ART */ = { - isa = PBXNativeTarget; - buildConfigurationList = 0CF68AD51AF0540F00FF9E5C /* Build configuration list for PBXNativeTarget "ART" */; - buildPhases = ( - 0CF68ABD1AF0540F00FF9E5C /* Sources */, - 0CF68ABE1AF0540F00FF9E5C /* Frameworks */, - 0CF68ABF1AF0540F00FF9E5C /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = ART; - productName = ART; - productReference = 0CF68AC11AF0540F00FF9E5C /* libART.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 0CF68AB91AF0540F00FF9E5C /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0620; - TargetAttributes = { - 0CF68AC01AF0540F00FF9E5C = { - CreatedOnToolsVersion = 6.2; - }; - }; - }; - buildConfigurationList = 0CF68ABC1AF0540F00FF9E5C /* Build configuration list for PBXProject "ART" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 0CF68AB81AF0540F00FF9E5C; - productRefGroup = 0CF68AC21AF0540F00FF9E5C /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 0CF68AC01AF0540F00FF9E5C /* ART */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 0CF68ABD1AF0540F00FF9E5C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 0CF68B161AF0549300FF9E5C /* ARTTextManager.m in Sources */, - 0CF68B111AF0549300FF9E5C /* ARTGroupManager.m in Sources */, - 0CF68B0D1AF0549300FF9E5C /* ARTPattern.m in Sources */, - 0CF68B0A1AF0549300FF9E5C /* ARTText.m in Sources */, - 0CF68B121AF0549300FF9E5C /* ARTNodeManager.m in Sources */, - 0CF68B051AF0549300FF9E5C /* ARTGroup.m in Sources */, - 0CF68B131AF0549300FF9E5C /* ARTRenderableManager.m in Sources */, - 0CF68B091AF0549300FF9E5C /* ARTSurfaceView.m in Sources */, - 0CF68B0E1AF0549300FF9E5C /* ARTRadialGradient.m in Sources */, - 0CF68B151AF0549300FF9E5C /* ARTSurfaceViewManager.m in Sources */, - 0CF68B081AF0549300FF9E5C /* ARTShape.m in Sources */, - 0CF68B071AF0549300FF9E5C /* ARTRenderable.m in Sources */, - 0CF68B101AF0549300FF9E5C /* RCTConvert+ART.m in Sources */, - 0CF68B061AF0549300FF9E5C /* ARTNode.m in Sources */, - 0CF68B0F1AF0549300FF9E5C /* ARTSolidColor.m in Sources */, - 0CF68B0C1AF0549300FF9E5C /* ARTLinearGradient.m in Sources */, - 0CF68B0B1AF0549300FF9E5C /* ARTBrush.m in Sources */, - 0CF68B141AF0549300FF9E5C /* ARTShapeManager.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 0CF68AD31AF0540F00FF9E5C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../../React/**", - ); - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 0CF68AD41AF0540F00FF9E5C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../../React/**", - ); - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 0CF68AD61AF0540F00FF9E5C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 0CF68AD71AF0540F00FF9E5C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 0CF68ABC1AF0540F00FF9E5C /* Build configuration list for PBXProject "ART" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 0CF68AD31AF0540F00FF9E5C /* Debug */, - 0CF68AD41AF0540F00FF9E5C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 0CF68AD51AF0540F00FF9E5C /* Build configuration list for PBXNativeTarget "ART" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 0CF68AD61AF0540F00FF9E5C /* Debug */, - 0CF68AD71AF0540F00FF9E5C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 0CF68AB91AF0540F00FF9E5C /* Project object */; -}