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 {
// 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)
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, ";
paint.setFontFeatureSettings(defaultFeatures + disableDiscretionaryLigatures + font.fontFeatureSettings);
}
paint.setLetterSpacing((float)(letterSpacing / (font.fontSize * mScale)));
}
return paint.measureText(line);
@@ -610,7 +611,7 @@ class TSpanView extends TextView {
// this will just retrieve the bounding rect for 'x'
paint.getTextBounds("x", 0, 1, bounds);
int xHeight = bounds.height();
baselineShift = xHeight / 2;
baselineShift = xHeight / 2.0;
break;
case central:
@@ -738,7 +739,6 @@ class TSpanView extends TextView {
final Matrix end = new Matrix();
final float[] startPointMatrixData = new float[9];
final float[] midPointMatrixData = new float[9];
final float[] endPointMatrixData = new float[9];
emoji.clear();
@@ -1008,6 +1008,9 @@ class TSpanView extends TextView {
paint.setTypeface(typeface);
paint.setTextSize((float) fontSize);
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.
// paint.setUnderlineText(underlineText);
@@ -213,23 +213,17 @@ class TextView extends GroupView {
TextView getTextAnchorRoot() {
GlyphContext gc = getTextRootGlyphContext();
FontData font = gc.getFont();
TextProperties.TextAnchor textAnchor = font.textAnchor;
if (textAnchor == TextProperties.TextAnchor.start) {
return this;
}
ArrayList<FontData> font = gc.mFontContext;
TextView node = this;
ViewParent parent = this.getParent();
if (parent instanceof TextView) {
TextView parentText = (TextView)parent;
GlyphContext parentGc = parentText.getGlyphContext();
FontData parentFont = parentGc.getFont();
if (parentFont.textAnchor == TextProperties.TextAnchor.start) {
return this;
} else {
return parentText.getTextAnchorRoot();
for (int i = font.size() - 1; i >= 0; i--) {
if (!(parent instanceof TextView) || font.get(i).textAnchor == TextProperties.TextAnchor.start) {
return node;
}
node = (TextView) parent;
parent = node.getParent();
}
return this;
return node;
}
double getSubtreeTextChunksTotalAdvance(Paint paint) {
@@ -240,7 +234,7 @@ class TextView extends GroupView {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof TextView) {
TextView text = (TextView)child;
TextView text = (TextView) child;
advance += text.getSubtreeTextChunksTotalAdvance(paint);
}
}
+10 -11
View File
@@ -121,7 +121,7 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
RNSVGFontData* font = [gc getFont];
CGFloat letterSpacing = font->letterSpacing;
bool autoKerning = !font->manualKerning;
CGFloat kerning = font->kerning;
bool allowOptionalLigatures = letterSpacing == 0 && font->fontVariantLigatures == RNSVGFontVariantLigaturesNormal;
@@ -133,19 +133,18 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
if (fontRef != nil) {
attrs[NSFontAttributeName] = (__bridge id)fontRef;
}
if (!autoKerning) {
NSNumber *noAutoKern = [NSNumber numberWithFloat:0.0f];
float kern = (float)(letterSpacing + kerning);
NSNumber *kernAttr = [NSNumber numberWithFloat:kern];
#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES
if (___useiOS6Attributes)
{
[attrs setObject:noAutoKern forKey:NSKernAttributeName];
}
else
if (___useiOS6Attributes)
{
[attrs setObject:kernAttr forKey:NSKernAttributeName];
}
else
#endif
{
[attrs setObject:noAutoKern forKey:(id)kCTKernAttributeName];
}
{
[attrs setObject:kernAttr forKey:(id)kCTKernAttributeName];
}
attributes = (__bridge CFDictionaryRef)attrs;