Skip to content

Commit b7a5281

Browse files
fix: drawing unicode emojis on iOS
1 parent fe295f6 commit b7a5281

File tree

1 file changed

+28
-30
lines changed

1 file changed

+28
-30
lines changed

apple/Text/RNSVGTSpan.mm

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,11 @@ - (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect
157157
NSUInteger count = [emoji count];
158158
CGFloat fontSize = [gc getFontSize];
159159
for (NSUInteger i = 0; i < count; i++) {
160-
RNSVGPlatformView *emojiLabel = [emoji objectAtIndex:i];
160+
NSAttributedString *attrStr = [emoji objectAtIndex:i];
161161
NSValue *transformValue = [emojiTransform objectAtIndex:i];
162162
CGAffineTransform transform = [transformValue CGAffineTransformValue];
163-
CGContextConcatCTM(context, transform);
164-
CGContextTranslateCTM(context, 0, -fontSize);
165-
[emojiLabel.layer renderInContext:context];
166-
CGContextTranslateCTM(context, 0, fontSize);
167-
CGContextConcatCTM(context, CGAffineTransformInvert(transform));
163+
164+
[self drawEmoji:attrStr transform:transform context:context fontSize:fontSize];
168165
}
169166
}
170167
[self renderPathTo:context rect:rect];
@@ -1042,34 +1039,16 @@ A negative value is an error (see Error processing).
10421039
CGFloat width = box.size.width;
10431040

10441041
if (width == 0) { // Render unicode emoji
1045-
RNSVGTextView *emojiLabel = [[RNSVGTextView alloc] init];
10461042
CFIndex startIndex = indices[g];
10471043
long len = MAX(1, endIndex - startIndex);
10481044
NSRange range = NSMakeRange(startIndex, len);
10491045
NSString *currChars = [str substringWithRange:range];
1050-
#if TARGET_OS_OSX
1051-
emojiLabel.string = currChars;
1052-
#else
1053-
emojiLabel.text = currChars;
1054-
emojiLabel.opaque = NO;
1055-
#endif // TARGET_OS_OSX
1056-
emojiLabel.backgroundColor = RNSVGColor.clearColor;
1057-
UIFont *customFont = [UIFont systemFontOfSize:fontSize];
1058-
1059-
CGSize measuredSize = [currChars sizeWithAttributes:@{NSFontAttributeName : customFont}];
1060-
emojiLabel.font = customFont;
1061-
CGFloat width = ceil(measuredSize.width);
1062-
CGFloat height = ceil(measuredSize.height);
1063-
CGRect bounds = CGRectMake(0, 0, width, height);
1064-
emojiLabel.frame = bounds;
1065-
1066-
CGContextConcatCTM(context, transform);
1067-
CGContextTranslateCTM(context, 0, -fontSize);
1068-
[emojiLabel.layer renderInContext:context];
1069-
CGContextTranslateCTM(context, 0, fontSize);
1070-
CGContextConcatCTM(context, CGAffineTransformInvert(transform));
1071-
1072-
[emoji addObject:emojiLabel];
1046+
1047+
UIFont *font = [UIFont systemFontOfSize:fontSize];
1048+
NSDictionary *attrs = @{ NSFontAttributeName: font };
1049+
NSAttributedString *emojiStr = [[NSAttributedString alloc] initWithString:currChars attributes:attrs];
1050+
[self drawEmoji:emojiStr transform:transform context:context fontSize:fontSize];
1051+
[emoji addObject:emojiStr];
10731052
[emojiTransform addObject:[NSValue valueWithCGAffineTransform:transform]];
10741053
} else {
10751054
transform = CGAffineTransformScale(transform, 1.0, -1.0);
@@ -1085,6 +1064,25 @@ A negative value is an error (see Error processing).
10851064
return (CGPathRef)CFAutorelease(path);
10861065
}
10871066

1067+
- (void)drawEmoji:(NSAttributedString *)emojiStr transform:(CGAffineTransform)transform context:(CGContextRef)context fontSize:(CGFloat)fontSize
1068+
{
1069+
CTLineRef emojiLine = CTLineCreateWithAttributedString((CFAttributedStringRef)emojiStr);
1070+
1071+
CGContextSaveGState(context);
1072+
1073+
// Flip CGContext vertically to match UIKit coordinates
1074+
CGRect bounds = CGContextGetClipBoundingBox(context);
1075+
CGContextTranslateCTM(context, 0, bounds.size.height);
1076+
CGContextScaleCTM(context, 1.0, -1.0);
1077+
1078+
CGContextConcatCTM(context, transform);
1079+
CGContextTranslateCTM(context, 0, -fontSize);
1080+
1081+
CTLineDraw(emojiLine, context);
1082+
CGContextRestoreGState(context);
1083+
CFRelease(emojiLine);
1084+
}
1085+
10881086
+ (CGFloat)getTextAnchorOffset:(RNSVGTextAnchor)textAnchor width:(CGFloat)width
10891087
{
10901088
switch (textAnchor) {

0 commit comments

Comments
 (0)