Skip to content

Commit 75bd2d3

Browse files
mellyeliufacebook-github-bot
authored andcommitted
add feature flag for line height gating (#46408)
Summary: Pull Request resolved: #46408 ## Context Adding feature flag for line height calculation centering. There is a recurring issue in React Native where text containing accented characters, non-latin scripts, and special glyphs experiences truncation when line height is set too small, even when the line height equals or exceeds the font size. This causes issues in rendering complex text in multiple languages or special character sets. See: https://docs.google.com/document/d/1W-A80gKAyhVbz_WKktSwwJP5qm6h6ZBjFNcsVbknXhI/edit?usp=sharing for more context ## Investigation Previously, when font metrics (ascent, descent, top, bottom) exceeded the line height, the logic arbitrarily prioritized descent over ascent and bottom top. This led to vertical misalignment and text clipping at the top of the text. ## Implementation: 1. Descent Exceeds Line Height: Descent is capped to fit within the line height, setting ascent and top to 0, similar to the current behavior. 2. Shrink ascent and descent equally: When the combined ascent and descent exceed the line height, the vertical deficit is split proportionally between them, ensuring even distribution of the space. 3. Proportionally shrink top and bottom: If the top and bottom together exceed the line height, reductions are now applied proportionally based on the delta between top and ascent and bottom and descent. Reviewed By: NickGerleman Differential Revision: D62421775
1 parent 4014aa4 commit 75bd2d3

19 files changed

Lines changed: 163 additions & 61 deletions

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<6cc52570dd571ddc792a0fd842c05dd9>>
7+
* @generated SignedSource<<312da6e350ea6b96180156a341810654>>
88
*/
99

1010
/**
@@ -64,6 +64,12 @@ public object ReactNativeFeatureFlags {
6464
@JvmStatic
6565
public fun enableAlignItemsBaselineOnFabricIOS(): Boolean = accessor.enableAlignItemsBaselineOnFabricIOS()
6666

67+
/**
68+
* When enabled, custom line height calculation will be centered from top to bottom.
69+
*/
70+
@JvmStatic
71+
public fun enableAndroidLineHeightCentering(): Boolean = accessor.enableAndroidLineHeightCentering()
72+
6773
/**
6874
* Enables mix-blend-mode prop on Android.
6975
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<eca842a1b1c823b72136c625b3bfd16e>>
7+
* @generated SignedSource<<a397b9b648fab0e8b1f9d8a9dba04ab4>>
88
*/
99

1010
/**
@@ -26,6 +26,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
2626
private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null
2727
private var destroyFabricSurfacesInReactInstanceManagerCache: Boolean? = null
2828
private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null
29+
private var enableAndroidLineHeightCenteringCache: Boolean? = null
2930
private var enableAndroidMixBlendModePropCache: Boolean? = null
3031
private var enableBackgroundStyleApplicatorCache: Boolean? = null
3132
private var enableCleanTextInputYogaNodeCache: Boolean? = null
@@ -123,6 +124,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
123124
return cached
124125
}
125126

127+
override fun enableAndroidLineHeightCentering(): Boolean {
128+
var cached = enableAndroidLineHeightCenteringCache
129+
if (cached == null) {
130+
cached = ReactNativeFeatureFlagsCxxInterop.enableAndroidLineHeightCentering()
131+
enableAndroidLineHeightCenteringCache = cached
132+
}
133+
return cached
134+
}
135+
126136
override fun enableAndroidMixBlendModeProp(): Boolean {
127137
var cached = enableAndroidMixBlendModePropCache
128138
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<ad54375c4ae3be2f377260887ae5aaf9>>
7+
* @generated SignedSource<<ba7f0d3c03fef86fb12e4d9842dcb241>>
88
*/
99

1010
/**
@@ -40,6 +40,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
4040

4141
@DoNotStrip @JvmStatic public external fun enableAlignItemsBaselineOnFabricIOS(): Boolean
4242

43+
@DoNotStrip @JvmStatic public external fun enableAndroidLineHeightCentering(): Boolean
44+
4345
@DoNotStrip @JvmStatic public external fun enableAndroidMixBlendModeProp(): Boolean
4446

4547
@DoNotStrip @JvmStatic public external fun enableBackgroundStyleApplicator(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<2a0cd5a4875a54bb724e5765ffe7753e>>
7+
* @generated SignedSource<<fa8245a05ab1f508318e1d18938f9dab>>
88
*/
99

1010
/**
@@ -35,6 +35,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
3535

3636
override fun enableAlignItemsBaselineOnFabricIOS(): Boolean = true
3737

38+
override fun enableAndroidLineHeightCentering(): Boolean = false
39+
3840
override fun enableAndroidMixBlendModeProp(): Boolean = false
3941

4042
override fun enableBackgroundStyleApplicator(): Boolean = true

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<d02af2a8ef015c57d45aba8280539606>>
7+
* @generated SignedSource<<069787b84036b763c47d128e66ddd1ab>>
88
*/
99

1010
/**
@@ -30,6 +30,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
3030
private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null
3131
private var destroyFabricSurfacesInReactInstanceManagerCache: Boolean? = null
3232
private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null
33+
private var enableAndroidLineHeightCenteringCache: Boolean? = null
3334
private var enableAndroidMixBlendModePropCache: Boolean? = null
3435
private var enableBackgroundStyleApplicatorCache: Boolean? = null
3536
private var enableCleanTextInputYogaNodeCache: Boolean? = null
@@ -133,6 +134,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
133134
return cached
134135
}
135136

137+
override fun enableAndroidLineHeightCentering(): Boolean {
138+
var cached = enableAndroidLineHeightCenteringCache
139+
if (cached == null) {
140+
cached = currentProvider.enableAndroidLineHeightCentering()
141+
accessedFeatureFlags.add("enableAndroidLineHeightCentering")
142+
enableAndroidLineHeightCenteringCache = cached
143+
}
144+
return cached
145+
}
146+
136147
override fun enableAndroidMixBlendModeProp(): Boolean {
137148
var cached = enableAndroidMixBlendModePropCache
138149
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<92b1214e3a526d7c67dcc7b0c2a131de>>
7+
* @generated SignedSource<<978d9e8d1129951f3c5750f95e2ff5d2>>
88
*/
99

1010
/**
@@ -35,6 +35,8 @@ public interface ReactNativeFeatureFlagsProvider {
3535

3636
@DoNotStrip public fun enableAlignItemsBaselineOnFabricIOS(): Boolean
3737

38+
@DoNotStrip public fun enableAndroidLineHeightCentering(): Boolean
39+
3840
@DoNotStrip public fun enableAndroidMixBlendModeProp(): Boolean
3941

4042
@DoNotStrip public fun enableBackgroundStyleApplicator(): Boolean

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<c23b21fca18699470580e54b99de1126>>
7+
* @generated SignedSource<<63ef974f6ed666553bc0be593730a08e>>
88
*/
99

1010
/**
@@ -75,6 +75,12 @@ class ReactNativeFeatureFlagsProviderHolder
7575
return method(javaProvider_);
7676
}
7777

78+
bool enableAndroidLineHeightCentering() override {
79+
static const auto method =
80+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableAndroidLineHeightCentering");
81+
return method(javaProvider_);
82+
}
83+
7884
bool enableAndroidMixBlendModeProp() override {
7985
static const auto method =
8086
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableAndroidMixBlendModeProp");
@@ -361,6 +367,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS(
361367
return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS();
362368
}
363369

370+
bool JReactNativeFeatureFlagsCxxInterop::enableAndroidLineHeightCentering(
371+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
372+
return ReactNativeFeatureFlags::enableAndroidLineHeightCentering();
373+
}
374+
364375
bool JReactNativeFeatureFlagsCxxInterop::enableAndroidMixBlendModeProp(
365376
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
366377
return ReactNativeFeatureFlags::enableAndroidMixBlendModeProp();
@@ -606,6 +617,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
606617
makeNativeMethod(
607618
"enableAlignItemsBaselineOnFabricIOS",
608619
JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS),
620+
makeNativeMethod(
621+
"enableAndroidLineHeightCentering",
622+
JReactNativeFeatureFlagsCxxInterop::enableAndroidLineHeightCentering),
609623
makeNativeMethod(
610624
"enableAndroidMixBlendModeProp",
611625
JReactNativeFeatureFlagsCxxInterop::enableAndroidMixBlendModeProp),

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<89d0da3b2bb56a4ee3c887e6c57491b2>>
7+
* @generated SignedSource<<d39aa0038255aedc5613fc2e44b9ad88>>
88
*/
99

1010
/**
@@ -48,6 +48,9 @@ class JReactNativeFeatureFlagsCxxInterop
4848
static bool enableAlignItemsBaselineOnFabricIOS(
4949
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
5050

51+
static bool enableAndroidLineHeightCentering(
52+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
53+
5154
static bool enableAndroidMixBlendModeProp(
5255
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
5356

packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<6139aa47aac3e5682a453a416bc10236>>
7+
* @generated SignedSource<<7c97c370b2f453691c153fb370bea149>>
88
*/
99

1010
/**
@@ -45,6 +45,10 @@ bool ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS() {
4545
return getAccessor().enableAlignItemsBaselineOnFabricIOS();
4646
}
4747

48+
bool ReactNativeFeatureFlags::enableAndroidLineHeightCentering() {
49+
return getAccessor().enableAndroidLineHeightCentering();
50+
}
51+
4852
bool ReactNativeFeatureFlags::enableAndroidMixBlendModeProp() {
4953
return getAccessor().enableAndroidMixBlendModeProp();
5054
}

packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<c8266eb27ec23aaa856fa95275503a81>>
7+
* @generated SignedSource<<c3f43e92b0710e4a68bb76d874b3058d>>
88
*/
99

1010
/**
@@ -67,6 +67,11 @@ class ReactNativeFeatureFlags {
6767
*/
6868
RN_EXPORT static bool enableAlignItemsBaselineOnFabricIOS();
6969

70+
/**
71+
* When enabled, custom line height calculation will be centered from top to bottom.
72+
*/
73+
RN_EXPORT static bool enableAndroidLineHeightCentering();
74+
7075
/**
7176
* Enables mix-blend-mode prop on Android.
7277
*/

0 commit comments

Comments
 (0)