mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-13 09:21:46 +08:00
Add support for RCTText under FlatUIImplementation
Summary: @public Initial version of FlatUIImplementation lacks any primitives support (such as RCTText, RCTImageView or RCTView). This diff add the first part, RCTText (alongside with RCTVirtualText and RCTRawText). Reviewed By: sriramramani Differential Revision: D2693348
This commit is contained in:
committed by
Ahmed El-Helw
parent
44d2ee1c3f
commit
5c2f536e9a
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.flat;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.ReactProp;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
|
||||
/**
|
||||
* RCTVirtualText is a {@link FlatTextShadowNode} that can contain font styling information.
|
||||
*/
|
||||
/* package */ class RCTVirtualText extends FlatTextShadowNode {
|
||||
|
||||
private static final String BOLD = "bold";
|
||||
private static final String ITALIC = "italic";
|
||||
private static final String NORMAL = "normal";
|
||||
|
||||
// TODO: cache CustomStyleSpan and move remove these values from here
|
||||
// (implemented in a followup patch)
|
||||
private double mTextColor = Double.NaN;
|
||||
private int mBgColor;
|
||||
private int mFontSize = getDefaultFontSize();
|
||||
private int mFontStyle = -1; // -1, Typeface.NORMAL or Typeface.ITALIC
|
||||
private int mFontWeight = -1; // -1, Typeface.NORMAL or Typeface.BOLD
|
||||
private @Nullable String mFontFamily;
|
||||
|
||||
// these 2 are only used between collectText() and applySpans() calls.
|
||||
private int mTextBegin;
|
||||
private int mTextEnd;
|
||||
|
||||
@Override
|
||||
protected void collectText(SpannableStringBuilder builder) {
|
||||
int childCount = getChildCount();
|
||||
|
||||
mTextBegin = builder.length();
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
FlatTextShadowNode child = (FlatTextShadowNode) getChildAt(i);
|
||||
child.collectText(builder);
|
||||
}
|
||||
mTextEnd = builder.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applySpans(SpannableStringBuilder builder) {
|
||||
if (mTextBegin == mTextEnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
builder.setSpan(
|
||||
// Future patch: cache last custom style span with a frozen flag
|
||||
new FontStylingSpan(mTextColor, mBgColor, mFontSize, mFontStyle, mFontWeight, mFontFamily),
|
||||
mTextBegin,
|
||||
mTextEnd,
|
||||
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
|
||||
int childCount = getChildCount();
|
||||
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
FlatTextShadowNode child = (FlatTextShadowNode) getChildAt(i);
|
||||
child.applySpans(builder);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.FONT_SIZE, defaultFloat = Float.NaN)
|
||||
public void setFontSize(float fontSizeSp) {
|
||||
final int fontSize;
|
||||
if (Float.isNaN(fontSizeSp)) {
|
||||
fontSize = getDefaultFontSize();
|
||||
} else {
|
||||
fontSize = fontSizeFromSp(fontSizeSp);
|
||||
}
|
||||
|
||||
if (mFontSize != fontSize) {
|
||||
mFontSize = fontSize;
|
||||
notifyChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.COLOR, defaultDouble = Double.NaN)
|
||||
public void setColor(double textColor) {
|
||||
if (mTextColor != textColor) {
|
||||
mTextColor = textColor;
|
||||
notifyChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.BACKGROUND_COLOR)
|
||||
public void setBackgroundColor(int backgroundColor) {
|
||||
if (mBgColor != backgroundColor) {
|
||||
mBgColor = backgroundColor;
|
||||
notifyChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.FONT_FAMILY)
|
||||
public void setFontFamily(@Nullable String fontFamily) {
|
||||
mFontFamily = fontFamily;
|
||||
notifyChanged(true);
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.FONT_WEIGHT)
|
||||
public void setFontWeight(@Nullable String fontWeightString) {
|
||||
final int fontWeight;
|
||||
if (fontWeightString == null) {
|
||||
fontWeight = -1;
|
||||
} else if (BOLD.equals(fontWeightString)) {
|
||||
fontWeight = Typeface.BOLD;
|
||||
} else if (NORMAL.equals(fontWeightString)) {
|
||||
fontWeight = Typeface.NORMAL;
|
||||
} else {
|
||||
int fontWeightNumeric = parseNumericFontWeight(fontWeightString);
|
||||
if (fontWeightNumeric == -1) {
|
||||
throw new RuntimeException("invalid font weight " + fontWeightString);
|
||||
}
|
||||
fontWeight = fontWeightNumeric >= 500 ? Typeface.BOLD : Typeface.NORMAL;
|
||||
}
|
||||
|
||||
if (mFontWeight != fontWeight) {
|
||||
mFontWeight = fontWeight;
|
||||
notifyChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.FONT_STYLE)
|
||||
public void setFontStyle(@Nullable String fontStyleString) {
|
||||
final int fontStyle;
|
||||
if (fontStyleString == null) {
|
||||
fontStyle = -1;
|
||||
} else if (ITALIC.equals(fontStyleString)) {
|
||||
fontStyle = Typeface.ITALIC;
|
||||
} else if (NORMAL.equals(fontStyleString)) {
|
||||
fontStyle = Typeface.NORMAL;
|
||||
} else {
|
||||
throw new RuntimeException("invalid font style " + fontStyleString);
|
||||
}
|
||||
|
||||
if (mFontStyle != fontStyle) {
|
||||
mFontStyle = fontStyle;
|
||||
notifyChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected int getDefaultFontSize() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* package */ static int fontSizeFromSp(float sp) {
|
||||
return (int) Math.ceil(PixelUtil.toPixelFromSP(sp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return -1 if the input string is not a valid numeric fontWeight (100, 200, ..., 900), otherwise
|
||||
* return the weight.
|
||||
*/
|
||||
private static int parseNumericFontWeight(String fontWeightString) {
|
||||
// This should be much faster than using regex to verify input and Integer.parseInt
|
||||
return fontWeightString.length() == 3 && fontWeightString.endsWith("00")
|
||||
&& fontWeightString.charAt(0) <= '9' && fontWeightString.charAt(0) >= '1' ?
|
||||
100 * (fontWeightString.charAt(0) - '0') : -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user