diff --git a/android/src/main/java/com/horcrux/svg/GlyphContext.java b/android/src/main/java/com/horcrux/svg/GlyphContext.java index 3c2d37fe..361a6d5a 100644 --- a/android/src/main/java/com/horcrux/svg/GlyphContext.java +++ b/android/src/main/java/com/horcrux/svg/GlyphContext.java @@ -20,8 +20,14 @@ import javax.annotation.Nullable; class GlyphContext { static final float DEFAULT_FONT_SIZE = 12f; - private static final float DEFAULT_KERNING = 0f; - private static final float DEFAULT_LETTER_SPACING = 0f; + + private static final String KERNING = "kerning"; + private static final String FONT_SIZE = "fontSize"; + private static final String FONT_STYLE = "fontStyle"; + private static final String FONT_WEIGHT = "fontWeight"; + private static final String FONT_FAMILY = "fontFamily"; + private static final String LETTER_SPACING = "letterSpacing"; + private static final String IS_KERNING_VALUE_SET = "isKerningValueSet"; // Unique input attribute lists (only added if node sets a value) private final ArrayList mXsContext = new ArrayList<>(); @@ -51,10 +57,12 @@ class GlyphContext { // Cached per push context private double fontSize = DEFAULT_FONT_SIZE; + // Current values + private float mr; + // Current accumulated values private float mx; private float my; - private float mr; private float mdx; private float mdy; @@ -343,8 +351,8 @@ class GlyphContext { for (int index = top; index >= 0; index--) { ReadableMap font = mFontContext.get(index); - if (mFontContext.get(index).hasKey("fontSize")) { - return font.getDouble("fontSize"); + if (mFontContext.get(index).hasKey(FONT_SIZE)) { + return font.getDouble(FONT_SIZE); } } @@ -357,11 +365,8 @@ class GlyphContext { ReadableMap getFont() { WritableMap map = Arguments.createMap(); - - map.putDouble("letterSpacing", DEFAULT_LETTER_SPACING); - map.putBoolean("isKerningValueSet", false); - map.putDouble("kerning", DEFAULT_KERNING); - map.putDouble("fontSize", fontSize); + map.putBoolean(IS_KERNING_VALUE_SET, false); + map.putDouble(FONT_SIZE, fontSize); boolean letterSpacingSet = false; boolean fontFamilySet = false; @@ -372,38 +377,40 @@ class GlyphContext { for (int index = top; index >= 0; index--) { ReadableMap font = mFontContext.get(index); - if (!fontFamilySet && font.hasKey("fontFamily")) { - String fontFamily = font.getString("fontFamily"); - map.putString("fontFamily", fontFamily); - fontFamilySet = true; - } - - if (!kerningSet && font.hasKey("kerning")) { - float kerning = Float.valueOf(font.getString("kerning")); - map.putBoolean("isKerningValueSet", true); - map.putDouble("kerning", kerning); - kerningSet = true; - } - - if (!letterSpacingSet && font.hasKey("letterSpacing")) { - float letterSpacing = Float.valueOf(font.getString("letterSpacing")); - map.putDouble("letterSpacing", letterSpacing); + if (!letterSpacingSet && font.hasKey(LETTER_SPACING)) { + String letterSpacingString = font.getString(LETTER_SPACING); + float letterSpacing = Float.valueOf(letterSpacingString); + map.putDouble(LETTER_SPACING, letterSpacing); letterSpacingSet = true; } - if (!fontWeightSet && font.hasKey("fontWeight")) { - String fontWeight = font.getString("fontWeight"); - map.putString("fontWeight", fontWeight); + if (!fontFamilySet && font.hasKey(FONT_FAMILY)) { + String fontFamily = font.getString(FONT_FAMILY); + map.putString(FONT_FAMILY, fontFamily); + fontFamilySet = true; + } + + if (!fontWeightSet && font.hasKey(FONT_WEIGHT)) { + String fontWeight = font.getString(FONT_WEIGHT); + map.putString(FONT_WEIGHT, fontWeight); fontWeightSet = true; } - if (!fontStyleSet && font.hasKey("fontStyle")) { - String fontStyle = font.getString("fontStyle"); - map.putString("fontStyle", fontStyle); + if (!fontStyleSet && font.hasKey(FONT_STYLE)) { + String fontStyle = font.getString(FONT_STYLE); + map.putString(FONT_STYLE, fontStyle); fontStyleSet = true; } - if (fontFamilySet && kerningSet && letterSpacingSet && fontWeightSet && fontStyleSet) { + if (!kerningSet && font.hasKey(KERNING)) { + String kerningString = font.getString(KERNING); + float kerning = Float.valueOf(kerningString); + map.putBoolean(IS_KERNING_VALUE_SET, true); + map.putDouble(KERNING, kerning); + kerningSet = true; + } + + if (letterSpacingSet && fontFamilySet && fontWeightSet && fontStyleSet && kerningSet) { break; } } diff --git a/android/src/main/java/com/horcrux/svg/TSpanShadowNode.java b/android/src/main/java/com/horcrux/svg/TSpanShadowNode.java index f52d8375..3577bc37 100644 --- a/android/src/main/java/com/horcrux/svg/TSpanShadowNode.java +++ b/android/src/main/java/com/horcrux/svg/TSpanShadowNode.java @@ -33,9 +33,15 @@ import static android.graphics.PathMeasure.TANGENT_MATRIX_FLAG; */ class TSpanShadowNode extends TextShadowNode { - private Path mCache; - private @Nullable String mContent; - private TextPathShadowNode textPath; + private static final String STRETCH = "stretch"; + private static final String ITALIC = "italic"; + private static final String FONTS = "fonts/"; + private static final String BOLD = "bold"; + private static final String OTF = ".otf"; + private static final String TTF = ".ttf"; + + private static final float DEFAULT_KERNING = 0f; + private static final float DEFAULT_LETTER_SPACING = 0f; private static final String PROP_KERNING = "kerning"; private static final String PROP_FONT_SIZE = "fontSize"; @@ -45,6 +51,10 @@ class TSpanShadowNode extends TextShadowNode { private static final String PROP_LETTER_SPACING = "letterSpacing"; private static final String PROP_IS_KERNING_VALUE_SET = "isKerningValueSet"; + private Path mCache; + private @Nullable String mContent; + private TextPathShadowNode textPath; + @ReactProp(name = "content") public void setContent(@Nullable String content) { mContent = content; @@ -128,7 +138,7 @@ class TSpanShadowNode extends TextShadowNode { offset = PropHelper.fromRelativeToFloat(startOffset, distance, 0, mScale, size); // String spacing = textPath.getSpacing(); // spacing = "auto | exact" String method = textPath.getMethod(); // method = "align | stretch" - if ("stretch".equals(method)) { + if (STRETCH.equals(method)) { renderMethodScaling = distance / textMeasure; } } @@ -148,8 +158,13 @@ class TSpanShadowNode extends TextShadowNode { String previous = ""; float previousWidth = 0; char[] chars = line.toCharArray(); - float kerning = (float) (font.getDouble(PROP_KERNING) * mScale); - boolean autoKerning = !font.getBoolean(PROP_IS_KERNING_VALUE_SET); + + boolean autoKerning = true; + float kerning = DEFAULT_KERNING; + if (font.getBoolean(PROP_IS_KERNING_VALUE_SET)) { + autoKerning = false; + kerning = (float) (font.getDouble(PROP_KERNING) * mScale); + } for (int index = 0; index < length; index++) { glyph = new Path(); @@ -205,7 +220,9 @@ class TSpanShadowNode extends TextShadowNode { paint.setTextAlign(Paint.Align.LEFT); float fontSize = (float) font.getDouble(PROP_FONT_SIZE) * mScale; - float letterSpacing = (float) font.getDouble(PROP_LETTER_SPACING) * mScale; + float letterSpacing = font.hasKey(PROP_LETTER_SPACING) ? + (float) font.getDouble(PROP_LETTER_SPACING) * mScale + : DEFAULT_LETTER_SPACING; paint.setTextSize(fontSize); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { @@ -218,9 +235,9 @@ class TSpanShadowNode extends TextShadowNode { paint.setStrikeThruText(decoration == TEXT_DECORATION_LINE_THROUGH); boolean isBold = font.hasKey(PROP_FONT_WEIGHT) && - "bold".equals(font.getString(PROP_FONT_WEIGHT)); + BOLD.equals(font.getString(PROP_FONT_WEIGHT)); boolean isItalic = font.hasKey(PROP_FONT_STYLE) && - "italic".equals(font.getString(PROP_FONT_STYLE)); + ITALIC.equals(font.getString(PROP_FONT_STYLE)); int fontStyle; if (isBold && isItalic) { @@ -237,11 +254,11 @@ class TSpanShadowNode extends TextShadowNode { Typeface tf = null; try { - String path = "fonts/" + font.getString(PROP_FONT_FAMILY) + ".otf"; + String path = FONTS + font.getString(PROP_FONT_FAMILY) + OTF; tf = Typeface.createFromAsset(a, path); } catch (Exception ignored) { try { - String path = "fonts/" + font.getString(PROP_FONT_FAMILY) + ".ttf"; + String path = FONTS + font.getString(PROP_FONT_FAMILY) + TTF; tf = Typeface.createFromAsset(a, path); } catch (Exception ignored2) { try {