objective-c - 自定义 CTLine 结构
问题描述
我正在为我的项目创建自定义 CTLine 结构。这是一个非常简单的实现,因为它不使用 CFAttributeString 来创建线。整行只有一种颜色,所有字形都具有相同的大小。但是CFString越长,创建它的时间就越长,而且比CTLineCreateWithAttributedString()慢。
#import <Cocoa/Cocoa.h>
#define sc (CFStringRef)
struct Line {
CGGlyph*line_glyphs;
CGPoint*point;
CTFontRef font;
int length;
};
typedef struct Line* LineRef;
LineRef create(CFStringRef str, CTFontRef font);
@interface View : NSView
{
LineRef line;
CTLineRef l;
CTFontRef font;
CGFontRef font2;
CFMutableStringRef string;
}
@end
#import "View.h"
#include <time.h>
LineRef create(CFStringRef str, CTFontRef font){
LineRef line = malloc(sizeof(struct Line));
long length = CFStringGetLength(str);
CGGlyph* gl = malloc(sizeof(CGGlyph)*length);
CGPoint* points = malloc(sizeof(CGPoint)*length);
CGRect rects[length];
UniChar buffer[length];
CFStringGetCharacters(str, CFRangeMake(0, length), buffer);
CTFontGetGlyphsForCharacters(font, buffer, gl, length);
CTFontGetBoundingRectsForGlyphs(font, kCTFontOrientationHorizontal, gl, rects, length);
int x_offset = 0;
int y = 200;
CGPoint temp;
for(int i = 0;i<length;i++)
{
temp = CGPointMake(x_offset , y);
x_offset += rects[i].size.width + (rects[i].size.width == 0)*10;
points[i] = temp;
}
line->line_glyphs = gl;
line->point = points;
line->font = font;
line->length = length;
return line;
}
@implementation View
-(void)awakeFromNib{
font = CTFontCreateWithName(CFSTR("Comic Sans MS"), 30, 0);
font2= CGFontCreateWithFontName(CFSTR("Comic Sans MS"));
line = create(CFSTR(""), font);
string = CFStringCreateMutable(kCFAllocatorDefault, 0);
[[self window] makeFirstResponder:self];
}
-(void)keyDown:(NSEvent *)event{
static int index = 0;
NSString* i = [event characters];
CFStringAppend(string,sc i);
CFMutableAttributedStringRef s = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
CFAttributedStringReplaceString(s, CFRangeMake(0, 0), string);
CFAttributedStringSetAttribute(s, CFRangeMake(0, CFStringGetLength(string)), kCTFontAttributeName, font);
CFAbsoluteTime t1 = CFAbsoluteTimeGetCurrent();
l = CTLineCreateWithAttributedString(s);
CFAbsoluteTime t2 = CFAbsoluteTimeGetCurrent();
double d1 = t2-t1;
CFAbsoluteTime T1 = CFAbsoluteTimeGetCurrent();
line = create(string, font);
CFAbsoluteTime T2 = CFAbsoluteTimeGetCurrent();
double d2 = T2 - T1;
printf("test:%i core text: %f my implem : %f \n",index, d1,d2);
index++;
}
@end
并输出:
test:0 core text: 0.000761 my implem : 0.000016
test:1 core text: 0.000047 my implem : 0.000029
test:2 core text: 0.000041 my implem : 0.000027
test:3 core text: 0.000045 my implem : 0.000032
test:4 core text: 0.000045 my implem : 0.000032
test:5 core text: 0.000046 my implem : 0.000034
...
test:176 core text: 0.000068 my implem : 0.000151
test:177 core text: 0.000084 my implem : 0.000171
test:178 core text: 0.000099 my implem : 0.000230
test:179 core text: 0.000061 my implem : 0.000145
test:180 core text: 0.000071 my implem : 0.000224
test:181 core text: 0.000057 my implem : 0.000149
您会看到前几次调用比创建 CTLine 更快,但我的实现开始需要更多时间来完成这项工作。也许是多个 CTFontGetGlyphsForCharacters() 调用错误?你能给出一些建议来加快这段代码的速度吗?
解决方案
tl; drCTLineCreateWithAttributedString()
在必要时使用并继续前进;在您的管道中的其他地方存在更大的性能问题。CGContextDrawPath()
是你真正的克星。
作为凭证,我编写了一个 iOS 应用程序,它允许OSM 的整个数据集被渲染并显示在 iPhone 上——一直到人行道和建筑物。它看起来像这样(请注意,人行道的所有小脚都是字体中的字形):
我的管道看起来有点像这样:
- 检查每个字符串的边界框并尽可能丢弃
- 调用
CTLineCreateWithAttributedString()
剩余的字符串。 - 遍历每个
CTRun
并使用CTFontCreatePathForGlyph()
来获取每个字形路径。 - 检查每个路径的边界框并尽可能丢弃。
- 调用
CGContextDrawPath()
剩余路径
第 1 步和第 4 步是优化的地方。绘制摆动线(字形)是计算密集型的,没有办法解决这个问题。唯一的获胜举措是不玩¹。
(为了获得更多优化乐趣,请查看MinimumRubber,特别是MRPathMetrics
可用于避免昂贵CGPath
的基于函数的函数)
推荐阅读
- azure-resource-manager - How do I deploy file share within storage account using ARM template
- html - Angular:显示或隐藏元素而不影响元素间距
- c - 在包装函数中包装几个具有不同参数计数的函数
- javascript - 在新屏幕上评估 redux 操作(this.props.function)时“未定义不是对象”
- javascript - 如何翻译 Powershell -> JavaScript for LDAP (dn -> canonicalName) 转换功能
- javascript - 为什么 '\n' 不适用于 ServiceNow 脚本?未创建新行
- javascript - 通过 java 脚本设置 asp 变量
- django-rest-framework - 更新时返回嵌套序列化程序
- scala - 缓存 circe 隐式解析的 Encoder/Decoder 实例
- xml - Scala - 如何提取包含在通用文本文件中的 XML 文件