Implement correct letterSpacing

This commit is contained in:
Mikael Sand
2017-07-23 06:38:18 +03:00
parent a1aad32e0d
commit f2352be2f5
2 changed files with 38 additions and 24 deletions
@@ -187,6 +187,22 @@ class GlyphContext {
}
}
private static void putD(String key, WritableMap map, ReadableMap font, ReadableMap parent, double fontSize) {
if (font.hasKey(key)) {
String string = font.getString(key);
double value = PropHelper.fromRelative(
string,
0,
0,
1,
fontSize
);
map.putDouble(key, value);
} else if (parent.hasKey(key)) {
map.putDouble(key, parent.getDouble(key));
}
}
private void pushNodeAndFont(GroupShadowNode node, @Nullable ReadableMap font) {
ReadableMap parent = getTopOrParentFont(node);
mTop++;
@@ -200,16 +216,6 @@ class GlyphContext {
mFontContext.add(map);
topFont = map;
put(LETTER_SPACING, map, font, parent);
put(FONT_FAMILY, map, font, parent);
put(FONT_WEIGHT, map, font, parent);
put(FONT_STYLE, map, font, parent);
put(KERNING, map, font, parent);
double parentFontSize = parent.getDouble(FONT_SIZE);
if (font.hasKey(FONT_SIZE)) {
@@ -228,6 +234,20 @@ class GlyphContext {
}
map.putDouble(FONT_SIZE, mFontSize);
put(FONT_FAMILY, map, font, parent);
put(FONT_WEIGHT, map, font, parent);
put(FONT_STYLE, map, font, parent);
// TODO https://www.w3.org/TR/SVG11/text.html#SpacingProperties
// https://drafts.csswg.org/css-text-3/#spacing
// calculated values for units in: kerning, letter-spacing and word-spacing
putD(LETTER_SPACING, map, font, parent, mFontSize);
putD(KERNING, map, font, parent, mFontSize);
}
void pushContext(GroupShadowNode node, @Nullable ReadableMap font) {
@@ -158,12 +158,13 @@ class TSpanShadowNode extends TextShadowNode {
double previousWidth = 0;
char[] chars = line.toCharArray();
boolean autoKerning = true;
double kerning = DEFAULT_KERNING;
if (font.hasKey(PROP_KERNING)) {
kerning = Double.valueOf(font.getString(PROP_KERNING)) * mScale;
autoKerning = false;
}
boolean hasKerning = font.hasKey(PROP_KERNING);
double kerning = hasKerning ? font.getDouble(PROP_KERNING) * mScale : DEFAULT_KERNING;
boolean autoKerning = !hasKerning;
double letterSpacing = font.hasKey(PROP_LETTER_SPACING) ?
font.getDouble(PROP_LETTER_SPACING) * mScale
: DEFAULT_LETTER_SPACING;
for (int index = 0; index < length; index++) {
glyph = new Path();
@@ -178,7 +179,7 @@ class TSpanShadowNode extends TextShadowNode {
previous = current;
}
x = gc.nextX(width + kerning);
x = gc.nextX(width + kerning + letterSpacing);
y = gc.nextY();
dx = gc.nextDeltaX();
dy = gc.nextDeltaY();
@@ -221,10 +222,6 @@ class TSpanShadowNode extends TextShadowNode {
double fontSize = font.getDouble(PROP_FONT_SIZE) * mScale;
double letterSpacing = font.hasKey(PROP_LETTER_SPACING) ?
Double.valueOf(font.getString(PROP_LETTER_SPACING)) * mScale
: DEFAULT_LETTER_SPACING;
boolean isBold = font.hasKey(PROP_FONT_WEIGHT) &&
BOLD.equals(font.getString(PROP_FONT_WEIGHT));
@@ -270,9 +267,6 @@ class TSpanShadowNode extends TextShadowNode {
paint.setTextAlign(Paint.Align.LEFT);
paint.setUnderlineText(underlineText);
paint.setStrikeThruText(strikeThruText);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
paint.setLetterSpacing((float) (letterSpacing / fontSize));
}
}
private void setupTextPath() {