Skip to content

Commit 0c8cb2a

Browse files
committed
New function flatHeights (Android)
1 parent e8f97f7 commit 0c8cb2a

File tree

9 files changed

+240
-238
lines changed

9 files changed

+240
-238
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
44

55
## [Unreleased]
66

7+
## [2.0.0-beta.5] - 2018-08-21
8+
79
### Added
10+
- New function `flatHeights` to calculate the height of multiple strings at once, much faster than` measure`.
811
- Revised REAME. Now it's clearer, part of its content moved to the Wiki.
912
- Docummented the iOS only properties `capHeight` and `xHeight` from the `fontFromSpecs` result.
1013
- New flag `usePreciseWidth` (default `false`) request the most accurate calculation of the width (Android) and the value of `lastWidth` (both), but its is a bit slower.

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ This function measures the text like RN does when the text does not have embedde
7272

7373
If you provide the `width`, the measurement will apply the restriction and take into account the automatic line breaks, in addition to the explicit ones.
7474

75+
**NOTE:**
76+
77+
Although this function is accurate and provides complete information, it can be heavy if the text is a lot, like the one that can be displayed in a FlatList. For these cases, it is better to use `flatHeights` which is much faster.
78+
7579
<a name="tsmeasureparams"></a>**TSMeasureParams**
7680

7781
JS object with the text to measure, the maximum width, and properties like ones in the react-native [`<Text>`](https://facebook.github.io/react-native/docs/text) component.
@@ -166,6 +170,46 @@ class Test extends Component<Props, State> {
166170

167171
---
168172

173+
## `flatHeights`
174+
175+
```ts
176+
flatHeights(options: TSHeightsParams): Promise<number[]>
177+
```
178+
179+
Calculate the height of each of the strings in an array.
180+
181+
This is an alternative to `measure` designed for cases in which you have to calculate the height of numerous text blocks with common characteristics (width, font, etc), a Typical case in the `<FlatList>`.
182+
183+
The measurement uses the same algorithm as `measure`, but it returns only the height of each block and, by avoiding multiple steps through the bridge, it is much faster (in my tests, with 3500 random blocks of text, it took 778 ms, while mesure took 33,218).
184+
185+
In the future I will prepare an example of its use with FlatList and multiple styles on the same card.
186+
187+
**TSHeightsParams**
188+
189+
This is an object similar to the one received by measure, with the difference that the text property is an array of strings, and the usePreciseWidth property is ignored.
190+
191+
The result is an array with the height of each block, in the same order was given.
192+
193+
This is an object similar to the one received by `measure`, but the `text` property is an array of strings and the `usePreciseWidth` property is ignored.
194+
195+
Property | Type | Default
196+
---------- | ------ | --------
197+
text | string | (none)
198+
width | number | Infinity
199+
fontFamily | string | OS dependent
200+
fontWeight | string | 'normal'
201+
fontSize | number | 14
202+
fontStyle | string | 'normal'
203+
fontVariant | array | (none)
204+
allowFontScaling | boolean | true
205+
letterSpacing | number | (none)
206+
includeFontPadding | boolean | true
207+
textBreakStrategy | string | 'highQuality'
208+
209+
The result is a Promise that resolves to an array with the height of each block (_SP_), in the same order in which they were received.
210+
211+
---
212+
169213
## `specsForTextStyles`
170214

171215
```ts

android/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,9 @@ task customClean(type: Delete) {
6969
delete rootProject.buildDir
7070
}
7171
clean.dependsOn customClean
72+
73+
//gradle.projectsEvaluated {
74+
// tasks.withType(JavaCompile) {
75+
// options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
76+
// }
77+
//}

android/src/main/java/com/github/amarcruz/rntextsize/RNTextSizeConf.java

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package com.github.amarcruz.rntextsize;
22

3-
import android.annotation.TargetApi;
43
import android.graphics.Typeface;
4+
import android.os.Build;
55
import android.support.annotation.NonNull;
66
import android.support.annotation.Nullable;
77
import android.text.Layout;
8+
import android.util.Log;
89

910
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
11+
import com.facebook.react.bridge.ReactApplicationContext;
12+
import com.facebook.react.bridge.ReadableArray;
1013
import com.facebook.react.bridge.ReadableMap;
11-
import com.facebook.react.modules.systeminfo.ReactNativeVersion;
14+
import com.facebook.react.bridge.ReadableType;
15+
import com.facebook.react.uimanager.PixelUtil;
16+
import com.facebook.react.views.text.ReactFontManager;
1217

1318
import java.util.Map;
1419

@@ -19,13 +24,32 @@ final class RNTextSizeConf {
1924
static {
2025
int version = 0;
2126
try {
22-
Map<String, Object> rnv = ReactNativeVersion.VERSION;
27+
Class.forName("com.facebook.react.modules.systeminfo.ReactNativeVersion");
28+
Map<String, Object> rnv = com.facebook.react.modules.systeminfo.ReactNativeVersion.VERSION;
2329
version = ((int) rnv.get("major") << 16) | (int) rnv.get("minor");
24-
} catch (Exception ignore) {
30+
} catch (Exception ex) {
31+
Log.v("RNTextSize", "Cannot get RN version.", ex);
2532
}
2633
reactNativeVersion = version;
2734
}
2835

36+
37+
/**
38+
* Make a Typeface from the supplied font family and style.
39+
*/
40+
@NonNull
41+
static Typeface getFont(
42+
@NonNull final ReactApplicationContext context,
43+
@Nullable String family,
44+
final int style
45+
) {
46+
final Typeface typeface = family != null
47+
? ReactFontManager.getInstance().getTypeface(family, style, context.getAssets())
48+
: null;
49+
50+
return typeface != null ? typeface : Typeface.defaultFromStyle(style);
51+
}
52+
2953
// letterSpacing is supported in RN 0.55+
3054
static boolean supportLetterSpacing() {
3155
return reactNativeVersion >= 55;
@@ -36,11 +60,11 @@ static float getDefaultFontSize() {
3660
}
3761

3862
private final ReadableMap mOpts;
63+
private final boolean allowFontScaling;
3964

4065
final String fontFamily;
4166
final float fontSize;
4267
final int fontStyle;
43-
final boolean allowFontScaling;
4468
final boolean includeFontPadding;
4569
final float letterSpacing;
4670

@@ -68,8 +92,8 @@ boolean has(@NonNull final String name) {
6892
return mOpts.hasKey(name);
6993
}
7094

71-
float getFloatOrNaN(@NonNull final String name) {
72-
return mOpts.hasKey(name) ? (float) mOpts.getDouble(name) : Float.NaN;
95+
boolean getBooleanOrTrue(@NonNull final String name) {
96+
return !mOpts.hasKey(name) || mOpts.getBoolean(name);
7397
}
7498

7599
@Nullable
@@ -78,8 +102,33 @@ String getString(@NonNull final String name) {
78102
? mOpts.getString(name) : null;
79103
}
80104

81-
@TargetApi(23)
105+
@SuppressWarnings("SameParameterValue")
106+
@Nullable
107+
ReadableArray getArray(@NonNull final String name) {
108+
return mOpts.hasKey(name) && mOpts.getType(name) == ReadableType.Array
109+
? mOpts.getArray(name) : null;
110+
}
111+
112+
float scale(final float measure) {
113+
return allowFontScaling
114+
? PixelUtil.toPixelFromSP(measure)
115+
: PixelUtil.toPixelFromDIP(measure);
116+
}
117+
118+
float getWidth(final float density) {
119+
float width = getFloatOrNaN("width");
120+
if (!Float.isNaN(width) && width > 0) {
121+
return width * density; // always DIP
122+
} else {
123+
return Float.MAX_VALUE;
124+
}
125+
}
126+
82127
int getTextBreakStrategy() {
128+
if (Build.VERSION.SDK_INT < 23) {
129+
return 0;
130+
}
131+
83132
final String textBreakStrategy = getString("textBreakStrategy");
84133

85134
if (textBreakStrategy != null) {
@@ -98,6 +147,10 @@ int getTextBreakStrategy() {
98147
return Layout.BREAK_STRATEGY_HIGH_QUALITY;
99148
}
100149

150+
private float getFloatOrNaN(@NonNull final String name) {
151+
return mOpts.hasKey(name) ? (float) mOpts.getDouble(name) : Float.NaN;
152+
}
153+
101154
private float getFontSizeOrDefault() {
102155
if (mOpts.hasKey("fontSize")) {
103156
final float num = (float) mOpts.getDouble("fontSize");
@@ -127,8 +180,4 @@ private int getFontStyle() {
127180
}
128181
return style;
129182
}
130-
131-
boolean getBooleanOrTrue(@NonNull final String name) {
132-
return !mOpts.hasKey(name) || mOpts.getBoolean(name);
133-
}
134183
}

0 commit comments

Comments
 (0)