【问题标题】:Core Graphics text is way faster than Core Text - I feel like I am missing somethingCore Graphics 文本比 Core Text 快得多 - 我觉得我错过了一些东西
【发布时间】:2012-05-16 03:01:11
【问题描述】:

这是我用来在核心图形中显示一些文本的代码:

int y = MESSAGE_FRAME.origin.y + 8;

if (month) y = y + 27;
int height = [JHomeViewCellContentView heightOfMessage:self.entry.message];

CGRect rect = CGRectMake(MESSAGE_FRAME.origin.x + 8, y, MESSAGE_FRAME.size.width - 16, height);

UIFont *font = [UIFont fontWithName:@"Crimson" size:15.0f];

[[UIColor colorWithWhite:0.2 alpha:1.0] setFill];

[self.entry.message drawInRect:rect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];

如果我想在核心文本中显示相同的文本,下面是代码:

CGRect rect2 = CGRectMake(MESSAGE_FRAME.origin.x + 8, self.bounds.size.height - y - height + 2, MESSAGE_FRAME.size.width - 16, height);


    UIFont *font = [UIFont fontWithName:@"Crimson" size:15.0f];
    CGFloat lineHeight = [font lineHeight];

    CTFontRef fontRef = CTFontCreateWithName((CFStringRef)@"Crimson", 15.0f, NULL);

    CGFloat lineSpacing = 0;

    CTParagraphStyleSetting settings[] = {
        { kCTParagraphStyleSpecifierMinimumLineHeight, sizeof(lineHeight), &lineHeight },
        { kCTParagraphStyleSpecifierMaximumLineSpacing, sizeof(lineSpacing), &lineSpacing },

    };

    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));

    NSMutableDictionary *attDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   (__bridge_transfer id)fontRef, (NSString *)kCTFontAttributeName,
                                          (id)[[UIColor colorWithWhite:0.2 alpha:1.0] CGColor], (NSString *)kCTForegroundColorAttributeName,
                                          paragraphStyle, kCTParagraphStyleAttributeName,
                                          nil];

     NSAttributedString *attString = [[NSAttributedString alloc] initWithString:self.entry.message attributes:attDictionary];

    //Flip the coordinate system
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);



    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, rect2);


    self.framesetter = CTFramesetterCreateWithAttributedString((__bridge_retained CFAttributedStringRef)attString);
    CTFrameRef theFrame = CTFramesetterCreateFrame(self.framesetter, CFRangeMake(0, [attString length]), path, NULL);

    CFRelease(path);

    CTFrameDraw(theFrame, context);
    CFRelease(theFrame);

显然,尽管更冗长,但核心文本意味着比核心图形更快,这就是我学会如何做到这一点的原因。但是在仪器中运行这段代码,核心图形实现了 5 毫秒,而核心文本在 14 毫秒内完成。我觉得我在这里错过了一些东西。 drawInRect 几乎快 3 倍,我听说它应该更慢。我已经尽我所知改进了底部的代码,但我不是专家,我将不胜感激。

为了澄清,我正在将一段文本绘制到视图上。这就是我想做的。并且所有的文本都具有相同的外观。

【问题讨论】:

  • Core Text 的强项在于文本布局,底层的绘制代码是在 Core Graphics 中实现的,我看不出在简单的文本绘制中如何能更快。

标签: iphone objective-c ios core-graphics core-text


【解决方案1】:

我不使用 CT 的东西,但在我看来,您在每次绘制时都设置了不变的字体和其他属性。尝试将所有内容分解为注释“翻转坐标系,并缓存 attString。

这应该会提高速度,以便进行更好的面对面测试。

【讨论】:

  • 问题是,虽然属性保持不变,但字符串本身每次都在变化。当您无法设置 NSMutableAttributedString 的字符串时,我将如何缓存它?
  • 我明白了。唔。这些属性都不涉及字符级别,因此一个想法是替换可变属性字符串中的所有字节,但这听起来很粗略。至少,您可以缓存 attDictionary(无论如何,大部分工作都在其中),然后每次都分配一个新的非可变属性字符串。
【解决方案2】:

NSMutableAttributedString 确实允许您通过 replaceCharactersInRange:withString:

设置属性字典后,您可以通过以下方式限制对属性字符串的进一步字符串更新: [myAttString replaceCharactersInRange:NSMakeRange(0, myAttString.text.length) withString:newString]

并绘制脏矩形。另外,我发现 CGContextSetTextMatrix 在使用 CTFrameDraw 时几乎没有意义。

另一个快速说明,我没有看到 CTFontRef 和 CTParagraphStyleRef 上的任何版本。它们也遵循“创建规则”,需要 CFRelease()。

我最近一直在努力完成自己的 Core Text 学习曲线,并且似乎取得了一些可喜的成果。我希望你自己的优化能给你同样的希望。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-01
    • 2015-07-15
    • 2010-09-06
    • 2010-10-17
    • 2018-01-08
    • 2019-09-18
    • 2022-01-03
    • 2021-06-18
    相关资源
    最近更新 更多