1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| - (NSMutableAttributedString *)getAtt{ NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:@"Core Text, Core Text, Core Text, Core Text, Core Text, Core Text, "]; CTFontRef font = CTFontCreateWithName(CFSTR("PingFang SC"), 24, NULL); [att addAttribute:(id)kCTFontAttributeName value:(__bridge id)font range:NSMakeRange(0, att.length)]; long number = 10; CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number); [att addAttribute:(id)kCTKernAttributeName value:(__bridge id)num range:NSMakeRange(10, 4)]; return att; }
- (NSMutableAttributedString *)getAttachment:(CGSize)size imageName:(NSString *)imageName{ CTRunDelegateCallbacks callBacks; callBacks.version = kCTRunDelegateVersion1; callBacks.dealloc = DelegateDeallocCallback; callBacks.getAscent = DelegateAscentCallBacks; callBacks.getDescent = DelegateDescentCallBacks; callBacks.getWidth = DelegateWidthCallBacks;
NSString *sizeStr = NSStringFromCGSize(size);
CTRunDelegateRef delegate = CTRunDelegateCreate(&callBacks, (__bridge void *)sizeStr);
unichar placeHolder = 0xFFFC; NSString * placeHolderStr = [NSString stringWithCharacters:&placeHolder length:1]; NSMutableAttributedString * imageAttachment = [[NSMutableAttributedString alloc] initWithString:placeHolderStr]; [imageAttachment addAttribute:@"imageName" value:imageName range:(NSMakeRange(0, 1))]; CFAttributedStringSetAttribute((CFMutableAttributedStringRef)imageAttachment, CFRangeMake(0, 1), kCTRunDelegateAttributeName, delegate); CFRelease(delegate);
return imageAttachment; }
void DelegateDeallocCallback (void *refCon){ NSLog(@"dealloc"); }
CGFloat DelegateAscentCallBacks(void * refCon){ CGSize size = CGSizeFromString((__bridge NSString *)refCon); return size.height; }
CGFloat DelegateDescentCallBacks(void * refCon){ return 0; }
CGFloat DelegateWidthCallBacks(void * refCon){ CGSize size = CGSizeFromString((__bridge NSString *)refCon); return size.width; }
- (BOOL)isImageAttachment:(CTRunRef)run{ NSDictionary * attributes = (NSDictionary *)CTRunGetAttributes(run); CTRunDelegateRef delegate = (__bridge CTRunDelegateRef)[attributes valueForKey:(id)kCTRunDelegateAttributeName]; NSString *sizeStr = CTRunDelegateGetRefCon(delegate); if (delegate == nil || ![sizeStr isKindOfClass:[NSString class]]) { return NO; } return YES; }
- (void)drawImage:(CTFrameRef)frame line:(CTLineRef)line run:(CTRunRef)run point:(CGPoint)point{
NSDictionary * attributes = (NSDictionary *)CTRunGetAttributes(run); NSString *imageName = attributes[@"imageName"]; if (!imageName) { return; } CGFloat ascent; CGFloat descent; CGRect boundsRun; boundsRun.size.width = CTRunGetTypographicBounds(run, CFRangeMake(0, 0), &ascent, &descent, NULL); boundsRun.size.height = ascent + descent; CGFloat xOffset = CTLineGetOffsetForStringIndex(line, CTRunGetStringRange(run).location, NULL); boundsRun.origin.x = point.x + xOffset; boundsRun.origin.y = point.y - descent; CGPathRef path = CTFrameGetPath(frame); CGRect colRect = CGPathGetBoundingBox(path); CGRect imageBounds = CGRectOffset(boundsRun, colRect.origin.x, colRect.origin.y);
[self drawWithImageName:imageName rect:imageBounds]; }
- (void)drawWithImageName:(NSString *)imageName rect:(CGRect)rect{ CGContextRef context = UIGraphicsGetCurrentContext(); UIImage * image = [UIImage imageNamed:imageName]; CGContextDrawImage(context, rect, image.CGImage); }
|