1616import android .graphics .Path ;
1717import android .graphics .RectF ;
1818import android .graphics .DashPathEffect ;
19+ import android .graphics .LinearGradient ;
20+ import android .graphics .Shader ;
21+ import android .graphics .Color ;
1922
2023import com .facebook .common .logging .FLog ;
2124import com .facebook .react .bridge .JSApplicationIllegalArgumentException ;
@@ -42,9 +45,16 @@ public class ARTShapeShadowNode extends ARTVirtualNode {
4245 private static final int PATH_TYPE_LINETO = 2 ;
4346 private static final int PATH_TYPE_MOVETO = 0 ;
4447
48+ // For color type JS and ObjectiveC definitions counterparts
49+ // refer to ReactNativeART.js and RCTConvert+ART.m
50+ private static final int COLOR_TYPE_SOLID_COLOR = 0 ;
51+ private static final int COLOR_TYPE_LINEAR_GRADIENT = 1 ;
52+ private static final int COLOR_TYPE_RADIAL_GRADIENT = 2 ;
53+ private static final int COLOR_TYPE_PATTERN = 3 ;
54+
4555 protected @ Nullable Path mPath ;
4656 private @ Nullable float [] mStrokeColor ;
47- private @ Nullable float [] mFillColor ;
57+ private @ Nullable float [] mBrushData ;
4858 private @ Nullable float [] mStrokeDash ;
4959 private float mStrokeWidth = 1 ;
5060 private int mStrokeCap = CAP_ROUND ;
@@ -71,7 +81,7 @@ public void setStrokeDash(@Nullable ReadableArray strokeDash) {
7181
7282 @ ReactProp (name = "fill" )
7383 public void setFill (@ Nullable ReadableArray fillColors ) {
74- mFillColor = PropHelper .toFloatArray (fillColors );
84+ mBrushData = PropHelper .toFloatArray (fillColors );
7585 markUpdated ();
7686 }
7787
@@ -169,21 +179,60 @@ protected boolean setupStrokePaint(Paint paint, float opacity) {
169179 * if the fill should be drawn, {@code false} if not.
170180 */
171181 protected boolean setupFillPaint (Paint paint , float opacity ) {
172- if (mFillColor != null && mFillColor .length > 0 ) {
182+ if (mBrushData != null && mBrushData .length > 0 ) {
173183 paint .reset ();
174184 paint .setFlags (Paint .ANTI_ALIAS_FLAG );
175185 paint .setStyle (Paint .Style .FILL );
176- int colorType = (int ) mFillColor [0 ];
186+ int colorType = (int ) mBrushData [0 ];
177187 switch (colorType ) {
178- case 0 :
188+ case COLOR_TYPE_SOLID_COLOR :
179189 paint .setARGB (
180- (int ) (mFillColor .length > 4 ? mFillColor [4 ] * opacity * 255 : opacity * 255 ),
181- (int ) (mFillColor [1 ] * 255 ),
182- (int ) (mFillColor [2 ] * 255 ),
183- (int ) (mFillColor [3 ] * 255 ));
190+ (int ) (mBrushData .length > 4 ? mBrushData [4 ] * opacity * 255 : opacity * 255 ),
191+ (int ) (mBrushData [1 ] * 255 ),
192+ (int ) (mBrushData [2 ] * 255 ),
193+ (int ) (mBrushData [3 ] * 255 ));
194+ break ;
195+ case COLOR_TYPE_LINEAR_GRADIENT :
196+ // For mBrushData format refer to LinearGradient and insertColorStopsIntoArray functions in ReactNativeART.js
197+ if (mBrushData .length < 5 ) {
198+ FLog .w (ReactConstants .TAG ,
199+ "[ARTShapeShadowNode setupFillPaint] expects 5 elements, received "
200+ + mBrushData .length );
201+ return false ;
202+ }
203+ float gradientStartX = mBrushData [1 ] * mScale ;
204+ float gradientStartY = mBrushData [2 ] * mScale ;
205+ float gradientEndX = mBrushData [3 ] * mScale ;
206+ float gradientEndY = mBrushData [4 ] * mScale ;
207+ int stops = (mBrushData .length - 5 ) / 5 ;
208+ int [] colors = null ;
209+ float [] positions = null ;
210+ if (stops > 0 ) {
211+ colors = new int [stops ];
212+ positions = new float [stops ];
213+ for (int i =0 ; i <stops ; i ++) {
214+ positions [i ] = mBrushData [5 + 4 *stops + i ];
215+ int r = (int ) (255 * mBrushData [5 + 4 *i + 0 ]);
216+ int g = (int ) (255 * mBrushData [5 + 4 *i + 1 ]);
217+ int b = (int ) (255 * mBrushData [5 + 4 *i + 2 ]);
218+ int a = (int ) (255 * mBrushData [5 + 4 *i + 3 ]);
219+ colors [i ] = Color .argb (a , r , g , b );
220+ }
221+ }
222+ paint .setShader (
223+ new LinearGradient (
224+ gradientStartX , gradientStartY ,
225+ gradientEndX , gradientEndY ,
226+ colors , positions ,
227+ Shader .TileMode .CLAMP
228+ )
229+ );
184230 break ;
231+ case COLOR_TYPE_RADIAL_GRADIENT :
232+ // TODO(6352048): Support radial gradient etc.
233+ case COLOR_TYPE_PATTERN :
234+ // TODO(6352048): Support patterns etc.
185235 default :
186- // TODO(6352048): Support gradients etc.
187236 FLog .w (ReactConstants .TAG , "ART: Color type " + colorType + " not supported!" );
188237 }
189238 return true ;
0 commit comments