Fix text-anchor subtree advance/extent calculation for letter-spacing

Related to
https://github.com/react-native-community/react-native-svg/issues/570
This commit is contained in:
Mikael Sand
2019-02-10 01:47:46 +02:00
parent 60a7b1fd53
commit d5fa136a0f
4 changed files with 25 additions and 29 deletions
@@ -19,7 +19,7 @@ import javax.annotation.Nullable;
class GlyphContext { class GlyphContext {
// Current stack (one per node push/pop) // Current stack (one per node push/pop)
private final ArrayList<FontData> mFontContext = new ArrayList<>(); final ArrayList<FontData> mFontContext = new ArrayList<>();
// Unique input attribute lists (only added if node sets a value) // Unique input attribute lists (only added if node sets a value)
private final ArrayList<SVGLength[]> mXsContext = new ArrayList<>(); private final ArrayList<SVGLength[]> mXsContext = new ArrayList<>();
@@ -146,6 +146,7 @@ class TSpanView extends TextView {
String disableDiscretionaryLigatures = "'liga' 0, 'clig' 0, 'dlig' 0, 'hlig' 0, 'cala' 0, "; String disableDiscretionaryLigatures = "'liga' 0, 'clig' 0, 'dlig' 0, 'hlig' 0, 'cala' 0, ";
paint.setFontFeatureSettings(defaultFeatures + disableDiscretionaryLigatures + font.fontFeatureSettings); paint.setFontFeatureSettings(defaultFeatures + disableDiscretionaryLigatures + font.fontFeatureSettings);
} }
paint.setLetterSpacing((float)(letterSpacing / (font.fontSize * mScale)));
} }
return paint.measureText(line); return paint.measureText(line);
@@ -610,7 +611,7 @@ class TSpanView extends TextView {
// this will just retrieve the bounding rect for 'x' // this will just retrieve the bounding rect for 'x'
paint.getTextBounds("x", 0, 1, bounds); paint.getTextBounds("x", 0, 1, bounds);
int xHeight = bounds.height(); int xHeight = bounds.height();
baselineShift = xHeight / 2; baselineShift = xHeight / 2.0;
break; break;
case central: case central:
@@ -738,7 +739,6 @@ class TSpanView extends TextView {
final Matrix end = new Matrix(); final Matrix end = new Matrix();
final float[] startPointMatrixData = new float[9]; final float[] startPointMatrixData = new float[9];
final float[] midPointMatrixData = new float[9];
final float[] endPointMatrixData = new float[9]; final float[] endPointMatrixData = new float[9];
emoji.clear(); emoji.clear();
@@ -1008,6 +1008,9 @@ class TSpanView extends TextView {
paint.setTypeface(typeface); paint.setTypeface(typeface);
paint.setTextSize((float) fontSize); paint.setTextSize((float) fontSize);
paint.setTextAlign(Paint.Align.LEFT); paint.setTextAlign(Paint.Align.LEFT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
paint.setLetterSpacing(0);
}
// Do these have any effect for anyone? Not for me (@msand) at least. // Do these have any effect for anyone? Not for me (@msand) at least.
// paint.setUnderlineText(underlineText); // paint.setUnderlineText(underlineText);
@@ -213,23 +213,17 @@ class TextView extends GroupView {
TextView getTextAnchorRoot() { TextView getTextAnchorRoot() {
GlyphContext gc = getTextRootGlyphContext(); GlyphContext gc = getTextRootGlyphContext();
FontData font = gc.getFont(); ArrayList<FontData> font = gc.mFontContext;
TextProperties.TextAnchor textAnchor = font.textAnchor; TextView node = this;
if (textAnchor == TextProperties.TextAnchor.start) {
return this;
}
ViewParent parent = this.getParent(); ViewParent parent = this.getParent();
if (parent instanceof TextView) { for (int i = font.size() - 1; i >= 0; i--) {
TextView parentText = (TextView)parent; if (!(parent instanceof TextView) || font.get(i).textAnchor == TextProperties.TextAnchor.start) {
GlyphContext parentGc = parentText.getGlyphContext(); return node;
FontData parentFont = parentGc.getFont();
if (parentFont.textAnchor == TextProperties.TextAnchor.start) {
return this;
} else {
return parentText.getTextAnchorRoot();
} }
node = (TextView) parent;
parent = node.getParent();
} }
return this; return node;
} }
double getSubtreeTextChunksTotalAdvance(Paint paint) { double getSubtreeTextChunksTotalAdvance(Paint paint) {
@@ -240,7 +234,7 @@ class TextView extends GroupView {
for (int i = 0; i < getChildCount(); i++) { for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i); View child = getChildAt(i);
if (child instanceof TextView) { if (child instanceof TextView) {
TextView text = (TextView)child; TextView text = (TextView) child;
advance += text.getSubtreeTextChunksTotalAdvance(paint); advance += text.getSubtreeTextChunksTotalAdvance(paint);
} }
} }
+10 -11
View File
@@ -121,7 +121,7 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
RNSVGFontData* font = [gc getFont]; RNSVGFontData* font = [gc getFont];
CGFloat letterSpacing = font->letterSpacing; CGFloat letterSpacing = font->letterSpacing;
bool autoKerning = !font->manualKerning; CGFloat kerning = font->kerning;
bool allowOptionalLigatures = letterSpacing == 0 && font->fontVariantLigatures == RNSVGFontVariantLigaturesNormal; bool allowOptionalLigatures = letterSpacing == 0 && font->fontVariantLigatures == RNSVGFontVariantLigaturesNormal;
@@ -133,19 +133,18 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
if (fontRef != nil) { if (fontRef != nil) {
attrs[NSFontAttributeName] = (__bridge id)fontRef; attrs[NSFontAttributeName] = (__bridge id)fontRef;
} }
if (!autoKerning) { float kern = (float)(letterSpacing + kerning);
NSNumber *noAutoKern = [NSNumber numberWithFloat:0.0f]; NSNumber *kernAttr = [NSNumber numberWithFloat:kern];
#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES #if DTCORETEXT_SUPPORT_NS_ATTRIBUTES
if (___useiOS6Attributes) if (___useiOS6Attributes)
{ {
[attrs setObject:noAutoKern forKey:NSKernAttributeName]; [attrs setObject:kernAttr forKey:NSKernAttributeName];
} }
else else
#endif #endif
{ {
[attrs setObject:noAutoKern forKey:(id)kCTKernAttributeName]; [attrs setObject:kernAttr forKey:(id)kCTKernAttributeName];
}
} }
attributes = (__bridge CFDictionaryRef)attrs; attributes = (__bridge CFDictionaryRef)attrs;