mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
[react-native] Open-source ReactART for native
This commit is contained in:
@@ -0,0 +1,371 @@
|
||||
// !$*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 = "<group>"; };
|
||||
0CF68ADC1AF0549300FF9E5C /* ARTContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTContainer.h; sourceTree = "<group>"; };
|
||||
0CF68ADD1AF0549300FF9E5C /* ARTGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTGroup.h; sourceTree = "<group>"; };
|
||||
0CF68ADE1AF0549300FF9E5C /* ARTGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTGroup.m; sourceTree = "<group>"; };
|
||||
0CF68ADF1AF0549300FF9E5C /* ARTNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTNode.h; sourceTree = "<group>"; };
|
||||
0CF68AE01AF0549300FF9E5C /* ARTNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTNode.m; sourceTree = "<group>"; };
|
||||
0CF68AE11AF0549300FF9E5C /* ARTRenderable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTRenderable.h; sourceTree = "<group>"; };
|
||||
0CF68AE21AF0549300FF9E5C /* ARTRenderable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTRenderable.m; sourceTree = "<group>"; };
|
||||
0CF68AE31AF0549300FF9E5C /* ARTShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTShape.h; sourceTree = "<group>"; };
|
||||
0CF68AE41AF0549300FF9E5C /* ARTShape.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTShape.m; sourceTree = "<group>"; };
|
||||
0CF68AE51AF0549300FF9E5C /* ARTSurfaceView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTSurfaceView.h; sourceTree = "<group>"; };
|
||||
0CF68AE61AF0549300FF9E5C /* ARTSurfaceView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSurfaceView.m; sourceTree = "<group>"; };
|
||||
0CF68AE71AF0549300FF9E5C /* ARTText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTText.h; sourceTree = "<group>"; };
|
||||
0CF68AE81AF0549300FF9E5C /* ARTText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTText.m; sourceTree = "<group>"; };
|
||||
0CF68AE91AF0549300FF9E5C /* ARTTextFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTTextFrame.h; sourceTree = "<group>"; };
|
||||
0CF68AEB1AF0549300FF9E5C /* ARTBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTBrush.h; sourceTree = "<group>"; };
|
||||
0CF68AEC1AF0549300FF9E5C /* ARTBrush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTBrush.m; sourceTree = "<group>"; };
|
||||
0CF68AED1AF0549300FF9E5C /* ARTLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTLinearGradient.h; sourceTree = "<group>"; };
|
||||
0CF68AEE1AF0549300FF9E5C /* ARTLinearGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTLinearGradient.m; sourceTree = "<group>"; };
|
||||
0CF68AEF1AF0549300FF9E5C /* ARTPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTPattern.h; sourceTree = "<group>"; };
|
||||
0CF68AF01AF0549300FF9E5C /* ARTPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTPattern.m; sourceTree = "<group>"; };
|
||||
0CF68AF11AF0549300FF9E5C /* ARTRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTRadialGradient.h; sourceTree = "<group>"; };
|
||||
0CF68AF21AF0549300FF9E5C /* ARTRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTRadialGradient.m; sourceTree = "<group>"; };
|
||||
0CF68AF31AF0549300FF9E5C /* ARTSolidColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTSolidColor.h; sourceTree = "<group>"; };
|
||||
0CF68AF41AF0549300FF9E5C /* ARTSolidColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSolidColor.m; sourceTree = "<group>"; };
|
||||
0CF68AF61AF0549300FF9E5C /* RCTConvert+ART.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+ART.h"; sourceTree = "<group>"; };
|
||||
0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+ART.m"; sourceTree = "<group>"; };
|
||||
0CF68AF91AF0549300FF9E5C /* ARTGroupManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTGroupManager.h; sourceTree = "<group>"; };
|
||||
0CF68AFA1AF0549300FF9E5C /* ARTGroupManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTGroupManager.m; sourceTree = "<group>"; };
|
||||
0CF68AFB1AF0549300FF9E5C /* ARTNodeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTNodeManager.h; sourceTree = "<group>"; };
|
||||
0CF68AFC1AF0549300FF9E5C /* ARTNodeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTNodeManager.m; sourceTree = "<group>"; };
|
||||
0CF68AFD1AF0549300FF9E5C /* ARTRenderableManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTRenderableManager.h; sourceTree = "<group>"; };
|
||||
0CF68AFE1AF0549300FF9E5C /* ARTRenderableManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTRenderableManager.m; sourceTree = "<group>"; };
|
||||
0CF68AFF1AF0549300FF9E5C /* ARTShapeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTShapeManager.h; sourceTree = "<group>"; };
|
||||
0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTShapeManager.m; sourceTree = "<group>"; };
|
||||
0CF68B011AF0549300FF9E5C /* ARTSurfaceViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTSurfaceViewManager.h; sourceTree = "<group>"; };
|
||||
0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSurfaceViewManager.m; sourceTree = "<group>"; };
|
||||
0CF68B031AF0549300FF9E5C /* ARTTextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTTextManager.h; sourceTree = "<group>"; };
|
||||
0CF68B041AF0549300FF9E5C /* ARTTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTTextManager.m; sourceTree = "<group>"; };
|
||||
/* 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 = (
|
||||
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 */,
|
||||
0CF68AEA1AF0549300FF9E5C /* Brushes */,
|
||||
0CF68AF61AF0549300FF9E5C /* RCTConvert+ART.h */,
|
||||
0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */,
|
||||
0CF68AF81AF0549300FF9E5C /* ViewManagers */,
|
||||
0CF68AC21AF0540F00FF9E5C /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0CF68AC21AF0540F00FF9E5C /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0CF68AC11AF0540F00FF9E5C /* libART.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
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 = "<group>";
|
||||
};
|
||||
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 = "<group>";
|
||||
};
|
||||
/* 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 = 8.2;
|
||||
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 = 8.2;
|
||||
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 */;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// A little helper to make sure we have the right memory allocation ready for use.
|
||||
// We assume that we will only this in one place so no reference counting is necessary.
|
||||
// Needs to be freed when dealloced.
|
||||
|
||||
// This is fragile since this relies on these values not getting reused. Consider
|
||||
// wrapping these in an Obj-C class or some ARC hackery to get refcounting.
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
CGFloat *array;
|
||||
} ARTCGFloatArray;
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol ARTContainer <NSObject>
|
||||
|
||||
// This is used as a hook for child to mark it's parent as dirty.
|
||||
// This bubbles up to the root which gets marked as dirty.
|
||||
- (void)invalidate;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "ARTContainer.h"
|
||||
#import "ARTNode.h"
|
||||
|
||||
@interface ARTGroup : ARTNode <ARTContainer>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTGroup.h"
|
||||
|
||||
@implementation ARTGroup
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
// TO-DO: Clipping rectangle
|
||||
|
||||
for (ARTNode *node in self.subviews) {
|
||||
[node renderTo:context];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
/**
|
||||
* ART nodes are implemented as empty UIViews but this is just an implementation detail to fit
|
||||
* into the existing view management. They should also be shadow views and painted on a background
|
||||
* thread.
|
||||
*/
|
||||
|
||||
@interface ARTNode : UIView
|
||||
|
||||
@property (nonatomic, assign) CGFloat opacity;
|
||||
|
||||
- (void)invalidate;
|
||||
- (void)renderTo:(CGContextRef)context;
|
||||
|
||||
/**
|
||||
* renderTo will take opacity into account and draw renderLayerTo off-screen if there is opacity
|
||||
* specified, then composite that onto the context. renderLayerTo always draws at opacity=1.
|
||||
* @abstract
|
||||
*/
|
||||
- (void)renderLayerTo:(CGContextRef)context;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTNode.h"
|
||||
|
||||
#import "ARTContainer.h"
|
||||
|
||||
@implementation ARTNode
|
||||
|
||||
- (void)insertSubview:(UIView *)subview atIndex:(NSInteger)index
|
||||
{
|
||||
[self invalidate];
|
||||
[super insertSubview:subview atIndex:index];
|
||||
}
|
||||
|
||||
- (void)removeFromSuperview
|
||||
{
|
||||
[self invalidate];
|
||||
[super removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void)setOpacity:(CGFloat)opacity
|
||||
{
|
||||
[self invalidate];
|
||||
_opacity = opacity;
|
||||
}
|
||||
|
||||
- (void)setTransform:(CGAffineTransform)transform
|
||||
{
|
||||
[self invalidate];
|
||||
super.transform = transform;
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
id<ARTContainer> container = (id<ARTContainer>)self.superview;
|
||||
[container invalidate];
|
||||
}
|
||||
|
||||
- (void)renderTo:(CGContextRef)context
|
||||
{
|
||||
if (self.opacity <= 0) {
|
||||
// Nothing to paint
|
||||
return;
|
||||
}
|
||||
if (self.opacity >= 1) {
|
||||
// Just paint at full opacity
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, 1);
|
||||
[self renderLayerTo:context];
|
||||
CGContextRestoreGState(context);
|
||||
return;
|
||||
}
|
||||
// This needs to be painted on a layer before being composited.
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, self.opacity);
|
||||
CGContextBeginTransparencyLayer(context, NULL);
|
||||
[self renderLayerTo:context];
|
||||
CGContextEndTransparencyLayer(context);
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "ARTBrush.h"
|
||||
#import "ARTCGFloatArray.h"
|
||||
#import "ARTNode.h"
|
||||
|
||||
@interface ARTRenderable : ARTNode
|
||||
|
||||
@property (nonatomic, strong) ARTBrush *fill;
|
||||
@property (nonatomic, assign) CGColorRef stroke;
|
||||
@property (nonatomic, assign) CGFloat strokeWidth;
|
||||
@property (nonatomic, assign) CGLineCap strokeCap;
|
||||
@property (nonatomic, assign) CGLineJoin strokeJoin;
|
||||
@property (nonatomic, assign) ARTCGFloatArray strokeDash;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTRenderable.h"
|
||||
|
||||
@implementation ARTRenderable
|
||||
|
||||
- (void)setFill:(ARTBrush *)fill
|
||||
{
|
||||
[self invalidate];
|
||||
_fill = fill;
|
||||
}
|
||||
|
||||
- (void)setStroke:(CGColorRef)stroke
|
||||
{
|
||||
if (stroke == _stroke) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
CGColorRelease(_stroke);
|
||||
_stroke = CGColorRetain(stroke);
|
||||
}
|
||||
|
||||
- (void)setStrokeWidth:(CGFloat)strokeWidth
|
||||
{
|
||||
[self invalidate];
|
||||
_strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
- (void)setStrokeCap:(CGLineCap)strokeCap
|
||||
{
|
||||
[self invalidate];
|
||||
_strokeCap = strokeCap;
|
||||
}
|
||||
|
||||
- (void)setStrokeJoin:(CGLineJoin)strokeJoin
|
||||
{
|
||||
[self invalidate];
|
||||
_strokeJoin = strokeJoin;
|
||||
}
|
||||
|
||||
- (void)setStrokeDash:(ARTCGFloatArray)strokeDash
|
||||
{
|
||||
if (strokeDash.array == _strokeDash.array) {
|
||||
return;
|
||||
}
|
||||
if (_strokeDash.array) {
|
||||
free(_strokeDash.array);
|
||||
}
|
||||
[self invalidate];
|
||||
_strokeDash = strokeDash;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGColorRelease(_stroke);
|
||||
if (_strokeDash.array) {
|
||||
free(_strokeDash.array);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)renderTo:(CGContextRef)context
|
||||
{
|
||||
if (self.opacity <= 0 || self.opacity >= 1 || (self.fill && self.stroke)) {
|
||||
// If we have both fill and stroke, we will need to paint this using normal compositing
|
||||
[super renderTo: context];
|
||||
return;
|
||||
}
|
||||
// This is a terminal with only one painting. Therefore we don't need to paint this
|
||||
// off-screen. We can just composite it straight onto the buffer.
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, self.opacity);
|
||||
[self renderLayerTo:context];
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @providesModule ARTSerializablePath
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
// TODO: Move this into an ART mode called "serialized" or something
|
||||
|
||||
var Class = require('art/core/class.js');
|
||||
var Path = require('art/core/path.js');
|
||||
|
||||
var MOVE_TO = 0;
|
||||
var CLOSE = 1;
|
||||
var LINE_TO = 2;
|
||||
var CURVE_TO = 3;
|
||||
var ARC = 4;
|
||||
|
||||
var SerializablePath = Class(Path, {
|
||||
|
||||
initialize: function(path) {
|
||||
this.reset();
|
||||
if (path instanceof SerializablePath) {
|
||||
this.path = path.path.slice(0);
|
||||
} else if (path) {
|
||||
if (path.applyToPath) {
|
||||
path.applyToPath(this);
|
||||
} else {
|
||||
this.push(path);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onReset: function() {
|
||||
this.path = [];
|
||||
},
|
||||
|
||||
onMove: function(sx, sy, x, y) {
|
||||
this.path.push(MOVE_TO, x, y);
|
||||
},
|
||||
|
||||
onLine: function(sx, sy, x, y) {
|
||||
this.path.push(LINE_TO, x, y);
|
||||
},
|
||||
|
||||
onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y) {
|
||||
this.path.push(CURVE_TO, p1x, p1y, p2x, p2y, x, y);
|
||||
},
|
||||
|
||||
_arcToBezier: Path.prototype.onArc,
|
||||
|
||||
onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation) {
|
||||
if (rx !== ry || rotation) {
|
||||
return this._arcToBezier(
|
||||
sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation
|
||||
);
|
||||
}
|
||||
this.path.push(ARC, cx, cy, rx, sa, ea, ccw ? 0 : 1);
|
||||
},
|
||||
|
||||
onClose: function() {
|
||||
this.path.push(CLOSE);
|
||||
},
|
||||
|
||||
toJSON: function() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = SerializablePath;
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "ARTRenderable.h"
|
||||
|
||||
@interface ARTShape : ARTRenderable
|
||||
|
||||
@property (nonatomic, assign) CGPathRef d;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTShape.h"
|
||||
|
||||
@implementation ARTShape
|
||||
|
||||
- (void)setD:(CGPathRef)d
|
||||
{
|
||||
if (d == _d) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
CGPathRelease(_d);
|
||||
_d = CGPathRetain(d);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGPathRelease(_d);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
if ((!self.fill && !self.stroke) || !self.d) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGPathDrawingMode mode = kCGPathStroke;
|
||||
if (self.fill) {
|
||||
if ([self.fill applyFillColor:context]) {
|
||||
mode = kCGPathFill;
|
||||
} else {
|
||||
CGContextSaveGState(context);
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextClip(context);
|
||||
[self.fill paint:context];
|
||||
CGContextRestoreGState(context);
|
||||
if (!self.stroke) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self.stroke) {
|
||||
CGContextSetStrokeColorWithColor(context, self.stroke);
|
||||
CGContextSetLineWidth(context, self.strokeWidth);
|
||||
CGContextSetLineCap(context, self.strokeCap);
|
||||
CGContextSetLineJoin(context, self.strokeJoin);
|
||||
ARTCGFloatArray dash = self.strokeDash;
|
||||
if (dash.count) {
|
||||
CGContextSetLineDash(context, 0, dash.array, dash.count);
|
||||
}
|
||||
if (mode == kCGPathFill) {
|
||||
mode = kCGPathFillStroke;
|
||||
}
|
||||
}
|
||||
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextDrawPath(context, mode);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "ARTContainer.h"
|
||||
|
||||
@interface ARTSurfaceView : UIView <ARTContainer>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTSurfaceView.h"
|
||||
|
||||
#import "ARTNode.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation ARTSurfaceView
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
for (ARTNode *node in self.subviews) {
|
||||
[node renderTo:context];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "ARTRenderable.h"
|
||||
#import "ARTTextFrame.h"
|
||||
|
||||
@interface ARTText : ARTRenderable
|
||||
|
||||
@property (nonatomic, assign) CTTextAlignment alignment;
|
||||
@property (nonatomic, assign) ARTTextFrame textFrame;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTText.h"
|
||||
|
||||
#import <CoreText/CoreText.h>
|
||||
|
||||
@implementation ARTText
|
||||
|
||||
- (void)setAlignment:(CTTextAlignment)alignment
|
||||
{
|
||||
[self invalidate];
|
||||
_alignment = alignment;
|
||||
}
|
||||
|
||||
- (void)setTextFrame:(ARTTextFrame)frame
|
||||
{
|
||||
if (frame.lines != _textFrame.lines && _textFrame.count) {
|
||||
// We must release each line before overriding the old one
|
||||
for (int i = 0; i < _textFrame.count; i++) {
|
||||
CFRelease(_textFrame.lines[0]);
|
||||
}
|
||||
free(_textFrame.lines);
|
||||
free(_textFrame.widths);
|
||||
}
|
||||
[self invalidate];
|
||||
_textFrame = frame;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (_textFrame.count) {
|
||||
// We must release each line before freeing up this struct
|
||||
for (int i = 0; i < _textFrame.count; i++) {
|
||||
CFRelease(_textFrame.lines[0]);
|
||||
}
|
||||
free(_textFrame.lines);
|
||||
free(_textFrame.widths);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
ARTTextFrame frame = self.textFrame;
|
||||
|
||||
if ((!self.fill && !self.stroke) || !frame.count) {
|
||||
return;
|
||||
}
|
||||
|
||||
// to-do: draw along a path
|
||||
|
||||
CGTextDrawingMode mode = kCGTextStroke;
|
||||
if (self.fill) {
|
||||
if ([self.fill applyFillColor:context]) {
|
||||
mode = kCGTextFill;
|
||||
} else {
|
||||
|
||||
for (int i = 0; i < frame.count; i++) {
|
||||
CGContextSaveGState(context);
|
||||
// Inverse the coordinate space since CoreText assumes a bottom-up coordinate space
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
CGContextSetTextDrawingMode(context, kCGTextClip);
|
||||
[self renderLineTo:context atIndex:i];
|
||||
// Inverse the coordinate space back to the original before filling
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
[self.fill paint:context];
|
||||
// Restore the state so that the next line can be clipped separately
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
if (!self.stroke) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self.stroke) {
|
||||
CGContextSetStrokeColorWithColor(context, self.stroke);
|
||||
CGContextSetLineWidth(context, self.strokeWidth);
|
||||
CGContextSetLineCap(context, self.strokeCap);
|
||||
CGContextSetLineJoin(context, self.strokeJoin);
|
||||
ARTCGFloatArray dash = self.strokeDash;
|
||||
if (dash.count) {
|
||||
CGContextSetLineDash(context, 0, dash.array, dash.count);
|
||||
}
|
||||
if (mode == kCGTextFill) {
|
||||
mode = kCGTextFillStroke;
|
||||
}
|
||||
}
|
||||
|
||||
CGContextSetTextDrawingMode(context, mode);
|
||||
|
||||
// Inverse the coordinate space since CoreText assumes a bottom-up coordinate space
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
for (int i = 0; i < frame.count; i++) {
|
||||
[self renderLineTo:context atIndex:i];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)renderLineTo:(CGContextRef)context atIndex:(int)index
|
||||
{
|
||||
ARTTextFrame frame = self.textFrame;
|
||||
CGFloat shift;
|
||||
switch (self.alignment) {
|
||||
case kCTTextAlignmentRight:
|
||||
shift = frame.widths[index];
|
||||
break;
|
||||
case kCTTextAlignmentCenter:
|
||||
shift = (frame.widths[index] / 2);
|
||||
break;
|
||||
default:
|
||||
shift = 0;
|
||||
break;
|
||||
}
|
||||
// We should consider snapping this shift to device pixels to improve rendering quality
|
||||
// when a line has subpixel width.
|
||||
CGContextSetTextPosition(context, -shift, -frame.baseLine - frame.lineHeight * index);
|
||||
CTLineRef line = frame.lines[index];
|
||||
CTLineDraw(line, context);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <CoreText/CoreText.h>
|
||||
|
||||
// A little helper to make sure we have a set of lines including width ready for use.
|
||||
// We assume that we will only this in one place so no reference counting is necessary.
|
||||
// Needs to be freed when dealloced.
|
||||
|
||||
// This is fragile since this relies on these values not getting reused. Consider
|
||||
// wrapping these in an Obj-C class or some ARC hackery to get refcounting.
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
CGFloat baseLine; // Distance from the origin to the base line of the first line
|
||||
CGFloat lineHeight; // Distance between lines
|
||||
CTLineRef *lines;
|
||||
CGFloat *widths; // Width of each line
|
||||
} ARTTextFrame;
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface ARTBrush : NSObject
|
||||
|
||||
/* @abstract */
|
||||
- (instancetype)initWithArray:(NSArray *)data NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* For certain brushes we can fast path a combined fill and stroke.
|
||||
* For those brushes we override applyFillColor which sets the fill
|
||||
* color to be used by those batch paints. Those return YES.
|
||||
* We can't batch gradient painting in CoreGraphics, so those will
|
||||
* return NO and paint gets called instead.
|
||||
* @abstract
|
||||
*/
|
||||
- (BOOL)applyFillColor:(CGContextRef)context;
|
||||
|
||||
/**
|
||||
* paint fills the context with a brush. The context is assumed to
|
||||
* be clipped.
|
||||
* @abstract
|
||||
*/
|
||||
- (void)paint:(CGContextRef)context;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTBrush.h"
|
||||
|
||||
@implementation ARTBrush
|
||||
|
||||
- (instancetype)initWithArray:(NSArray *)data
|
||||
{
|
||||
return [super init];
|
||||
}
|
||||
|
||||
- (BOOL)applyFillColor:(CGContextRef)context
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)paint:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTBrush.h"
|
||||
|
||||
@interface ARTLinearGradient : ARTBrush
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTLinearGradient.h"
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation ARTLinearGradient
|
||||
{
|
||||
CGGradientRef _gradient;
|
||||
CGPoint _startPoint;
|
||||
CGPoint _endPoint;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
if (array.count < 5) {
|
||||
RCTLogError(@"-[%@ %@] expects 5 elements, received %@",
|
||||
self.class, NSStringFromSelector(_cmd), array);
|
||||
return nil;
|
||||
}
|
||||
_startPoint = [RCTConvert CGPoint:array offset:1];
|
||||
_endPoint = [RCTConvert CGPoint:array offset:3];
|
||||
_gradient = CGGradientRetain([RCTConvert CGGradient:array offset:5]);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGGradientRelease(_gradient);
|
||||
}
|
||||
|
||||
- (void)paint:(CGContextRef)context
|
||||
{
|
||||
CGGradientDrawingOptions extendOptions =
|
||||
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
|
||||
CGContextDrawLinearGradient(context, _gradient, _startPoint, _endPoint, extendOptions);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTBrush.h"
|
||||
|
||||
@interface ARTPattern : ARTBrush
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTPattern.h"
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation ARTPattern
|
||||
{
|
||||
CGImageRef _image;
|
||||
CGRect _rect;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
if (array.count < 6) {
|
||||
RCTLogError(@"-[%@ %@] expects 6 elements, received %@",
|
||||
self.class, NSStringFromSelector(_cmd), array);
|
||||
return nil;
|
||||
}
|
||||
_image = CGImageRetain([RCTConvert CGImage:array[1]]);
|
||||
_rect = [RCTConvert CGRect:array offset:2];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGImageRelease(_image);
|
||||
}
|
||||
|
||||
// Note: This could use applyFillColor with a pattern. This could be more efficient but
|
||||
// to do that, we need to calculate our own user space CTM.
|
||||
|
||||
- (void)paint:(CGContextRef)context
|
||||
{
|
||||
CGContextDrawTiledImage(context, _rect, _image);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTBrush.h"
|
||||
|
||||
@interface ARTRadialGradient : ARTBrush
|
||||
|
||||
@end
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
#import "ARTRadialGradient.h"
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation ARTRadialGradient
|
||||
{
|
||||
CGGradientRef _gradient;
|
||||
CGPoint _focusPoint;
|
||||
CGPoint _centerPoint;
|
||||
CGFloat _radius;
|
||||
CGFloat _radiusRatio;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
if (array.count < 7) {
|
||||
RCTLogError(@"-[%@ %@] expects 7 elements, received %@",
|
||||
self.class, NSStringFromSelector(_cmd), array);
|
||||
return nil;
|
||||
}
|
||||
_radius = [RCTConvert CGFloat:array[3]];
|
||||
_radiusRatio = [RCTConvert CGFloat:array[4]] / _radius;
|
||||
_focusPoint.x = [RCTConvert CGFloat:array[1]];
|
||||
_focusPoint.y = [RCTConvert CGFloat:array[2]] / _radiusRatio;
|
||||
_centerPoint.x = [RCTConvert CGFloat:array[5]];
|
||||
_centerPoint.y = [RCTConvert CGFloat:array[6]] / _radiusRatio;
|
||||
_gradient = CGGradientRetain([RCTConvert CGGradient:array offset:7]);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGGradientRelease(_gradient);
|
||||
}
|
||||
|
||||
- (void)paint:(CGContextRef)context
|
||||
{
|
||||
CGAffineTransform transform = CGAffineTransformMakeScale(1, _radiusRatio);
|
||||
CGContextConcatCTM(context, transform);
|
||||
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
|
||||
CGContextDrawRadialGradient(context, _gradient, _focusPoint, 0, _centerPoint, _radius, extendOptions);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTBrush.h"
|
||||
|
||||
@interface ARTSolidColor : ARTBrush
|
||||
|
||||
@end
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
#import "ARTSolidColor.h"
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation ARTSolidColor
|
||||
{
|
||||
CGColorRef _color;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
_color = CGColorRetain([RCTConvert CGColor:array offset:1]);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGColorRelease(_color);
|
||||
}
|
||||
|
||||
- (BOOL)applyFillColor:(CGContextRef)context
|
||||
{
|
||||
CGContextSetFillColorWithColor(context, _color);
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
#import "ARTBrush.h"
|
||||
#import "ARTCGFloatArray.h"
|
||||
#import "ARTTextFrame.h"
|
||||
#import "RCTConvert.h"
|
||||
|
||||
@interface RCTConvert (ART)
|
||||
|
||||
+ (CGPathRef)CGPath:(id)json;
|
||||
+ (CTFontRef)CTFont:(id)json;
|
||||
+ (CTTextAlignment)CTTextAlignment:(id)json;
|
||||
+ (ARTTextFrame)ARTTextFrame:(id)json;
|
||||
+ (ARTCGFloatArray)ARTCGFloatArray:(id)json;
|
||||
+ (ARTBrush *)ARTBrush:(id)json;
|
||||
|
||||
+ (CGPoint)CGPoint:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGRect)CGRect:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGColorRef)CGColor:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGGradientRef)CGGradient:(id)json offset:(NSUInteger)offset;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
|
||||
#import "ARTLinearGradient.h"
|
||||
#import "ARTPattern.h"
|
||||
#import "ARTRadialGradient.h"
|
||||
#import "ARTSolidColor.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RCTConvert (ART)
|
||||
|
||||
+ (CGPathRef)CGPath:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSNumberArray:json];
|
||||
|
||||
NSUInteger count = [arr count];
|
||||
|
||||
#define NEXT_VALUE [self double:arr[i++]]
|
||||
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathMoveToPoint(path, NULL, 0, 0);
|
||||
|
||||
@try {
|
||||
NSUInteger i = 0;
|
||||
while (i < count) {
|
||||
NSUInteger type = [arr[i++] unsignedIntegerValue];
|
||||
switch (type) {
|
||||
case 0:
|
||||
CGPathMoveToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 1:
|
||||
CGPathCloseSubpath(path);
|
||||
break;
|
||||
case 2:
|
||||
CGPathAddLineToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 3:
|
||||
CGPathAddCurveToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 4:
|
||||
CGPathAddArc(path, NULL, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE == 0);
|
||||
break;
|
||||
default:
|
||||
RCTLogError(@"Invalid CGPath type %zd at element %zd of %@", type, i, arr);
|
||||
CGPathRelease(path);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
RCTLogError(@"Invalid CGPath format: %@", arr);
|
||||
CGPathRelease(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (CGPathRef)CFAutorelease(path);
|
||||
}
|
||||
|
||||
+ (CTFontRef)CTFont:(id)json
|
||||
{
|
||||
NSDictionary *dict = [self NSDictionary:json];
|
||||
if (!dict) {
|
||||
return nil;
|
||||
}
|
||||
CTFontDescriptorRef fontDescriptor = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)dict);
|
||||
CTFontRef font = CTFontCreateWithFontDescriptor(fontDescriptor, 0.0, NULL);
|
||||
CFRelease(fontDescriptor);
|
||||
return (CTFontRef)CFAutorelease(font);
|
||||
}
|
||||
|
||||
RCT_ENUM_CONVERTER(CTTextAlignment, (@{
|
||||
@"auto": @(kCTTextAlignmentNatural),
|
||||
@"left": @(kCTTextAlignmentLeft),
|
||||
@"center": @(kCTTextAlignmentCenter),
|
||||
@"right": @(kCTTextAlignmentRight),
|
||||
@"justify": @(kCTTextAlignmentJustified),
|
||||
}), kCTTextAlignmentNatural, integerValue)
|
||||
|
||||
// This takes a tuple of text lines and a font to generate a CTLine for each text line.
|
||||
// This prepares everything for rendering a frame of text in ARTText.
|
||||
+ (ARTTextFrame)ARTTextFrame:(id)json
|
||||
{
|
||||
NSDictionary *dict = [self NSDictionary:json];
|
||||
ARTTextFrame frame;
|
||||
frame.count = 0;
|
||||
|
||||
NSArray *lines = [self NSArray:dict[@"lines"]];
|
||||
NSUInteger lineCount = [lines count];
|
||||
if (lineCount == 0) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
CTFontRef font = [self CTFont:dict[@"font"]];
|
||||
if (!font) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Create a dictionary for this font
|
||||
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{
|
||||
(NSString *)kCTFontAttributeName: (__bridge id)font,
|
||||
(NSString *)kCTForegroundColorFromContextAttributeName: @YES
|
||||
};
|
||||
|
||||
// Set up text frame with font metrics
|
||||
CGFloat size = CTFontGetSize(font);
|
||||
frame.count = lineCount;
|
||||
frame.baseLine = size; // estimate base line
|
||||
frame.lineHeight = size * 1.1; // Base on ART canvas line height estimate
|
||||
frame.lines = malloc(sizeof(CTLineRef) * lineCount);
|
||||
frame.widths = malloc(sizeof(CGFloat) * lineCount);
|
||||
|
||||
[lines enumerateObjectsUsingBlock:^(NSString *text, NSUInteger i, BOOL *stop) {
|
||||
|
||||
CFStringRef string = (__bridge CFStringRef)text;
|
||||
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
||||
CTLineRef line = CTLineCreateWithAttributedString(attrString);
|
||||
CFRelease(attrString);
|
||||
|
||||
frame.lines[i] = line;
|
||||
frame.widths[i] = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
|
||||
}];
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
+ (ARTCGFloatArray)ARTCGFloatArray:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSNumberArray:json];
|
||||
NSUInteger count = arr.count;
|
||||
|
||||
ARTCGFloatArray array;
|
||||
array.count = count;
|
||||
array.array = NULL;
|
||||
|
||||
if (count) {
|
||||
// Ideally, these arrays should already use the same memory layout.
|
||||
// In that case we shouldn't need this new malloc.
|
||||
array.array = malloc(sizeof(CGFloat) * count);
|
||||
for (NSUInteger i = 0; i < count; i++) {
|
||||
array.array[i] = [arr[i] doubleValue];
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
+ (ARTBrush *)ARTBrush:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
NSUInteger type = [self NSUInteger:arr[0]];
|
||||
switch (type) {
|
||||
case 0: // solid color
|
||||
// These are probably expensive allocations since it's often the same value.
|
||||
// We should memoize colors but look ups may be just as expensive.
|
||||
return [[ARTSolidColor alloc] initWithArray:arr];
|
||||
case 1: // linear gradient
|
||||
return [[ARTLinearGradient alloc] initWithArray:arr];
|
||||
case 2: // radial gradient
|
||||
return [[ARTRadialGradient alloc] initWithArray:arr];
|
||||
case 3: // pattern
|
||||
return [[ARTPattern alloc] initWithArray:arr];
|
||||
default:
|
||||
RCTLogError(@"Unknown brush type: %zd", type);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
+ (CGPoint)CGPoint:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 2) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", 2 + offset, arr);
|
||||
return CGPointZero;
|
||||
}
|
||||
return (CGPoint){
|
||||
[self CGFloat:arr[offset]],
|
||||
[self CGFloat:arr[offset + 1]],
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGRect)CGRect:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 4) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", 4 + offset, arr);
|
||||
return CGRectZero;
|
||||
}
|
||||
return (CGRect){
|
||||
{[self CGFloat:arr[offset]], [self CGFloat:arr[offset + 1]]},
|
||||
{[self CGFloat:arr[offset + 2]], [self CGFloat:arr[offset + 3]]},
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGColorRef)CGColor:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 4) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", 4 + offset, arr);
|
||||
return NULL;
|
||||
}
|
||||
return [self CGColor:[arr subarrayWithRange:(NSRange){offset, 4}]];
|
||||
}
|
||||
|
||||
+ (CGGradientRef)CGGradient:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", offset, arr);
|
||||
return NULL;
|
||||
}
|
||||
arr = [arr subarrayWithRange:(NSRange){offset, arr.count - offset}];
|
||||
ARTCGFloatArray colorsAndOffsets = [self ARTCGFloatArray:arr];
|
||||
size_t stops = colorsAndOffsets.count / 5;
|
||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
||||
CGGradientRef gradient = CGGradientCreateWithColorComponents(
|
||||
rgb,
|
||||
colorsAndOffsets.array,
|
||||
colorsAndOffsets.array + stops * 4,
|
||||
stops
|
||||
);
|
||||
CGColorSpaceRelease(rgb);
|
||||
free(colorsAndOffsets.array);
|
||||
return (CGGradientRef)CFAutorelease(gradient);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,611 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @providesModule ReactIOSART
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var Color = require('art/core/color');
|
||||
var Path = require('ARTSerializablePath');
|
||||
var Transform = require('art/core/transform');
|
||||
|
||||
var React = require('React');
|
||||
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
|
||||
|
||||
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
|
||||
var merge = require('merge');
|
||||
|
||||
// Diff Helpers
|
||||
|
||||
function arrayDiffer(a, b) {
|
||||
if (a == null) {
|
||||
return true;
|
||||
}
|
||||
if (a.length !== b.length) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function fontAndLinesDiffer(a, b) {
|
||||
if (a === b) {
|
||||
return false;
|
||||
}
|
||||
if (a.font !== b.font) {
|
||||
if (a.font === null) {
|
||||
return true;
|
||||
}
|
||||
if (b.font === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var aTraits = a.font.NSCTFontTraitsAttribute;
|
||||
var bTraits = b.font.NSCTFontTraitsAttribute;
|
||||
|
||||
if (
|
||||
a.font.fontFamily !== b.font.fontFamily ||
|
||||
a.font.fontSize !== b.font.fontSize ||
|
||||
a.font.fontWeight !== b.font.fontWeight ||
|
||||
a.font.fontStyle !== b.font.fontStyle ||
|
||||
// TODO(6364240): remove iOS-specific attrs
|
||||
a.font.NSFontFamilyAttribute !== b.font.NSFontFamilyAttribute ||
|
||||
a.font.NSFontSizeAttribute !== b.font.NSFontSizeAttribute ||
|
||||
aTraits.NSCTFontSymbolicTrait !== bTraits.NSCTFontSymbolicTrait
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return arrayDiffer(a.lines, b.lines);
|
||||
}
|
||||
|
||||
// Native Attributes
|
||||
|
||||
var SurfaceViewAttributes = merge(ReactIOSViewAttributes.UIView, {
|
||||
// This should contain pixel information such as width, height and
|
||||
// resolution to know what kind of buffer needs to be allocated.
|
||||
// Currently we rely on UIViews and style to figure that out.
|
||||
});
|
||||
|
||||
var NodeAttributes = {
|
||||
transform: { diff: arrayDiffer },
|
||||
opacity: true,
|
||||
};
|
||||
|
||||
var GroupAttributes = merge(NodeAttributes, {
|
||||
clipping: { diff: arrayDiffer }
|
||||
});
|
||||
|
||||
var RenderableAttributes = merge(NodeAttributes, {
|
||||
fill: { diff: arrayDiffer },
|
||||
stroke: { diff: arrayDiffer },
|
||||
strokeWidth: true,
|
||||
strokeCap: true,
|
||||
strokeJoin: true,
|
||||
strokeDash: { diff: arrayDiffer },
|
||||
});
|
||||
|
||||
var ShapeAttributes = merge(RenderableAttributes, {
|
||||
d: { diff: arrayDiffer },
|
||||
});
|
||||
|
||||
var TextAttributes = merge(RenderableAttributes, {
|
||||
alignment: true,
|
||||
frame: { diff: fontAndLinesDiffer },
|
||||
path: { diff: arrayDiffer }
|
||||
});
|
||||
|
||||
// Native Components
|
||||
|
||||
var NativeSurfaceView = createReactIOSNativeComponentClass({
|
||||
validAttributes: SurfaceViewAttributes,
|
||||
uiViewClassName: 'ARTSurfaceView',
|
||||
});
|
||||
|
||||
var NativeGroup = createReactIOSNativeComponentClass({
|
||||
validAttributes: GroupAttributes,
|
||||
uiViewClassName: 'ARTGroup',
|
||||
});
|
||||
|
||||
var NativeShape = createReactIOSNativeComponentClass({
|
||||
validAttributes: ShapeAttributes,
|
||||
uiViewClassName: 'ARTShape',
|
||||
});
|
||||
|
||||
var NativeText = createReactIOSNativeComponentClass({
|
||||
validAttributes: TextAttributes,
|
||||
uiViewClassName: 'ARTText',
|
||||
});
|
||||
|
||||
// Utilities
|
||||
|
||||
function childrenAsString(children) {
|
||||
if (!children) {
|
||||
return '';
|
||||
}
|
||||
if (typeof children === 'string') {
|
||||
return children;
|
||||
}
|
||||
if (children.length) {
|
||||
return children.join('\n');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// Surface - Root node of all ART
|
||||
|
||||
var Surface = React.createClass({
|
||||
|
||||
render: function() {
|
||||
var props = this.props;
|
||||
var w = extractNumber(props.width, 0);
|
||||
var h = extractNumber(props.height, 0);
|
||||
return (
|
||||
<NativeSurfaceView style={[props.style, { width: w, height: h }]}>
|
||||
{this.props.children}
|
||||
</NativeSurfaceView>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Node Props
|
||||
|
||||
// TODO: The desktop version of ART has title and cursor. We should have
|
||||
// accessibility support here too even though hovering doesn't work.
|
||||
|
||||
function extractNumber(value, defaultValue) {
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return +value;
|
||||
}
|
||||
|
||||
var pooledTransform = new Transform();
|
||||
|
||||
function extractTransform(props) {
|
||||
var scaleX = props.scaleX != null ? props.scaleX :
|
||||
props.scale != null ? props.scale : 1;
|
||||
var scaleY = props.scaleY != null ? props.scaleY :
|
||||
props.scale != null ? props.scale : 1;
|
||||
|
||||
pooledTransform
|
||||
.transformTo(1, 0, 0, 1, 0, 0)
|
||||
.move(props.x || 0, props.y || 0)
|
||||
.rotate(props.rotation || 0, props.originX, props.originY)
|
||||
.scale(scaleX, scaleY, props.originX, props.originY);
|
||||
|
||||
if (props.transform != null) {
|
||||
pooledTransform.transform(props.transform);
|
||||
}
|
||||
|
||||
return [
|
||||
pooledTransform.xx, pooledTransform.yx,
|
||||
pooledTransform.xy, pooledTransform.yy,
|
||||
pooledTransform.x, pooledTransform.y,
|
||||
];
|
||||
}
|
||||
|
||||
function extractOpacity(props) {
|
||||
// TODO: visible === false should also have no hit detection
|
||||
if (props.visible === false) {
|
||||
return 0;
|
||||
}
|
||||
if (props.opacity == null) {
|
||||
return 1;
|
||||
}
|
||||
return +props.opacity;
|
||||
}
|
||||
|
||||
// Groups
|
||||
|
||||
// Note: ART has a notion of width and height on Group but AFAIK it's a noop in
|
||||
// ReactART.
|
||||
|
||||
var Group = React.createClass({
|
||||
|
||||
render: function() {
|
||||
var props = this.props;
|
||||
return (
|
||||
<NativeGroup
|
||||
opacity={extractOpacity(props)}
|
||||
transform={extractTransform(props)}>
|
||||
{this.props.children}
|
||||
</NativeGroup>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var ClippingRectangle = React.createClass({
|
||||
|
||||
render: function() {
|
||||
var props = this.props;
|
||||
var x = extractNumber(props.x, 0);
|
||||
var y = extractNumber(props.y, 0);
|
||||
var w = extractNumber(props.width, 0);
|
||||
var h = extractNumber(props.height, 0);
|
||||
var clipping = new Path()
|
||||
.moveTo(x, y)
|
||||
.line(w, 0)
|
||||
.line(0, h)
|
||||
.line(w, 0)
|
||||
.close()
|
||||
.toJSON();
|
||||
// The current clipping API requires x and y to be ignored in the transform
|
||||
var propsExcludingXAndY = merge(props);
|
||||
delete propsExcludingXAndY.x;
|
||||
delete propsExcludingXAndY.y;
|
||||
return (
|
||||
<NativeGroup
|
||||
clipping={clipping}
|
||||
opacity={extractOpacity(props)}
|
||||
transform={extractTransform(propsExcludingXAndY)}>
|
||||
{this.props.children}
|
||||
</NativeGroup>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Renderables
|
||||
|
||||
var SOLID_COLOR = 0;
|
||||
var LINEAR_GRADIENT = 1;
|
||||
var RADIAL_GRADIENT = 2;
|
||||
var PATTERN = 3;
|
||||
|
||||
function insertColorIntoArray(color, targetArray, atIndex) {
|
||||
var c = new Color(color);
|
||||
targetArray[atIndex + 0] = c.red / 255;
|
||||
targetArray[atIndex + 1] = c.green / 255;
|
||||
targetArray[atIndex + 2] = c.blue / 255;
|
||||
targetArray[atIndex + 3] = c.alpha;
|
||||
}
|
||||
|
||||
function insertColorsIntoArray(stops, targetArray, atIndex) {
|
||||
var i = 0;
|
||||
if ('length' in stops) {
|
||||
while (i < stops.length) {
|
||||
insertColorIntoArray(stops[i], targetArray, atIndex + i * 4);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (var offset in stops) {
|
||||
insertColorIntoArray(stops[offset], targetArray, atIndex + i * 4);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return atIndex + i * 4;
|
||||
}
|
||||
|
||||
function insertOffsetsIntoArray(stops, targetArray, atIndex, multi, reverse) {
|
||||
var offsetNumber;
|
||||
var i = 0;
|
||||
if ('length' in stops) {
|
||||
while (i < stops.length) {
|
||||
offsetNumber = i / (stops.length - 1) * multi;
|
||||
targetArray[atIndex + i] = reverse ? 1 - offsetNumber : offsetNumber;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (var offsetString in stops) {
|
||||
offsetNumber = (+offsetString) * multi;
|
||||
targetArray[atIndex + i] = reverse ? 1 - offsetNumber : offsetNumber;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return atIndex + i;
|
||||
}
|
||||
|
||||
function insertColorStopsIntoArray(stops, targetArray, atIndex) {
|
||||
var lastIndex = insertColorsIntoArray(stops, targetArray, atIndex);
|
||||
insertOffsetsIntoArray(stops, targetArray, lastIndex, 1, false);
|
||||
}
|
||||
|
||||
function insertDoubleColorStopsIntoArray(stops, targetArray, atIndex) {
|
||||
var lastIndex = insertColorsIntoArray(stops, targetArray, atIndex);
|
||||
lastIndex = insertColorsIntoArray(stops, targetArray, lastIndex);
|
||||
lastIndex = insertOffsetsIntoArray(stops, targetArray, lastIndex, 0.5, false);
|
||||
insertOffsetsIntoArray(stops, targetArray, lastIndex, 0.5, true);
|
||||
}
|
||||
|
||||
function applyBoundingBoxToBrushData(brushData, props) {
|
||||
var type = brushData[0];
|
||||
var width = +props.width;
|
||||
var height = +props.height;
|
||||
if (type === LINEAR_GRADIENT) {
|
||||
brushData[1] *= width;
|
||||
brushData[2] *= height;
|
||||
brushData[3] *= width;
|
||||
brushData[4] *= height;
|
||||
} else if (type === RADIAL_GRADIENT) {
|
||||
brushData[1] *= width;
|
||||
brushData[2] *= height;
|
||||
brushData[3] *= width;
|
||||
brushData[4] *= height;
|
||||
brushData[5] *= width;
|
||||
brushData[6] *= height;
|
||||
} else if (type === PATTERN) {
|
||||
// todo
|
||||
}
|
||||
}
|
||||
|
||||
function extractBrush(colorOrBrush, props) {
|
||||
if (colorOrBrush == null) {
|
||||
return null;
|
||||
}
|
||||
if (colorOrBrush._brush) {
|
||||
if (colorOrBrush._bb) {
|
||||
// The legacy API for Gradients allow for the bounding box to be used
|
||||
// as a convenience for specifying gradient positions. This should be
|
||||
// deprecated. It's not properly implemented in canvas mode. ReactART
|
||||
// doesn't handle update to the bounding box correctly. That's why we
|
||||
// mutate this so that if it's reused, we reuse the same resolved box.
|
||||
applyBoundingBoxToBrushData(colorOrBrush._brush, props);
|
||||
colorOrBrush._bb = false;
|
||||
}
|
||||
return colorOrBrush._brush;
|
||||
}
|
||||
var c = new Color(colorOrBrush);
|
||||
return [SOLID_COLOR, c.red / 255, c.green / 255, c.blue / 255, c.alpha];
|
||||
}
|
||||
|
||||
function extractColor(color) {
|
||||
if (color == null) {
|
||||
return null;
|
||||
}
|
||||
var c = new Color(color);
|
||||
return [c.red / 255, c.green / 255, c.blue / 255, c.alpha];
|
||||
}
|
||||
|
||||
function extractStrokeCap(strokeCap) {
|
||||
switch (strokeCap) {
|
||||
case 'butt': return 0;
|
||||
case 'square': return 2;
|
||||
default: return 1; // round
|
||||
}
|
||||
}
|
||||
|
||||
function extractStrokeJoin(strokeJoin) {
|
||||
switch (strokeJoin) {
|
||||
case 'miter': return 0;
|
||||
case 'bevel': return 2;
|
||||
default: return 1; // round
|
||||
}
|
||||
}
|
||||
|
||||
// Shape
|
||||
|
||||
// Note: ART has a notion of width and height on Shape but AFAIK it's a noop in
|
||||
// ReactART.
|
||||
|
||||
var Shape = React.createClass({
|
||||
|
||||
render: function() {
|
||||
var props = this.props;
|
||||
var path = props.d || childrenAsString(props.children);
|
||||
var d = new Path(path).toJSON();
|
||||
return (
|
||||
<NativeShape
|
||||
fill={extractBrush(props.fill, props)}
|
||||
opacity={extractOpacity(props)}
|
||||
stroke={extractColor(props.stroke)}
|
||||
strokeCap={extractStrokeCap(props.strokeCap)}
|
||||
strokeDash={props.strokeDash || null}
|
||||
strokeJoin={extractStrokeJoin(props.strokeJoin)}
|
||||
strokeWidth={extractNumber(props.strokeWidth, 1)}
|
||||
transform={extractTransform(props)}
|
||||
|
||||
d={d}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Text
|
||||
|
||||
var cachedFontObjectsFromString = {};
|
||||
|
||||
function extractFontTraits(isBold, isItalic) {
|
||||
var italic = isItalic ? 1 : 0;
|
||||
var bold = isBold ? 2 : 0;
|
||||
return {
|
||||
NSCTFontSymbolicTrait: italic | bold
|
||||
};
|
||||
}
|
||||
|
||||
var fontFamilyPrefix = /^[\s"']*/;
|
||||
var fontFamilySuffix = /[\s"']*$/;
|
||||
|
||||
function extractSingleFontFamily(fontFamilyString) {
|
||||
// ART on the web allows for multiple font-families to be specified.
|
||||
// For compatibility, we extract the first font-family, hoping
|
||||
// we'll get a match.
|
||||
return fontFamilyString.split(',')[0]
|
||||
.replace(fontFamilyPrefix, '')
|
||||
.replace(fontFamilySuffix, '');
|
||||
}
|
||||
|
||||
function parseFontString(font) {
|
||||
if (cachedFontObjectsFromString.hasOwnProperty(font)) {
|
||||
return cachedFontObjectsFromString[font];
|
||||
}
|
||||
var regexp = /^\s*((?:(?:normal|bold|italic)\s+)*)(?:(\d+(?:\.\d+)?)[ptexm\%]*(?:\s*\/.*?)?\s+)?\s*\"?([^\"]*)/i;
|
||||
var match = regexp.exec(font);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
var fontFamily = extractSingleFontFamily(match[3]);
|
||||
var fontSize = +match[2] || 12;
|
||||
var isBold = /bold/.exec(match[1]);
|
||||
var isItalic = /italic/.exec(match[1]);
|
||||
cachedFontObjectsFromString[font] = {
|
||||
fontFamily: fontFamily,
|
||||
fontSize: fontSize,
|
||||
fontWeight: isBold ? 'bold' : 'normal',
|
||||
fontStyle: isItalic ? 'italic' : 'normal',
|
||||
// TODO(6364240): remove iOS-specific attrs
|
||||
NSFontFamilyAttribute: fontFamily,
|
||||
NSFontSizeAttribute: fontSize,
|
||||
NSCTFontTraitsAttribute: extractFontTraits(isBold, isItalic)
|
||||
};
|
||||
return cachedFontObjectsFromString[font];
|
||||
}
|
||||
|
||||
function extractFont(font) {
|
||||
if (font == null) {
|
||||
return null;
|
||||
}
|
||||
if (typeof font === 'string') {
|
||||
return parseFontString(font);
|
||||
}
|
||||
var fontFamily = extractSingleFontFamily(font.fontFamily);
|
||||
var fontSize = +font.fontSize || 12;
|
||||
return {
|
||||
// Normalize
|
||||
fontFamily: fontFamily,
|
||||
fontSize: fontSize,
|
||||
fontWeight: font.fontWeight,
|
||||
fontStyle: font.fontStyle,
|
||||
// TODO(6364240): remove iOS-specific attrs
|
||||
NSFontFamilyAttribute: fontFamily,
|
||||
NSFontSizeAttribute: fontSize,
|
||||
NSCTFontTraitsAttribute: extractFontTraits(
|
||||
font.fontWeight === 'bold',
|
||||
font.fontStyle === 'italic'
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
var newLine = /\n/g;
|
||||
function extractFontAndLines(font, text) {
|
||||
return { font: extractFont(font), lines: text.split(newLine) };
|
||||
}
|
||||
|
||||
function extractAlignment(alignment) {
|
||||
switch (alignment) {
|
||||
case 'right':
|
||||
return 1;
|
||||
case 'center':
|
||||
return 2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
var Text = React.createClass({
|
||||
|
||||
render: function() {
|
||||
var props = this.props;
|
||||
var textPath = props.path ? new Path(props.path).toJSON() : null;
|
||||
var textFrame = extractFontAndLines(
|
||||
props.font,
|
||||
childrenAsString(props.children)
|
||||
);
|
||||
return (
|
||||
<NativeText
|
||||
fill={extractBrush(props.fill, props)}
|
||||
opacity={extractOpacity(props)}
|
||||
stroke={extractColor(props.stroke)}
|
||||
strokeCap={extractStrokeCap(props.strokeCap)}
|
||||
strokeDash={props.strokeDash || null}
|
||||
strokeJoin={extractStrokeJoin(props.strokeJoin)}
|
||||
strokeWidth={extractNumber(props.strokeWidth, 1)}
|
||||
transform={extractTransform(props)}
|
||||
|
||||
alignment={extractAlignment(props.alignment)}
|
||||
frame={textFrame}
|
||||
path={textPath}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Declarative fill type objects - API design not finalized
|
||||
|
||||
function LinearGradient(stops, x1, y1, x2, y2) {
|
||||
var type = LINEAR_GRADIENT;
|
||||
|
||||
if (arguments.length < 5) {
|
||||
var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
|
||||
|
||||
var x = Math.cos(angle);
|
||||
var y = -Math.sin(angle);
|
||||
var l = (Math.abs(x) + Math.abs(y)) / 2;
|
||||
|
||||
x *= l; y *= l;
|
||||
|
||||
x1 = 0.5 - x;
|
||||
x2 = 0.5 + x;
|
||||
y1 = 0.5 - y;
|
||||
y2 = 0.5 + y;
|
||||
this._bb = true;
|
||||
} else {
|
||||
this._bb = false;
|
||||
}
|
||||
|
||||
var brushData = [type, +x1, +y1, +x2, +y2];
|
||||
insertColorStopsIntoArray(stops, brushData, 5);
|
||||
this._brush = brushData;
|
||||
}
|
||||
|
||||
function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
|
||||
if (ry == null) {
|
||||
ry = rx;
|
||||
}
|
||||
if (cx == null) {
|
||||
cx = fx;
|
||||
}
|
||||
if (cy == null) {
|
||||
cy = fy;
|
||||
}
|
||||
if (fx == null) {
|
||||
// As a convenience we allow the whole radial gradient to cover the
|
||||
// bounding box. We should consider dropping this API.
|
||||
fx = fy = rx = ry = cx = cy = 0.5;
|
||||
this._bb = true;
|
||||
} else {
|
||||
this._bb = false;
|
||||
}
|
||||
// The ART API expects the radial gradient to be repeated at the edges.
|
||||
// To simulate this we render the gradient twice as large and add double
|
||||
// color stops. Ideally this API would become more restrictive so that this
|
||||
// extra work isn't needed.
|
||||
var brushData = [RADIAL_GRADIENT, +fx, +fy, +rx * 2, +ry * 2, +cx, +cy];
|
||||
insertDoubleColorStopsIntoArray(stops, brushData, 7);
|
||||
this._brush = brushData;
|
||||
}
|
||||
|
||||
function Pattern(url, width, height, left, top) {
|
||||
this._brush = [PATTERN, url, +left || 0, +top || 0, +width, +height];
|
||||
}
|
||||
|
||||
var ReactART = {
|
||||
|
||||
LinearGradient: LinearGradient,
|
||||
RadialGradient: RadialGradient,
|
||||
Pattern: Pattern,
|
||||
Transform: Transform,
|
||||
Path: Path,
|
||||
Surface: Surface,
|
||||
Group: Group,
|
||||
ClippingRectangle: ClippingRectangle,
|
||||
Shape: Shape,
|
||||
Text: Text,
|
||||
|
||||
};
|
||||
|
||||
module.exports = ReactART;
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTNodeManager.h"
|
||||
|
||||
@interface ARTGroupManager : ARTNodeManager
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTGroupManager.h"
|
||||
|
||||
#import "ARTGroup.h"
|
||||
|
||||
@implementation ARTGroupManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (ARTNode *)node
|
||||
{
|
||||
return [[ARTGroup alloc] init];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTNode.h"
|
||||
#import "RCTViewManager.h"
|
||||
|
||||
@interface ARTNodeManager : RCTViewManager
|
||||
|
||||
- (ARTNode *)node;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTNodeManager.h"
|
||||
|
||||
#import "ARTNode.h"
|
||||
|
||||
@implementation ARTNodeManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (ARTNode *)node
|
||||
{
|
||||
return [[ARTNode alloc] init];
|
||||
}
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [self node];
|
||||
}
|
||||
|
||||
- (RCTShadowView *)shadowView
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(transform, CGAffineTransform)
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTNodeManager.h"
|
||||
#import "ARTRenderable.h"
|
||||
|
||||
@interface ARTRenderableManager : ARTNodeManager
|
||||
|
||||
- (ARTRenderable *)node;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTRenderableManager.h"
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
|
||||
@implementation ARTRenderableManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (ARTRenderable *)node
|
||||
{
|
||||
return [[ARTRenderable alloc] init];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeCap, CGLineCap)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeJoin, CGLineJoin)
|
||||
RCT_EXPORT_VIEW_PROPERTY(fill, ARTBrush)
|
||||
RCT_EXPORT_VIEW_PROPERTY(stroke, CGColor)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeDash, ARTCGFloatArray)
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTRenderableManager.h"
|
||||
|
||||
@interface ARTShapeManager : ARTRenderableManager
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTShapeManager.h"
|
||||
|
||||
#import "ARTShape.h"
|
||||
#import "RCTConvert+ART.h"
|
||||
|
||||
@implementation ARTShapeManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (ARTRenderable *)node
|
||||
{
|
||||
return [[ARTShape alloc] init];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(d, CGPath)
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTViewManager.h"
|
||||
|
||||
@interface ARTSurfaceViewManager : RCTViewManager
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTSurfaceViewManager.h"
|
||||
|
||||
#import "ARTSurfaceView.h"
|
||||
|
||||
@implementation ARTSurfaceViewManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [[ARTSurfaceView alloc] init];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTRenderableManager.h"
|
||||
|
||||
@interface ARTTextManager : ARTRenderableManager
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ARTTextManager.h"
|
||||
|
||||
#import "ARTText.h"
|
||||
#import "RCTConvert+ART.h"
|
||||
|
||||
@implementation ARTTextManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (ARTRenderable *)node
|
||||
{
|
||||
return [[ARTText alloc] init];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(alignment, CTTextAlignment)
|
||||
RCT_REMAP_VIEW_PROPERTY(frame, textFrame, ARTTextFrame)
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user