Skip to content

Commit 9c12869

Browse files
Keep minimumFontSize and serialize minimumFontScale under a new MapBuffer key
1 parent da325ad commit 9c12869

9 files changed

Lines changed: 73 additions & 24 deletions

File tree

‎packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ bool ParagraphAttributes::operator==(const ParagraphAttributes& rhs) const {
3333
rhs.includeFontPadding,
3434
rhs.android_hyphenationFrequency,
3535
rhs.textAlignVertical) &&
36+
floatEquality(minimumFontSize, rhs.minimumFontSize) &&
3637
floatEquality(minimumFontScale, rhs.minimumFontScale);
3738
}
3839

@@ -62,6 +63,10 @@ SharedDebugStringConvertibleList ParagraphAttributes::getDebugProps() const {
6263
"minimumFontScale",
6364
minimumFontScale,
6465
paragraphAttributes.minimumFontScale),
66+
debugStringConvertibleItem(
67+
"minimumFontSize",
68+
minimumFontSize,
69+
paragraphAttributes.minimumFontSize),
6570
debugStringConvertibleItem(
6671
"includeFontPadding",
6772
includeFontPadding,

‎packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,17 @@ class ParagraphAttributes : public DebugStringConvertible {
6767
*/
6868
HyphenationFrequency android_hyphenationFrequency{};
6969

70+
/*
71+
* In case of font size adjustment enabled, defines the minimum font size.
72+
* Deprecated in favor of minimumFontScale.
73+
*/
74+
Float minimumFontSize{std::numeric_limits<Float>::quiet_NaN()};
75+
7076
/*
7177
* Specifies the smallest possible scale a font can reach when
7278
* adjustsFontSizeToFit is enabled. (values 0.01-1.0).
7379
*/
74-
Float minimumFontScale{0.0};
80+
Float minimumFontScale{std::numeric_limits<Float>::quiet_NaN()};
7581

7682
/*
7783
* The vertical alignment of the text, causing the glyphs to be vertically
@@ -102,6 +108,7 @@ struct hash<facebook::react::ParagraphAttributes> {
102108
attributes.textBreakStrategy,
103109
attributes.textWidthMode,
104110
attributes.adjustsFontSizeToFit,
111+
attributes.minimumFontSize,
105112
attributes.includeFontPadding,
106113
attributes.android_hyphenationFrequency,
107114
attributes.minimumFontScale,

‎packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,12 @@ inline ParagraphAttributes convertRawProp(
10851085
"minimumFontScale",
10861086
sourceParagraphAttributes.minimumFontScale,
10871087
defaultParagraphAttributes.minimumFontScale);
1088+
paragraphAttributes.minimumFontSize = convertRawProp(
1089+
context,
1090+
rawProps,
1091+
"minimumFontSize",
1092+
sourceParagraphAttributes.minimumFontSize,
1093+
defaultParagraphAttributes.minimumFontSize);
10881094
paragraphAttributes.includeFontPadding = convertRawProp(
10891095
context,
10901096
rawProps,
@@ -1187,9 +1193,10 @@ constexpr static MapBuffer::Key PA_KEY_TEXT_BREAK_STRATEGY = 2;
11871193
constexpr static MapBuffer::Key PA_KEY_ADJUST_FONT_SIZE_TO_FIT = 3;
11881194
constexpr static MapBuffer::Key PA_KEY_INCLUDE_FONT_PADDING = 4;
11891195
constexpr static MapBuffer::Key PA_KEY_HYPHENATION_FREQUENCY = 5;
1190-
constexpr static MapBuffer::Key PA_KEY_MINIMUM_FONT_SCALE = 6;
1196+
constexpr static MapBuffer::Key PA_KEY_MINIMUM_FONT_SIZE = 6;
11911197
constexpr static MapBuffer::Key PA_KEY_TEXT_ALIGN_VERTICAL = 8;
11921198
constexpr static MapBuffer::Key PA_KEY_TEXT_WIDTH_MODE = 9;
1199+
constexpr static MapBuffer::Key PA_KEY_MINIMUM_FONT_SCALE = 10;
11931200

11941201
inline MapBuffer toMapBuffer(const ParagraphAttributes &paragraphAttributes)
11951202
{
@@ -1204,6 +1211,7 @@ inline MapBuffer toMapBuffer(const ParagraphAttributes &paragraphAttributes)
12041211
if (paragraphAttributes.textAlignVertical.has_value()) {
12051212
builder.putString(PA_KEY_TEXT_ALIGN_VERTICAL, toString(*paragraphAttributes.textAlignVertical));
12061213
}
1214+
builder.putDouble(PA_KEY_MINIMUM_FONT_SIZE, paragraphAttributes.minimumFontSize);
12071215
builder.putDouble(PA_KEY_MINIMUM_FONT_SCALE, paragraphAttributes.minimumFontScale);
12081216

12091217
return builder.build();

‎packages/react-native/ReactCommon/react/renderer/attributedstring/tests/ParagraphAttributesTest.cpp‎

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
#include <react/renderer/attributedstring/ParagraphAttributes.h>
1010
#include <react/renderer/attributedstring/conversions.h>
1111

12-
#include <limits>
13-
1412
namespace facebook::react {
1513

16-
// Two freshly default-constructed ParagraphAttributes must compare equal.
14+
// The two Float fields default to NaN, and NaN != NaN under IEEE-754.
15+
// operator== must special-case NaN via floatEquality so two freshly
16+
// default-constructed ParagraphAttributes compare equal.
1717
TEST(
1818
ParagraphAttributesTest,
1919
testOperatorEqualsDefaultConstructedInstancesAreEqual) {
@@ -23,40 +23,52 @@ TEST(
2323
EXPECT_TRUE(a == b);
2424
}
2525

26-
// operator== compares minimumFontScale with an epsilon tolerance (0.005)
27-
// rather than an exact ==. Differences below the epsilon must still compare
28-
// equal; differences well above the epsilon must compare unequal.
26+
// operator== compares Float fields with an epsilon tolerance (0.005) rather
27+
// than an exact ==. Differences below the epsilon must still compare equal;
28+
// differences well above the epsilon must compare unequal.
2929
TEST(
3030
ParagraphAttributesTest,
3131
testOperatorEqualsFloatFieldsUseEpsilonComparison) {
3232
ParagraphAttributes a{};
33+
a.minimumFontSize = 12.0f;
3334
a.minimumFontScale = 0.5f;
3435
auto b = a;
3536

37+
b.minimumFontSize = a.minimumFontSize + 0.001f;
3638
b.minimumFontScale = a.minimumFontScale + 0.001f;
3739
EXPECT_TRUE(a == b);
3840

3941
b = a;
40-
b.minimumFontScale = a.minimumFontScale + 0.1f;
42+
b.minimumFontSize = a.minimumFontSize + 1.0f;
4143
EXPECT_FALSE(a == b);
4244
}
4345

4446
// floatEquality returns true only when *both* operands are NaN or when
45-
// *neither* is. Two NaN minimumFontScale values must compare equal, and a
46-
// NaN-vs-finite mismatch must compare unequal.
47-
TEST(ParagraphAttributesTest, testOperatorEqualsHandlesNaNMinimumFontScale) {
47+
// *neither* is. A NaN-vs-finite mismatch in either float field must
48+
// therefore make the instances unequal, even though both operands are
49+
// "invalid" font sizes.
50+
TEST(
51+
ParagraphAttributesTest,
52+
testOperatorEqualsNaNVsFiniteFloatComparesUnequal) {
4853
ParagraphAttributes withNaN{};
49-
withNaN.minimumFontScale = std::numeric_limits<Float>::quiet_NaN();
50-
auto otherWithNaN = withNaN;
51-
52-
EXPECT_TRUE(withNaN == otherWithNaN);
53-
5454
ParagraphAttributes withFinite{};
55-
withFinite.minimumFontScale = 0.5f;
55+
withFinite.minimumFontSize = 12.0f;
5656

5757
EXPECT_FALSE(withNaN == withFinite);
5858
}
5959

60+
// minimumFontScale defaults to NaN, meaning "unset"; an instance with a scale
61+
// must compare unequal to one without.
62+
TEST(
63+
ParagraphAttributesTest,
64+
testOperatorEqualsNaNVsFiniteMinimumFontScaleComparesUnequal) {
65+
ParagraphAttributes unset{};
66+
ParagraphAttributes withScale{};
67+
withScale.minimumFontScale = 0.5f;
68+
69+
EXPECT_FALSE(unset == withScale);
70+
}
71+
6072
// textAlignVertical is a std::optional; operator== must treat "unset" and
6173
// "set" as distinct, independent of the wrapped value.
6274
TEST(

‎packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ void BaseParagraphProps::setProp(
9898
paragraphAttributes,
9999
minimumFontScale,
100100
"minimumFontScale");
101+
REBUILD_FIELD_SWITCH_CASE(
102+
paDefaults,
103+
value,
104+
paragraphAttributes,
105+
minimumFontSize,
106+
"minimumFontSize");
101107
REBUILD_FIELD_SWITCH_CASE(
102108
paDefaults,
103109
value,

‎packages/react-native/ReactCommon/react/renderer/components/text/platform/android/react/renderer/components/text/HostPlatformParagraphProps.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ folly::dynamic HostPlatformParagraphProps::getDiffProps(
122122
result["minimumFontScale"] = paragraphAttributes.minimumFontScale;
123123
}
124124

125+
if (!floatEquality(
126+
paragraphAttributes.minimumFontSize,
127+
oldProps->paragraphAttributes.minimumFontSize)) {
128+
result["minimumFontSize"] = paragraphAttributes.minimumFontSize;
129+
}
130+
125131
if (paragraphAttributes.includeFontPadding !=
126132
oldProps->paragraphAttributes.includeFontPadding) {
127133
result["includeFontPadding"] = paragraphAttributes.includeFontPadding;

‎packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ void BaseTextInputProps::setProp(
177177
paDefaults,
178178
value,
179179
paragraphAttributes,
180-
minimumFontScale,
181-
"minimumFontScale");
180+
minimumFontSize,
181+
"minimumFontSize");
182182
REBUILD_FIELD_SWITCH_CASE(
183183
paDefaults,
184184
value,

‎packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,9 @@ folly::dynamic AndroidTextInputProps::getDiffProps(
390390
}
391391

392392
if (!floatEquality(
393-
paragraphAttributes.minimumFontScale,
394-
oldProps->paragraphAttributes.minimumFontScale)) {
395-
result["minimumFontScale"] = paragraphAttributes.minimumFontScale;
393+
paragraphAttributes.minimumFontSize,
394+
oldProps->paragraphAttributes.minimumFontSize)) {
395+
result["minimumFontSize"] = paragraphAttributes.minimumFontSize;
396396
}
397397

398398
if (paragraphAttributes.includeFontPadding !=

‎packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,12 @@ - (NSTextStorage *)_textStorageAndLayoutManagerWithAttributesString:(NSAttribute
455455

456456
if (paragraphAttributes.adjustsFontSizeToFit) {
457457
CGFloat maximumFontSize = [self _maximumFontSizeInAttributedString:attributedString];
458-
CGFloat minimumFontSize = MAX(paragraphAttributes.minimumFontScale * maximumFontSize, 4.0);
458+
CGFloat minimumFontSize = 4.0;
459+
if (!isnan(paragraphAttributes.minimumFontSize)) {
460+
minimumFontSize = paragraphAttributes.minimumFontSize;
461+
} else if (!isnan(paragraphAttributes.minimumFontScale)) {
462+
minimumFontSize = MAX(paragraphAttributes.minimumFontScale * maximumFontSize, 4.0);
463+
}
459464
[textStorage scaleFontSizeToFitSize:size minimumFontSize:minimumFontSize maximumFontSize:maximumFontSize];
460465
}
461466

0 commit comments

Comments
 (0)