@@ -163,61 +163,26 @@ public void measure(@Nullable final ReadableMap specs, final Promise promise) {
163163 }
164164 }
165165
166- // https://stackoverflow.com/questions/3654321/measuring-text-height-to-be-drawn-on-canvas-android
166+ /**
167+ * Retrieves sizes of each entry in an array of strings rendered with the same style.
168+ *
169+ * https://stackoverflow.com/questions/3654321/measuring-text-height-to-be-drawn-on-canvas-android
170+ */
167171 @ SuppressWarnings ("unused" )
168172 @ ReactMethod
169- public void flatHeights (@ Nullable final ReadableMap specs , final Promise promise ) {
170- final RNTextSizeConf conf = getConf (specs , promise , true );
171- if (conf == null ) {
172- return ;
173- }
174-
175- final ReadableArray texts = conf .getArray ("text" );
176- if (texts == null ) {
177- promise .reject (E_MISSING_TEXT , "Missing required text, must be an array." );
178- return ;
179- }
180-
181- final float density = getCurrentDensity ();
182- final float width = conf .getWidth (density );
183- final boolean includeFontPadding = conf .includeFontPadding ;
184- final int textBreakStrategy = conf .getTextBreakStrategy ();
185-
186- final WritableArray result = Arguments .createArray ();
187-
188- final SpannableStringBuilder sb = new SpannableStringBuilder (" " );
189- RNTextSizeSpannedText .spannedFromSpecsAndText (mReactContext , conf , sb );
190-
191- final TextPaint textPaint = new TextPaint (TextPaint .ANTI_ALIAS_FLAG );
192- Layout layout ;
193- try {
194-
195- for (int ix = 0 ; ix < texts .size (); ix ++) {
196-
197- // If this element is `null` or another type, return zero
198- if (texts .getType (ix ) != ReadableType .String ) {
199- result .pushInt (0 );
200- continue ;
201- }
202-
203- final String text = texts .getString (ix );
204-
205- // If empty, return the minimum height of <Text> components
206- if (text .isEmpty ()) {
207- result .pushDouble (minimalHeight (density , includeFontPadding ));
208- continue ;
209- }
210-
211- // Reset the SB text, the attrs will expand to its full length
212- sb .replace (0 , sb .length (), text );
213- layout = buildStaticLayout (conf , includeFontPadding , sb , textPaint , (int ) width );
214- result .pushDouble (layout .getHeight () / density );
215- }
173+ public void flatSizes (@ Nullable final ReadableMap specs , final Promise promise ) {
174+ flatHeightsInner (specs , promise , true );
175+ }
216176
217- promise .resolve (result );
218- } catch (Exception e ) {
219- promise .reject (E_UNKNOWN_ERROR , e );
220- }
177+ /**
178+ * Retrieves heights of each entry in an array of strings rendered with the same style.
179+ *
180+ * https://stackoverflow.com/questions/3654321/measuring-text-height-to-be-drawn-on-canvas-android
181+ */
182+ @ SuppressWarnings ("unused" )
183+ @ ReactMethod
184+ public void flatHeights (@ Nullable final ReadableMap specs , final Promise promise ) {
185+ flatHeightsInner (specs , promise , false );
221186 }
222187
223188 /**
@@ -313,6 +278,77 @@ public void fontNamesForFamilyName(final String ignored, final Promise promise)
313278 //
314279 // ============================================================================
315280
281+ private void flatHeightsInner (@ Nullable final ReadableMap specs , final Promise promise , boolean includeWidths ) {
282+ final RNTextSizeConf conf = getConf (specs , promise , true );
283+ if (conf == null ) {
284+ return ;
285+ }
286+
287+ final ReadableArray texts = conf .getArray ("text" );
288+ if (texts == null ) {
289+ promise .reject (E_MISSING_TEXT , "Missing required text, must be an array." );
290+ return ;
291+ }
292+
293+ final float density = getCurrentDensity ();
294+ final float width = conf .getWidth (density );
295+ final boolean includeFontPadding = conf .includeFontPadding ;
296+ final int textBreakStrategy = conf .getTextBreakStrategy ();
297+
298+ final WritableArray heights = Arguments .createArray ();
299+ final WritableArray widths = Arguments .createArray ();
300+
301+ final SpannableStringBuilder sb = new SpannableStringBuilder (" " );
302+ RNTextSizeSpannedText .spannedFromSpecsAndText (mReactContext , conf , sb );
303+
304+ final TextPaint textPaint = new TextPaint (TextPaint .ANTI_ALIAS_FLAG );
305+ Layout layout ;
306+ try {
307+
308+ for (int ix = 0 ; ix < texts .size (); ix ++) {
309+
310+ // If this element is `null` or another type, return zero
311+ if (texts .getType (ix ) != ReadableType .String ) {
312+ heights .pushInt (0 );
313+ continue ;
314+ }
315+
316+ final String text = texts .getString (ix );
317+
318+ // If empty, return the minimum height of <Text> components
319+ if (text .isEmpty ()) {
320+ heights .pushDouble (minimalHeight (density , includeFontPadding ));
321+ continue ;
322+ }
323+
324+ // Reset the SB text, the attrs will expand to its full length
325+ sb .replace (0 , sb .length (), text );
326+ layout = buildStaticLayout (conf , includeFontPadding , sb , textPaint , (int ) width );
327+ heights .pushDouble (layout .getHeight () / density );
328+
329+ if (includeWidths ) {
330+ final int lineCount = layout .getLineCount ();
331+ float measuredWidth = 0 ;
332+ for (int i = 0 ; i < lineCount ; i ++) {
333+ measuredWidth = Math .max (measuredWidth , layout .getLineMax (i ));
334+ }
335+ widths .pushDouble (measuredWidth / density );
336+ }
337+ }
338+
339+ if (includeWidths ) {
340+ final WritableMap output = Arguments .createMap ();
341+ output .putArray ("widths" , widths );
342+ output .putArray ("heights" , heights );
343+ promise .resolve (output );
344+ } else {
345+ promise .resolve (heights );
346+ }
347+ } catch (Exception e ) {
348+ promise .reject (E_UNKNOWN_ERROR , e );
349+ }
350+ }
351+
316352 @ Nullable
317353 private RNTextSizeConf getConf (final ReadableMap specs , final Promise promise , boolean forText ) {
318354 if (specs == null ) {
0 commit comments