Skip to content

Commit

Permalink
fix: native method signatures web compatibility / spec conformance
Browse files Browse the repository at this point in the history
  • Loading branch information
msand committed Oct 4, 2019
1 parent c28499b commit 8687a3d
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 39 deletions.
45 changes: 34 additions & 11 deletions android/src/main/java/com/horcrux/svg/RNSVGRenderableManager.java
Expand Up @@ -15,12 +15,14 @@
import android.graphics.RectF;
import android.graphics.Region;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableMap;

import javax.annotation.Nonnull;

Expand Down Expand Up @@ -115,7 +117,12 @@ public void getPointAtLength(int tag, ReadableMap options, Callback successCallb
float[] pos = new float[2];
float[] tan = new float[2];
pm.getPosTan(Math.max(0, Math.min(length, pathLength)), pos, tan);
successCallback.invoke(pos[0], pos[1]);
double angle = Math.atan2(tan[1], tan[0]);
WritableMap result = Arguments.createMap();
result.putDouble("x", pos[0]);
result.putDouble("y", pos[1]);
result.putDouble("angle", angle);
successCallback.invoke(result);
}

@SuppressWarnings("unused")
Expand All @@ -139,9 +146,17 @@ public void getBBox(int tag, ReadableMap options, Callback successCallback) {
bounds.union(svg.mMarkerBounds);
}
if (clipped) {
bounds.intersect(svg.mClipBounds);
RectF clipBounds = svg.mClipBounds;
if (clipBounds != null) {
bounds.intersect(svg.mClipBounds);
}
}
successCallback.invoke(bounds.left, bounds.top, bounds.width(), bounds.height());
WritableMap result = Arguments.createMap();
result.putDouble("x", bounds.left);
result.putDouble("y", bounds.top);
result.putDouble("width", bounds.width());
result.putDouble("height", bounds.height());
successCallback.invoke(result);
}

@SuppressWarnings("unused")
Expand All @@ -155,10 +170,14 @@ public void getCTM(int tag, Callback successCallback) {

float[] values = new float[9];
ctm.getValues(values);
successCallback.invoke(
values[Matrix.MSCALE_X], values[Matrix.MSKEW_X], values[Matrix.MTRANS_X],
values[Matrix.MSKEW_Y], values[Matrix.MSCALE_Y], values[Matrix.MTRANS_Y]
);
WritableMap result = Arguments.createMap();
result.putDouble("a", values[Matrix.MSCALE_X]);
result.putDouble("b", values[Matrix.MSKEW_Y]);
result.putDouble("c", values[Matrix.MSKEW_X]);
result.putDouble("d", values[Matrix.MSCALE_Y]);
result.putDouble("e", values[Matrix.MTRANS_X]);
result.putDouble("f", values[Matrix.MTRANS_Y]);
successCallback.invoke(result);
}

@SuppressWarnings("unused")
Expand All @@ -168,9 +187,13 @@ public void getScreenCTM(int tag, Callback successCallback) {
Matrix screenCTM = svg.mCTM;
float[] values = new float[9];
screenCTM.getValues(values);
successCallback.invoke(
values[Matrix.MSCALE_X], values[Matrix.MSKEW_X], values[Matrix.MTRANS_X],
values[Matrix.MSKEW_Y], values[Matrix.MSCALE_Y], values[Matrix.MTRANS_Y]
);
WritableMap result = Arguments.createMap();
result.putDouble("a", values[Matrix.MSCALE_X]);
result.putDouble("b", values[Matrix.MSKEW_Y]);
result.putDouble("c", values[Matrix.MSKEW_X]);
result.putDouble("d", values[Matrix.MSCALE_Y]);
result.putDouble("e", values[Matrix.MTRANS_X]);
result.putDouble("f", values[Matrix.MTRANS_Y]);
successCallback.invoke(result);
}
}
4 changes: 2 additions & 2 deletions ios/Text/RNSVGTSpan.m
Expand Up @@ -959,7 +959,7 @@ A negative value is an error (see Error processing).
CGFloat angle;
CGFloat px;
CGFloat py;
[measure getPosAndTan:&angle midPoint:midPoint px:&px py:&py];
[measure getPosAndTan:&angle midPoint:midPoint x:&px y:&py];

transform = CGAffineTransformConcat(CGAffineTransformMakeTranslation(px, py), transform);
transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(angle + r), transform);
Expand Down Expand Up @@ -1032,7 +1032,7 @@ - (void)setupTextPath:(CGContextRef)context
{
textPath = nil;
RNSVGText *parent = (RNSVGText*)[self superview];
CGPathRef path;
CGPathRef path = nil;
while (parent) {
if ([parent class] == [RNSVGTextPath class]) {
textPath = (RNSVGTextPath*) parent;
Expand Down
2 changes: 1 addition & 1 deletion ios/Utils/RNSVGPathMeasure.h
Expand Up @@ -19,6 +19,6 @@

- (void)reset;
- (void)extractPathData:(CGPathRef)path;
- (void)getPosAndTan:(CGFloat *)angle midPoint:(CGFloat)midPoint px:(CGFloat *)px py:(CGFloat *)py;
- (void)getPosAndTan:(CGFloat *)angle midPoint:(CGFloat)midPoint x:(CGFloat *)x y:(CGFloat *)y;

@end
6 changes: 3 additions & 3 deletions ios/Utils/RNSVGPathMeasure.m
Expand Up @@ -189,7 +189,7 @@ - (void)extractPathData:(CGPathRef)path {
}
}

- (void)getPosAndTan:(CGFloat *)angle midPoint:(CGFloat)midPoint px:(CGFloat *)px py:(CGFloat *)py {
- (void)getPosAndTan:(CGFloat *)angle midPoint:(CGFloat)midPoint x:(CGFloat *)x y:(CGFloat *)y {
// Investigation suggests binary search is faster at lineCount >= 16
// https://gist.github.com/msand/4c7993319425f9d7933be58ad9ada1a4
NSUInteger i = _lineCount < 16 ?
Expand Down Expand Up @@ -220,8 +220,8 @@ - (void)getPosAndTan:(CGFloat *)angle midPoint:(CGFloat)midPoint px:(CGFloat *)p
CGFloat ldx = p2.x - p1.x;
CGFloat ldy = p2.y - p1.y;
*angle = atan2(ldy, ldx);
*px = p1.x + ldx * percent;
*py = p1.y + ldy * percent;
*x = p1.x + ldx * percent;
*y = p1.y + ldy * percent;
}

@end
74 changes: 52 additions & 22 deletions ios/ViewManagers/RNSVGRenderableManager.m
Expand Up @@ -132,7 +132,6 @@ - (void)withTag:(nonnull NSNumber *)reactTag success:(RNSVGSuccessBlock)successB
CGPathRef target = [svg getPath:nil];
RNSVGPathMeasure *measure = [[RNSVGPathMeasure alloc]init];
[measure extractPathData:target];

CGFloat pathLegth = measure.pathLength;
callback(@[[NSNumber numberWithDouble:pathLegth]]);
}
Expand All @@ -145,18 +144,26 @@ - (void)withTag:(nonnull NSNumber *)reactTag success:(RNSVGSuccessBlock)successB
RCT_EXPORT_METHOD(getPointAtLength:(nonnull NSNumber *)reactTag options:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback)
{
id length = [options objectForKey:@"length"];
CGFloat x = (CGFloat)[length floatValue];
CGFloat position = (CGFloat)[length floatValue];
[self
withTag:reactTag
success:^(RNSVGRenderable *svg){
CGPathRef target = [svg getPath:nil];
RNSVGPathMeasure *measure = [[RNSVGPathMeasure alloc]init];
[measure extractPathData:target];
CGFloat angle;
CGFloat px;
CGFloat py;
[measure getPosAndTan:&angle midPoint:fmax(0, fmin(measure.pathLength, x)) px:&px py:&py];
callback(@[[NSNumber numberWithDouble:px], [NSNumber numberWithDouble:py]]);
CGFloat x;
CGFloat y;
[measure getPosAndTan:&angle midPoint:fmax(0, fmin(position, measure.pathLength)) x:&x y:&y];
callback(
@[
@{
@"x":@(x),
@"y":@(y),
@"angle":@(angle)
}
]
);
}
fail:^{
callback(@[[NSNumber numberWithBool:false]]);
Expand Down Expand Up @@ -187,16 +194,22 @@ - (void)withTag:(nonnull NSNumber *)reactTag success:(RNSVGSuccessBlock)successB
if (clipped) {
CGPathRef clipPath = [svg getClipPath];
CGRect clipBounds = CGPathGetBoundingBox(clipPath);
bounds = CGRectIntersection(bounds, clipBounds);
if (clipPath && !CGRectIsEmpty(clipBounds)) {
bounds = CGRectIntersection(bounds, clipBounds);
}
}
CGPoint origin = bounds.origin;
CGSize size = bounds.size;
callback(@[
[NSNumber numberWithDouble:origin.x],
[NSNumber numberWithDouble:origin.y],
[NSNumber numberWithDouble:size.width],
[NSNumber numberWithDouble:size.height]
]);
callback(
@[
@{
@"x":@(origin.x),
@"y":@(origin.y),
@"width":@(size.width),
@"height":@(size.height)
}
]
);
}
fail:^{
callback(@[[NSNumber numberWithBool:false]]);
Expand All @@ -210,10 +223,18 @@ - (void)withTag:(nonnull NSNumber *)reactTag success:(RNSVGSuccessBlock)successB
withTag:reactTag
success:^(RNSVGRenderable *svg){
CGAffineTransform ctm = svg.ctm;
callback(@[
n(ctm.a), n(ctm.c), n(ctm.tx),
n(ctm.b), n(ctm.d), n(ctm.ty)
]);
callback(
@[
@{
@"a":n(ctm.a),
@"b":n(ctm.b),
@"c":n(ctm.c),
@"d":n(ctm.d),
@"e":n(ctm.tx),
@"f":n(ctm.ty)
}
]
);
}
fail:^{
callback(@[[NSNumber numberWithBool:false]]);
Expand All @@ -230,11 +251,19 @@ - (void)withTag:(nonnull NSNumber *)reactTag success:(RNSVGSuccessBlock)successB
[self
withTag:reactTag
success:^(RNSVGRenderable *svg){
CGAffineTransform screenCTM = svg.screenCTM;
callback(@[
n(screenCTM.a), n(screenCTM.c), n(screenCTM.tx),
n(screenCTM.b), n(screenCTM.d), n(screenCTM.ty)
]);
CGAffineTransform ctm = svg.screenCTM;
callback(
@[
@{
@"a":n(ctm.a),
@"b":n(ctm.b),
@"c":n(ctm.c),
@"d":n(ctm.d),
@"e":n(ctm.tx),
@"f":n(ctm.ty)
}
]
);
}
fail:^{
callback(@[[NSNumber numberWithBool:false]]);
Expand All @@ -243,3 +272,4 @@ - (void)withTag:(nonnull NSNumber *)reactTag success:(RNSVGSuccessBlock)successB
}

@end

0 comments on commit 8687a3d

Please sign in to comment.