mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-20 14:05:09 +00:00
First letterSpacing implementation attempt
This commit is contained in:
@@ -37,6 +37,8 @@ public class GlyphContext {
|
||||
private float mHeight;
|
||||
private int mContextLength = 0;
|
||||
private static final float DEFAULT_FONT_SIZE = 12f;
|
||||
private static final float DEFAULT_KERNING = 0f;
|
||||
private static final float DEFAULT_LETTER_SPACING = 0f;
|
||||
|
||||
GlyphContext(float scale, float width, float height) {
|
||||
mScale = scale;
|
||||
@@ -171,7 +173,11 @@ public class GlyphContext {
|
||||
public ReadableMap getGlyphFont() {
|
||||
String fontFamily = null;
|
||||
float fontSize = DEFAULT_FONT_SIZE;
|
||||
float kerning = DEFAULT_KERNING;
|
||||
float letterSpacing = DEFAULT_LETTER_SPACING;
|
||||
boolean fontSizeSet = false;
|
||||
boolean kerningSet = false;
|
||||
boolean letterSpacingSet = false;
|
||||
String fontWeight = null;
|
||||
String fontStyle = null;
|
||||
|
||||
@@ -189,6 +195,18 @@ public class GlyphContext {
|
||||
fontSizeSet = true;
|
||||
}
|
||||
|
||||
// TODO: add support for other length units
|
||||
if (!kerningSet && font.hasKey("kerning")) {
|
||||
kerning = Float.valueOf(font.getString("kerning"));
|
||||
kerningSet = true;
|
||||
}
|
||||
|
||||
// TODO: add support for other length units
|
||||
if (!letterSpacingSet && font.hasKey("letterSpacing")) {
|
||||
letterSpacing = Float.valueOf(font.getString("letterSpacing"));
|
||||
letterSpacingSet = true;
|
||||
}
|
||||
|
||||
if (fontWeight == null && font.hasKey("fontWeight")) {
|
||||
fontWeight = font.getString("fontWeight");
|
||||
}
|
||||
@@ -196,7 +214,7 @@ public class GlyphContext {
|
||||
fontStyle = font.getString("fontStyle");
|
||||
}
|
||||
|
||||
if (fontFamily != null && fontSizeSet && fontWeight != null && fontStyle != null) {
|
||||
if (fontFamily != null && fontSizeSet && kerningSet && letterSpacingSet && fontWeight != null && fontStyle != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -206,6 +224,8 @@ public class GlyphContext {
|
||||
map.putDouble("fontSize", fontSize);
|
||||
map.putString("fontWeight", fontWeight);
|
||||
map.putString("fontStyle", fontStyle);
|
||||
map.putDouble("kerning", kerning);
|
||||
map.putDouble("letterSpacing", letterSpacing);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ public class TSpanShadowNode extends TextShadowNode {
|
||||
private static final String PROP_FONT_SIZE = "fontSize";
|
||||
private static final String PROP_FONT_STYLE = "fontStyle";
|
||||
private static final String PROP_FONT_WEIGHT = "fontWeight";
|
||||
private static final String PROP_KERNING = "kerning";
|
||||
private static final String PROP_LETTER_SPACING = "letterSpacing";
|
||||
|
||||
@ReactProp(name = "content")
|
||||
public void setContent(@Nullable String content) {
|
||||
@@ -101,12 +103,12 @@ public class TSpanShadowNode extends TextShadowNode {
|
||||
|
||||
paint.getTextPath(letter, 0, 1, 0, 0, glyph);
|
||||
PointF glyphDelta = getGlyphDeltaFromContext();
|
||||
PointF glyphPoint = getGlyphPointFromContext(glyphPosition * 1.2f, width);
|
||||
PointF glyphPoint = getGlyphPointFromContext(glyphPosition, width);
|
||||
glyphPosition += width;
|
||||
Matrix matrix = new Matrix();
|
||||
|
||||
if (mBezierTransformer != null) {
|
||||
matrix = mBezierTransformer.getTransformAtDistance(glyphPoint.x + glyphDelta.x + width / 2);
|
||||
matrix = mBezierTransformer.getTransformAtDistance(glyphPoint.x * 1.2f + glyphDelta.x + width / 2);
|
||||
|
||||
if (textPathHasReachedEnd()) {
|
||||
break;
|
||||
@@ -132,10 +134,22 @@ public class TSpanShadowNode extends TextShadowNode {
|
||||
|
||||
paint.setTextAlign(Paint.Align.LEFT);
|
||||
|
||||
float fontSize = (float)font.getDouble(PROP_FONT_SIZE);
|
||||
float fontSize = (float)font.getDouble(PROP_FONT_SIZE) * mScale;
|
||||
float kerning = (float)font.getDouble(PROP_KERNING);
|
||||
float letterSpacing = (float)font.getDouble(PROP_LETTER_SPACING);
|
||||
|
||||
paint.setTextSize(fontSize * mScale);
|
||||
if (mBezierTransformer == null) {
|
||||
letterSpacing *= mScale;
|
||||
} else {
|
||||
// What is going on here? This helps get closer to how e.g. chrome renders things
|
||||
// But, still off, depending on the font size and letter-spacing.
|
||||
letterSpacing *= java.lang.Math.pow(120 / fontSize, 6);
|
||||
}
|
||||
|
||||
paint.setTextSize(fontSize);
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
|
||||
paint.setLetterSpacing(letterSpacing / fontSize); // setLetterSpacing is only available from LOLLIPOP and on
|
||||
}
|
||||
|
||||
boolean isBold = font.hasKey(PROP_FONT_WEIGHT) && "bold".equals(font.getString(PROP_FONT_WEIGHT));
|
||||
boolean isItalic = font.hasKey(PROP_FONT_STYLE) && "italic".equals(font.getString(PROP_FONT_STYLE));
|
||||
|
||||
@@ -23,7 +23,9 @@ function fontDiffer(a, b) {
|
||||
return a.fontSize !== b.fontSize ||
|
||||
a.fontFamily !== b.fontFamily ||
|
||||
a.fontStyle !== b.fontStyle ||
|
||||
a.fontWeight !== b.fontWeight;
|
||||
a.fontWeight !== b.fontWeight ||
|
||||
a.kerning !== b.kerning ||
|
||||
a.letterSpacing !== b.letterSpacing;
|
||||
}
|
||||
|
||||
const ViewBoxAttributes = {
|
||||
|
||||
@@ -55,7 +55,9 @@ export function extractFont(props) {
|
||||
fontFamily: extractSingleFontFamily(props.fontFamily),
|
||||
fontSize: isNaN(fontSize) ? null : fontSize,
|
||||
fontWeight: props.fontWeight,
|
||||
fontStyle: props.fontStyle
|
||||
fontStyle: props.fontStyle,
|
||||
kerning: props.kerning,
|
||||
letterSpacing: props.letterSpacing,
|
||||
};
|
||||
|
||||
if (typeof props.font === 'string') {
|
||||
|
||||
@@ -53,6 +53,8 @@ const fontProps = {
|
||||
fontSize: numberProp,
|
||||
fontWeight: numberProp,
|
||||
fontStyle: PropTypes.string,
|
||||
letterSpacing: PropTypes.string,
|
||||
kerning: PropTypes.string,
|
||||
font: PropTypes.object
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user