Ios 在CGFontRefs中处理字体级联列表
我试图在iOS应用程序中实现一个非常特定的动画,这要求我能够使用各种属性分别绘制字形和字形范围。我正在使用Ios 在CGFontRefs中处理字体级联列表,ios,objective-c,uikit,core-graphics,Ios,Objective C,Uikit,Core Graphics,我试图在iOS应用程序中实现一个非常特定的动画,这要求我能够使用各种属性分别绘制字形和字形范围。我正在使用NSLayoutManager和相关的基础结构对这些图示符进行排版,然后使用-[NSLayoutManager showcglyphs:positions:count:font:matrix:attributes:inContext:方法进行绘图 这适用于英语、俄语和某些其他语言。然而,对于某些语言,比如韩语或阿拉伯语,我会收到垃圾 问题似乎是我使用的字体。我使用的是系统字体(旧金山的一个变
NSLayoutManager
和相关的基础结构对这些图示符进行排版,然后使用-[NSLayoutManager showcglyphs:positions:count:font:matrix:attributes:inContext:
方法进行绘图
这适用于英语、俄语和某些其他语言。然而,对于某些语言,比如韩语或阿拉伯语,我会收到垃圾
问题似乎是我使用的字体。我使用的是系统字体(旧金山的一个变体,我相信,从<代码> -[UIFONT System FufOfStime:] /<代码>)。如果我将字体切换为“ApplesdGothicno Medium”,则会绘制我期望的韩国语字形
在“高级”API(如UILabel
)中,字体有一个字体“级联列表”,为阿拉伯语等语言提供字形。我的结论是,我在核心图形上下文中必须使用的CGFontRef
无法访问此级联列表,因此无法正常工作
似乎有某种方法可以获得这个级联列表,因为-[NSLayoutManager drawGlyphsForGlyphRange:atPoint:
工作得很好,所以它一定是在使用这个功能
我的问题是,有没有办法创建一个包含此列表的CGFontRef
?如果不是,为每个字形选择正确字体的最佳方法是什么
在我的CALayer
方法的drawInContext:
中,我的一些代码演示了这个问题,如下所示:
NSRange range = [self.layoutManager glyphRangeForBoundingRect:CGContextGetClipBoundingBox(context)
inTextContainer:self.textContainer];
NSLayoutManager *layoutManager = self.layoutManager;
NSMutableArray<NSValue *> *glyphs = [NSMutableArray array];
NSMutableArray<NSValue *> *points = [NSMutableArray array];
for (NSUInteger i = range.location; i < range.length; i++) {
CGGlyph glyph = [layoutManager CGGlyphAtIndex:i]; /* in the real code, I use a category on NSLayoutManager to make this safe for iOS 8 and iOS 9 both, but it doesn't matter here */
[glyphs addObject:[NSValue value:&glyph
withObjCType:@encode(CGGlyph)]];
CGPoint fragmentLocation = [layoutManager lineFragmentRectForGlyphAtIndex:i
effectiveRange:NULL].origin;
CGPoint location = [layoutManager locationForGlyphAtIndex:i];
[points addObject:[NSValue valueWithCGPoint:CGPointMake(self.horizontalOffsetForText + fragmentLocation.x + location.x,
self.bounds.size.height - (fragmentLocation.y + location.y))]];
}
CGGlyph *rawGlyphs = malloc(sizeof(CGGlyph) * glyphs.count);
CGPoint *rawPoints = malloc(sizeof(CGPoint) * points.count);
for (NSUInteger i = 0; i < glyphs.count; i++) {
[glyphs[i] getValue:rawGlyphs + i];
[points[i] getValue:rawPoints + i];
}
CGFontRef cgFont = CGFontCreateWithFontName((__bridge_retained CFStringRef)self.font.fontName);
CGContextSetFont(context, cgFont);
CGContextSetFontSize(context, self.font.pointSize);
CGAffineTransform t = CGContextGetTextMatrix(context);
t = CGAffineTransformScale(t, 1, -1);
CGContextSetTextMatrix(context, t);
CGContextSetFillColorWithColor(context, self.textColor.CGColor);
[layoutManager showCGGlyphs:rawGlyphs
positions:rawPoints
count:glyphs.count
font:self.font
matrix:t
attributes:@{NSForegroundColorAttributeName: self.textColor,
NSFontAttributeName: self.font,
NSParagraphStyleAttributeName: self.paragraphStyle}
inContext:context];
free(rawGlyphs);
free(rawPoints);
CFRelease(cgFont);
NSRange range=[self.layoutManager glyphRangeForBoundingRect:CGContextGetClipBoundingBox(上下文)
inTextContainer:self.textContainer];
NSLayoutManager*layoutManager=self.layoutManager;
NSMutableArray*glyphs=[NSMutableArray];
NSMutableArray*点=[NSMutableArray];
对于(i=range.location;i
你找到这个问题的答案了吗?我也面临着类似的问题,网上的信息非常少,我没有。已经两年了,但我相信我确实找到了一个非常糟糕的解决方法,那就是在每个glyph的基础上使用CTFontCreateForString
。