Skip to content

Commit

Permalink
fix: marker onPress & gestures
Browse files Browse the repository at this point in the history
  • Loading branch information
msand committed Oct 3, 2019
1 parent 0c127dc commit bff92f0
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 27 deletions.
18 changes: 10 additions & 8 deletions android/src/main/java/com/horcrux/svg/MarkerView.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class MarkerView extends GroupView {
String mAlign;
int mMeetOrSlice;

Matrix markerTransform = new Matrix();

public MarkerView(ReactContext reactContext) {
super(reactContext);
}
Expand Down Expand Up @@ -130,21 +132,19 @@ void saveDefinition() {
void renderMarker(Canvas canvas, Paint paint, float opacity, RNSVGMarkerPosition position, float strokeWidth) {
int count = saveAndSetupCanvas(canvas, mCTM);

markerTransform.reset();
Point origin = position.origin;
Matrix transform = new Matrix();
transform.setTranslate((float)origin.x * mScale, (float)origin.y * mScale);
markerTransform.setTranslate((float)origin.x * mScale, (float)origin.y * mScale);

double markerAngle = "auto".equals(mOrient) ? -1 : Double.parseDouble(mOrient);
float degrees = 180 + (float) (markerAngle == -1 ? position.angle : markerAngle);
transform.preRotate(degrees);
markerTransform.preRotate(degrees);

boolean useStrokeWidth = "strokeWidth".equals(mMarkerUnits);
if (useStrokeWidth) {
transform.preScale(strokeWidth, strokeWidth);
markerTransform.preScale(strokeWidth, strokeWidth);
}

canvas.concat(transform);

double width = relativeOnWidth(mMarkerWidth) / mScale;
double height = relativeOnHeight(mMarkerHeight) / mScale;
RectF eRect = new RectF(0, 0, (float)width, (float)height);
Expand All @@ -153,12 +153,14 @@ void renderMarker(Canvas canvas, Paint paint, float opacity, RNSVGMarkerPosition
Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice);
float[] values = new float[9];
viewBoxMatrix.getValues(values);
canvas.scale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]);
markerTransform.preScale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]);
}

double x = relativeOnWidth(mRefX);
double y = relativeOnHeight(mRefY);
canvas.translate((float)-x, (float)-y);
markerTransform.preTranslate((float)-x, (float)-y);

canvas.concat(markerTransform);

drawGroup(canvas, paint, opacity);

Expand Down
24 changes: 17 additions & 7 deletions android/src/main/java/com/horcrux/svg/RenderableView.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
Expand Down Expand Up @@ -382,24 +383,29 @@ void renderMarkers(Canvas canvas, Paint paint, float opacity) {
contextElement = this;
ArrayList<RNSVGMarkerPosition> positions = RNSVGMarkerPosition.fromPath(elements);
float width = (float)(this.strokeWidth != null ? relativeOnOther(this.strokeWidth) : 1);
mMarkerPath = new Path();
for (RNSVGMarkerPosition position : positions) {
RNSVGMarkerType type = position.type;
MarkerView marker = null;
switch (type) {
case kStartMarker:
if (markerStart != null) markerStart.renderMarker(canvas, paint, opacity, position, width);
marker = markerStart;
break;

case kMidMarker:
if (markerMid != null) markerMid.renderMarker(canvas, paint, opacity, position, width);
marker = markerMid;
break;

case kEndMarker:
if (markerEnd != null) markerEnd.renderMarker(canvas, paint, opacity, position, width);
break;

default:
marker = markerEnd;
break;
}
if (marker == null) {
continue;
}
marker.renderMarker(canvas, paint, opacity, position, width);
Matrix transform = marker.markerTransform;
mMarkerPath.addPath(marker.getPath(canvas, paint), transform);
}
contextElement = null;
}
Expand Down Expand Up @@ -520,9 +526,13 @@ int hitTest(final float[] src) {
if (mStrokeRegion == null && mStrokePath != null) {
mStrokeRegion = getRegion(mStrokePath);
}
if (mMarkerRegion == null && mMarkerPath != null) {
mMarkerRegion = getRegion(mMarkerPath);
}
if (
(mRegion == null || !mRegion.contains(x, y)) &&
(mStrokeRegion == null || !mStrokeRegion.contains(x, y))
(mStrokeRegion == null || !mStrokeRegion.contains(x, y) &&
(mMarkerRegion == null || !mMarkerRegion.contains(x, y)))
) {
return -1;
}
Expand Down
3 changes: 3 additions & 0 deletions android/src/main/java/com/horcrux/svg/VirtualView.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@ abstract public class VirtualView extends ReactViewGroup {
Path mPath;
Path mFillPath;
Path mStrokePath;
Path mMarkerPath;
RectF mBox;
Region mRegion;
Region mMarkerRegion;
Region mStrokeRegion;
Region mClipRegion;
Path mClipRegionPath;
Expand All @@ -114,6 +116,7 @@ void clearCache() {
canvasWidth = -1;
fontSize = -1;
mStrokeRegion = null;
mMarkerRegion = null;
mRegion = null;
mPath = null;
}
Expand Down
1 change: 1 addition & 0 deletions ios/Elements/RNSVGGroup.m
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ - (CGPathRef)getPath:(CGContextRef)context
if ([node isKindOfClass:[RNSVGNode class]] && ![node isKindOfClass:[RNSVGMask class]]) {
CGAffineTransform transform = CGAffineTransformConcat(node.matrix, node.transforms);
CGPathAddPath(path, &transform, [node getPath:context]);
CGPathAddPath(path, &transform, [node markerPath]);
node.dirty = false;
}
return YES;
Expand Down
9 changes: 5 additions & 4 deletions ios/Elements/RNSVGMarker.m
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,6 @@ - (void)renderMarker:(CGContextRef)context rect:(CGRect)rect position:(RNSVGMark
transform = CGAffineTransformScale(transform, strokeWidth, strokeWidth);
}

CGContextConcatCTM(context, transform);

CGFloat width = [self relativeOnWidth:self.markerWidth];
CGFloat height = [self relativeOnHeight:self.markerHeight];
CGRect eRect = CGRectMake(0, 0, width, height);
Expand All @@ -183,12 +181,15 @@ - (void)renderMarker:(CGContextRef)context rect:(CGRect)rect position:(RNSVGMark
eRect:eRect
align:self.align
meetOrSlice:self.meetOrSlice];
CGContextScaleCTM(context, viewBoxTransform.a, viewBoxTransform.d);
transform = CGAffineTransformScale(transform, viewBoxTransform.a, viewBoxTransform.d);
}

CGFloat x = [self relativeOnWidth:self.refX];
CGFloat y = [self relativeOnHeight:self.refY];
CGContextTranslateCTM(context, -x, -y);
transform = CGAffineTransformTranslate(transform, -x, -y);

self.transform = transform;
CGContextConcatCTM(context, transform);

[self renderGroupTo:context rect:eRect];

Expand Down
2 changes: 2 additions & 0 deletions ios/RNSVGNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE;
@property (nonatomic, assign) BOOL skip;
@property (nonatomic, assign) CGPathRef path;
@property (nonatomic, assign) CGPathRef strokePath;
@property (nonatomic, assign) CGPathRef markerPath;
@property (nonatomic, assign) CGRect clientRect;
@property (nonatomic, assign) CGRect pathBounds;
@property (nonatomic, assign) CGRect markerBounds;
@property (nonatomic, copy) RCTDirectEventBlock onLayout;


Expand Down
1 change: 1 addition & 0 deletions ios/RNSVGRenderable.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@property (nonatomic, assign) CGFloat strokeDashoffset;
@property (nonatomic, assign) RNSVGVectorEffect vectorEffect;
@property (nonatomic, copy) NSArray<NSString *> *propList;
@property (nonatomic, assign) CGPathRef hitArea;

- (void)setHitArea:(CGPathRef)path;

Expand Down
31 changes: 23 additions & 8 deletions ios/RNSVGRenderable.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ @implementation RNSVGRenderable
NSArray<RNSVGLength *> *_sourceStrokeDashArray;
CGFloat *_strokeDashArrayData;
CGPathRef _srcHitPath;
CGPathRef _hitArea;
}

static RNSVGRenderable * _contextElement;
Expand Down Expand Up @@ -311,25 +310,39 @@ - (void)renderMarkers:(CGContextRef)context path:(CGPathRef)path rect:(const CGR
_contextElement = self;
NSArray<RNSVGMarkerPosition*>* positions = [RNSVGMarkerPosition fromCGPath:path];
CGFloat width = self.strokeWidth ? [self relativeOnOther:self.strokeWidth] : 1;
__block CGRect bounds = CGRectNull;
CGMutablePathRef markerPath = CGPathCreateMutable();
for (RNSVGMarkerPosition* position in positions) {
RNSVGMarkerType type = [position type];
RNSVGMarker *marker;
switch (type) {
case kStartMarker:
[markerStart renderMarker:context rect:*rect position:position strokeWidth:width];
marker = markerStart;
break;

case kMidMarker:
[markerMid renderMarker:context rect:*rect position:position strokeWidth:width];
marker = markerMid;
break;

case kEndMarker:
[markerEnd renderMarker:context rect:*rect position:position strokeWidth:width];
marker = markerEnd;
break;
}
if (!marker) {
continue;
}

default:
break;
[marker renderMarker:context rect:*rect position:position strokeWidth:width];
CGAffineTransform transform = marker.transform;
CGPathRef hitArea = marker.hitArea;
CGPathAddPath(markerPath, &transform, hitArea);
CGRect nodeRect = marker.pathBounds;
if (!CGRectIsEmpty(nodeRect)) {
bounds = CGRectUnion(bounds, CGRectApplyAffineTransform(nodeRect, transform));
}
}
self.markerBounds = bounds;
self.markerPath = markerPath;
_contextElement = nil;
}
}
Expand Down Expand Up @@ -513,13 +526,15 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);

if (!CGRectContainsPoint(self.pathBounds, transformed)) {
if (!CGRectContainsPoint(self.pathBounds, transformed) &&
!CGRectContainsPoint(self.markerBounds, transformed)) {
return nil;
}

BOOL evenodd = self.fillRule == kRNSVGCGFCRuleEvenodd;
if (!CGPathContainsPoint(_hitArea, nil, transformed, evenodd) &&
!CGPathContainsPoint(self.strokePath, nil, transformed, NO)) {
!CGPathContainsPoint(self.strokePath, nil, transformed, NO) &&
!CGPathContainsPoint(self.markerPath, nil, transformed, NO)) {
return nil;
}

Expand Down

0 comments on commit bff92f0

Please sign in to comment.