mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-06 00:12:21 +00:00
Fix re-rendering of emoji when path data is cached, closes #927
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user