mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-05-23 19:25:54 +00:00
Merge pull request #558 from msand/tailormade_distance_along_path
Implement tailor made data structure and logic for text on a path, and various bugfixes.
This commit is contained in:
@@ -160,7 +160,7 @@ class ImageShadowNode extends RenderableShadowNode {
|
||||
@Override
|
||||
protected Path getPath(Canvas canvas, Paint paint) {
|
||||
Path path = new Path();
|
||||
path.addRect(new RectF(getRect()), Path.Direction.CW);
|
||||
path.addRect(getRect(), Path.Direction.CW);
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -187,51 +187,37 @@ class ImageShadowNode extends RenderableShadowNode {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Rect getRect() {
|
||||
private RectF getRect() {
|
||||
double x = relativeOnWidth(mX);
|
||||
double y = relativeOnHeight(mY);
|
||||
double w = relativeOnWidth(mW);
|
||||
double h = relativeOnHeight(mH);
|
||||
if (w == 0) {
|
||||
w = mImageWidth * mScale;
|
||||
}
|
||||
if (h == 0) {
|
||||
h = mImageHeight * mScale;
|
||||
}
|
||||
|
||||
return new Rect((int) x, (int) y, (int) (x + w), (int) (y + h));
|
||||
return new RectF((float)x, (float)y, (float)(x + w), (float)(y + h));
|
||||
}
|
||||
|
||||
private void doRender(Canvas canvas, Paint paint, Bitmap bitmap, float opacity) {
|
||||
// apply viewBox transform on Image render.
|
||||
Rect rect = getRect();
|
||||
float rectWidth = (float)rect.width();
|
||||
float rectHeight = (float)rect.height();
|
||||
float rectX = (float)rect.left;
|
||||
float rectY = (float)rect.top;
|
||||
float canvasLeft = getCanvasLeft();
|
||||
float canvasTop = getCanvasTop();
|
||||
|
||||
if (mImageWidth == 0 || mImageHeight == 0) {
|
||||
mImageWidth = bitmap.getWidth();
|
||||
mImageHeight = bitmap.getHeight();
|
||||
}
|
||||
|
||||
RectF renderRect = new RectF(0, 0, mImageWidth, mImageHeight);
|
||||
|
||||
RectF renderRect = getRect();
|
||||
RectF vbRect = new RectF(0, 0, mImageWidth, mImageHeight);
|
||||
RectF eRect = new RectF(canvasLeft, canvasTop, (rectWidth / mScale) + canvasLeft, (rectHeight / mScale) + canvasTop);
|
||||
Matrix transform = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice);
|
||||
Matrix transform = ViewBox.getTransform(vbRect, renderRect, mAlign, mMeetOrSlice);
|
||||
transform.mapRect(vbRect);
|
||||
|
||||
Matrix translation = new Matrix();
|
||||
transform.mapRect(renderRect);
|
||||
if (mMatrix != null) {
|
||||
translation.postConcat(mMatrix);
|
||||
//mMatrix.mapRect(renderRect);
|
||||
mMatrix.mapRect(vbRect);
|
||||
}
|
||||
float dx = rectX / mScale + canvasLeft;
|
||||
float dy = rectY / mScale + canvasTop;
|
||||
translation.postTranslate(dx, dy);
|
||||
translation.postScale(mScale, mScale);
|
||||
translation.mapRect(renderRect);
|
||||
|
||||
|
||||
Path clip = new Path();
|
||||
|
||||
Path clipPath = getClipPath(canvas, paint);
|
||||
Path path = getPath(canvas, paint);
|
||||
if (clipPath != null) {
|
||||
@@ -256,7 +242,7 @@ class ImageShadowNode extends RenderableShadowNode {
|
||||
|
||||
Paint alphaPaint = new Paint();
|
||||
alphaPaint.setAlpha((int) (opacity * 255));
|
||||
canvas.drawBitmap(bitmap, null, renderRect, alphaPaint);
|
||||
canvas.drawBitmap(bitmap, null, vbRect, alphaPaint);
|
||||
}
|
||||
|
||||
private void tryRender(ImageRequest request, Canvas canvas, Paint paint, float opacity) {
|
||||
|
||||
@@ -726,7 +726,7 @@ class TSpanShadowNode extends TextShadowNode {
|
||||
double spacing = wordSpace + letterSpacing;
|
||||
double advance = charWidth + spacing;
|
||||
|
||||
double x = gc.nextX(kerning + advance);
|
||||
double x = gc.nextX(alreadyRenderedGraphemeCluster ? 0 : kerning + advance);
|
||||
double y = gc.nextY();
|
||||
double dx = gc.nextDeltaX();
|
||||
double dy = gc.nextDeltaY();
|
||||
|
||||
+23
-32
@@ -96,55 +96,46 @@
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
CGRect rect = [self getRect:context];
|
||||
// add hit area
|
||||
CGPathRef hitArea = CGPathCreateWithRect(rect, nil);
|
||||
[self setHitArea:hitArea];
|
||||
CGPathRelease(hitArea);
|
||||
|
||||
CGContextSaveGState(context);
|
||||
CGContextTranslateCTM(context, 0, rect.size.height + 2 * rect.origin.y);
|
||||
CGContextScaleCTM(context, 1, -1);
|
||||
|
||||
// add hit area
|
||||
CGRect hitArea = [self getHitArea];
|
||||
CGPathRef hitAreaPath = CGPathCreateWithRect(hitArea, nil);
|
||||
[self setHitArea:hitAreaPath];
|
||||
CGPathRelease(hitAreaPath);
|
||||
|
||||
// apply viewBox transform on Image render.
|
||||
CGRect renderRect = CGRectMake(0, 0, _imageSize.width, _imageSize.height);
|
||||
|
||||
CGFloat rectWidth = CGRectGetWidth(rect);
|
||||
CGFloat rectHeight = CGRectGetHeight(rect);
|
||||
CGFloat rectX = CGRectGetMinX(rect);
|
||||
CGFloat rectY = CGRectGetMinY(rect);
|
||||
CGFloat canvasLeft = [self getContextLeft];
|
||||
CGFloat canvasTop = [self getContextTop];
|
||||
|
||||
CGRect eRect = CGRectMake(canvasLeft, canvasTop, rectWidth, rectHeight);
|
||||
CGRect vbRect = CGRectMake(0, 0, CGRectGetWidth(renderRect), CGRectGetHeight(renderRect));
|
||||
CGAffineTransform transform = [RNSVGViewBox getTransform:vbRect eRect:eRect align:self.align meetOrSlice:self.meetOrSlice];
|
||||
renderRect = CGRectApplyAffineTransform(renderRect, transform);
|
||||
|
||||
CGFloat dx = rectX + canvasLeft;
|
||||
CGFloat dy = rectY + canvasTop;
|
||||
renderRect = CGRectApplyAffineTransform(renderRect, CGAffineTransformMakeTranslation(dx, dy));
|
||||
|
||||
CGRect imageBounds = CGRectMake(0, 0, _imageSize.width, _imageSize.height);
|
||||
CGAffineTransform viewbox = [RNSVGViewBox getTransform:imageBounds eRect:hitArea align:self.align meetOrSlice:self.meetOrSlice];
|
||||
|
||||
CGContextTranslateCTM(context, 0, hitArea.size.height);
|
||||
CGContextScaleCTM(context, 1, -1);
|
||||
[self clip:context];
|
||||
CGContextClipToRect(context, rect);
|
||||
|
||||
CGContextDrawImage(context, renderRect, _image);
|
||||
CGContextClipToRect(context, hitArea);
|
||||
CGContextConcatCTM(context, viewbox);
|
||||
CGContextDrawImage(context, imageBounds, _image);
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
}
|
||||
|
||||
- (CGRect)getRect:(CGContextRef)context
|
||||
- (CGRect)getHitArea
|
||||
{
|
||||
CGFloat x = [self relativeOnWidth:self.x];
|
||||
CGFloat y = [self relativeOnHeight:self.y];
|
||||
CGFloat width = [self relativeOnWidth:self.width];
|
||||
CGFloat height = [self relativeOnHeight:self.height];
|
||||
if (width == 0) {
|
||||
width = _imageSize.width;
|
||||
}
|
||||
if (height == 0) {
|
||||
height = _imageSize.height;
|
||||
}
|
||||
|
||||
return CGRectMake(x, y, width, height);
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
return (CGPathRef)CFAutorelease(CGPathCreateWithRect([self getRect:context], nil));
|
||||
return (CGPathRef)CFAutorelease(CGPathCreateWithRect([self getHitArea], nil));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,6 +14,4 @@
|
||||
|
||||
@property (nonatomic, strong) RNSVGPathParser *d;
|
||||
|
||||
- (NSArray *)getBezierCurves;
|
||||
|
||||
@end
|
||||
|
||||
@@ -30,11 +30,6 @@
|
||||
return _path;
|
||||
}
|
||||
|
||||
- (NSArray *)getBezierCurves
|
||||
{
|
||||
return [_d getBezierCurves];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGPathRelease(_path);
|
||||
|
||||
@@ -49,14 +49,12 @@
|
||||
7F08CE9B1E23476900650F83 /* RNSVGTSpanManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F08CE991E23476900650F83 /* RNSVGTSpanManager.m */; };
|
||||
7F08CEA01E23479700650F83 /* RNSVGTextPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F08CE9D1E23479700650F83 /* RNSVGTextPath.m */; };
|
||||
7F08CEA11E23479700650F83 /* RNSVGTSpan.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F08CE9F1E23479700650F83 /* RNSVGTSpan.m */; };
|
||||
7F4BB50A1FB1E50000663D5F /* QuartzBookPack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F4BB5051FB1DEC300663D5F /* QuartzBookPack.framework */; };
|
||||
7F9CDAFA1E1F809C00E0C805 /* RNSVGPathParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F9CDAF91E1F809C00E0C805 /* RNSVGPathParser.m */; };
|
||||
7FC260CE1E3499BC00A39833 /* RNSVGViewBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC260CD1E3499BC00A39833 /* RNSVGViewBox.m */; };
|
||||
7FC260D11E34A12000A39833 /* RNSVGSymbol.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC260D01E34A12000A39833 /* RNSVGSymbol.m */; };
|
||||
7FC260D41E34A12A00A39833 /* RNSVGSymbolManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC260D31E34A12A00A39833 /* RNSVGSymbolManager.m */; };
|
||||
945A8AF81F4CE3E8004BBF6B /* AlignmentBaseline.m in Sources */ = {isa = PBXBuildFile; fileRef = 945A8AF71F4CE3E8004BBF6B /* AlignmentBaseline.m */; };
|
||||
945A8AF91F4CE3E8004BBF6B /* AlignmentBaseline.m in Sources */ = {isa = PBXBuildFile; fileRef = 945A8AF71F4CE3E8004BBF6B /* AlignmentBaseline.m */; };
|
||||
9494C47A1F47116800D5BCFD /* PerformanceBezier.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4771F4710FE00D5BCFD /* PerformanceBezier.framework */; };
|
||||
9494C4D81F473BA700D5BCFD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4D71F473BA700D5BCFD /* QuartzCore.framework */; };
|
||||
9494C4DA1F473BCB00D5BCFD /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4D91F473BCB00D5BCFD /* CoreText.framework */; };
|
||||
9494C4DC1F473BD900D5BCFD /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4DB1F473BD900D5BCFD /* CoreGraphics.framework */; };
|
||||
@@ -89,6 +87,7 @@
|
||||
9494C5471F4C44DD00D5BCFD /* TextPathSide.m in Sources */ = {isa = PBXBuildFile; fileRef = 9494C5361F4C44DD00D5BCFD /* TextPathSide.m */; };
|
||||
9494C5481F4C44DD00D5BCFD /* TextPathSpacing.m in Sources */ = {isa = PBXBuildFile; fileRef = 9494C5371F4C44DD00D5BCFD /* TextPathSpacing.m */; };
|
||||
9494C5491F4C44DD00D5BCFD /* TextPathSpacing.m in Sources */ = {isa = PBXBuildFile; fileRef = 9494C5371F4C44DD00D5BCFD /* TextPathSpacing.m */; };
|
||||
94C70B1A1FF6B1C0004DFD49 /* BezierElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 94C70B171FF6B1C0004DFD49 /* BezierElement.m */; };
|
||||
A361E76E1EB0C33D00646005 /* RNSVGTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D331CE74E3100887C2B /* RNSVGTextManager.m */; };
|
||||
A361E76F1EB0C33D00646005 /* RNSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2841CE71EB7001E90A8 /* RNSVGImage.m */; };
|
||||
A361E7701EB0C33D00646005 /* RNSVGRect.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D471CE74E3D00887C2B /* RNSVGRect.m */; };
|
||||
@@ -137,37 +136,6 @@
|
||||
A361E79D1EB0C33D00646005 /* RNSVGDefsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B48C1D3DDCCE0051496D /* RNSVGDefsManager.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
7F4BB5041FB1DEC300663D5F /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 7F4BB4FF1FB1DEC300663D5F /* QuartzBookPack.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 7F917B141FB1D5E900A75AA4;
|
||||
remoteInfo = QuartzBookPack;
|
||||
};
|
||||
7F4BB5061FB1DEC300663D5F /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 7F4BB4FF1FB1DEC300663D5F /* QuartzBookPack.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 7F917B1D1FB1D5E900A75AA4;
|
||||
remoteInfo = QuartzBookPackTests;
|
||||
};
|
||||
9494C4761F4710FE00D5BCFD /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9494C4711F4710FE00D5BCFD /* PerformanceBezier.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 66F2EBE31A8DC05100D536E9;
|
||||
remoteInfo = PerformanceBezier;
|
||||
};
|
||||
9494C4781F4710FE00D5BCFD /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9494C4711F4710FE00D5BCFD /* PerformanceBezier.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 66B9D28C1A8D5FDE00CAC341;
|
||||
remoteInfo = PerformanceBezierTests;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
0CF68ABF1AF0540F00FF9E5C /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
@@ -280,8 +248,6 @@
|
||||
7F08CE9D1E23479700650F83 /* RNSVGTextPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGTextPath.m; path = Text/RNSVGTextPath.m; sourceTree = "<group>"; };
|
||||
7F08CE9E1E23479700650F83 /* RNSVGTSpan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGTSpan.h; path = Text/RNSVGTSpan.h; sourceTree = "<group>"; };
|
||||
7F08CE9F1E23479700650F83 /* RNSVGTSpan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGTSpan.m; path = Text/RNSVGTSpan.m; sourceTree = "<group>"; };
|
||||
7F08CEA31E23481F00650F83 /* RNSVGTextAnchor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGTextAnchor.h; path = Utils/RNSVGTextAnchor.h; sourceTree = "<group>"; };
|
||||
7F4BB4FF1FB1DEC300663D5F /* QuartzBookPack.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = QuartzBookPack.xcodeproj; path = QuartzBookPack/QuartzBookPack.xcodeproj; sourceTree = "<group>"; };
|
||||
7F69160D1E3703D800DA6EDC /* RNSVGUnits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGUnits.h; path = Utils/RNSVGUnits.h; sourceTree = "<group>"; };
|
||||
7F9CDAF81E1F809C00E0C805 /* RNSVGPathParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPathParser.h; path = Utils/RNSVGPathParser.h; sourceTree = "<group>"; };
|
||||
7F9CDAF91E1F809C00E0C805 /* RNSVGPathParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPathParser.m; path = Utils/RNSVGPathParser.m; sourceTree = "<group>"; };
|
||||
@@ -293,7 +259,6 @@
|
||||
7FC260D31E34A12A00A39833 /* RNSVGSymbolManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSymbolManager.m; sourceTree = "<group>"; };
|
||||
945A8AF71F4CE3E8004BBF6B /* AlignmentBaseline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AlignmentBaseline.m; path = Text/AlignmentBaseline.m; sourceTree = "<group>"; };
|
||||
945A8AFA1F4CE41E004BBF6B /* AlignmentBaseline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AlignmentBaseline.h; path = Text/AlignmentBaseline.h; sourceTree = "<group>"; };
|
||||
9494C4711F4710FE00D5BCFD /* PerformanceBezier.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PerformanceBezier.xcodeproj; path = PerformanceBezier/PerformanceBezier.xcodeproj; sourceTree = "<group>"; };
|
||||
9494C4D71F473BA700D5BCFD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
9494C4D91F473BCB00D5BCFD /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
|
||||
9494C4DB1F473BD900D5BCFD /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
@@ -326,6 +291,8 @@
|
||||
9494C5351F4C44DD00D5BCFD /* TextPathMidLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TextPathMidLine.m; path = Text/TextPathMidLine.m; sourceTree = "<group>"; };
|
||||
9494C5361F4C44DD00D5BCFD /* TextPathSide.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TextPathSide.m; path = Text/TextPathSide.m; sourceTree = "<group>"; };
|
||||
9494C5371F4C44DD00D5BCFD /* TextPathSpacing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TextPathSpacing.m; path = Text/TextPathSpacing.m; sourceTree = "<group>"; };
|
||||
94C70B151FF6B1BF004DFD49 /* BezierElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BezierElement.h; path = Utils/BezierElement.h; sourceTree = "<group>"; };
|
||||
94C70B171FF6B1C0004DFD49 /* BezierElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BezierElement.m; path = Utils/BezierElement.m; sourceTree = "<group>"; };
|
||||
94DDAC5C1F3D024300EED511 /* libRNSVG-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRNSVG-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -334,14 +301,12 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7F4BB50A1FB1E50000663D5F /* QuartzBookPack.framework in Frameworks */,
|
||||
9494C4E01F473BED00D5BCFD /* Accelerate.framework in Frameworks */,
|
||||
9494C4D81F473BA700D5BCFD /* QuartzCore.framework in Frameworks */,
|
||||
9494C4DA1F473BCB00D5BCFD /* CoreText.framework in Frameworks */,
|
||||
9494C4DC1F473BD900D5BCFD /* CoreGraphics.framework in Frameworks */,
|
||||
9494C4DE1F473BDD00D5BCFD /* UIKit.framework in Frameworks */,
|
||||
9494C4E21F473BF500D5BCFD /* Foundation.framework in Frameworks */,
|
||||
9494C47A1F47116800D5BCFD /* PerformanceBezier.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -358,8 +323,6 @@
|
||||
0CF68AB81AF0540F00FF9E5C = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7F4BB4FF1FB1DEC300663D5F /* QuartzBookPack.xcodeproj */,
|
||||
9494C4711F4710FE00D5BCFD /* PerformanceBezier.xcodeproj */,
|
||||
1039D29A1CE7212C001E90A8 /* Utils */,
|
||||
1039D2801CE71DCF001E90A8 /* Elements */,
|
||||
1039D27F1CE71D9B001E90A8 /* Text */,
|
||||
@@ -532,10 +495,11 @@
|
||||
1039D29A1CE7212C001E90A8 /* Utils */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94C70B151FF6B1BF004DFD49 /* BezierElement.h */,
|
||||
94C70B171FF6B1C0004DFD49 /* BezierElement.m */,
|
||||
7F69160D1E3703D800DA6EDC /* RNSVGUnits.h */,
|
||||
10ABC7381D43982B006CCF6E /* RNSVGVBMOS.h */,
|
||||
10ABC7371D439779006CCF6E /* RNSVGCGFCRule.h */,
|
||||
7F08CEA31E23481F00650F83 /* RNSVGTextAnchor.h */,
|
||||
7FC260CC1E3499BC00A39833 /* RNSVGViewBox.h */,
|
||||
7FC260CD1E3499BC00A39833 /* RNSVGViewBox.m */,
|
||||
1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */,
|
||||
@@ -549,15 +513,6 @@
|
||||
name = Utils;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7F4BB5001FB1DEC300663D5F /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7F4BB5051FB1DEC300663D5F /* QuartzBookPack.framework */,
|
||||
7F4BB5071FB1DEC300663D5F /* QuartzBookPackTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9494C2B31F46139600D5BCFD /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -571,15 +526,6 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9494C4721F4710FE00D5BCFD /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9494C4771F4710FE00D5BCFD /* PerformanceBezier.framework */,
|
||||
9494C4791F4710FE00D5BCFD /* PerformanceBezierTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -640,16 +586,6 @@
|
||||
mainGroup = 0CF68AB81AF0540F00FF9E5C;
|
||||
productRefGroup = 0CF68AC21AF0540F00FF9E5C /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 9494C4721F4710FE00D5BCFD /* Products */;
|
||||
ProjectRef = 9494C4711F4710FE00D5BCFD /* PerformanceBezier.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 7F4BB5001FB1DEC300663D5F /* Products */;
|
||||
ProjectRef = 7F4BB4FF1FB1DEC300663D5F /* QuartzBookPack.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
0CF68AC01AF0540F00FF9E5C /* RNSVG */,
|
||||
@@ -658,37 +594,6 @@
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
7F4BB5051FB1DEC300663D5F /* QuartzBookPack.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
path = QuartzBookPack.framework;
|
||||
remoteRef = 7F4BB5041FB1DEC300663D5F /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7F4BB5071FB1DEC300663D5F /* QuartzBookPackTests.xctest */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.cfbundle;
|
||||
path = QuartzBookPackTests.xctest;
|
||||
remoteRef = 7F4BB5061FB1DEC300663D5F /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
9494C4771F4710FE00D5BCFD /* PerformanceBezier.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework.static;
|
||||
path = PerformanceBezier.framework;
|
||||
remoteRef = 9494C4761F4710FE00D5BCFD /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
9494C4791F4710FE00D5BCFD /* PerformanceBezierTests.xctest */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.cfbundle;
|
||||
path = PerformanceBezierTests.xctest;
|
||||
remoteRef = 9494C4781F4710FE00D5BCFD /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
0CF68ABD1AF0540F00FF9E5C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
@@ -734,6 +639,7 @@
|
||||
9494C5251F4B605F00D5BCFD /* GlyphContext.m in Sources */,
|
||||
10BA0D481CE74E3D00887C2B /* RNSVGCircle.m in Sources */,
|
||||
9494C5401F4C44DD00D5BCFD /* TextLengthAdjust.m in Sources */,
|
||||
94C70B1A1FF6B1C0004DFD49 /* BezierElement.m in Sources */,
|
||||
10BA0D351CE74E3100887C2B /* RNSVGEllipseManager.m in Sources */,
|
||||
1039D2A01CE72177001E90A8 /* RCTConvert+RNSVG.m in Sources */,
|
||||
9494C4FF1F4B5BE800D5BCFD /* FontData.m in Sources */,
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <PerformanceBezier/PerformanceBezier.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreText/CoreText.h>
|
||||
#import "RNSVGText.h"
|
||||
|
||||
+491
-525
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,6 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "RNSVGGroup.h"
|
||||
#import "RNSVGTextAnchor.h"
|
||||
#import "AlignmentBaseline.h"
|
||||
|
||||
@interface RNSVGText : RNSVGGroup
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
@property (nonatomic, strong) NSString *spacing;
|
||||
@property (nonatomic, strong) NSString *startOffset;
|
||||
|
||||
- (RNSVGPath *)getPath;
|
||||
- (void)getPathLength:(CGFloat*)length lineCount:(NSUInteger*)lineCount lengths:(NSArray* __strong *)lengths lines:(NSArray* __strong *)lines isClosed:(BOOL*)isClosed;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
+198
-14
@@ -8,28 +8,212 @@
|
||||
|
||||
|
||||
#import "RNSVGTextPath.h"
|
||||
#import "BezierElement.h"
|
||||
|
||||
/* Some Bezier logic from PerformanceBezier */
|
||||
/*
|
||||
|
||||
## License
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/3.0/us/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/us/">Creative Commons Attribution 3.0 United States License</a>.
|
||||
|
||||
For attribution, please include:
|
||||
|
||||
1. Mention original author "Adam Wulf for Loose Leaf app"
|
||||
2. Link to https://getlooseleaf.com/opensource/
|
||||
3. Link to https://github.com/adamwulf/PerformanceBezier
|
||||
|
||||
*/
|
||||
static CGFloat idealFlatness = .01;
|
||||
|
||||
/**
|
||||
* returns the distance between two points
|
||||
*/
|
||||
CGFloat distance(CGPoint p1, CGPoint p2)
|
||||
{
|
||||
CGFloat dx = p2.x - p1.x;
|
||||
CGFloat dy = p2.y - p1.y;
|
||||
|
||||
return hypot(dx, dy);
|
||||
}
|
||||
|
||||
// Subdivide a Bézier (specific division)
|
||||
/*
|
||||
* (c) 2004 Alastair J. Houghton
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of the author of this software may not be used to endorse
|
||||
* or promote products derived from the software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
void subdivideBezierAtT(const CGPoint bez[4], CGPoint bez1[4], CGPoint bez2[4], CGFloat t)
|
||||
{
|
||||
CGPoint q;
|
||||
CGFloat mt = 1 - t;
|
||||
|
||||
bez1[0].x = bez[0].x;
|
||||
bez1[0].y = bez[0].y;
|
||||
bez2[3].x = bez[3].x;
|
||||
bez2[3].y = bez[3].y;
|
||||
|
||||
q.x = mt * bez[1].x + t * bez[2].x;
|
||||
q.y = mt * bez[1].y + t * bez[2].y;
|
||||
bez1[1].x = mt * bez[0].x + t * bez[1].x;
|
||||
bez1[1].y = mt * bez[0].y + t * bez[1].y;
|
||||
bez2[2].x = mt * bez[2].x + t * bez[3].x;
|
||||
bez2[2].y = mt * bez[2].y + t * bez[3].y;
|
||||
|
||||
bez1[2].x = mt * bez1[1].x + t * q.x;
|
||||
bez1[2].y = mt * bez1[1].y + t * q.y;
|
||||
bez2[1].x = mt * q.x + t * bez2[2].x;
|
||||
bez2[1].y = mt * q.y + t * bez2[2].y;
|
||||
|
||||
bez1[3].x = bez2[0].x = mt * bez1[2].x + t * bez2[1].x;
|
||||
bez1[3].y = bez2[0].y = mt * bez1[2].y + t * bez2[1].y;
|
||||
}
|
||||
|
||||
void addLine(CGPoint *last, const CGPoint *next, NSMutableArray *lines, CGFloat *length, NSMutableArray *lengths) {
|
||||
NSArray *line = @[[NSValue valueWithCGPoint:*last], [NSValue valueWithCGPoint:*next]];
|
||||
[lines addObject:line];
|
||||
*length += distance(*last, *next);
|
||||
[lengths addObject:[NSNumber numberWithDouble:*length]];
|
||||
*last = *next;
|
||||
}
|
||||
|
||||
@implementation RNSVGTextPath
|
||||
{
|
||||
CGPathRef _path;
|
||||
NSMutableArray *lengths;
|
||||
NSMutableArray *lines;
|
||||
NSUInteger lineCount;
|
||||
CGFloat length;
|
||||
BOOL isClosed;
|
||||
}
|
||||
|
||||
- (void)getPathLength:(CGFloat*)lengthP lineCount:(NSUInteger*)lineCountP lengths:(NSArray* __strong *)lengthsP lines:(NSArray* __strong *)linesP isClosed:(BOOL*)isClosedP
|
||||
{
|
||||
RNSVGSvgView *svg = [self getSvgView];
|
||||
RNSVGNode *template = [svg getDefinedTemplate:self.href];
|
||||
CGPathRef path = [template getPath:nil];
|
||||
|
||||
if (_path != path) {
|
||||
_path = path;
|
||||
CGPoint origin = CGPointMake (0.0, 0.0);
|
||||
CGPoint last = CGPointMake (0.0, 0.0);
|
||||
lengths = [NSMutableArray array];
|
||||
lines = [NSMutableArray array];
|
||||
isClosed = NO;
|
||||
lineCount = 0;
|
||||
length = 0;
|
||||
|
||||
NSArray *elements = [BezierElement elementsFromCGPath:path];
|
||||
for (BezierElement *element in elements) {
|
||||
switch (element.elementType)
|
||||
{
|
||||
case kCGPathElementMoveToPoint:
|
||||
origin = last = element.point;
|
||||
break;
|
||||
|
||||
case kCGPathElementAddLineToPoint: {
|
||||
CGPoint next = element.point;
|
||||
addLine(&last, &next, lines, &length, lengths);
|
||||
lineCount++;
|
||||
break;
|
||||
}
|
||||
case kCGPathElementAddQuadCurveToPoint:
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
{
|
||||
// handle both curve types gracefully
|
||||
CGPoint curveTo = element.point;
|
||||
CGPoint ctrl1 = element.controlPoint1;
|
||||
CGPoint ctrl2 = element.elementType == kCGPathElementAddQuadCurveToPoint ? ctrl1 : element.controlPoint2;
|
||||
|
||||
// this is the bezier for our current element
|
||||
CGPoint bezier[4] = { last, ctrl1, ctrl2, curveTo };
|
||||
NSValue *arr = [NSValue valueWithBytes:&bezier objCType:@encode(CGPoint[4])];
|
||||
NSMutableArray *curves = [NSMutableArray arrayWithObjects:arr, nil];
|
||||
|
||||
for (NSInteger curveIndex = 0; curveIndex >= 0; curveIndex--) {
|
||||
CGPoint bez[4];
|
||||
[curves[curveIndex] getValue:&bez];
|
||||
[curves removeLastObject];
|
||||
|
||||
// calculate the error rate of the curve vs
|
||||
// a line segment between the start and end points
|
||||
CGPoint ctrl1 = bez[1];
|
||||
CGPoint ctrl2 = bez[2];
|
||||
CGPoint next = bez[3];
|
||||
CGFloat polyLen =
|
||||
distance(last, ctrl1) +
|
||||
distance(ctrl1, ctrl2) +
|
||||
distance(ctrl2, next);
|
||||
CGFloat chordLen = distance(last, next);
|
||||
CGFloat error = polyLen - chordLen;
|
||||
|
||||
// if the error is less than our accepted level of error
|
||||
// then add a line, else, split the curve in half
|
||||
if (error <= idealFlatness) {
|
||||
addLine(&last, &next, lines, &length, lengths);
|
||||
lineCount++;
|
||||
} else {
|
||||
CGPoint bez1[4], bez2[4];
|
||||
subdivideBezierAtT(bez, bez1, bez2, .5);
|
||||
[curves addObject:[NSValue valueWithBytes:&bez2 objCType:@encode(CGPoint[4])]];
|
||||
[curves addObject:[NSValue valueWithBytes:&bez1 objCType:@encode(CGPoint[4])]];
|
||||
curveIndex += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kCGPathElementCloseSubpath: {
|
||||
CGPoint next = origin;
|
||||
addLine(&last, &next, lines, &length, lengths);
|
||||
lineCount++;
|
||||
isClosed = YES;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*lineCountP = lineCount;
|
||||
*isClosedP = isClosed;
|
||||
*lengthsP = lengths;
|
||||
*lengthP = length;
|
||||
*linesP = lines;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
[self renderGroupTo:context];
|
||||
}
|
||||
|
||||
- (RNSVGPath *)getPath
|
||||
{
|
||||
RNSVGSvgView *svg = [self getSvgView];
|
||||
RNSVGNode *template = [svg getDefinedTemplate:self.href];
|
||||
|
||||
if ([template class] != [RNSVGPath class]) {
|
||||
// warning about this.
|
||||
return nil;
|
||||
}
|
||||
|
||||
RNSVGPath *path = (RNSVGPath *)template;
|
||||
return path;
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
return [self getGroupPath:context];
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
|
||||
Erica Sadun, http://ericasadun.com
|
||||
https://github.com/erica/iOS-Drawing/tree/master/C08/Quartz%20Book%20Pack/Bezier
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#define NULLPOINT CGRectNull.origin
|
||||
|
||||
@interface BezierElement : NSObject
|
||||
|
||||
// Element storage
|
||||
@property (nonatomic, assign) CGPathElementType elementType;
|
||||
@property (nonatomic, assign) CGPoint point;
|
||||
@property (nonatomic, assign) CGPoint controlPoint1;
|
||||
@property (nonatomic, assign) CGPoint controlPoint2;
|
||||
|
||||
// Instance creation
|
||||
+ (instancetype) elementWithPathElement: (CGPathElement) element;
|
||||
+ (NSArray *) elementsFromCGPath:(CGPathRef)path;
|
||||
|
||||
@end;
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
|
||||
Erica Sadun, http://ericasadun.com
|
||||
https://github.com/erica/iOS-Drawing/tree/master/C08/Quartz%20Book%20Pack/Bezier
|
||||
*/
|
||||
|
||||
#import "BezierElement.h"
|
||||
|
||||
#pragma mark - Bezier Element -
|
||||
|
||||
@implementation BezierElement
|
||||
- (instancetype) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
_elementType = kCGPathElementMoveToPoint;
|
||||
_point = NULLPOINT;
|
||||
_controlPoint1 = NULLPOINT;
|
||||
_controlPoint2 = NULLPOINT;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype) elementWithPathElement: (CGPathElement) element
|
||||
{
|
||||
BezierElement *newElement = [[self alloc] init];
|
||||
newElement.elementType = element.type;
|
||||
|
||||
switch (newElement.elementType)
|
||||
{
|
||||
case kCGPathElementCloseSubpath:
|
||||
break;
|
||||
case kCGPathElementMoveToPoint:
|
||||
case kCGPathElementAddLineToPoint:
|
||||
{
|
||||
newElement.point = element.points[0];
|
||||
break;
|
||||
}
|
||||
case kCGPathElementAddQuadCurveToPoint:
|
||||
{
|
||||
newElement.point = element.points[1];
|
||||
newElement.controlPoint1 = element.points[0];
|
||||
break;
|
||||
}
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
{
|
||||
newElement.point = element.points[2];
|
||||
newElement.controlPoint1 = element.points[0];
|
||||
newElement.controlPoint2 = element.points[1];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return newElement;
|
||||
}
|
||||
|
||||
// Convert one element to BezierElement and save to array
|
||||
void GetBezierElements(void *info, const CGPathElement *element)
|
||||
{
|
||||
NSMutableArray *bezierElements = (__bridge NSMutableArray *)info;
|
||||
if (element)
|
||||
[bezierElements addObject:[BezierElement elementWithPathElement:*element]];
|
||||
}
|
||||
|
||||
// Retrieve array of component elements
|
||||
+ (NSArray *) elementsFromCGPath:(CGPathRef)path
|
||||
{
|
||||
NSMutableArray *elements = [NSMutableArray array];
|
||||
CGPathApply(path, (__bridge void *)elements, GetBezierElements);
|
||||
return elements;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#import <React/RCTConvert.h>
|
||||
#import "RNSVGCGFCRule.h"
|
||||
#import "RNSVGVBMOS.h"
|
||||
#import "RNSVGTextAnchor.h"
|
||||
#import "RNSVGUnits.h"
|
||||
#import "RNSVGPathParser.h"
|
||||
|
||||
@@ -21,7 +20,6 @@
|
||||
|
||||
@interface RCTConvert (RNSVG)
|
||||
|
||||
+ (RNSVGTextAnchor)RNSVGTextAnchor:(id)json;
|
||||
+ (RNSVGCGFCRule)RNSVGCGFCRule:(id)json;
|
||||
+ (RNSVGVBMOS)RNSVGVBMOS:(id)json;
|
||||
+ (RNSVGUnits)RNSVGUnits:(id)json;
|
||||
|
||||
@@ -26,13 +26,6 @@ RCT_ENUM_CONVERTER(RNSVGVBMOS, (@{
|
||||
@"none": @(kRNSVGVBMOSNone)
|
||||
}), kRNSVGVBMOSMeet, intValue)
|
||||
|
||||
RCT_ENUM_CONVERTER(RNSVGTextAnchor, (@{
|
||||
@"auto": @(kRNSVGTextAnchorAuto),
|
||||
@"start": @(kRNSVGTextAnchorStart),
|
||||
@"middle": @(kRNSVGTextAnchorMiddle),
|
||||
@"end": @(kRNSVGTextAnchorEnd)
|
||||
}), kRNSVGTextAnchorAuto, intValue)
|
||||
|
||||
RCT_ENUM_CONVERTER(RNSVGUnits, (@{
|
||||
@"objectBoundingBox": @(kRNSVGUnitsObjectBoundingBox),
|
||||
@"userSpaceOnUse": @(kRNSVGUnitsUserSpaceOnUse),
|
||||
|
||||
@@ -13,6 +13,5 @@
|
||||
|
||||
- (instancetype) initWithPathString:(NSString *)d;
|
||||
- (CGPathRef)getPath;
|
||||
- (NSArray *)getBezierCurves;
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,14 +9,13 @@
|
||||
#import "RNSVGPathParser.h"
|
||||
#import <React/RCTLog.h>
|
||||
#import "math.h"
|
||||
#import "BezierElement.h"
|
||||
|
||||
@implementation RNSVGPathParser
|
||||
{
|
||||
NSString* _d;
|
||||
NSString* _originD;
|
||||
NSRegularExpression* _pathRegularExpression;
|
||||
NSMutableArray<NSArray *>* _bezierCurves;
|
||||
NSValue *_lastStartPoint;
|
||||
float _penX;
|
||||
float _penY;
|
||||
float _penDownX;
|
||||
@@ -42,7 +41,6 @@
|
||||
{
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
NSArray<NSTextCheckingResult *>* results = [_pathRegularExpression matchesInString:_d options:0 range:NSMakeRange(0, [_d length])];
|
||||
_bezierCurves = [[NSMutableArray alloc] init];
|
||||
unsigned long count = [results count];
|
||||
|
||||
if (count) {
|
||||
@@ -121,15 +119,6 @@
|
||||
return (CGPathRef)CFAutorelease(path);
|
||||
}
|
||||
|
||||
- (NSArray *)getBezierCurves
|
||||
{
|
||||
if (!_bezierCurves) {
|
||||
CGPathRelease([self getPath]);
|
||||
}
|
||||
|
||||
return [_bezierCurves copy];
|
||||
}
|
||||
|
||||
- (NSString *)getNextValue:(NSTextCheckingResult *)result
|
||||
{
|
||||
if (!result) {
|
||||
@@ -158,9 +147,6 @@
|
||||
_pivotX = _penX = x;
|
||||
_pivotY = _penY = y;
|
||||
CGPathMoveToPoint(path, nil, x, y);
|
||||
|
||||
_lastStartPoint = [NSValue valueWithCGPoint: CGPointMake(x, y)];
|
||||
[_bezierCurves addObject: @[_lastStartPoint]];
|
||||
}
|
||||
|
||||
- (void)line:(CGMutablePathRef)path x:(float)x y:(float)y
|
||||
@@ -173,9 +159,6 @@
|
||||
_pivotX = _penX = x;
|
||||
_pivotY = _penY = y;
|
||||
CGPathAddLineToPoint(path, nil, x, y);
|
||||
|
||||
NSValue * destination = [NSValue valueWithCGPoint:CGPointMake(x, y)];
|
||||
[_bezierCurves addObject: @[destination, destination, destination]];
|
||||
}
|
||||
|
||||
- (void)curve:(CGMutablePathRef)path c1x:(float)c1x c1y:(float)c1y c2x:(float)c2x c2y:(float)c2y ex:(float)ex ey:(float)ey
|
||||
@@ -201,12 +184,6 @@
|
||||
_penX = ex;
|
||||
_penY = ey;
|
||||
CGPathAddCurveToPoint(path, nil, c1x, c1y, c2x, c2y, ex, ey);
|
||||
|
||||
[_bezierCurves addObject: @[
|
||||
[NSValue valueWithCGPoint:CGPointMake(c1x, c1y)],
|
||||
[NSValue valueWithCGPoint:CGPointMake(c2x, c2y)],
|
||||
[NSValue valueWithCGPoint:CGPointMake(ex, ey)]
|
||||
]];
|
||||
}
|
||||
|
||||
- (void)smoothCurve:(CGMutablePathRef)path c1x:(float)c1x c1y:(float)c1y ex:(float)ex ey:(float)ey
|
||||
@@ -367,14 +344,13 @@
|
||||
float cp2x = x + k * y;
|
||||
float cp2y = y - k * x;
|
||||
|
||||
CGPathAddCurveToPoint(path,
|
||||
nil,
|
||||
cx + xx * cp1x + yx * cp1y,
|
||||
cy + xy * cp1x + yy * cp1y,
|
||||
cx + xx * cp2x + yx * cp2y,
|
||||
cy + xy * cp2x + yy * cp2y,
|
||||
cx + xx * x + yx * y,
|
||||
cy + xy * x + yy * y);
|
||||
float c1x = cx + xx * cp1x + yx * cp1y;
|
||||
float c1y = cy + xy * cp1x + yy * cp1y;
|
||||
float c2x = cx + xx * cp2x + yx * cp2y;
|
||||
float c2y = cy + xy * cp2x + yy * cp2y;
|
||||
float ex = cx + xx * x + yx * y;
|
||||
float ey = cy + xy * x + yy * y;
|
||||
CGPathAddCurveToPoint(path, nil, c1x, c1y, c2x, c2y, ex, ey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +361,6 @@
|
||||
_penY = _penDownY;
|
||||
_penDownSet = NO;
|
||||
CGPathCloseSubpath(path);
|
||||
[_bezierCurves addObject: @[_lastStartPoint, _lastStartPoint, _lastStartPoint]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Horcrux.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the MIT-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
typedef CF_ENUM(int32_t, RNSVGTextAnchor) {
|
||||
kRNSVGTextAnchorAuto,
|
||||
kRNSVGTextAnchorStart,
|
||||
kRNSVGTextAnchorMiddle,
|
||||
kRNSVGTextAnchorEnd
|
||||
};
|
||||
@@ -9,7 +9,6 @@
|
||||
#import "RNSVGTSpanManager.h"
|
||||
|
||||
#import "RNSVGTSpan.h"
|
||||
#import "RNSVGTextAnchor.h"
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
|
||||
@implementation RNSVGTSpanManager
|
||||
|
||||
@@ -16,7 +16,7 @@ function transformToMatrix(props, transform) {
|
||||
|
||||
const transformParser = peg.generate(`
|
||||
{
|
||||
const deg2rad = Math.PI / 180;
|
||||
var deg2rad = Math.PI / 180;
|
||||
|
||||
/*
|
||||
╔═ ═╗ ╔═ ═╗ ╔═ ═╗
|
||||
@@ -26,15 +26,15 @@ const transformParser = peg.generate(`
|
||||
╚═ ═╝ ╚═ ═╝ ╚═ ═╝
|
||||
*/
|
||||
function multiply_matrices(l, r) {
|
||||
const [al, cl, el, bl, dl, fl] = l;
|
||||
const [ar, cr, er, br, dr, fr] = r;
|
||||
var [al, cl, el, bl, dl, fl] = l;
|
||||
var [ar, cr, er, br, dr, fr] = r;
|
||||
|
||||
const a = al * ar + cl * br;
|
||||
const c = al * cr + cl * dr;
|
||||
const e = al * er + cl * fr + el;
|
||||
const b = bl * ar + dl * br;
|
||||
const d = bl * cr + dl * dr;
|
||||
const f = bl * er + dl * fr + fl;
|
||||
var a = al * ar + cl * br;
|
||||
var c = al * cr + cl * dr;
|
||||
var e = al * er + cl * fr + el;
|
||||
var b = bl * ar + dl * br;
|
||||
var d = bl * cr + dl * dr;
|
||||
var f = bl * er + dl * fr + fl;
|
||||
|
||||
return [a, c, e, b, d, f];
|
||||
}
|
||||
@@ -44,7 +44,7 @@ transformList
|
||||
= wsp* ts:transforms? wsp* { return ts; }
|
||||
|
||||
transforms
|
||||
= t:transform commaWsp+ ts:transforms
|
||||
= t:transform commaWsp* ts:transforms
|
||||
{
|
||||
return multiply_matrices(t, ts);
|
||||
}
|
||||
@@ -94,10 +94,10 @@ scale
|
||||
rotate
|
||||
= "rotate" wsp* "(" wsp* angle:number c:commaWspTwoNumbers? wsp* ")"
|
||||
{
|
||||
const cos = Math.cos(deg2rad * angle);
|
||||
const sin = Math.sin(deg2rad * angle);
|
||||
var cos = Math.cos(deg2rad * angle);
|
||||
var sin = Math.sin(deg2rad * angle);
|
||||
if (c !== null) {
|
||||
const [x, y] = c;
|
||||
var [x, y] = c;
|
||||
return [
|
||||
cos, -sin, cos * -x + -sin * -y + x,
|
||||
sin, cos, sin * -x + cos * -y + y
|
||||
@@ -147,15 +147,15 @@ integerConstant
|
||||
= ds:digitSequence { return ds.join(""); }
|
||||
|
||||
floatingPointConstant
|
||||
= fractionalConstant exponent?
|
||||
/ digitSequence exponent
|
||||
= f:(fractionalConstant exponent?) { return f.join(""); }
|
||||
/ d:(digitSequence exponent) { return d.join(""); }
|
||||
|
||||
fractionalConstant "fractionalConstant"
|
||||
fractionalConstant "fractionalConstant"
|
||||
= d1:digitSequence? "." d2:digitSequence { return [d1 ? d1.join("") : null, ".", d2.join("")].join(""); }
|
||||
/ d:digitSequence "." { return d.join(""); }
|
||||
|
||||
exponent
|
||||
= [eE] sign? digitSequence
|
||||
= e:([eE] sign? digitSequence) { return [e[0], e[1], e[2].join("")].join(""); }
|
||||
|
||||
sign
|
||||
= [+-]
|
||||
|
||||
+1
-2
@@ -19,8 +19,7 @@
|
||||
"gradient"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "eslint ./",
|
||||
"postinstall": "node scripts/install.js"
|
||||
"lint": "eslint ./"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.50.0",
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
var path = require('path');
|
||||
var ghdownload = require('github-download');
|
||||
|
||||
function downloadSubModuleFromGithub(user, repo, callback) {
|
||||
var dist = path.join(process.cwd(), 'ios/' + repo);
|
||||
|
||||
console.log('\r\n Start downloading ' + repo + ' to `' + dist + '`');
|
||||
ghdownload({user: user, repo: repo, ref: 'master'}, dist)
|
||||
.on('end', function() {
|
||||
console.log('Download ' + repo + ' library success!');
|
||||
callback && callback();
|
||||
})
|
||||
.on('error', function (err) {
|
||||
console.error('Download ' + repo + ' library from github failed with err:', err);
|
||||
});
|
||||
}
|
||||
|
||||
downloadSubModuleFromGithub('adamwulf', 'PerformanceBezier', function () {
|
||||
downloadSubModuleFromGithub('magicismight', 'QuartzBookPack');
|
||||
});
|
||||
Reference in New Issue
Block a user