c++ - 使用 appendBezierPathWithGlyphs 获取字形轮廓的问题

标签 c++ objective-c cocoa objective-c++ glyph

我正在使用 Objective-C++。

我正在尝试使用 NSBezierPathappendBezierPathWithGlyphs 获取文本的路径轮廓。问题是:输出相当无意义:(

我写的:

  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

这对我来说真的很不对劲!

最佳答案

“看起来不对”是什么意思?您是否尝试过渲染数据?这是有效的。

下面是修改后的代码以输出曲线数据的 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");

关于c++ - 使用 appendBezierPathWithGlyphs 获取字形轮廓的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3692549/

相关文章:

ios - UIVisualEffectView setHidden=YES 非常慢 - 奇怪的错误?

macos - NSTextView 通过 Cocoa Bindings 显示 HTML

c++ - 如何在 C 中使用 C++ 对象?

c++ - 如何基于枚举创建容器

c++ - 如何处理太长的 STL 模板错误报告?

c++ - Xcode iPhone : Removing text from a . txt 文件

iphone - 自定义 UITabBar 背景图像在 iOS 5 及更高版本中不起作用

objective-c - 将集群类作为单例?

ios - 添加抽象父实体时如何迁移核心数据数据模型?

c++ - 'this'指针如何用作成员函数的参数