IOS рдореЗрдВ рдЯреЗрдХреНрд╕реНрдЯ рдЖрдЙрдЯрдкреБрдЯ: CoreText, NSAttributedString

рдореИрдВ рдЖрдкрдХреЛ iOS рдореЗрдВ рд╕реНрдХреНрд░реАрди рдкрд░ рдЯреЗрдХреНрд╕реНрдЯ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдкрд╣рд▓реЗ рдпрд╣ рдПрдХ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд▓реНрдкрдирд╛ рдХреА рдЧрдИ рдереА, рдлрд┐рд░ рдЧреИрд░-рд╕реНрдкрд╖реНрдЯ рддрдереНрдпреЛрдВ рдХреЗ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд░реВрдк рдореЗрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣реБрдЖ рдХрд┐ рдХреНрдпрд╛ рд╣реБрдЖред

рдкрд╛рда рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╕рд╢рд░реНрдд рд░реВрдк рд╕реЗ рдХрдИ рд╢реНрд░реЗрдгрд┐рдпреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ:



NSAttributedString


рдЕрдЧрд░ рд╣рдо рдЯреЛрд▓-рдлреНрд░реА-рдмреНрд░рд┐рдЬ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдПрдХ рдмреБрдирд┐рдпрд╛рджреА рдЪреАрдЬрд╝ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ, рдЬрд┐рд╕реЗ NSAttributedString рдпрд╛ CFAttributedStringRef рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд░реНрд╢рди рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

NSDictionary *textAttributes = @{(NSString *)kCTFontAttributeName : [UIFont systemFontOfSize:16]}; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:LoremIpsum attributes:textAttributes]; 

рдпрд╣ рдХреЛрдб рдПрдХрд▓ рдкреНрд░рджрд░реНрд╢рди рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдкрдВрдХреНрддрд┐ рдмрдирд╛рддрд╛ рд╣реИ: рд░реЗрдЦрд╛ рдЦреАрдВрдЪрддреЗ рд╕рдордп рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдлрд╝реЙрдиреНрдЯред рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


рдпрд╣рд╛рдБ рдореБрдЭреЗ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдкрд░ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдбреЗрдореЛрдирд┐рдпрд╛рдХреНрд░реЗрдб рдиреЗ рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдпрд╛рдж рджрд┐рд▓рд╛рдпрд╛: рдХреЛрд░рдЯреЗрдХреНрд╕реНрдЯ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП CTFont рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЯреЛрд▓-рдлреНрд░реА-рдмреНрд░рд┐рдЬ рд╣реИ рдЬреЛ рдХреЗрд╡рд▓ iOS6 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЯрд╛рдЗрдк рдХрд╛рд╕реНрдЯ, рдЬреЛ рд╕рдВрдХреНрд╖рд┐рдкреНрддрддрд╛ рдХреЗ рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреЗрд╡рд▓ iOS6 рдкрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рдФрд░ рдиреАрдЪреЗ рджреА рдЧрдИ рд╣рд░ рдЪреАрдЬ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ UIFont рдХреЗ рдЖрдзрд╛рд░ рдкрд░ CTFont рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 CTFont ctFont = (__bridge_transfer id)CTFontCreateWithName(uiFont.fontName, uiFont.pointSize, NULL); 

рдЗрд╕рд▓рд┐рдП, рдХреБрдЫ рдорд╛рдирдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ:


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд░реНрд▓рд┐рдВрдЧ 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 }; 



рдбреНрд░рд╛рдЗрдВрдЧ


UIKit


рдЕрдм рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред IOS6 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ, NSAttributedString рдореЗрдВ USSit рдореЗрдВ 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; 

рдЬреЛ рдкрд╛рд░рд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ рдФрд░ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕рдВрджрд░реНрдн рдХреА рдорджрдж рд╕реЗ рдЕрдиреБрдХреВрд▓рди рдХрд░рдиреЗ рдХрд╛ рджрд┐рдЦрд╛рд╡рд╛ рдХрд░рддрд╛ рд╣реИред рд╕рдЪ рдХрд╣реВрдВ, рддреЛ рдореИрдВрдиреЗ рдХрднреА рдЗрди рддрд░реАрдХреЛрдВ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдЙрддреНрдкрд╛рдж рдореЗрдВ рдЖрдИрдУрдПрд╕ рдХрд╛ рдиреНрдпреВрдирддрдо рд╕рдВрд╕реНрдХрд░рдг 4.3 рд╣реИред
рдЖрдк рд╕реЗрдЯ рдХрд┐рдП рдЧрдП NSAttributedString рдХреЛ рднреА рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ UAlabel , UITextField рдпрд╛ UITextView рдХреЛ setAttributedString: рдкрджреНрдзрддрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗред рдпрд╣ рд╡рд┐рдзрд┐ рднреА рдХреЗрд╡рд▓ iOS6.0 рдХреЗ рд╕рд╛рде рд╕рдорд░реНрдерд┐рдд рд╣реИред рд╡реИрд╕реЗ, iOS6.0 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЗрди рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП, рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рд╕реАрдзреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ xib рдпрд╛ рд╕реНрдЯреЛрд░реАрдмреЛрд░реНрдб рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

CoreText


CoreText рдПрдХ рдРрд╕реА рдорд╕реНрдд рдЪреАрдЬрд╝ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдХрдИ рд╕реНрддрд░реЛрдВ рдХреЗ рд╕рд╛рд░ рддрддреНрд╡реЛрдВ рдкрд░ рдкрд╛рда рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдХрдИ рд╕реНрддрд░реЛрдВ рдкрд░ рдкрд╛рда рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдкреНрд░рд╛рдердорд┐рдХ рднрд╛рдЧреЛрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рднреА рджреЗрддрд╛ рд╣реИред
рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдореИрдВ рдЖрдЧреЗ рдмрддрд╛рдирд╛ рд╢реБрд░реВ рдХрд░реВрдВ, рдореИрдВ рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕ рдХреНрд╖рдг рддрдХ рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЧреНрд░рд╛рдлрд┐рдХ рд╕рдВрджрд░реНрдн рдХреНрдпрд╛ рд╣реИ рдФрд░ рдПрдлрд╛рдЗрди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВред
рдореИрдВ Apple рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╕реЗ рдПрдХ рддрд╕реНрд╡реАрд░ рднреА рдЪреБрд░рд╛ рд▓реВрдВрдЧрд╛:



рдкрд╣рд▓рд╛ рд╕реНрддрд░ред 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); 

рдпрд╣рд╛рдВ, рдкрд╛рда рдХреЛ рджрд░реНрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪреМрдбрд╝рд╛рдИ рддрдп рдХреА рдЧрдИ рд╣реИред рд╕реБрдЭрд╛рдП рдЧрдП рдЖрдХрд╛рд░ рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдкрд╛рда рдКрдБрдЪрд╛рдИ рд╣реЛрдЧреАред рдЪреМрдбрд╝рд╛рдИ рдХреЗ рд╕рд╛рде рднреА рдРрд╕рд╛ рд╣реА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рджреВрд╕рд░рд╛ рд╕реНрддрд░ред 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 ) 


рдЙрджрд╛рд╣рд░рдг рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗред

 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 рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрд┐рдд рдХреНрд╖реЗрддреНрд░ рднреА рдкрд╛рда рд╕реЗ рднрд░реЗ рд╣реБрдП рд╣реИрдВред

рджреЛ рдЕрдиреНрдп рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ:
  1. рдпрджрд┐ рдЖрдк рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкрд░рд┐рдгрд╛рдо рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рджрд┐рдП рдЧрдП рд╕реЗ рдмрд╣реБрдд рдЕрд▓рдЧ рд╣реЛрдЧрд╛, рдЕрд░реНрдерд╛рддреН: рдЫрд╡рд┐ рдХреЛ рдЙрд▓рдЯрд╛ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ CoreText рдирд┐рдЪрд▓реЗ рдмрд╛рдПрдБ рдХреЛрдиреЗ рд╕реЗ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдЫрд╡рд┐ рдмрдирд╛рддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдХрд┐рд╕реА рднреА CGContext рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, CGBitmapContext ред рдЗрд╕рд▓рд┐рдП, рд╕рд╣реА рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╡рд░реНрддрдорд╛рди рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рд╕рдВрджрд░реНрдн рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
  2. рдХреЗрд╡рд▓ рдкрд╛рда рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рди рдХрд┐ рдкреВрд░реЗ рдЧреНрд░рд╛рдлрд┐рдХ рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдПред рдпрд╣ 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 рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╕реЗ рдПрдХ рдФрд░ рддрд╕реНрд╡реАрд░ рдЪреБрд░рд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛:



рдЧреАрддрд╛рддреНрдордХ рд╡рд┐рд╖рдпрд╛рдВрддрд░ред CTTypesetter

рдпрд╣ рд╡рд╣ рд╕рдВрд╕реНрдерд╛ рд╣реИ рдЬреЛ CTFrame рдмрдирд╛рдиреЗ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИред рдЗрд╕рдХреА рднреВрдорд┐рдХрд╛ рдмрд╣реБрдд рд╣реА рдЧреНрд░рд╛рдлрд┐рдХ рдЧреНрд░рд╛рдлрд┐рдХ рдкреНрд░рд┐рдорд┐рдЯрд┐рд╡ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рд╕реНрддрд░ рдкрд░ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред рдпрд╣ рдПрдХ рджрд┐рдП рдЧрдП рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо (рд╢рдмреНрджреЛрдВ, рд╡рд░реНрдгреЛрдВ рдЖрджрд┐ рдХреЗ рдЕрдиреБрд╕рд╛рд░) рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд▓рд╛рдЗрди рдмреНрд░реЗрдХ рд▓рдЧрд╛рддрд╛ рд╣реИ, рдЙрди рд╕рднреА рдЪреАрдЬреЛрдВ рдХреЛ рдХрд╛рдЯ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдлрд┐рдЯ рдирд╣реАрдВ рдереЗред

рд╕реНрддрд░ рддреАрдиред CTLine

рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рдПрдХ CTFrame рдХреЗ рд╣реЛрддреЗ рд╣реИрдВред CTLine рдХреЛ рдЙрди рдкрджреЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдХреЗ рдЦреАрдВрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рдирдХреЗ рджреНрд╡рд╛рд░рд╛ рд╡реЗ рд╕реНрдерд┐рдд рд╣реЛрдВрдЧреЗ: CTFrame рд╕реЗ CTFrameGetLineOrigins рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЧрдгрдирд╛ рдХрд░рдирд╛ рдпрд╛ рдЗрд╕реЗ рдХреБрдЫ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╕реЗрдЯ рдХрд░рдирд╛ред

 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 рдмрд┐рд▓реНрдХреБрд▓ рдЖрдзрд╛рд░ рд░реЗрдЦрд╛ рджреЗрддрд╛ рд╣реИред рд╢реЗрд╖ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 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) 

рдЪреМрдерд╛ рд╕реНрддрд░ред CTrun

рд╕рдВрднрд╡рддрдГ рдХрд┐рд╕реА рдРрд╕реЗ рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЕрдореВрд░реНрдд рдЬреЛ рдкрд╛рда рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рддрддреНрд╡ рд▓рд┐рдЦрддрд╛ рд╣реИред CTRun рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ рд╕рдорд╛рди рд╢реИрд▓рд┐рдпреЛрдВ рд╡рд╛рд▓реЗ рд╡рд░реНрдгреЛрдВ рдХреЛ рд╕рдореВрд╣реЛрдВ рдореЗрдВ рдЖрдХрд░реНрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдмрд▓реНрдХрд┐, рдЙрдиреНрд╣реЗрдВ iOS6.0 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рд╣рд░ рдЪреАрдЬ рдореЗрдВ рдЫреЛрдЯрд╛ - рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рд┐рддреНрд░ рдПрдХ рдЕрд▓рдЧ CTRun рд╣реЛрдЧрд╛ ред рдмрд╣реБрдд рд╢реБрд░реБрдЖрдд рд╕реЗ, рдПрдХ рдЖрд╕рд╛рди рдФрд░ рд╕реНрдкрд╖реНрдЯ рдмрд┐рдВрджреБ рдХреЛ рд╕реНрдкрд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП: рдкреНрд░рддреАрдХ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЧреНрд▓рд┐рдлрд╝ рд╣реИрдВ ред рдЗрд╕ рддрдереНрдп рд╕реЗ рджреЛ рдЕрдиреНрдп рдмрд┐рдВрджреБрдУрдВ рдХрд╛ рдкрд╛рд▓рди рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдЖрд╕рд╛рди рднреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрд╡рдЬреНрдЮрд╛рдХрд╛рд░реА рд╣реИрдВ: рдПрдХ рдЪрд░рд┐рддреНрд░ рдореЗрдВ рдПрдХ рдЧреНрд▓рд┐рдлрд╝ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╛ рд╢рд╛рдпрдж рдХрдИ; рдПрдХ рдЧреНрд▓рд┐рдлрд╝ рдПрдХ рдмрд╛рд░ рдореЗрдВ рдХрдИ рд╡рд░реНрдгреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдзрд┐рдХрд╛рдВрд╢ рдЗрдореЛрдЯрд┐рдХреЙрдиреНрд╕ рдПрдХ рдПрдХрд▓ рдЧреНрд▓рд┐рдлрд╝ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдХрдИ рдпреВрдЯреАрдПрдл рд╡рд░реНрдг рд╢рд╛рдорд┐рд▓ рд╣реИрдВред
рдЙрди рд╕рднреА рдХреЗ рд▓рд┐рдП рдЬреЛ 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"
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдЧреНрд▓рд┐рдлрд╝ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреЛ рд╡рд░реНрдг рд╣реЛрддреЗ рд╣реИрдВред CTRunGetStringIndices рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реЛрдЧрд╛: [0,2,4]ред

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЗрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ рджреЛ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ: рд╡рд╛рдВрдЫрд┐рдд рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдХреЛ рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рдЖрд╡рдВрдЯрд┐рдд рдмрдлрд░ рдореЗрдВ рдХреЙрдкреА рдХрд░реЗрдВ рдпрд╛ CTRun рдХреЗ рдЕрдВрджрд░ рд╕рд░рдгреА рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рдЪреБрдиреЗрдВ рдХрд┐ рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХреНрдпрд╛ рд╣реИред рдРрд╕реЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ, рдпрд╣ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдореИрдВ рдЗрд╕ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред

 CFDictionaryRef CTRunGetAttributes(CTRunRef run) 

CTRun рдХреА рд╡рд░реНрддрдорд╛рди рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдЬреЛ CFAttributedString рдореЗрдВ рд╕реЗрдЯ рдХреА рдЧрдИ рдереАрдВ ред

 CTRunStatus CTRunGetStatus(CTRunRef run) 

рдПрдХ рдмрд┐рдЯрдорд╛рд╕реНрдХ рд░рд┐рдЯрд░реНрди рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреИрд░рд╛рдореАрдЯрд░ред KCTRunStatusRightToLeft рдкрд░ рд╡рд┐рд╢реЗрд╖ рдзреНрдпрд╛рди рджреЗрдВ - рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ CTRun рдореЗрдВ рдЧреНрд▓рд┐рдлрд╝ рдХреА рд╡рд░реНрддрдиреА рджрд╛рдИрдВ рд╕реЗ рдмрд╛рдИрдВ рдУрд░ рд╣реИред

 const CGPoint* CTRunGetPositionsPtr(CTRunRef run) void CTRunGetPositions(CTRunRef run, CFRange range, CGPoint buffer[]) 

CTFrame рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ CTRun рдХреЗ рднреАрддрд░ рдЧреНрд▓рд┐рдлрд╝ рдХреА рд╕реНрдерд┐рддрд┐ред рдореИрдВ рдЗрд╕ рддрдереНрдп рдкрд░ рд╡рд┐рд╢реЗрд╖ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдпрджрд┐ рдЖрдк рд╡рд┐рдзрд┐ рдХреЗ рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рджреВрд╕рд░рд╛ рдЧреНрд▓рд┐рдлрд╝ рдХреЗ рдкрджреЛрдВ рдХреЛ рд▓реЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд░реЗрдВрдЬ рдореЗрдВ рдЖрдкрдХреЛ 1 рдирд╣реАрдВ (1 рд╕реЗ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╕рдВрдЦреНрдпрд╛) рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд▓рд╛рдЗрди рдореЗрдВ рдЗрд╕ рдЧреНрд▓рд┐рдлрд╝ рдХреА рд╕реНрдерд┐рддрд┐ред рдЙрдкрд░реЛрдХреНрдд рдЗрдореЛрдЯрд┐рдХреЙрдиреНрд╕ рд╡рд╛рд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╕реНрдерд┐рддрд┐ 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; 

рд╣рдо рдкрд┐рдЫрд▓реЗ рддреАрди рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред рддрд░реАрдХреЗ рд╕реНрд╡рддрдВрддреНрд░ рдХрд╛рд░реНрдп рд╣реИрдВ рдЬреЛ рд╡рдВрд╢ , рдЪрдврд╝рд╛рдИ, рдФрд░ рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдЯреИрдЧ рдХрд┐рдП рдЧрдП рдЧреНрд▓рд┐рдлрд╝ рдХреА рдЪреМрдбрд╝рд╛рдИ рдХреЛ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ ред рд╣рд░ рдмрд╛рд░ рддрд░реАрдХреЛрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдм рд╡рд░реНрддрдорд╛рди рдЧреНрд▓рд┐рдлрд╝ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдЬреНрдпрд╛рдорд┐рддреАрдп рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЧрдгрдирд╛ рдореЗрдВ рднрд╛рдЧ рд▓реЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдкрдХреЗ рдЕрдкрдиреЗ рдЧреНрд▓рд┐рдлрд╝ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

 void CTRunDraw(CTRunRef run, CGContextRef context, CFRange range) 

рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рд╕рдВрджрд░реНрдн рдореЗрдВ CTRun рдбреНрд░рд╛ рдХрд░реЗрдВред

CoreGraphics


рдкрд╛рдБрдЪрд╡рд╛рдБ рд╕реНрддрд░ред рдЧреНрд▓рд┐рдлрд╝

рд╕рдЪ рдХрд╣реВрдБ рддреЛ, рдпрд╣ рд╕реНрддрд░ рдЕрдм 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); 

рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрдВрдбрд░рд▓рд╛рдЗрди рд╢реИрд▓рд┐рдпреЛрдВ рдЬреИрд╕реА рдЪреАрдЬреЗрдВ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реЛрдВрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдХреЛрд░рдЯреИрдХреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ ред рд▓реЗрдХрд┐рди рдЬрдм рдкреНрд░рддрд┐рдкрд╛рджрди, рдЖрдк рдХреА рддрд░рд╣ рд╣рдо рдЧреНрд▓рд┐рдлрд╝ рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рд╣реИрдВред

Apple, рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдПрдкреАрдЖрдИ рдбрд┐рдЬрд╛рдЗрди рдХрд░рдиреЗ рдореЗрдВ рдЕрдкрдиреА рдкрд░рдВрдкрд░рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╣реИ: рд╕рд╛рдзрд╛рд░рдг рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП, рдЖрдк рдмрд╣реБрдд рджреВрд░ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдмрд╕ "рдореБрдЭреЗ рдЕрдЪреНрдЫрд╛ рдХрд░реЛ" рд╡рд┐рдзрд┐ рдХрд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдк рд░рд╕реНрд╕рд┐рдпреЛрдВ рдХреЛ рдореЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкрд╣рд┐рдпреЛрдВ рдХреЛ рдЦреАрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/In172661/


All Articles