iOSã®ç»é¢ã«ããã¹ãã衚瀺ããããšã«ã€ããŠã話ãããããšæããŸãã æåã¯ãã¥ãŒããªã¢ã«ãšããŠã次ã«éèªæãªäºå®ã®ã³ã¬ã¯ã·ã§ã³ãšããŠèæ¡ãããŸããããäœãèµ·ãã£ãã®ããå€æããŸããã
ããã¹ãã衚瀺ããæ¹æ³ã¯ãæ¡ä»¶ä»ãã§ããã€ãã®ã«ããŽãªã«åé¡ã§ããŸãã
- UIKit-䜿ãæ
£ããUIã³ã³ãããŒã«ã åºæ¬çãªè¡šç€ºæ©èœã®ã¿ãæäŸããæžåŒèšå®ãªãã·ã§ã³ã¯ã»ãšãã©ãããŸãã
- UIKit + NSAttributedString-衚瀺å±æ§ã§æååãèšå®ããæ©èœãæã€äœ¿ãæ
£ããUIã³ã³ãããŒã«ã å€æ°ã®ãã©ãŒããããªãã·ã§ã³
- CoreText-ããã¹ãããã³ããã¹ããã¬ãŒã³ããŒã·ã§ã³ãæäœããããã®ãã¬ãŒã ã¯ãŒã¯ã NSAttributedStringãšçµã¿åãããŠãããã¹ãããã©ãŒãããããããã®å€ãã®å¯èœæ§ããããããã¹ãèŠçŽ ã«å¯Ÿããæœè±¡åã®ããã€ãã®ã¬ãã«ã®ãããã§ããããã衚瀺ããããã®é«åºŠãªæ¹æ³
- CoreGraphics-ããã䜿çšããŠãããã¹ããæç»ããããšãã§ããŸã
NSAttributedString
æåã«ãããªãŒãã€ã€ã«ããªããžãªããžã§ã¯ãã
䜿çšããå Žåã¯ã
NSAttributedStringãŸãã¯
CFAttributedStringRefãšåŒã°ããåºæ¬çãªããšã«ã€ããŠè©±ãå¿
èŠããããŸãã ããã¯ã衚瀺å±æ§ãèšå®ã§ããæååã§ãã
NSDictionary *textAttributes = @{(NSString *)kCTFontAttributeName : [UIFont systemFontOfSize:16]}; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:LoremIpsum attributes:textAttributes];
ãã®ã³ãŒãã¯ãåäžã®è¡šç€ºå±æ§ãæã€ç·ãäœæããŸããç·ãæç»ãããšãã«äœ¿çšãããã©ã³ãã§ãã 次ã®ããã«ãªããŸãã

ããã§ãDemoniacDeathãã³ã¡ã³ãã§èŠªåã«æãåºãããŠããã1ã€ã®éèŠãªãã€ã³ãã匷調ããå¿
èŠããããŸããCoreTextã¯ãã¬ã³ããªã³ã°ã«CTFontã䜿çšããŸãã ãããã£ãŠãç°¡æœãã®äŸã§äœ¿çšãããŠããåãã£ã¹ãã¯iOS6ã§ã®ã¿æ©èœãã以äžã®ãã¹ãŠã«ã€ããŠãUIFontã«åºã¥ããŠCTFontãäœæããå¿
èŠããããŸãã
CTFont ctFont = (__bridge_transfer id)CTFontCreateWithName(uiFont.fontName, uiFont.pointSize, NULL);
ãã®ããã䜿çšå¯èœãªæšæºå±æ§ãããªããããŸãã
- kCTForegroundColorAttributeName-ãã©ã³ãã®è²
- kCTUnderlineStyleAttributeName-ããã¹ãã®äžç·ã¹ã¿ã€ã«ïŒ CTUnderlineStyleã¯äžç·ã®ã¿ã€ãã«åœ±é¿ããŸãïŒåç·ã倪ç·ãåç·ãäºéç·ã CTUnderlineStyleModifiersã¯ãç·ã®çš®é¡ã«åœ±é¿ããŸãïŒç Žæãç¹ç·ãªã©
- kCTUnderlineColorAttributeName-äžç·ã®è²
- kCTForegroundColorFromContextAttributeName-ã°ã©ãã£ãã¯ã¹ã³ã³ããã¹ãããè²ãååŸãããã©ããã YESã®å Žåããã©ã¡ãŒã¿ãŒkCTUnderlineColorAttributeNameããã³kCTUnderlineStyleAttributeNameã¯è²ã«åœ±é¿ããŸããããã³ã³ããã¹ãè²CGContextSetFillColorWithColorã䜿çšãããŸã
- kCTLigatureAttributeName- ååã®äœ¿çšã¢ãŒãã ã¢ãŒãïŒ
- 0ã¯ãæåã®éåžžã®è¡šç€ºã«å¿
èŠãªååã®ã¿ã䜿çšãããããšã決å®ããŸã
- 1ã¯ãæšæºã®ååã®ã¿ã䜿çšãããããšã決å®ããŸãã ã©ã®ååãæšæºã«ãªããã¯ããã©ã³ããšèšèªã«ãã£ãŠç°ãªããŸãã ããšãã°ãè±èªã®å Žåã¯flãšfiã§ãã ããã©ã€èªãã¢ã©ãã¢èªãã¿ã€èª-ãã®èå³æ·±ãèšå·
- 2ã¯ãå¯èœãªéãæ倧æåãååã«ã°ã«ãŒãåããå¿
èŠãããå Žåã«æ±ºå®ããŸã
- kCTParagraphStyleAttributeName-ããã¹ãã«æ®µèœãããå ŽåããããŸãã ãã®ãã©ã¡ãŒã¿ãŒã¯ã段èœã®ã¹ã¿ã€ã«ã決å®ããŸãã ãã¹ãŠã®ãã©ã¡ãŒã¿ãŒã¯ã CTParagraphStyleSpecifierã®å®çŸ©ã§èŠã€ããããšãã§ããŸãã kCTParagraphStyleSpecifierBaseWritingDirectionã«åå¥ã«æ³šæãæããã -çŸåšã®æ®µèœã®ããã¹ãã®è¡šç€ºæ¹åïŒå·Šããå³/å³ããå·ŠïŒã決å®ããŸãã ããã©ã«ãã§ã¯ã kCTWritingDirectionNaturalã䜿çšãããŸã- ãã®ããã¥ã¡ã³ãã«åŸã£ãŠã衚瀺æ¹åãéžæãããŸã ã ãã ãã kCTWritingDirectionLeftToRight / kCTWritingDirectionRightToLeftãèšå®ããããšã«ãããå
¥åæ¹åãæåã§èšå®ã§ããŸãã
- kCTRunDelegateAttributeNameã¯ãéåžžã«éèŠã§èå³æ·±ããã©ã¡ãŒã¿ãŒã§ãã å
¥åã§ã¯ãå¹
ãšæ°åã®ãã©ã¡ãŒã¿ãŒãè¿ãäžé£ã®é¢æ°ã䜿çšããããã«åºã¥ããŠç·ã®é«ããèšç®ãããŸãã 次ã«ããã®ãã©ã¡ãŒã¿ãŒãšãã®å¿çšã«ã€ããŠè©³ãã説æããŸãã
ããšãã°ãã«ãŒãã³ã°3.0ããã©ã³ããµã€ãº14ãäžç·ä»ãã®ããã¹ãã¯ãå³åŽã®ãã¹ãŠã®ããã¹ãã20.0ãã€ã³ããèµ€ç·ã40.0ãã€ã³ãã30.0ãã€ã³ãã®æ®µèœééã§ã€ã³ãã³ãããŸãã
CTParagraphStyleSetting paragraphSettings[] = (CTParagraphStyleSetting[]){ (CTParagraphStyleSetting){ kCTParagraphStyleSpecifierFirstLineHeadIndent, sizeof(float_t), (float_t[]){ 40.0f } }, (CTParagraphStyleSetting){ kCTParagraphStyleSpecifierHeadIndent, sizeof(float_t), (float_t[]){ 20.0f } }, (CTParagraphStyleSetting){ kCTParagraphStyleSpecifierParagraphSpacing, sizeof(float_t), (float_t[]){ 30.0f } } }; id paragraphStyle = (__bridge_transfer id)CTParagraphStyleCreate(paragraphSettings, sizeof(paragraphSettings) / sizeof(paragraphSettings[0])); NSDictionary *textAttributes = @{ (NSString *)kCTFontAttributeName : [UIFont systemFontOfSize:14], (NSString *)kCTKernAttributeName : @(3.0), (NSString *)kCTUnderlineStyleAttributeName : @(kCTUnderlineStyleSingle), (NSString *)kCTParagraphStyleAttributeName : paragraphStyle };

æç»
ãŠã€ããã
次ã«ãããããã¹ãŠãã¬ã³ããªã³ã°ããæ¹æ³ã«ã€ããŠèª¬æããŸãã iOS6以éã
NSAttributedStringã«ã¯UIKitã«
NSStringDrawingã«ããŽãªã
ãã ããããç°¡åã«è¡ãããšãã§ããŸãã
NSDictionary *textAttributes = @{(NSString *)kCTFontAttributeName : [UIFont systemFontOfSize:16]}; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:LoremIpsum attributes:textAttributes]; [attributedString drawInRect:rect];
å¥ã®æ¹æ³ããããŸãïŒ
- (void)drawWithRect:(CGRect)rect options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context;
ããã¯ãæž¡ããããã©ã¡ãŒã¿ãŒãšç¹å¥ãªã³ã³ããã¹ãã䜿çšããŠã«ã¹ã¿ãã€ãºå¯èœã«ãªããŸãã ççŽã«èšã£ãŠãç§ãã¡ã補åã§ãµããŒãããiOSã®æå°ããŒãžã§ã³ã¯4.3ã§ããããããããã®ã¡ãœããã䜿çšããããšã¯ãããŸããã
äœæããã
NSAttributedStringã
setAttributedStringïŒã¡ãœãããä»ããŠ
UILabel ã
UITextFieldããŸãã¯
UITextViewã«æž¡ãããšãã§ããŸãã ãã®ã¡ãœãããiOS6.0ã§ã®ã¿ãµããŒããããŠããŸãã ã¡ãªã¿ã«ãiOS6.0以éã®ãããã®èŠçŽ ã§ã¯ã衚瀺ã®å±æ§ãxibãŸãã¯ã¹ããŒãªãŒããŒãã®InterfaceBuilderã§çŽæ¥èšå®ã§ããŸãã
ã³ã¢ããã¹ã
CoreTextã¯ãæœè±¡åã®ããã€ãã®ã¬ãã«ã§ããã¹ããæç»ã§ããããã«ãã
çŽ æŽããããã®ã§ãã ãŸããããã€ãã®ã¬ãã«ã§ããã¹ã衚瀺ã®åºæ¬éšåã«ã¢ã¯ã»ã¹ã§ããŸãã
ããã«èª¬æãå§ããåã«ããã®ç¬éãŸã§ã«ãã°ã©ãã£ãã¯ã³ã³ããã¹ããšã¯äœããç¥ã£ãŠãããã¢ãã£ã³å€æã«ç²ŸéããŠããããšãç解ããããšæããŸãã
ãŸããApple Webãµã€ãããåçãçã¿ãŸãã

æåã®ã¬ãã«ã CTFramesetter
ãã®ã¬ãã«ã§ã¯ããŸã æç»ã§ããŸããã ãã®æœè±¡åã®å¯äžã®åœ¹å²ã¯ãæå®ãããã¹ã¿ã€ã«ã®ããã¹ãã䜿çšããŠã幟äœããªããã£ãã«å
æ¥ããæç»ãªããžã§ã¯ããäœæããããšã§ãã ãŸãã
CTFramesetterã䜿çšãããšãå¹
ãŸãã¯é«ããä¿®æ£ããŠãçŸåšã®è¡šç€ºèšå®ã§çŸåšã®ããã¹ãã®é«ããŸãã¯å¹
ãèŠã€ããããšãã§ããŸãã
NSDictionary *textAttributes = @{(NSString *)kCTFontAttributeName : [UIFont systemFontOfSize:16]}; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:LoremIpsum attributes:textAttributes]; CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attributedString)); CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, CGSizeMake(CGRectGetWidth(rect), CGFLOAT_MAX), NULL);
ããã§ã¯ãããã¹ããå
¥åããå¹
ãåºå®ãããŠããŸãã
suggestSizeã«ã¯ãç®çã®ããã¹ãã®é«
ããå«ãŸããŸãã åãããšã¯å¹
ã§è¡ãããšãã§ããŸãã
第2ã¬ãã«ã CTFrame
ãã®ãªããžã§ã¯ãã¯ãäžèšã®
CTFramesetterãäœæãããã§ã«å®å
šã«ã¬ã³ããªã³ã°ã®æºåãã§ããŠããŸãã
CGPathRef path = CGPathCreateWithRect((CGRect){CGPointZero, suggestedSize}, NULL); CTFrameRef textFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL); CTFrameDraw(textFrame, context);
次ã®ã¡ãœããã®ãã©ã¡ãŒã¿ãŒã«ã€ããŠè©³ãã説æããŸãã
CTFrameRef CTFramesetterCreateFrame( CTFramesetterRef framesetter, CFRange stringRange, CGPathRef path, CFDictionaryRef frameAttributes )
- ãã¬ãŒã ã»ãã¿ãŒ -å®éã«ã¯ãã°ã©ãã£ãã¯è¡šç€ºãæ§ç¯ããå±æ§ãæã€æååãå«ããªããžã§ã¯ã
- stringRange-ãããã³ã°ãæ§ç¯ãããæååã®éšåã é·ã0ã¯ãçŸåšäœçœ®ããéå§ããŠãè¡ãæåŸãŸã§ååŸããå¿
èŠãããããšãæå³ããŸãã ã€ãŸããCFRangeïŒ0,0ïŒã¯æåããæåŸãŸã§ã®è¡ã瀺ããŸã
- path-ããã¹ããå
æ¥ãã幟äœåŠçããªããã£ãã®ã»ãããå®çŸ©ããŸã
- frameAttributes-ãã£ããã£ã³ã°çšã®è¿œå ãã©ã¡ãŒã¿ãŒã ããšãã°ã kCTFramePathFillRuleAttributeNameã¯ã 亀差ããé åã§ã®ããã¹ãã®åäœèŠåãèšå®ããŸã ã kCTFrameProgressionAttributeNameã¯ãè¡ãäœæãããé åºãå®çŸ©ããŸããäžããäžïŒæ°Žå¹³ããã¹ãïŒãŸãã¯å³ããå·ŠïŒåçŽããã¹ãïŒ
ããã€ãã®äŸã
CGMutablePathRef path = CGPathCreateMutable(); CGPathAddEllipseInRect(path, NULL, (CGRect){CGPointZero, CGSizeMake(suggestedSize.width, suggestedSize.height / 2)}); CGPathAddEllipseInRect(path, NULL, (CGRect){0, suggestedSize.height / 2, CGSizeMake(suggestedSize.width, suggestedSize.height / 2)});

CGAffineTransform transformation = CGAffineTransformMakeRotation(M_PI_4); CGPathAddEllipseInRect(path, &transformation, CGRectMake(20, -200, 400, 130)); CGPathAddRect(path, &transformation, CGRectMake(50, -150, 200, 200));

æåŸã®äŸã§ã¯ã
CTFrameã«kCTFramePathFillWindingNumberãã©ã¡ãŒã¿ãŒã䜿çšããŠããããã亀差ããé åã«ãããã¹ããå
¥åãããŸãã
ä»ã®2ã€ã®éèŠãªãã€ã³ãïŒ
- äžèšã®äŸã®ãããããè©ŠããŠã¿ããšãçµæã¯ç§ããäžããããçµæãšã¯éåžžã«ç°ãªããŸããã€ãŸããç»åã¯å転ããŸããCoreTextã¯ãããšãã°CGBitmapContextã®ããã«äœæãããCGContextã®ããã«å·Šäžé
ããå§ãŸãç»åã圢æããããã§ã ãããã£ãŠãæ£ããåºåãåŸãã«ã¯ãçŸåšã®ã°ã©ãã£ãã¯ã¹ã³ã³ããã¹ããå€æããå¿
èŠããããŸã
- ã°ã©ãã£ãã¯ã³ã³ããã¹ãå
šäœã§ã¯ãªããããã¹ãã®ã¿ã«å€æãæå®ããããšãå¯èœã§ãããå¿
èŠã§ãã ããã¯CGContextSetTextMatrixãä»ããŠè¡ãããŸãã ãã®ããšã®ç¹åŸŽã¯ã CGSave / RestoreContextãããã¹ãã®å€æãããªãã¯ã¹ãä¿åãŸãã¯åŸ©å
ããªãããšã§ãã ãããã£ãŠãã¬ã³ããªã³ã°ã®åã«åžžã«èšå®ããå¿
èŠããããŸããããããªããšãã·ã¹ãã ã©ã€ãã©ãªã®è
žãŸãã¯ããã°ã©ã ã®ä»ã®éšåã§ãã®ã¡ãœãããåŒã³åºããšãã«èšå®ãããå€ãå«ãŸããå ŽåããããŸãã
CGContextSetTextMatrix(context, CGAffineTransformIdentity); CGContextScaleCTM(context, 1.0f, -1.0f); CGContextTranslateCTM(context, 0.0f, -suggestedSize.height);
éæçå€æè¡åã¯ã©ããªããŸããïŒ
CGContextSetTextMatrix(context, CGAffineTransformMakeRotation(M_PI_4)); CGContextScaleCTM(context, 1.0f, -1.0f); CGContextTranslateCTM(context, 0.0f, -suggestedSize.height);

ããã«è°è«ããåã«ãAppleã®Webãµã€ãããå¥ã®åçãçã¿ãããšæããŸãã

åæ
çãªäœè«ã CTTypesetter
CTFrameã®äœæã«é¢äžããã®ã¯ãã®ãšã³ãã£ãã£ã§ãã ãã®åœ¹å²ã¯ããã®æ®µéã§ãã§ã«ã¬ã³ããªã³ã°ã®æºåãã§ããŠããéåžžã«ããã¹ã圢åŒã®ã°ã©ãã£ãã¯ããªããã£ããäœæããããšã§ãã äžããããã¢ã«ãŽãªãºã ïŒåèªãæåãªã©ïŒã«åŸã£ãŠæ¹è¡ãå®è¡ããé©åããªãã£ããã®ããã¹ãŠåãåããŸãã
ã¬ãã«3ã CTLine
ããã
CTFrameã®æ§æ
èŠçŽ ã§ãã
CTLineã¯ãé
眮ããäœçœ®ãèšå®ããããšã§æç»ã§ããŸã
ãCTFrameGetLineOriginsã¡ãœããã䜿çšããŠ
CTFrameããèšç®ããããéåžžã«ããªãããŒãªã¢ã«ãŽãªãºã ã«åŸã£ãŠèšå®ããŸãã
CFArrayRef lines = CTFrameGetLines(textFrame); for (CFIndex i = 0, linesCount = CFArrayGetCount(lines); i < linesCount; ++i) { CGPoint lineOrigin = CGPointZero; CTFrameGetLineOrigins(textFrame, CFRangeMake(i, 1), &lineOrigin); CGContextSetTextPosition(context, lineOrigin.x, lineOrigin.y); CTLineDraw(CFArrayGetValueAtIndex(lines, i), context); }
ä»ã«ç¥ã£ãŠãã䟡å€ã®ãããã®ã¯ééããããŸããã ãã®è¡ã«ã¯ã
ããŒã¹ã©ã€ã³ ã
ã¢ã»ã³ã ã
ãã£ã»ã³ã ã
ãªãŒãã£ã³ã°ãšããããã€ãã®å°å·äžã®ãã©ã¡ãŒã¿ãŒããããŸãã
ããã§ã¿ããªã«ã€ããŠèªãããšãã§ã
ãŸã ã
CTFrameGetLineOriginsã¯ã¡ããã©
baselineãè¿ããŸãã æ®ãã®ãã©ã¡ãŒã¿ãŒã¯ãã¡ãœãããéããŠèŠã€ããããšãã§ããŸãã
doubCTLineGetTypographicBounds(CTLineRef line, CGFloat* ascent, CGFloat* descent, CGFloat* leading);

èµ€ã¯äžéãé»ã¯ããŒã¹ã©ã€ã³ãéã¯äžæã§ãã
ãããã®ãã©ã¡ãŒã¿ãŒã«æ»ããŸãã ãããŸã§ã®éãã©ã€ã³ã§äœ¿çšããããã¹ãŠã®ãã©ã³ãã®æå°å€ãšæ倧å€ãšããŠãã©ã€ã³å
šäœã§
äžéãš
äžæãè¡ãããããšã«æ³šæããŠãã ããã ããšãã°ãäžèšã®ããã¹ãã®å Žåãããã©ã€èªãååšããè¡ã§ã¯ã
éäžã倧ããããšãã¯ã£ãããšããããŸãã
ãã䟿å©ãªæ¹æ³ïŒ
CFRange CTLineGetStringRange(CTLineRef line)
çŸåšã®è¡ã®æååééãè¿ããŸãã éžæããæååééã«è©²åœããç¹å®ã®è¡ã®ã¿ãå¿
èŠãªå Žåã«ãã¢ã«ãŽãªãºã ã§ãã䜿çšãããŸãã
CFIndex CTLineGetStringIndexForPosition(CTLineRef line, CGPoint position)
æååå
ã®æå®ãããäœçœ®ã®æååã€ã³ããã¯ã¹ãè¿ããŸãã ããšãã°ãããã¹ãã®ç¹å®ã®é åã®ã¯ãªãã¯ãå€å¥ããããã«äœ¿çšã§ããŸãã ã³ã³ããã¹ããäžäžéã«ãªã£ãŠãããïŒ0,0ïŒãæçµè¡ã«ããããšã«æ³šæããŠãã ããã
CTLineRef CTLineCreateWithAttributedString(CFAttributedStringRef string)
ç·ãåŒãããã«ãCTFramesetter-> CTFrame-> CTLineãããã§ãŒã³å
šäœãäœæããå¿
èŠã¯ãããŸããã ããã«è¡ãäœæã§ããŸãã å€ãã®å Žåãããã¹ããç¹å®ã®é åã«åãŸããªãå Žåã¯ãã¿ã¹ã¯ãããªãã³ã°ããããšããããŸãã
CTLineRef CTLineCreateTruncatedLine(CTLineRef line, double width, CTLineTruncationType truncationType, CTLineRef truncationToken)
第4ã¬ãã«ã CTrun
ãããããããã¹ããå
¥åããããã®ç¬èªã®èŠçŽ ãäœæãã人ã«ãšã£ãŠæã䟿å©ãªæœè±¡åã§ãã
CTRunã¯ãåãã¹ã¿ã€ã«ã®æåãã°ã«ãŒãåããŠã°ã«ãŒãåããå Žæã§ãã ãããããããã¯iOS6.0ããã°ã«ãŒãåãããŠãããããããè¥ããã®ã§ã¯ãã¹ãŠã®ãã£ã©ã¯ã¿ãŒãåå¥ã®
CTRunã«ãªããŸãã æåãããç°¡åã§æçœãª1ã€ã®ãã€ã³ããæ確ã«ããå¿
èŠããã
ãŸã ãã·ã³ãã«ããããŸããã
ã°ãªãããã
ãŸã ã ãã®äºå®ãããä»ã«ã2ã€ã®ãã€ã³ããç¶ããŸããããããç°¡åã§ããããã§ã«æããã§ã¯ãããŸããã 1ã€ã®ã°ãªãã§äžåºŠã«è€æ°ã®æåãè¡šãããšãã§ããŸãã ããšãã°ãã»ãšãã©ã®çµµæåã¯åäžã®ã°ãªãã§ãããããã€ãã®UTFæåã§æ§æãããŠããŸãã
CTRunã䜿çšãããã¹ãŠã®äººã«ã¯ã
CTRun.hã«æ
£ããããšã匷ããå§ãããŸã-ããã«ãããã¹ãŠã®ã¡ãœããã¯éåžžã«äŸ¿å©ã§ãã
CFIndex CTRunGetGlyphCount(CTRunRef run)
CTRunã®ã°ãªãã®æ°ãè¿ããŸãã
CFRange CTRunGetStringRange(CTRunRef run)
CTRunãé
眮ãããŠããæååå
šäœããç¯å²ãè¿ããŸãã ãã®ç¯å²ã®é·ãã¯ãåžžã«åã®æ¹æ³ã®çµæãšåãã§ã¯ãããŸããïŒ
const CFIndex* CTRunGetStringIndicesPtr(CTRunRef run) void CTRunGetStringIndices(CTRunRef run, CFRange range, CFIndex buffer[])
ãã®ã¡ãœããã¯åã®ã¡ãœããã«é¢é£ããŠããŸãã æååå
ã®ã°ãªãã®äœçœ®ãè¿ããŸãã ããšãã°ãããã€ãã®çµµæåã®ããã¹ãããããŸãã

iOS6.0以éã
CTrunã¯æ¬¡ã®ããã«ãªããŸãã
CTRun: string range = (0, 6), string = "\U0001f437\U0001f434\U0001f428"
ã芧ã®ãšãããåã°ãªãã¯å®éã«ã¯2ã€ã®æåã§æ§æãããŠããŸãã
CTRunGetStringIndicesã¡ãœãããåŒã³åºããçµæã¯[0,2,4]ã«ãªããŸãã
ãã®ã¡ãœããã«ã¯2ã€ã®ãªãã·ã§ã³ãããããšã«æ³šæããŠãã ãããå¿
èŠãªæ°ã®ã€ã³ããã¯ã¹ãäºåã«å²ãåœãŠããããããã¡ãŒã«ã³ããŒãããã
CTRunå
ã®é
åã®å
é ãžã®ãã€ã³ã¿ãŒãååŸããŸãã ãã䟿å©ãªãã®ãéžæããŠãã ããã ãã®ãããªæ¹æ³ã¯ãããããããŸãããããã¯çœ²åããèŠãããšãã§ããŸããç§ã¯ããã«çŠç¹ãåãããŸããã
CFDictionaryRef CTRunGetAttributes(CTRunRef run)
CFAttributedStringã§èšå®ããã
CTRunã®çŸåšã®å±æ§ã
CTRunStatus CTRunGetStatus(CTRunRef run)
ããããã¹ã¯ã®åœ¢åŒã§ããã£ã¹ãã¬ã€åºæã®ãã©ã¡ãŒã¿ãŒãè¿ããŸãã
kCTRunStatusRightToLeftã«ç¹ã«æ³šæããŠ
ãã ãã-CTRunã®ã°ãªãã«ã¯å³ããå·Šãžã®ç¶Žãæ¹åãããããšã瀺ããŠããŸãã
const CGPoint* CTRunGetPositionsPtr(CTRunRef run) void CTRunGetPositions(CTRunRef run, CFRange range, CGPoint buffer[])
CTFrameã«å¯Ÿãã
CTRunå
ã®ã°ãªãã®äœçœ®ã ã¡ãœããã®2çªç®ã®ããŒãžã§ã³ã䜿çšããŠãããšãã°2çªç®ã®ã°ãªãã®äœçœ®ãååŸããå Žåãç¯å²å
ã§1ïŒçªå·ä»ãã¯0ããå§ãŸãïŒã§ã¯ãªããè¡å
ã®ãã®ã°ãªãã®äœçœ®ãæž¡ãå¿
èŠããããšããäºå®ã«ç¹ã«æ³šæãæããŸãã äžèšã®çµµæåãæã€ããªã¢ã³ãã®å Žåãããã¯äœçœ®2ã«ãªããŸããããã¯ããã¹ãŠã®åæ§ã®æ¹æ³ã«é©çšãããŸãã
const CGSize* CTRunGetAdvancesPtr(CTRunRef run) void CTRunGetAdvances(CTRunRef run, CFRange range, CGSize buffer[])
ã°ãªãã®ãµã€ãºãè¿ããŸãã
double CTRunGetTypographicBounds(CTRunRef run, CFRange range, CGFloat* ascent, CGFloat* descent, CGFloat* leading)
åäžã®
CTRunã®æŽ»çå°å·ãã©ã¡ãŒã¿ãŒãè¿ããŸãã èŠããŠãããŠããã®ã©ã€ã³ã§äœ¿çšããããã©ã³ãã§ã¯ãã©ã€ã³ã®
äžéãš
äžæã¯æ¥µç«¯ãªãã®ãšèŠãªããããšèšã£ãã®ã§ããïŒ ãããã£ãŠãè¡ã®åéšåã«ã€ããŠãåå¥ã«èªèã§ããããã«ãªããŸããã

ãŸãã
äžéãš
äžæãæ確ã«ãªã£ããã
kCTRunDelegateAttributeNameå±æ§ã«ã€ããŠ
説æããŸãã å
¥åã§ã¯ãããã€ãã®ã¡ãœããã«åºã¥ããŠäœæããã
CTRunDelegateã䜿çšããŸãã
typedef struct { CFIndex version; CTRunDelegateDeallocateCallback dealloc; CTRunDelegateGetAscentCallback getAscent; CTRunDelegateGetDescentCallback getDescent; CTRunDelegateGetWidthCallback getWidth; } CTRunDelegateCallbacks;
æåŸã®3ã€ã«èå³ããããŸãã ã¡ãœããã¯ããã®å±æ§ã§ã¿ã°ä»ããããã°ãªãã®
ãã£ã»ã³ã ã
ã¢ã»ã³ããå¹
ãè¿ãç¡æã®é¢æ°ã§ãã çŸåšã®ã°ãªãã®ãã©ã¡ãŒã¿ãŒãäžè¬çãªå¹ŸäœåŠçãã©ã¡ãŒã¿ãŒã®èšç®ã«åå ãããã³ã«ãäžé£ã®ã¡ãœãããåŒã³åºãããŸãã ããã䜿çšããŠãç¬èªã®ã°ãªããäœæã§ããŸãã
void CTRunDraw(CTRunRef run, CGContextRef context, CFRange range)
ã°ã©ãã£ãã¯ã³ã³ããã¹ãã§
CTRunãæç»ããŸãã
Coregraphics
第5ã¬ãã«ã ã°ãªã
ççŽã«èšã£ãŠããã®ã¬ãã«ã¯ãã¯ã
CoreTextã§ã¯ãªãã
CoreGraphicsã§ãã以åã¯å©çšå¯èœã§ããã ã°ãªããååŸããã®ãç°¡åã«ãªã£ãã®ã¯ä»ã§ãã
CFIndex glyphCount = CTRunGetGlyphCount(run); CGPoint positions[glyphCount]; CGGlyph glyphs[glyphCount]; CTRunGetPositions(run, CFRangeMake(0, 0), positions); CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs); CGContextSetFont(context, cgFont); CGContextSetFontSize(context, CTFontGetSize(runFont)); CGContextSetFillColorWithColor(context, runColor); CGContextShowGlyphsAtPositions(context, glyphs, positions, glyphCount);
ãã®å Žåãäžç·ã¹ã¿ã€ã«ã¯
CoreTextãä»ããŠå®è£
ãããããã䜿çšã§ããªãããšãç解ããå¿
èŠããããŸãã ãã ããã¬ã³ããªã³ã°æã«ã¯ãèªç±ã«ã°ãªããé
眮ã§ããŸãã
Appleã¯ãã€ãã®ããã«ãAPIèšèšã®äŒçµ±ãå¿ å®ã«å®ã£ãŠããŸããåçŽãªããšã¯é ããŸã§è¡ãããåçŽã«ãdo Me Goodãã¡ãœãããåŒã³åºãããšã¯ã§ããŸããã