我正在使用Objective-C ++。
我正在尝试使用NSBezierPath
s 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
对我来说这看起来真的不对!
答案 0 :(得分: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");