3

Objective-C++ を使用しています。

NSBezierPathsを使用してテキストのパス アウトラインを取得しようとしていますappendBezierPathWithGlyphs。問題は次のとおりです。出力はかなりナンセンスです:(

私が書いたこと:

  String str = Ascii8("test string");
  int length = str.getLength();

  NSFont* font = [NSFont fontWithDescriptor: [NSFontDescriptor fontDescriptorWithName:@"Times"
                                                                                 size:20]
                            textTransform: transform];

  NSTextStorage *storage = [[NSTextStorage alloc] initWithString:toNSString(str)];
  NSLayoutManager *manager = [[NSLayoutManager alloc] init];
  NSTextContainer *container = [[NSTextContainer alloc] init];

  [storage addLayoutManager:manager];
  [manager addTextContainer:container];

  NSGlyph* glyphs = new NSGlyph[length+1];
  [manager getGlyphs:glyphs range:NSMakeRange(0, length)];

  [container release];
  [manager release];
  [storage release];

  NSBezierPath* path = [NSBezierPath bezierPath];
  // If I don't do this I get an exception that currentPoint doesn't exist ...
  [path moveToPoint: NSMakePoint(0, 0)]; 
  [path appendBezierPathWithGlyphs:glyphs count:length inFont:font];

  delete[] glyphs;

  // NSBezierPath -> DoublePath
  for (NSInteger i=0; i<[path elementCount]; ++i)
  {
    NSPoint controlPoints[3];
    NSBezierPathElement el = [path elementAtIndex:i associatedPoints:controlPoints];
    if (el == NSMoveToBezierPathElement)
    {
      printf("move to (%f,%f)\n", controlPoints[0].x, controlPoints[0].y);
    }
    else if (el == NSLineToBezierPathElement)
    {
      printf("line to (%f, %f)\n", controlPoints[0].x, controlPoints[0].y);
    }
    else if (el == NSCurveToBezierPathElement)
    {
      printf("cubic to (%f, %f) (%f, %f) (%f, %f)\n", 
         controlPoints[0].x, controlPoints[0].y,
         controlPoints[1].x, controlPoints[1].y,
         controlPoints[2].x, controlPoints[2].y);
    }   
    else if (el == NSClosePathBezierPathElement) 
    {
      printf("close\n");
    }
  }

たとえば、文字「t」の場合、次の出力が得られます。

move to (0.277832, 0.000000)
move to (0.254395, 0.450195)
line to (0.254395, 0.415039)
line to (0.154785, 0.415039)
line to (0.153809, 0.133789)
cubic to (0.153809, 0.109049) (0.155924, 0.090332) (0.160156, 0.077637)
cubic to (0.167969, 0.055176) (0.183268, 0.043945) (0.206055, 0.043945)
cubic to (0.217773, 0.043945) (0.227946, 0.046712) (0.236572, 0.052246)
cubic to (0.245199, 0.057780) (0.255046, 0.066569) (0.266113, 0.078613)
line to (0.278809, 0.067871)
line to (0.268066, 0.053223)
cubic to (0.251139, 0.030436) (0.233236, 0,014323) (0.214355, 0.004883)
cubic to (0.195475, -0.004557) (0.177246, -0.009277) (0.159668, -0.009277)
cubic to (0.121256, -0.009277) (0.095215, 0.007812) (0.081543, 0.041992)
cubic to (0.074056, 0.060547) (0.070312, 0.086263) (0.070312, 0.119141)
line to (0.070312, 0.415039)
line to (0.017090, 0.415039)
cubic to (0.015462, 0.416016) (0.014242, 0.416992) (0.013428, 0.417969)
cubic to (0.012614, 0.418945) (0.012207, 0.420247) (0.012207, 0.421875)
cubic to (0.012207, 0.425130) (0.012939, 0.427653) (0.014404, 0.429443)
cubic to (0.015869, 0.431234) (0.020508, 0.435384) (0.028320, 0.441895)
cubic to (0.050781, 0.460449) (0.066976, 0.475504) (0.076904, 0.487061)
cubic to (0.086833, 0.498617) (0.110189, 0.529134) (0.146973, 0.578613)
cubic to (0.151204, 0.578613) (0.153727, 0.578288) (0.154541, 0.577637)
cubic to (0.155355, 0.576986) (0.155762, 0.574544) (0.155762, 0.570312)
line to (0.155762, 0.450195)
close

これは私にとって本当に間違っているようです!

4

1 に答える 1

2

「見た目が悪い」とはどういう意味ですか? データをレンダリングしようとしましたか? 有効です。

以下は、曲線データの SVG を出力するように変更されたコードです。これは正しいように見えます (ただし、SVG の座標規則が異なるため、上下が逆になっています)。それ以外に、いくつかのランダムな C++ を削除transformし、抽出で定義されていないものを追加すると、唯一の違いは、グリフの数を で正しくカウントすること[manager numberOfGlyphs]です。テストケースでは、これは違いはありませんが、一般に、グリフ数は文字列の長さと同じではありません。

NSString *str = @"test string";
int length = str.length;
NSAffineTransform *transform = [NSAffineTransform transform];

NSFont* font = [NSFont fontWithDescriptor: [NSFontDescriptor fontDescriptorWithName:@"Times" size:20]
                            textTransform: transform];

NSTextStorage *storage = [[NSTextStorage alloc] initWithString:str];
NSLayoutManager *manager = [[NSLayoutManager alloc] init];
NSTextContainer *container = [[NSTextContainer alloc] init];

[storage addLayoutManager:manager];
[manager addTextContainer:container];

NSUInteger glyphCount = [manager numberOfGlyphs];
NSGlyph glyphs[glyphCount];
[manager getGlyphs:glyphs range:NSMakeRange(0, glyphCount)];

[container release];
[manager release];
[storage release];

NSBezierPath* path = [NSBezierPath bezierPath];
[path moveToPoint: NSMakePoint(0, 0)]; // If I don't do this I get an exception that currentPoint doesn't exist ...
[path appendBezierPathWithGlyphs:glyphs count:length inFont:font];


printf("<?xml version=\"1.0\" standalone=\"no\"?>\n"
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
       "<svg viewBox=\"-5 -5 10 10\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n"
       "\t<desc>Debug dump</desc>\n"
       "\t\n<path d=\"");

// NSBezierPath -> DoublePath
for (NSInteger i=0; i<[path elementCount]; ++i)
{
    if (i != 0)  printf(" ");

    NSPoint controlPoints[3];
    NSBezierPathElement el = [path elementAtIndex:i associatedPoints:controlPoints];
    if (el == NSMoveToBezierPathElement)
    {
    //  printf("move to (%f,%f)\n", controlPoints[0].x, controlPoints[0].y);
        printf("M%g %g", controlPoints[0].x, controlPoints[0].y);
    }
    else if (el == NSLineToBezierPathElement)
    {
    //  printf("line to (%f, %f)\n", controlPoints[0].x, controlPoints[0].y);
        printf("L%g %g", controlPoints[0].x, controlPoints[0].y);
    }
    else if (el == NSCurveToBezierPathElement)
    {
    //  printf("cubic to (%f, %f) (%f, %f) (%f, %f)\n", 
        printf("C%g %g %g %g %g %g",
               controlPoints[0].x, controlPoints[0].y,
               controlPoints[1].x, controlPoints[1].y,
               controlPoints[2].x, controlPoints[2].y);
    }   
    else if (el == NSClosePathBezierPathElement) 
    {
    //  printf("close\n");
        printf("Z");
    }
}

printf("\"/>\n</svg>\n");
于 2010-09-11T21:12:35.757 に答える