2017-07-16 6 views
0

テキストをCGPathRefsを使ってすべての異なる部分に分割しようとしています。たとえば、Lには1つのパスがあり、? 2つ(ドットと残りの部分)があります。CGPathRefを複数のパスに分割します。

現在、「?」の例では、パスとして各文字を取得できます。パスには、ドットと残りの両方が1つに含まれます。私はそれらを分割したいが、私はそれを働かせるように見えない。

テキストをパスに分割する私はスタックオーバーフローから何らかの答えを使用しましたが、これはうまく動作し、ここでは各文字をパスとして取得した部分です。

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)); 
} 

は、これは私にこのような出力を提供します:ここで私はまた、私は、このようgetPointsFromBezierに各ポイントを見て、個々の地点で

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

を見て「CGPathApply」機能を介して実行します

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} 

が、私はここに入力された文字だったก็と我々はそれが出力に2つの異なるパスを持っていることをはっきりと見ることができます(つまり、2 kCGPathElementMoveToPointと2つのkCGPathElementCloseSubpath)。

これから2つの別々のCGPathRefを適切にまたはうまく作成する方法がわかりません。

答えて

0

実際、質問を書いているうちに私はそれをほぼ解決しました。

静的に変更可能な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); 

1つの問題は、適切なカーブを得られないため、結果として得られるパスが滑らかではないことです。私はそれを解決すれば私は更新されます。

これはこれまでの結果で、元の画像と比較して少しばらつきがあることがわかります。しかし、彼らは解決するための最初の問題だった2つの異なる色を持っています。

enter image description here

UPDATE:私は各点(、エレメント>点)ことが見出され、残りのデータ(xとyの)が適切に点を描画するために含まれています。例:

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); 
} 

これは、各グリフを適切に描画します。

関連する問題