Skip to content

Commit d61a59f

Browse files
authored
Merge pull request #58 from nativescript-community/feat-ios-clip-fill-rule
fix(ui-canvas): iOS drawPath and clipPath ignored fill rule
2 parents 4a47422 + 96ae862 commit d61a59f

File tree

1 file changed

+53
-32
lines changed

1 file changed

+53
-32
lines changed

src/ui-canvas/canvas.ios.ts

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -494,19 +494,19 @@ export class Matrix implements IMatrix {
494494
return CGAffineTransformIsIdentity(this.mTransform);
495495
}
496496
// public toString(): string {
497-
// return NSStringFromCGAffineTransform(this._transform);
497+
// return NSStringFromCGAffineTransform(this.mTransform);
498498
// }
499499
public preTranslate(tx: number, ty: number): boolean {
500500
return this.preConcat(CGAffineTransformMakeTranslation(tx, ty));
501501
}
502502
public setValues(values: number[]): void {
503503
this.mTransform = CGAffineTransformMake(values[0], values[3], values[1], values[4], values[2], values[5]);
504-
// this._transform.a = values[0];
505-
// this._transform.c = values[1];
506-
// this._transform.tx = values[2];
507-
// this._transform.b = values[3];
508-
// this._transform.d = values[4];
509-
// this._transform.ty = values[5];
504+
// this.mTransform.a = values[0];
505+
// this.mTransform.c = values[1];
506+
// this.mTransform.tx = values[2];
507+
// this.mTransform.b = values[3];
508+
// this.mTransform.d = values[4];
509+
// this.mTransform.ty = values[5];
510510
}
511511
public invert(output: IMatrix): boolean {
512512
(output as Matrix).mTransform = CGAffineTransformInvert(this.mTransform);
@@ -549,7 +549,13 @@ export class DashPathEffect extends PathEffect {
549549
export class Path implements IPath {
550550
private mPath: any;
551551
private mBPath?: UIBezierPath;
552-
mFillType: FillType;
552+
private mFillType: FillType;
553+
554+
constructor() {
555+
this.mPath = CGPathCreateMutable();
556+
this.mFillType = FillType.WINDING;
557+
// this._path = UIBezierPath.bezierPath();
558+
}
553559

554560
getOrCreateBPath() {
555561
if (!this.mBPath) {
@@ -577,11 +583,6 @@ export class Path implements IPath {
577583
this.mBPath = bPath;
578584
// this._path = this._bPath.CGPath;
579585
}
580-
constructor() {
581-
this.mPath = CGPathCreateMutable();
582-
this.mFillType = FillType.WINDING;
583-
// this._path = UIBezierPath.bezierPath();
584-
}
585586
computeBounds(rect: RectF, exact: boolean) {
586587
if (this.mBPath) {
587588
rect.cgRect = this.mBPath.bounds;
@@ -1693,30 +1694,42 @@ export class Canvas implements ICanvas {
16931694
const path = args[0] as Path;
16941695
const op = args[1] as Op;
16951696
const ctx = this.ctx;
1697+
1698+
let clipCGPath;
1699+
16961700
if (op !== undefined) {
16971701
const cgPath = ctx.path;
1698-
let clipPath = cgPath ? UIBezierPath.bezierPathWithCGPath(cgPath) : UIBezierPath.bezierPathWithRect(CGRectMake(0, 0, this.mWidth, this.mHeight));
1702+
let clipBPath = cgPath ? UIBezierPath.bezierPathWithCGPath(cgPath) : UIBezierPath.bezierPathWithRect(CGRectMake(0, 0, this.mWidth, this.mHeight));
1703+
16991704
if (op === Op.DIFFERENCE) {
1700-
clipPath.appendPath(path.getOrCreateBPath().bezierPathByReversingPath());
1705+
clipBPath.appendPath(path.getOrCreateBPath().bezierPathByReversingPath());
17011706
} else if (op === Op.REVERSE_DIFFERENCE) {
1702-
clipPath = clipPath.bezierPathByReversingPath();
1703-
clipPath.appendPath(path.getOrCreateBPath());
1707+
clipBPath = clipBPath.bezierPathByReversingPath();
1708+
clipBPath.appendPath(path.getOrCreateBPath());
17041709
} else if (op === Op.UNION) {
1705-
clipPath.appendPath(path.getOrCreateBPath());
1710+
clipBPath.appendPath(path.getOrCreateBPath());
17061711
} else if (op === Op.REPLACE) {
17071712
CGContextResetClip(ctx);
1708-
clipPath = path.getOrCreateBPath();
1713+
clipBPath = path.getOrCreateBPath();
17091714
} else if (op === Op.INTERSECT) {
17101715
console.error('clipPath Op.INTERSECT not implemented yet');
17111716
} else if (op === Op.XOR) {
17121717
console.error('clipPath Op.INTERSECT not implemented yet');
17131718
}
1714-
CGContextAddPath(ctx, clipPath.CGPath);
1715-
CGContextClip(ctx);
1719+
1720+
clipCGPath = clipBPath.CGPath;
1721+
} else {
1722+
clipCGPath = path.getCGPath();
1723+
}
1724+
1725+
CGContextAddPath(ctx, clipCGPath);
1726+
1727+
if (path.getFillType() === FillType.EVEN_ODD || path.getFillType() === FillType.INVERSE_EVEN_ODD) {
1728+
CGContextEOClip(ctx);
17161729
} else {
1717-
CGContextAddPath(ctx, path.getCGPath());
17181730
CGContextClip(ctx);
17191731
}
1732+
17201733
// clipPath(path: IPath): boolean;
17211734
// clipPath(path: IPath, op: Op): boolean;
17221735
// clipPath(path: any, op?: any)
@@ -1908,30 +1921,38 @@ export class Canvas implements ICanvas {
19081921
CGContextClipToRect(ctx, rect);
19091922
return true;
19101923
}
1911-
private _drawPath(paint: Paint, ctx, path?) {
1924+
private _drawPath(paint: Paint, ctx, path?: Path | UIBezierPath) {
19121925
let bPath: UIBezierPath;
19131926
let cgPath;
1927+
let fillType: FillType;
1928+
19141929
if (path instanceof Path) {
19151930
bPath = path.getBPath();
19161931
cgPath = path.getCGPath();
1917-
} else if (path instanceof UIBezierPath) {
1918-
bPath = path;
1919-
cgPath = bPath.CGPath;
1932+
fillType = path.getFillType();
19201933
} else {
1921-
cgPath = path;
1934+
if (path instanceof UIBezierPath) {
1935+
bPath = path;
1936+
cgPath = bPath.CGPath;
1937+
} else {
1938+
cgPath = path;
1939+
}
1940+
fillType = FillType.WINDING;
19221941
}
1923-
function createBPath() {
1942+
1943+
const createBPath = () => {
19241944
if (!bPath) {
19251945
if (!cgPath) {
19261946
cgPath = CGContextCopyPath(ctx);
19271947
}
19281948
bPath = UIBezierPath.bezierPathWithCGPath(cgPath);
19291949
}
1930-
}
1950+
};
1951+
19311952
if (paint.shader && !cgPath) {
19321953
cgPath = CGContextCopyPath(ctx);
19331954
}
1934-
if (path && (path._fillType === FillType.INVERSE_WINDING || path._fillType === FillType.INVERSE_EVEN_ODD)) {
1955+
if (fillType === FillType.INVERSE_WINDING || fillType === FillType.INVERSE_EVEN_ODD) {
19351956
createBPath();
19361957
bPath = bPath.bezierPathByReversingPath();
19371958
cgPath = bPath.CGPath;
@@ -1977,15 +1998,15 @@ export class Canvas implements ICanvas {
19771998
}
19781999
if (paint.style === Style.FILL) {
19792000
// CGContextFillPath(ctx);
1980-
if (path && (path._fillType === FillType.EVEN_ODD || path._fillType === FillType.INVERSE_EVEN_ODD)) {
2001+
if (fillType === FillType.EVEN_ODD || fillType === FillType.INVERSE_EVEN_ODD) {
19812002
CGContextDrawPath(ctx, CGPathDrawingMode.kCGPathEOFill);
19822003
} else {
19832004
CGContextDrawPath(ctx, CGPathDrawingMode.kCGPathFill);
19842005
}
19852006
} else if (paint.style === Style.STROKE) {
19862007
CGContextDrawPath(ctx, CGPathDrawingMode.kCGPathStroke);
19872008
} else {
1988-
if (path && (path._fillType === FillType.EVEN_ODD || path._fillType === FillType.INVERSE_EVEN_ODD)) {
2009+
if (fillType === FillType.EVEN_ODD || fillType === FillType.INVERSE_EVEN_ODD) {
19892010
CGContextDrawPath(ctx, CGPathDrawingMode.kCGPathEOFillStroke);
19902011
} else {
19912012
CGContextDrawPath(ctx, CGPathDrawingMode.kCGPathFillStroke);

0 commit comments

Comments
 (0)