Modified: trunk/Source/WebCore/ChangeLog (282781 => 282782)
--- trunk/Source/WebCore/ChangeLog 2021-09-20 21:12:34 UTC (rev 282781)
+++ trunk/Source/WebCore/ChangeLog 2021-09-20 21:16:42 UTC (rev 282782)
@@ -1,5 +1,19 @@
2021-09-20 Alan Bujtas <[email protected]>
+ [IFC][Integration] canUseForText should take surrogate pairs into account when checking for directional characters
+ https://bugs.webkit.org/show_bug.cgi?id=230498
+
+ Reviewed by Antti Koivisto.
+
+ In this patch we start using U16_NEXT to properly loop through the characters to find their directions (RTL vs LTR).
+ (Note that this is temporary and will be removed when bidi handling is enabled for IFC)
+
+ * layout/integration/LayoutIntegrationCoverage.cpp:
+ (WebCore::LayoutIntegration::canUseForText):
+ (WebCore::LayoutIntegration::canUseForCharacter): Deleted. These functions have shrunk so much, we don't need to template them anymore.
+
+2021-09-20 Alan Bujtas <[email protected]>
+
[LFC][IFC] Incorrect surrogate handling when dealing with short lines
https://bugs.webkit.org/show_bug.cgi?id=230487
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp (282781 => 282782)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp 2021-09-20 21:12:34 UTC (rev 282781)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp 2021-09-20 21:16:42 UTC (rev 282782)
@@ -397,52 +397,45 @@
}
#endif
-template <typename CharacterType> OptionSet<AvoidanceReason> canUseForCharacter(CharacterType, IncludeReasons);
-
-template<> OptionSet<AvoidanceReason> canUseForCharacter(UChar character, IncludeReasons includeReasons)
+static OptionSet<AvoidanceReason> canUseForText(StringView text, const FontCascade& fontCascade, IncludeReasons includeReasons)
{
OptionSet<AvoidanceReason> reasons;
- UCharDirection direction = u_charDirection(character);
- if (direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC
- || direction == U_RIGHT_TO_LEFT_EMBEDDING || direction == U_RIGHT_TO_LEFT_OVERRIDE
- || direction == U_LEFT_TO_RIGHT_EMBEDDING || direction == U_LEFT_TO_RIGHT_OVERRIDE
- || direction == U_POP_DIRECTIONAL_FORMAT || direction == U_BOUNDARY_NEUTRAL)
- SET_REASON_AND_RETURN_IF_NEEDED(FlowTextHasDirectionCharacter, reasons, includeReasons);
+ auto& primaryFont = fontCascade.primaryFont();
+ auto length = text.length();
- return reasons;
-}
+ auto glpyhIsInPrimaryFont = [&](auto character) {
+ auto glyphData = fontCascade.glyphDataForCharacter(character, false);
+ return glyphData.isValid() && glyphData.font == &primaryFont;
+ };
-template<> OptionSet<AvoidanceReason> canUseForCharacter(LChar, IncludeReasons)
-{
- return { };
-}
+ if (text.is8Bit()) {
+ for (size_t i = 0; i < length; ++i) {
+ if (!glpyhIsInPrimaryFont(text[i]))
+ SET_REASON_AND_RETURN_IF_NEEDED(FlowPrimaryFontIsInsufficient, reasons, includeReasons);
+ }
+ } else {
+ size_t position = 0;
+ while (position < length) {
+ UChar32 character;
+ U16_NEXT(text.characters16(), position, length, character);
-template <typename CharacterType>
-static OptionSet<AvoidanceReason> canUseForText(const CharacterType* text, unsigned length, const FontCascade& fontCascade, IncludeReasons includeReasons)
-{
- OptionSet<AvoidanceReason> reasons;
- auto& primaryFont = fontCascade.primaryFont();
+ if (!glpyhIsInPrimaryFont(character))
+ SET_REASON_AND_RETURN_IF_NEEDED(FlowPrimaryFontIsInsufficient, reasons, includeReasons);
- for (unsigned i = 0; i < length; ++i) {
- auto character = text[i];
- auto characterReasons = canUseForCharacter(character, includeReasons);
- if (characterReasons)
- ADD_REASONS_AND_RETURN_IF_NEEDED(characterReasons, reasons, includeReasons);
-
- auto glyphData = fontCascade.glyphDataForCharacter(character, false);
- if (!glyphData.isValid() || glyphData.font != &primaryFont)
- SET_REASON_AND_RETURN_IF_NEEDED(FlowPrimaryFontIsInsufficient, reasons, includeReasons);
+ auto isRTLDirectional = [&](auto character) {
+ auto direction = u_charDirection(character);
+ return direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC
+ || direction == U_RIGHT_TO_LEFT_EMBEDDING || direction == U_RIGHT_TO_LEFT_OVERRIDE
+ || direction == U_LEFT_TO_RIGHT_EMBEDDING || direction == U_LEFT_TO_RIGHT_OVERRIDE
+ || direction == U_POP_DIRECTIONAL_FORMAT || direction == U_BOUNDARY_NEUTRAL;
+ };
+ if (isRTLDirectional(character))
+ SET_REASON_AND_RETURN_IF_NEEDED(FlowTextHasDirectionCharacter, reasons, includeReasons);
+ }
}
- return reasons;
+ return { };
}
-static OptionSet<AvoidanceReason> canUseForText(StringView text, const FontCascade& fontCascade, IncludeReasons includeReasons)
-{
- if (text.is8Bit())
- return canUseForText(text.characters8(), text.length(), fontCascade, includeReasons);
- return canUseForText(text.characters16(), text.length(), fontCascade, includeReasons);
-}
-
static OptionSet<AvoidanceReason> canUseForFontAndText(const RenderBoxModelObject& container, IncludeReasons includeReasons)
{
OptionSet<AvoidanceReason> reasons;