@@ -136,54 +136,68 @@ enum class IncludeReasons { First , All };
136
136
}
137
137
#endif
138
138
139
+
140
+ template <typename CharacterType> AvoidanceReasonFlags canUseForCharacter (CharacterType, bool textIsJustified, IncludeReasons);
141
+
142
+ template <> AvoidanceReasonFlags canUseForCharacter (UChar character, bool textIsJustified, IncludeReasons includeReasons)
143
+ {
144
+ AvoidanceReasonFlags reasons = { };
145
+ if (textIsJustified) {
146
+ // Include characters up to Latin Extended-B and some punctuation range when text is justified.
147
+ bool isLatinIncludingExtendedB = character <= 0x01FF ;
148
+ bool isPunctuationRange = character >= 0x2010 && character <= 0x2027 ;
149
+ if (!(isLatinIncludingExtendedB || isPunctuationRange))
150
+ SET_REASON_AND_RETURN_IF_NEEDED (FlowHasJustifiedNonLatinText, reasons, includeReasons);
151
+ }
152
+
153
+ UCharDirection direction = u_charDirection (character);
154
+ if (direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC
155
+ || direction == U_RIGHT_TO_LEFT_EMBEDDING || direction == U_RIGHT_TO_LEFT_OVERRIDE
156
+ || direction == U_LEFT_TO_RIGHT_EMBEDDING || direction == U_LEFT_TO_RIGHT_OVERRIDE
157
+ || direction == U_POP_DIRECTIONAL_FORMAT || direction == U_BOUNDARY_NEUTRAL)
158
+ SET_REASON_AND_RETURN_IF_NEEDED (FlowTextHasDirectionCharacter, reasons, includeReasons);
159
+
160
+ return reasons;
161
+ }
162
+
163
+ template <> AvoidanceReasonFlags canUseForCharacter (LChar, bool , IncludeReasons)
164
+ {
165
+ return { };
166
+ }
167
+
139
168
template <typename CharacterType>
140
169
static AvoidanceReasonFlags canUseForText (const CharacterType* text, unsigned length, const FontCascade& fontCascade, std::optional<float > lineHeightConstraint,
141
170
bool textIsJustified, IncludeReasons includeReasons)
142
171
{
143
172
AvoidanceReasonFlags reasons = { };
144
173
auto & primaryFont = fontCascade.primaryFont ();
145
- // FIXME: <textarea maxlength=0> generates empty text node.
146
- if (!length)
147
- SET_REASON_AND_RETURN_IF_NEEDED (FlowTextIsEmpty, reasons, includeReasons);
148
-
149
174
for (unsigned i = 0 ; i < length; ++i) {
150
- UChar character = text[i];
151
- if (character == ' ' )
175
+ auto character = text[i];
176
+ if (FontCascade::treatAsSpace ( character) )
152
177
continue ;
153
178
154
- if (textIsJustified) {
155
- // Include characters up to Latin Extended-B and some punctuation range when text is justified.
156
- bool isLatinIncludingExtendedB = character <= 0x01FF ;
157
- bool isPunctuationRange = character >= 0x2010 && character <= 0x2027 ;
158
- if (!(isLatinIncludingExtendedB || isPunctuationRange))
159
- SET_REASON_AND_RETURN_IF_NEEDED (FlowHasJustifiedNonLatinText, reasons, includeReasons);
160
- }
161
-
162
179
if (character == softHyphen)
163
180
SET_REASON_AND_RETURN_IF_NEEDED (FlowTextHasSoftHyphen, reasons, includeReasons);
164
181
165
- UCharDirection direction = u_charDirection (character);
166
- if (direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC
167
- || direction == U_RIGHT_TO_LEFT_EMBEDDING || direction == U_RIGHT_TO_LEFT_OVERRIDE
168
- || direction == U_LEFT_TO_RIGHT_EMBEDDING || direction == U_LEFT_TO_RIGHT_OVERRIDE
169
- || direction == U_POP_DIRECTIONAL_FORMAT || direction == U_BOUNDARY_NEUTRAL)
170
- SET_REASON_AND_RETURN_IF_NEEDED (FlowTextHasDirectionCharacter, reasons, includeReasons);
171
-
172
182
auto glyphData = fontCascade.glyphDataForCharacter (character, false );
173
183
if (!glyphData.isValid () || glyphData.font != &primaryFont)
174
184
SET_REASON_AND_RETURN_IF_NEEDED (FlowPrimaryFontIsInsufficient, reasons, includeReasons);
175
185
176
186
if (lineHeightConstraint && primaryFont.boundsForGlyph (glyphData.glyph ).height () > *lineHeightConstraint)
177
187
SET_REASON_AND_RETURN_IF_NEEDED (FlowFontHasOverflowGlyph, reasons, includeReasons);
188
+
189
+ auto characterReasons = canUseForCharacter (character, textIsJustified, includeReasons);
190
+ if (characterReasons != NoReason)
191
+ SET_REASON_AND_RETURN_IF_NEEDED (characterReasons, reasons, includeReasons);
178
192
}
179
193
return reasons;
180
194
}
181
195
182
- static AvoidanceReasonFlags canUseForText (const RenderText& textRenderer , const FontCascade& fontCascade, std::optional<float > lineHeightConstraint, bool textIsJustified, IncludeReasons includeReasons)
196
+ static AvoidanceReasonFlags canUseForText (StringView text , const FontCascade& fontCascade, std::optional<float > lineHeightConstraint, bool textIsJustified, IncludeReasons includeReasons)
183
197
{
184
- if (textRenderer .is8Bit ())
185
- return canUseForText (textRenderer .characters8 (), textRenderer. textLength (), fontCascade, lineHeightConstraint, false , includeReasons);
186
- return canUseForText (textRenderer .characters16 (), textRenderer. textLength (), fontCascade, lineHeightConstraint, textIsJustified, includeReasons);
198
+ if (text .is8Bit ())
199
+ return canUseForText (text .characters8 (), text. length (), fontCascade, lineHeightConstraint, textIsJustified , includeReasons);
200
+ return canUseForText (text .characters16 (), text. length (), fontCascade, lineHeightConstraint, textIsJustified, includeReasons);
187
201
}
188
202
189
203
static AvoidanceReasonFlags canUseForFontAndText (const RenderBlockFlow& flow, IncludeReasons includeReasons)
@@ -199,6 +213,9 @@ static AvoidanceReasonFlags canUseForFontAndText(const RenderBlockFlow& flow, In
199
213
lineHeightConstraint = lineHeightFromFlow (flow).toFloat ();
200
214
bool flowIsJustified = style.textAlign () == JUSTIFY;
201
215
for (const auto & textRenderer : childrenOfType<RenderText>(flow)) {
216
+ // FIXME: Do not return until after checking all children.
217
+ if (!textRenderer.textLength ())
218
+ SET_REASON_AND_RETURN_IF_NEEDED (FlowTextIsEmpty, reasons, includeReasons);
202
219
if (textRenderer.isCombineText ())
203
220
SET_REASON_AND_RETURN_IF_NEEDED (FlowTextIsCombineText, reasons, includeReasons);
204
221
if (textRenderer.isCounter ())
@@ -212,7 +229,7 @@ static AvoidanceReasonFlags canUseForFontAndText(const RenderBlockFlow& flow, In
212
229
if (!textRenderer.canUseSimpleFontCodePath ())
213
230
SET_REASON_AND_RETURN_IF_NEEDED (FlowHasComplexFontCodePath, reasons, includeReasons);
214
231
215
- auto textReasons = canUseForText (textRenderer, fontCascade, lineHeightConstraint, flowIsJustified, includeReasons);
232
+ auto textReasons = canUseForText (textRenderer. stringView () , fontCascade, lineHeightConstraint, flowIsJustified, includeReasons);
216
233
if (textReasons != NoReason)
217
234
SET_REASON_AND_RETURN_IF_NEEDED (textReasons, reasons, includeReasons);
218
235
}
0 commit comments