Fix re-rendering of emoji when path data is cached, closes #927

This commit is contained in:
Mikael Sand
2019-02-08 03:19:21 +02:00
parent fa07f6ef8a
commit abb17bc7f0
2 changed files with 53 additions and 6 deletions
@@ -28,6 +28,8 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.text.ReactFontManager;
import java.util.ArrayList;
import javax.annotation.Nullable;
import static android.graphics.Matrix.MTRANS_X;
@@ -47,6 +49,8 @@ class TSpanView extends TextView {
@Nullable String mContent;
private TextPathView textPath;
ArrayList<String> emoji = new ArrayList<>();
ArrayList<Matrix> emojiTransforms = new ArrayList<>();
public TSpanView(ReactContext reactContext) {
super(reactContext);
@@ -61,6 +65,20 @@ class TSpanView extends TextView {
@Override
void draw(Canvas canvas, Paint paint, float opacity) {
if (mContent != null) {
int numEmoji = emoji.size();
if (numEmoji > 0) {
GlyphContext gc = getTextRootGlyphContext();
FontData font = gc.getFont();
applyTextPropertiesToPaint(paint, font);
for (int i = 0; i < numEmoji; i++) {
String current = emoji.get(i);
Matrix mid = emojiTransforms.get(i);
canvas.save();
canvas.concat(mid);
canvas.drawText(current, 0, 0, paint);
canvas.restore();
}
}
drawPath(canvas, paint, opacity);
} else {
clip(canvas, paint);
@@ -676,6 +694,9 @@ class TSpanView extends TextView {
final float[] midPointMatrixData = new float[9];
final float[] endPointMatrixData = new float[9];
emoji.clear();
emojiTransforms.clear();
for (int index = 0; index < length; index++) {
char currentChar = chars[index];
String current = String.valueOf(currentChar);
@@ -855,12 +876,12 @@ class TSpanView extends TextView {
glyph.computeBounds(bounds, true);
float width = bounds.width();
if (width == 0) { // Render unicode emoji
mid.getValues(midPointMatrixData);
double midX = midPointMatrixData[MTRANS_X];
double midY = midPointMatrixData[MTRANS_Y];
canvas.rotate((float) r, (float)midX, (float)midY);
canvas.drawText(current, (float)midX, (float)midY, paint);
canvas.rotate((float) -r, (float)midX, (float)midY);
canvas.save();
canvas.concat(mid);
emoji.add(current);
emojiTransforms.add(new Matrix(mid));
canvas.drawText(current, 0, 0, paint);
canvas.restore();
} else {
glyph.transform(mid);
path.addPath(glyph);
+26
View File
@@ -23,6 +23,8 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
NSArray *lines;
NSUInteger lineCount;
BOOL isClosed;
NSMutableArray *emoji;
NSMutableArray *emojiTransform;
}
- (id)init
@@ -33,6 +35,9 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
RNSVGTSpan_separators = [NSCharacterSet whitespaceCharacterSet];
}
emoji = [NSMutableArray arrayWithCapacity:0];
emojiTransform = [NSMutableArray arrayWithCapacity:0];
return self;
}
@@ -48,6 +53,21 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect
{
if (self.content) {
if (self.path) {
NSUInteger count = [emoji count];
RNSVGGlyphContext* gc = [self.textRoot getGlyphContext];
CGFloat fontSize = [gc getFontSize];
for (NSUInteger i = 0; i < count; i++) {
UILabel *label = [emoji objectAtIndex:i];
NSValue *transformValue = [emojiTransform objectAtIndex:i];
CGAffineTransform transform = [transformValue CGAffineTransformValue];
CGContextConcatCTM(context, transform);
CGContextTranslateCTM(context, 0, -fontSize);
[label.layer renderInContext:context];
CGContextTranslateCTM(context, 0, fontSize);
CGContextConcatCTM(context, CGAffineTransformInvert(transform));
}
}
[self renderPathTo:context rect:rect];
} else {
[self clip:context];
@@ -658,6 +678,9 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
}
}
[emoji removeAllObjects];
[emojiTransform removeAllObjects];
CFArrayRef runs = CTLineGetGlyphRuns(line);
CFIndex runEnd = CFArrayGetCount(runs);
for (CFIndex r = 0; r < runEnd; r++) {
@@ -829,6 +852,9 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
[label.layer renderInContext:context];
CGContextTranslateCTM(context, 0, fontSize);
CGContextConcatCTM(context, CGAffineTransformInvert(transform));
[emoji addObject:label];
[emojiTransform addObject:[NSValue valueWithCGAffineTransform:transform]];
} else {
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGPathAddPath(path, &transform, glyphPath);