我正在使用 Objective-C++。
我正在尝试使用 NSBezierPath
的 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
这对我来说真的很不对劲!
最佳答案
“看起来不对”是什么意思?您是否尝试过渲染数据?这是有效的。
下面是修改后的代码以输出曲线数据的 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/