gpt4 book ai didi

ios - 将 CGPathRef 拆分为多个路径

转载 作者:行者123 更新时间:2023-11-29 11:43:39 25 4
gpt4 key购买 nike

我试图通过 CGPathRefs 将文本分成所有不同的部分。例如,L 有一条路径,而 ?有两个(点和其余部分)。

目前,我能够将每个字母作为路径,但是在“?”的示例中该路径同时包含点和其余部分。我想将它们分开,但似乎无法正常工作。

为了将文本划分为路径,我使用了堆栈溢出的一些答案,效果很好,这是我将每个字母作为路径的部分。在这里,我还通过“CGPathApply”函数运行它来查看每个单独的点

CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, NULL);
NSMutableArray *pathElements = [NSMutableArray array];
CGPathApply(letter, (__bridge void * _Nullable)(pathElements), getPointsFromBezier);

然后我会像这样查看 getPointsFromBezier 中的每个点:

void getPointsFromBezier(void *info, const CGPathElement *element){
CGPoint *p = element->points;
NSString *name;
switch (element->type) {
case kCGPathElementMoveToPoint: name = @"kCGPathElementMoveToPoint"; break;
case kCGPathElementAddLineToPoint: name = @"kCGPathElementAddLineToPoint"; break;
case kCGPathElementAddQuadCurveToPoint: name = @"kCGPathElementAddQuadCurveToPoint"; break;
case kCGPathElementAddCurveToPoint: name = @"kCGPathElementAddCurveToPoint"; break;
case kCGPathElementCloseSubpath: name = @"kCGPathElementCloseSubpath"; break;
default: name = @"default"; break;
}
NSLog(@"Type: %@ || Point: %@", name, NSStringFromCGPoint(*p));
}

这给了我这样的输出:

Type: kCGPathElementMoveToPoint || Point: {11.75, 0}
Type: kCGPathElementAddLineToPoint || Point: {11.75, 9.729}
Type: kCGPathElementAddQuadCurveToPoint || Point: {11.75, 11.26}
..
..
Type: kCGPathElementAddQuadCurveToPoint || Point: {13.00, 10.52}
Type: kCGPathElementAddLineToPoint || Point: {13.00, 0}
Type: kCGPathElementCloseSubpath || Point: {13.00, 0}
Type: kCGPathElementMoveToPoint || Point: {12.75, 18.75}
Type: kCGPathElementAddQuadCurveToPoint || Point: {11.5, 18.94}
Type: kCGPathElementAddLineToPoint || Point: {11.5, 19.95}
Type: kCGPathElementAddQuadCurveToPoint || Point: {11.5, 20.41}
..
..
Type: kCGPathElementAddQuadCurveToPoint || Point: {12.75, 18.169}
Type: kCGPathElementCloseSubpath || Point: {12.75, 18.169}

我在这里输入的字符是ก็,我们可以清楚地看到它在输出中有两个不同的路径(即两个 kCGPathElementMoveToPoint 和两个 kCGPathElementCloseSubpath)。

我不确定如何从中正确或很好地创建两个单独的 CGPathRef。

最佳答案

实际上,在写问题时我几乎解决了它。

我创建了一个静态可变 CGPath,然后在通过 CGPathApply 调用的函数中添加点。像这样:

static CGMutablePathRef path;

void getPointsFromBezier(void *info, const CGPathElement *element){
CGPoint *p = element->points;

if ( element->type == kCGPathElementMoveToPoint ){
path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, p->x, p->y);
}
else if ( element->type == kCGPathElementAddLineToPoint ){
CGPathAddLineToPoint(path, nil, p->x, p->y);
}
else if ( element->type == kCGPathElementAddQuadCurveToPoint ){
CGPathAddQuadCurveToPoint(path, nil, p->x, p->y, p->x, p->y);
}
else if ( element->type == kCGPathElementAddCurveToPoint ){
// ...
}
else if ( element->type == kCGPathElementCloseSubpath ){
CGPathCloseSubpath(path);
[((__bridge NSMutableArray*)info) addObject:(__bridge id _Nonnull)(path)];
path = nil;
CGPathRelease(path);
}
}

然后我简单地循环遍历原始方法中的每个路径并绘制它们而不是原始的“字母”CGPath。

CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, NULL);
NSMutableArray *pathElements = [NSMutableArray array];
CGPathApply(letter, (__bridge void * _Nullable)(pathElements), getPointsFromBezier);

for (id e in pathElements) {
CGContextSaveGState(ctx);
CGContextTranslateCTM(ctx,position.x,0 - 40 + CGRectGetMidY(rect) - self.font.descender + position.y);
CGContextScaleCTM(ctx, 1, -1);
CGContextAddPath(ctx, (CGPathRef)e);
[[self r] setFill];
CGContextFillPath(ctx);
CGContextRestoreGState(ctx);
}

CGPathRelease(letter);

这有点像。一个问题是我没有得到正确的曲线,因此生成的路径不像它们应该的那样平滑。如果我解决了,我会更新。

这是目前的结果,您可以看到与底部的原始图像相比,图像有点 block 状。然而,它们有两种不同的颜色,这是最初要解决的问题。

enter image description here

更新:我发现每个点 (element->points) 都包含剩余数据(x 和 y's)以正确绘制点。例如:

if ( element->type == kCGPathElementAddQuadCurveToPoint ){
CGPoint *p0 = &points[0]; // Control points for bezier path
CGPoint *p1 = &points[1]; // Actual points
CGPathAddQuadCurveToPoint(path,
nil,
p0->x,
p0->y,
p1->x,
p1->y);
}

这将正确绘制每个字形。

关于ios - 将 CGPathRef 拆分为多个路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45130960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com