//
|
// UIBezierPath+YYAdd.m
|
// YYCategories <https://github.com/ibireme/YYCategories>
|
//
|
// Created by ibireme on 14/10/30.
|
// Copyright (c) 2015 ibireme.
|
//
|
// This source code is licensed under the MIT-style license found in the
|
// LICENSE file in the root directory of this source tree.
|
//
|
|
#import "UIBezierPath+YYAdd.h"
|
#import "UIFont+YYAdd.h"
|
#import <CoreText/CoreText.h>
|
#import "YYCategoriesMacro.h"
|
|
YYSYNTH_DUMMY_CLASS(UIBezierPath_YYAdd)
|
|
|
@implementation UIBezierPath (YYAdd)
|
|
+ (UIBezierPath *)bezierPathWithText:(NSString *)text font:(UIFont *)font {
|
CTFontRef ctFont = font.CTFontRef;
|
if (!ctFont) return nil;
|
NSDictionary *attrs = @{ (__bridge id)kCTFontAttributeName:(__bridge id)ctFont };
|
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:text attributes:attrs];
|
CFRelease(ctFont);
|
|
CTLineRef line = CTLineCreateWithAttributedString((__bridge CFTypeRef)attrString);
|
if (!line) return nil;
|
|
CGMutablePathRef cgPath = CGPathCreateMutable();
|
CFArrayRef runs = CTLineGetGlyphRuns(line);
|
for (CFIndex iRun = 0, iRunMax = CFArrayGetCount(runs); iRun < iRunMax; iRun++) {
|
CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, iRun);
|
CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName);
|
|
for (CFIndex iGlyph = 0, iGlyphMax = CTRunGetGlyphCount(run); iGlyph < iGlyphMax; iGlyph++) {
|
CFRange glyphRange = CFRangeMake(iGlyph, 1);
|
CGGlyph glyph;
|
CGPoint position;
|
CTRunGetGlyphs(run, glyphRange, &glyph);
|
CTRunGetPositions(run, glyphRange, &position);
|
|
CGPathRef glyphPath = CTFontCreatePathForGlyph(runFont, glyph, NULL);
|
if (glyphPath) {
|
CGAffineTransform transform = CGAffineTransformMakeTranslation(position.x, position.y);
|
CGPathAddPath(cgPath, &transform, glyphPath);
|
CGPathRelease(glyphPath);
|
}
|
}
|
}
|
UIBezierPath *path = [UIBezierPath bezierPathWithCGPath:cgPath];
|
CGRect boundingBox = CGPathGetPathBoundingBox(cgPath);
|
CFRelease(cgPath);
|
CFRelease(line);
|
|
[path applyTransform:CGAffineTransformMakeScale(1.0, -1.0)];
|
[path applyTransform:CGAffineTransformMakeTranslation(0.0, boundingBox.size.height)];
|
|
return path;
|
}
|
|
@end
|