Skip to content

Commit

Permalink
Cherry-pick b8f448e. rdar://122663646
Browse files Browse the repository at this point in the history
    [IFC][Ruby] Failure to line break before/between ruby sequences
    https://bugs.webkit.org/show_bug.cgi?id=271209
    <rdar://122663646>

    Reviewed by Antti Koivisto.

    Not all "do not break before" characters have "do not break after" meaning. (e.g. no line should begin with KATAKANA MIDDLE DOT but it's ok to have it at the end of the line).
    Let's divide them into 2 categories as seen in https://www.w3.org/TR/jlreq.

    *LayoutTests/fast/ruby/ruby-with-unbreakable-characters-incorrect-width.html: use different punctuation to force line breaking at the right position.
    * LayoutTests/fast/ruby/can-break-before-after-expected.html: Added.
    * LayoutTests/fast/ruby/can-break-before-after.html: Added.
    * Source/WebCore/layout/formattingContexts/inline/ruby/RubyFormattingContext.cpp:
    (WebCore::Layout::canBreakBefore):
    (WebCore::Layout::canBreakAfter):
    (WebCore::Layout::RubyFormattingContext::isAtSoftWrapOpportunity):
    (WebCore::Layout::canBreakAtCharacter): Deleted.

    Canonical link: https://commits.webkit.org/276353@main

Identifier: 272448.821@safari-7618-branch
  • Loading branch information
alanbaradlay authored and drobson1005 committed Mar 29, 2024
1 parent f3567ff commit 2368888
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
12 changes: 12 additions & 0 deletions LayoutTests/fast/ruby/can-break-before-after-expected.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<meta charset="utf8">
<style>
div {
font-family: Ahem;
text-align-last: justify;
font-size: 20px;
width: 380px;
}
</style>
<div>X X X X ・<ruby>b a s e</ruby></div>
<div><ruby>b a s e</ruby></div>
<pre>PASS if ・ is not at the start of 'base...' line</pre>
11 changes: 11 additions & 0 deletions LayoutTests/fast/ruby/can-break-before-after.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<meta charset="utf8">
<style>
div {
font-family: Ahem;
text-align: justify;
font-size: 20px;
width: 380px;
}
</style>
<div>X X X X ・<ruby>b a s e</ruby><ruby>b a s e</ruby></div>
<pre>PASS if ・ is not at the start of 'base...' line</pre>
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
}
</style>
<!-- PASS if all content is inside the green box -->
<div><ruby>XX<rt>XXXXXX</rt></ruby> <ruby>X<rt>XXX</rt></ruby><ruby>X<rt>XXX</rt></ruby><ruby>XXXX</ruby></div>
<div><ruby>XX<rt>XXXXXX</rt></ruby> <ruby>X<rt>XXX</rt></ruby><ruby>X<rt>XXX</rt></ruby><ruby>XXXX</ruby></div>
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ static bool annotationOverlapCheck(const InlineDisplay::Box& adjacentDisplayBox,
return false;
}

static bool canBreakAtCharacter(UChar character)
static bool canBreakBefore(UChar character)
{
auto lineBreak = (ULineBreak)u_getIntPropertyValue(character, UCHAR_LINE_BREAK);
// UNICODE LINE BREAKING ALGORITHM
// http://www.unicode.org/reports/tr14/
// And Requirements for Japanese Text Layout, 3.1.7 Characters Not Starting a Line
// http://www.w3.org/TR/2012/NOTE-jlreq-20120403/#characters_not_starting_a_line
// https://www.w3.org/TR/jlreq/#characters_not_starting_a_line
switch (lineBreak) {
case U_LB_NONSTARTER:
case U_LB_CLOSE_PARENTHESIS:
Expand Down Expand Up @@ -148,6 +148,33 @@ static bool canBreakAtCharacter(UChar character)
return true;
}

static bool canBreakAfter(UChar character)
{
// https://www.w3.org/TR/jlreq/#characters_not_ending_a_line
switch (character) {
case 0x2018: // LEFT SINGLE QUOTATION MARK
case 0x201C: // LEFT DOUBLE QUOTATION MARK
case 0x0028: // LEFT PARENTHESIS
case 0x3014: // LEFT TORTOISE SHELL BRACKET
case 0x005B: // LEFT SQUARE BRACKET
case 0x007B: // LEFT CURLY BRACKET
case 0x3008: // LEFT ANGLE BRACKET
case 0x300A: // LEFT DOUBLE ANGLE BRACKET
case 0x300C: // LEFT CORNER BRACKET
case 0x300E: // LEFT WHITE CORNER BRACKET
case 0x3010: // LEFT BLACK LENTICULAR BRACKET
case 0x2985: // LEFT WHITE PARENTHESIS
case 0x3018: // LEFT WHITE TORTOISE SHELL BRACKET
case 0x3016: // LEFT WHITE LENTICULAR BRACKET
case 0x00AB: // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
case 0x301D: // REVERSED DOUBLE PRIME QUOTATION MARK
return false;
default:
break;
}
return true;
}

bool RubyFormattingContext::isAtSoftWrapOpportunity(const InlineItem& previous, const InlineItem& current)
{
auto& previousLayoutBox = previous.layoutBox();
Expand All @@ -167,7 +194,7 @@ bool RubyFormattingContext::isAtSoftWrapOpportunity(const InlineItem& previous,
return true;
}
auto lastCharacter = leadingTextItem.inlineTextBox().content()[leadingTextItem.end() - 1];
return canBreakAtCharacter(lastCharacter);
return canBreakAfter(lastCharacter);
}
// Don't break between base end and <ruby> end.
return false;
Expand All @@ -191,7 +218,7 @@ bool RubyFormattingContext::isAtSoftWrapOpportunity(const InlineItem& previous,
return true;
}
auto firstCharacter = trailingTextItem.inlineTextBox().content()[trailingTextItem.start()];
return canBreakAtCharacter(firstCharacter);
return canBreakBefore(firstCharacter);
}
// We should handled this case already when looking at current: base, previous: ruby.
ASSERT_NOT_REACHED();
Expand Down

0 comments on commit 2368888

Please sign in to comment.