3232import com .facebook .csslayout .CSSNode ;
3333import com .facebook .csslayout .MeasureOutput ;
3434import com .facebook .infer .annotation .Assertions ;
35+ import com .facebook .react .bridge .ReadableMap ;
3536import com .facebook .react .common .annotations .VisibleForTesting ;
3637import com .facebook .react .uimanager .IllegalViewOperationException ;
3738import com .facebook .react .uimanager .LayoutShadowNode ;
@@ -63,6 +64,11 @@ public class ReactTextShadowNode extends LayoutShadowNode {
6364 @ VisibleForTesting
6465 public static final String PROP_TEXT = "text" ;
6566
67+ public static final String PROP_SHADOW_OFFSET = "textShadowOffset" ;
68+ public static final String PROP_SHADOW_RADIUS = "textShadowRadius" ;
69+ public static final String PROP_SHADOW_COLOR = "textShadowColor" ;
70+ public static final int DEFAULT_TEXT_SHADOW_COLOR = 0x55000000 ;
71+
6672 private static final TextPaint sTextPaintInstance = new TextPaint ();
6773
6874 static {
@@ -114,8 +120,7 @@ private static final void buildSpannedFromTextCSSNode(
114120 ops .add (new SetSpanOperation (start , end , new ForegroundColorSpan (textCSSNode .mColor )));
115121 }
116122 if (textCSSNode .mIsBackgroundColorSet ) {
117- ops .add (
118- new SetSpanOperation (
123+ ops .add (new SetSpanOperation (
119124 start ,
120125 end ,
121126 new BackgroundColorSpan (textCSSNode .mBackgroundColor )));
@@ -135,6 +140,16 @@ private static final void buildSpannedFromTextCSSNode(
135140 textCSSNode .mFontFamily ,
136141 textCSSNode .getThemedContext ().getAssets ())));
137142 }
143+ if (textCSSNode .mTextShadowOffsetDx != 0 || textCSSNode .mTextShadowOffsetDy != 0 ) {
144+ ops .add (new SetSpanOperation (
145+ start ,
146+ end ,
147+ new ShadowStyleSpan (
148+ textCSSNode .mTextShadowOffsetDx ,
149+ textCSSNode .mTextShadowOffsetDy ,
150+ textCSSNode .mTextShadowRadius ,
151+ textCSSNode .mTextShadowColor )));
152+ }
138153 ops .add (new SetSpanOperation (start , end , new ReactTagSpan (textCSSNode .getReactTag ())));
139154 }
140155 }
@@ -279,6 +294,11 @@ private static int parseNumericFontWeight(String fontWeightString) {
279294 protected int mNumberOfLines = UNSET ;
280295 protected int mFontSize = UNSET ;
281296
297+ private float mTextShadowOffsetDx = 0 ;
298+ private float mTextShadowOffsetDy = 0 ;
299+ private float mTextShadowRadius = 1 ;
300+ private int mTextShadowColor = DEFAULT_TEXT_SHADOW_COLOR ;
301+
282302 /**
283303 * mFontStyle can be {@link Typeface#NORMAL} or {@link Typeface#ITALIC}.
284304 * mFontWeight can be {@link Typeface#NORMAL} or {@link Typeface#BOLD}.
@@ -413,6 +433,34 @@ public void setFontStyle(@Nullable String fontStyleString) {
413433 }
414434 }
415435
436+ @ ReactProp (name = PROP_SHADOW_OFFSET )
437+ public void setTextShadowOffset (ReadableMap offsetMap ) {
438+ if (offsetMap == null ) {
439+ mTextShadowOffsetDx = 0 ;
440+ mTextShadowOffsetDy = 0 ;
441+ } else {
442+ mTextShadowOffsetDx = PixelUtil .toPixelFromDIP (offsetMap .getDouble ("width" ));
443+ mTextShadowOffsetDy = PixelUtil .toPixelFromDIP (offsetMap .getDouble ("height" ));
444+ }
445+ markUpdated ();
446+ }
447+
448+ @ ReactProp (name = PROP_SHADOW_RADIUS , defaultInt = 1 )
449+ public void setTextShadowRadius (float textShadowRadius ) {
450+ if (textShadowRadius != mTextShadowRadius ) {
451+ mTextShadowRadius = textShadowRadius ;
452+ markUpdated ();
453+ }
454+ }
455+
456+ @ ReactProp (name = PROP_SHADOW_COLOR , defaultInt = DEFAULT_TEXT_SHADOW_COLOR , customType = "Color" )
457+ public void setTextShadowColor (int textShadowColor ) {
458+ if (textShadowColor != mTextShadowColor ) {
459+ mTextShadowColor = textShadowColor ;
460+ markUpdated ();
461+ }
462+ }
463+
416464 @ Override
417465 public boolean isVirtualAnchor () {
418466 return !mIsVirtual ;
0 commit comments