-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] LetterSpacing support for Android Lollipop and above (21) #16801
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -635,6 +635,19 @@ exports.examples = [ | |
); | ||
} | ||
}, | ||
{ | ||
title: 'Letter spacing', | ||
platform: 'android', | ||
render: function() { | ||
return ( | ||
<View> | ||
<TextInput lineSpacing={1.2} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You probably mean to use |
||
placeholder="Line spacing of 1.2" | ||
/> | ||
</View> | ||
); | ||
} | ||
}, | ||
{ | ||
title: 'Auto-expanding', | ||
render: function() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -242,6 +242,8 @@ private static int parseNumericFontWeight(String fontWeightString) { | |
protected int mTextAlign = Gravity.NO_GRAVITY; | ||
protected int mTextBreakStrategy = | ||
(Build.VERSION.SDK_INT < Build.VERSION_CODES.M) ? 0 : Layout.BREAK_STRATEGY_HIGH_QUALITY; | ||
protected float mLetterSpacing = 0.0f; | ||
protected float mPreviousLetterSpacing = Float.NaN; | ||
|
||
protected float mTextShadowOffsetDx = 0; | ||
protected float mTextShadowOffsetDy = 0; | ||
|
@@ -291,6 +293,14 @@ public float getEffectiveLineHeight() { | |
return useInlineViewHeight ? mHeightOfTallestInlineImage : mLineHeight; | ||
} | ||
|
||
private static float calculateLetterSpacing(float letterSpacing, int fontSize) { | ||
if (Float.isNaN(letterSpacing) || letterSpacing == 0.0f) { | ||
return 0.0f; | ||
} | ||
|
||
return letterSpacing / fontSize * 2.0f; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
// Return text alignment according to LTR or RTL style | ||
private int getTextAlign() { | ||
int textAlign = mTextAlign; | ||
|
@@ -304,6 +314,13 @@ private int getTextAlign() { | |
return textAlign; | ||
} | ||
|
||
@ReactProp(name = ViewProps.LETTER_SPACING, defaultFloat = Float.NaN) | ||
public void setLetterSpacing(float letterSpacing) { | ||
mPreviousLetterSpacing = letterSpacing; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick (though I'm not an authority on this codebase): "previous" implies you're keeping an old state, but in fact you're just converting units for the same state; maybe something like |
||
mLetterSpacing = calculateLetterSpacing(letterSpacing, mFontSize); | ||
markUpdated(); | ||
} | ||
|
||
@ReactProp(name = ViewProps.NUMBER_OF_LINES, defaultInt = UNSET) | ||
public void setNumberOfLines(int numberOfLines) { | ||
mNumberOfLines = numberOfLines == 0 ? UNSET : numberOfLines; | ||
|
@@ -363,6 +380,7 @@ public void setFontSize(float fontSize) { | |
: (float) Math.ceil(PixelUtil.toPixelFromDIP(fontSize)); | ||
} | ||
mFontSize = (int) fontSize; | ||
mLetterSpacing = calculateLetterSpacing(mPreviousLetterSpacing, mFontSize); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still on the subject of unit conversions:
|
||
markUpdated(); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
import android.graphics.PorterDuff; | ||
import android.graphics.Typeface; | ||
import android.graphics.drawable.Drawable; | ||
import android.os.Build; | ||
import android.support.v4.content.ContextCompat; | ||
import android.text.Editable; | ||
import android.text.InputFilter; | ||
|
@@ -419,6 +420,14 @@ public void setTextAlignVertical(ReactEditText view, @Nullable String textAlignV | |
} | ||
} | ||
|
||
@ReactProp(name = ViewProps.LETTER_SPACING, defaultFloat = 0.0f) | ||
public void setLetterSpacing(ReactEditText view, float spacing) { | ||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wondering aloud: Is there a precedent for RN enabling an Android-version-dependent feature with neither a fallback nor a warning for older versions? |
||
// Only set letter spacing on Android 21 and up devices, not available otherwise | ||
view.setLetterSpacing(spacing); | ||
} | ||
} | ||
|
||
@ReactProp(name = "inlineImageLeft") | ||
public void setInlineImageLeft(ReactEditText view, @Nullable String resource) { | ||
int id = ResourceDrawableIdHelper.getInstance().getResourceDrawableId(view.getContext(), resource); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -347,6 +347,20 @@ public void testTextAlign() { | |
assertThat(view.getGravity()).isEqualTo(defaultGravity); | ||
} | ||
|
||
@Test | ||
public void testLetterSpacing() { | ||
ReactEditText view = mManager.createViewInstance(mThemedContext); | ||
|
||
mManager.updateProperties(view, buildStyles()); | ||
assertThat(view.getLetterSpacing()).isEqualTo(0.0); | ||
|
||
mManager.updateProperties(view, buildStyles("numberOfLines", 0.5)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You probably mean |
||
assertThat(view.getLetterSpacing()).isEqualTo(0.5); | ||
|
||
mManager.updateProperties(view, buildStyles("numberOfLines", 1.2)); | ||
assertThat(view.getLetterSpacing()).isEqualTo(1.2); | ||
} | ||
|
||
@Test | ||
public void testMaxLength() { | ||
ReactEditText view = mManager.createViewInstance(mThemedContext); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -493,7 +493,7 @@ default is `true`. | |
|
||
- **`fontVariant`**: array of enum('small-caps', 'oldstyle-nums', 'lining-nums', 'tabular-nums', 'proportional-nums') (_iOS_) | ||
|
||
- **`letterSpacing`**: number (_iOS_) | ||
- **`letterSpacing`**: number | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's probably prudent to amend this, perhaps to say something like |
||
|
||
- **`textDecorationColor`**: [color](docs/colors.html) (_iOS_) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: Kerning seems to be the wrong term per Wikipedia.