CodeV

4.7-从字符串创建贝塞尔路径

Core Text简化了将字符串转换为Bezier路径的过程。代码清单4-7提供了一个简单的转换函数。它将其字符串转换为单个Core Text字形,表示为单个CGPath项。该函数将每个字母路径添加到生成的Bezier路径中,在每个字母后面按该字母的大小进行偏移。

添加所有字母后,路径将垂直镜像。这会将面向Quartz的输出转换为适合UIKit的布局。你可以像任何其他人一样处理这些字符串路径,设置它们的线宽,用颜色和图案填充它们,并且根据你喜欢的样子来变换它们。 图4-9显示了一个从粗体Baskerville字体创建并填充有绿色图案的路径。

图4-9

图4-9这是一个填充和描边的Bezier路径,由清单4-7从NSString实例创建。

以下是创建该路径的代码段:

1
2
3
4
5
UIFont *font = [UIFont fontWithName:@"Baskerville-Bold" size:16];
UIBezierPath *path = BezierPathFromString(@"Hello World", font);
FitPathToRect(path, targetRect);
[path fill:GreenStripesColor()];
[path strokeInside:4];

有趣的是,字体大小在这个特定的图形中不起作用。路径按比例缩放到目标矩形,因此您可以使用几乎任何字体来创建源。

如果你想让路径看起来像正常的排版文字,只需使用黑色填充颜色填充返回的路径。这个绿色填充的示例使用内部描边,以确保类型路径的边缘保持清晰。

清单4-7 从字符串创建贝塞尔路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
UIBezierPath *BezierPathFromString(
NSString *string, UIFont *font)
{
// Initialize path
UIBezierPath *path = [UIBezierPath bezierPath];
if (!string.length) return path;

// Create font ref
CTFontRef fontRef = CTFontCreateWithName(
(__bridge CFStringRef)font.fontName,
font.pointSize, NULL);
if (fontRef == NULL)
{
NSLog(@"Error retrieving CTFontRef from UIFont");
return nil;
}

// Create glyphs (that is, individual letter shapes)
CGGlyph *glyphs = malloc(sizeof(CGGlyph) * string.length);
const unichar *chars = (const unichar *)[string
cStringUsingEncoding:NSUnicodeStringEncoding];
BOOL success = CTFontGetGlyphsForCharacters(
fontRef, chars, glyphs, string.length);
if (!success)
{
NSLog(@"Error retrieving string glyphs");
CFRelease(fontRef);
free(glyphs);
return nil;
}

// Draw each char into path
for (int i = 0; i < string.length; i++)
{
// Glyph to CGPath
CGGlyph glyph = glyphs[i];
CGPathRef pathRef =
CTFontCreatePathForGlyph(fontRef, glyph, NULL);

// Append CGPath
[path appendPath:[UIBezierPath
bezierPathWithCGPath:pathRef]]

// Offset by size
CGSize size =
[[string substringWithRange: NSMakeRange(i, 1)] sizeWithAttributes:@{NSFontAttributeName:font}];
OffsetPath(path, CGSizeMake(-size.width, 0));
}

// Clean up
free(glyphs); CFRelease(fontRef);

// Return the path to the UIKit coordinate system
MirrorPathVertically(path);
return path;
}

本文翻译自《iOS Drawing Practical UIKit Solutions》作者:Erica Sadun,翻译:Cheng Dong。如果觉得本书不错请购买支持正版:亚马逊购买传送门,本书所有源代码可在GitHub上下载。译者虽然力求做到信,达,雅,但是由于时间仓促加之译者水平十分有限,文中难免会出现不正确,不准确,词不达意,难于理解的地方,还望各位批评指正,共同进步,谢谢。转载请注明出处。