-2

这里的代码似乎大部分都有效——我可以打印出每次运行,看起来运行是有效的,但是当我打印出字形时,它们是垃圾。而且位置都在(0,0),我的界限对我来说看起来不正确。有人可以帮助我,也许我没有正确地做这些事情,顺便说一下,这只是一个示例程序,所以我可以查看运行中的实际数据。

-(void) printRuns:(CTFrameRef)ctframe {
    CFArrayRef lines;
    lines = CTFrameGetLines(ctframe);

    CGPoint origins[CFArrayGetCount(lines)];//the origins of each line at the baseline
    CTFrameGetLineOrigins(ctframe, CFRangeMake(0, 0), origins);

    NSUInteger lineIndex = 0;

    for(int i = 0; i < CFArrayGetCount(lines); i++)
    //for(id lineObj in lines)
    {
        CTLineRef line = CFArrayGetValueAtIndex(lines, i);

        NSLog(@"LineOrigin:%@", NSStringFromCGPoint(origins[i]));

        CFArrayRef runs = CTLineGetGlyphRuns(line);

        for(int j = 0; j < CFArrayGetCount(runs); j++)
        //for(id runObj in (__bridge NSArray*)CTLineGetGlyphRuns(line))
        {
            CTRunRef run = CFArrayGetValueAtIndex(runs, j);
            CFRange runRange = CTRunGetStringRange(run);


            CGRect runBounds;

            CGFloat ascent;//height above the baseline
            CGFloat descent;//height below the baseline
            runBounds.size.width = CTRunGetTypographicBounds(run, runRange, &ascent, &descent, NULL);
            runBounds.size.height = ascent + descent;

            CGFloat xOffset = CTLineGetOffsetForStringIndex(line, CTRunGetStringRange(run).location, NULL);
            runBounds.origin.x = origins[lineIndex].x + 0 + xOffset;
            runBounds.origin.y = origins[lineIndex].y + 0;
            runBounds.origin.y -= descent;

            CGGlyph glyphBuffer[runRange.length];

            CTRunGetGlyphs(run, runRange, glyphBuffer);

            //const CGGlyph *glyphs = CTRunGetGlyphsPtr(run);
            //NSLog(@"Glyph:%c", glyph);

            for(int i = 0; i < runRange.length; i++)
            {
                NSLog(@"Glyph:%c", glyphBuffer[i]);

                if(i % 10 == 0)
                {
                    NSString *test = @"";
                }
            }

            CFIndex glyphCount = CTRunGetGlyphCount(run);
            CGPoint *positions = calloc(glyphCount, sizeof(CGPoint));
            CTRunGetPositions(run, runRange, positions);

            for(int i = 0; i < glyphCount; i++)
            {
                CGPoint *position = &positions[i];
                NSLog(@"Position:%@", NSStringFromCGPoint(*position));
            }


            NSLog(@"%@", NSStringFromCGRect(runBounds));
        }
        lineIndex++;
    }
}
4

1 回答 1

3

最可能的问题是您从中提取字形的字体与您尝试显示它们的字体不同。如果是这样,这将解释“垃圾”字形,因为一种字体中的字形可以表示与另一种字体中的相同字形不同的字母(CGGlyph 只是字体的单个字形表的索引,不同的字体可以布置其字符集字形不同)。这也可以解释边界框不匹配。

至于定位,您是否尝试使用 CTFontGetAdvancesForGlyphs 代替?我怀疑位置数据仅表示当前字形的边界框相对于“光标”当前位置的位置,而不是相对于运行开始的位置。

最后,上面的示例代码假设一个字符映射到一个字形。一般情况下这是不正确的。英语有时会用连字排版(其中两个或多个字符由一个字形表示),但许多语言到处都有连字。您需要使用 CTRunGetGlyphCount()。

于 2012-09-14T17:40:14.853 回答