Commit 151c8374 authored by mitz@apple.com's avatar mitz@apple.com
Browse files

<rdar://problem/8783318> Text emphasis marks should not appear over characters...

<rdar://problem/8783318> Text emphasis marks should not appear over characters that have ruby annotations
https://bugs.webkit.org/show_bug.cgi?id=51267

Reviewed by Darin Adler.

WebCore: 

Test: fast/text/emphasis-avoid-ruby.html

* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::placeBoxesInBlockDirection): Use getEmphasisMarkPosition() to check if
there are text emphasis marks.
(WebCore::InlineFlowBox::addTextBoxVisualOverflow): Ditto.
(WebCore::InlineFlowBox::computeOverAnnotationAdjustment): Ditto.
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::getEmphasisMarkPosition): Added. Returns true and sets the emphasis mark
position if the text is style with emphasis marks and there isn’t a ruby annotation that should
suppress them. Otherwise returns false.
(WebCore::InlineTextBox::paint): Use getEmphasisMarkPosition() to check if emphasis marks should
be painted.
* rendering/InlineTextBox.h:

LayoutTests: 

* fast/text/emphasis-avoid-ruby-expected.checksum: Added.
* fast/text/emphasis-avoid-ruby-expected.png: Added.
* fast/text/emphasis-avoid-ruby-expected.txt: Added.
* fast/text/emphasis-avoid-ruby.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75257 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3e127212
2011-01-07 Dan Bernstein <mitz@apple.com>
Reviewed by Darin Adler.
<rdar://problem/8783318> Text emphasis marks should not appear over characters that have ruby annotations
https://bugs.webkit.org/show_bug.cgi?id=51267
* fast/text/emphasis-avoid-ruby-expected.checksum: Added.
* fast/text/emphasis-avoid-ruby-expected.png: Added.
* fast/text/emphasis-avoid-ruby-expected.txt: Added.
* fast/text/emphasis-avoid-ruby.html: Added.
2011-01-07 Alejandro G. Castro <alex@igalia.com>
 
Reviewed by Martin Robinson.
......
4ef4691a40629a62ad06454f88716821
\ No newline at end of file
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x67
RenderText {#text} at (0,19) size 64x32
text run at (0,19) width 64: "1 "
RenderRuby (inline) {RUBY} at (0,0) size 160x32
RenderRubyRun (anonymous) at (64,19) size 160x48
RenderRubyText {RT} at (0,-19) size 160x19
RenderText {#text} at (51,0) size 57x19
text run at (51,0) width 57: "678"
RenderRubyBase (anonymous) at (0,0) size 160x48
RenderInline {RB} at (0,0) size 160x32
RenderText {#text} at (0,0) size 96x32
text run at (0,0) width 96: "23 "
RenderInline {SPAN} at (0,0) size 64x32
RenderText {#text} at (96,0) size 64x32
text run at (96,0) width 64: "45"
RenderText {#text} at (0,0) size 0x0
RenderBlock {DIV} at (0,75) size 784x48
RenderText {#text} at (0,16) size 64x32
text run at (0,16) width 64: "1 "
RenderRuby (inline) {RUBY} at (0,0) size 160x32
RenderRubyRun (anonymous) at (64,0) size 160x48
RenderRubyText {RT} at (0,0) size 160x0
RenderRubyBase (anonymous) at (0,0) size 160x48
RenderInline {RB} at (0,0) size 160x32
RenderText {#text} at (0,16) size 96x32
text run at (0,16) width 96: "23 "
RenderInline {SPAN} at (0,0) size 64x32
RenderText {#text} at (96,16) size 64x32
text run at (96,16) width 64: "45"
RenderText {#text} at (0,0) size 0x0
RenderBlock {DIV} at (0,131) size 784x51
RenderText {#text} at (0,19) size 64x32
text run at (0,19) width 64: "1 "
RenderRuby (inline) {RUBY} at (0,0) size 160x32
RenderRubyRun (anonymous) at (64,19) size 160x32
RenderRubyText {RT} at (0,-19) size 160x19
RenderText {#text} at (51,0) size 57x19
text run at (51,0) width 57: "678"
RenderRubyBase (anonymous) at (0,0) size 160x32
RenderInline {RB} at (0,0) size 160x32
RenderText {#text} at (0,0) size 96x32
text run at (0,0) width 96: "23 "
RenderInline {SPAN} at (0,0) size 64x32
RenderText {#text} at (96,0) size 64x32
text run at (96,0) width 64: "45"
RenderText {#text} at (0,0) size 0x0
RenderBlock {DIV} at (0,190) size 784x67
RenderText {#text} at (0,0) size 64x32
text run at (0,0) width 64: "1 "
RenderRuby (inline) {RUBY} at (0,0) size 160x32
RenderRubyRun (anonymous) at (64,0) size 160x48
RenderRubyText {RT} at (0,48) size 160x19
RenderText {#text} at (51,0) size 57x19
text run at (51,0) width 57: "678"
RenderRubyBase (anonymous) at (0,0) size 160x48
RenderInline {RB} at (0,0) size 160x32
RenderText {#text} at (0,16) size 96x32
text run at (0,16) width 96: "23 "
RenderInline {SPAN} at (0,0) size 64x32
RenderText {#text} at (96,16) size 64x32
text run at (96,16) width 64: "45"
RenderText {#text} at (0,0) size 0x0
RenderBlock {DIV} at (0,265) size 784x48
RenderText {#text} at (0,16) size 64x32
text run at (0,16) width 64: "1 "
RenderRuby (inline) {RUBY} at (0,0) size 160x32
RenderRubyRun (anonymous) at (64,0) size 160x48
RenderRubyText {RT} at (0,32) size 160x0
RenderRubyBase (anonymous) at (0,0) size 160x48
RenderInline {RB} at (0,0) size 160x32
RenderText {#text} at (0,0) size 96x32
text run at (0,0) width 96: "23 "
RenderInline {SPAN} at (0,0) size 64x32
RenderText {#text} at (96,0) size 64x32
text run at (96,0) width 64: "45"
RenderText {#text} at (0,0) size 0x0
RenderBlock {DIV} at (0,321) size 784x51
RenderText {#text} at (0,0) size 64x32
text run at (0,0) width 64: "1 "
RenderRuby (inline) {RUBY} at (0,0) size 160x32
RenderRubyRun (anonymous) at (64,0) size 160x32
RenderRubyText {RT} at (0,32) size 160x19
RenderText {#text} at (51,0) size 57x19
text run at (51,0) width 57: "678"
RenderRubyBase (anonymous) at (0,0) size 160x32
RenderInline {RB} at (0,0) size 160x32
RenderText {#text} at (0,0) size 96x32
text run at (0,0) width 96: "23 "
RenderInline {SPAN} at (0,0) size 64x32
RenderText {#text} at (96,0) size 64x32
text run at (96,0) width 64: "45"
RenderText {#text} at (0,0) size 0x0
<style>
div { margin: 8px 0; }
span { -webkit-text-emphasis: 'x'; }
.flipped { -webkit-writing-mode: horizontal-bt; }
</style>
<body style="font-family: ahem; font-size: 32px; -webkit-font-smoothing: none;">
<!-- emphasis under, should not be suppressed by ruby -->
<div>
1 <ruby><rb>23 <span style="-webkit-text-emphasis-position: under;">45</span></rb><rt>678</rt></ruby>
</div>
<!-- emphasis over, but no lines in ruby text, should not inhibit emphasis -->
<div>
1 <ruby><rb>23 <span style="-webkit-text-emphasis-position: over;">45</span></rb><rt> </rt></ruby>
</div>
<!-- emphasis over should be suppressed by ruby -->
<div>
1 <ruby><rb>23 <span style="-webkit-text-emphasis-position: over; -webkit-text-emphasis-color: red;">45</span></rb><rt>678</rt></ruby>
</div>
<!-- emphasis under, should not be suppressed by ruby -->
<div class="flipped">
1 <ruby><rb>23 <span style="-webkit-text-emphasis-position: under;">45</span></rb><rt>678</rt></ruby>
</div>
<!-- emphasis over, but no lines in ruby text, should not inhibit emphasis -->
<div class="flipped">
1 <ruby><rb>23 <span style="-webkit-text-emphasis-position: over;">45</span></rb><rt> </rt></ruby>
</div>
<!-- emphasis over should be suppressed by ruby -->
<div class="flipped">
1 <ruby><rb>23 <span style="-webkit-text-emphasis-position: over; -webkit-text-emphasis-color: red;">45</span></rb><rt>678</rt></ruby>
</div>
</body>
2011-01-07 Dan Bernstein <mitz@apple.com>
Reviewed by Darin Adler.
<rdar://problem/8783318> Text emphasis marks should not appear over characters that have ruby annotations
https://bugs.webkit.org/show_bug.cgi?id=51267
Test: fast/text/emphasis-avoid-ruby.html
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::placeBoxesInBlockDirection): Use getEmphasisMarkPosition() to check if
there are text emphasis marks.
(WebCore::InlineFlowBox::addTextBoxVisualOverflow): Ditto.
(WebCore::InlineFlowBox::computeOverAnnotationAdjustment): Ditto.
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::getEmphasisMarkPosition): Added. Returns true and sets the emphasis mark
position if the text is style with emphasis marks and there isn’t a ruby annotation that should
suppress them. Otherwise returns false.
(WebCore::InlineTextBox::paint): Use getEmphasisMarkPosition() to check if emphasis marks should
be painted.
* rendering/InlineTextBox.h:
2011-01-07 Alejandro G. Castro <alex@igalia.com>
 
Reviewed by Martin Robinson.
......
......@@ -643,12 +643,15 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
boxHeight -= (topRubyBaseLeading + bottomRubyBaseLeading);
}
}
if (curr->isInlineTextBox() && curr->renderer()->style(m_firstLine)->textEmphasisMark() != TextEmphasisMarkNone) {
bool emphasisMarkIsOver = curr->renderer()->style(m_firstLine)->textEmphasisPosition() == TextEmphasisPositionOver;
if (emphasisMarkIsOver != curr->renderer()->style(m_firstLine)->isFlippedLinesWritingMode())
hasAnnotationsBefore = true;
else
hasAnnotationsAfter = true;
if (curr->isInlineTextBox()) {
TextEmphasisPosition emphasisMarkPosition;
if (static_cast<InlineTextBox*>(curr)->getEmphasisMarkPosition(curr->renderer()->style(m_firstLine), emphasisMarkPosition)) {
bool emphasisMarkIsOver = emphasisMarkPosition == TextEmphasisPositionOver;
if (emphasisMarkIsOver != curr->renderer()->style(m_firstLine)->isFlippedLinesWritingMode())
hasAnnotationsBefore = true;
else
hasAnnotationsAfter = true;
}
}
if (!setLineTop) {
......@@ -745,9 +748,10 @@ void InlineFlowBox::addTextBoxVisualOverflow(const InlineTextBox* textBox, Glyph
int leftGlyphOverflow = -strokeOverflow - leftGlyphEdge;
int rightGlyphOverflow = strokeOverflow + rightGlyphEdge;
if (style->textEmphasisMark() != TextEmphasisMarkNone) {
TextEmphasisPosition emphasisMarkPosition;
if (style->textEmphasisMark() != TextEmphasisMarkNone && textBox->getEmphasisMarkPosition(style, emphasisMarkPosition)) {
int emphasisMarkHeight = style->font().emphasisMarkHeight(style->textEmphasisMarkString());
if ((style->textEmphasisPosition() == TextEmphasisPositionOver) == (!style->isFlippedLinesWritingMode()))
if ((emphasisMarkPosition == TextEmphasisPositionOver) == (!style->isFlippedLinesWritingMode()))
topGlyphOverflow = min(topGlyphOverflow, -emphasisMarkHeight);
else
bottomGlyphOverflow = max(bottomGlyphOverflow, emphasisMarkHeight);
......@@ -1292,7 +1296,8 @@ int InlineFlowBox::computeOverAnnotationAdjustment(int allowedPosition) const
if (curr->isInlineTextBox()) {
RenderStyle* style = curr->renderer()->style(m_firstLine);
if (style->textEmphasisMark() != TextEmphasisMarkNone && style->textEmphasisPosition() == TextEmphasisPositionOver) {
TextEmphasisPosition emphasisMarkPosition;
if (style->textEmphasisMark() != TextEmphasisMarkNone && static_cast<InlineTextBox*>(curr)->getEmphasisMarkPosition(style, emphasisMarkPosition) && emphasisMarkPosition == TextEmphasisPositionOver) {
if (!style->isFlippedLinesWritingMode()) {
int topOfEmphasisMark = curr->logicalTop() - style->font().emphasisMarkHeight(style->textEmphasisMarkString());
result = max(result, allowedPosition - topOfEmphasisMark);
......
......@@ -35,6 +35,8 @@
#include "Page.h"
#include "RenderArena.h"
#include "RenderBlock.h"
#include "RenderRubyRun.h"
#include "RenderRubyText.h"
#include "RenderTheme.h"
#include "Text.h"
#include "break_lines.h"
......@@ -400,6 +402,29 @@ static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
} while (shadow || stroked || !opaque);
}
bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosition& emphasisPosition) const
{
// This function returns true if there are text emphasis marks and they are suppressed by ruby text.
if (style->textEmphasisMark() == TextEmphasisMarkNone)
return false;
emphasisPosition = style->textEmphasisPosition();
if (emphasisPosition == TextEmphasisPositionUnder)
return true; // Ruby text is always over, so it cannot suppress emphasis marks under.
RenderBlock* containingBlock = renderer()->containingBlock();
if (!containingBlock->isRubyBase())
return true; // This text is not inside a ruby base, so it does not have ruby text over it.
if (!containingBlock->parent()->isRubyRun())
return true; // Cannot get the ruby text.
RenderRubyText* rubyText = static_cast<RenderRubyRun*>(containingBlock->parent())->rubyText();
// The emphasis marks over are suppressed only if there is a ruby text box and it not empty.
return !rubyText || !rubyText->firstLineBox();
}
void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
{
if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE ||
......@@ -595,13 +620,11 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
}
int emphasisMarkOffset = 0;
const AtomicString& emphasisMark = styleToUse->textEmphasisMarkString();
if (!emphasisMark.isEmpty()) {
if (styleToUse->textEmphasisPosition() == TextEmphasisPositionOver)
emphasisMarkOffset = -font.ascent() - font.emphasisMarkDescent(emphasisMark);
else
emphasisMarkOffset = font.descent() + font.emphasisMarkAscent(emphasisMark);
}
TextEmphasisPosition emphasisMarkPosition;
bool hasTextEmphasis = getEmphasisMarkPosition(styleToUse, emphasisMarkPosition);
const AtomicString& emphasisMark = hasTextEmphasis ? styleToUse->textEmphasisMarkString() : nullAtom;
if (!emphasisMark.isEmpty())
emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.ascent() - font.emphasisMarkDescent(emphasisMark) : font.descent() + font.emphasisMarkAscent(emphasisMark);
if (!paintSelectedTextOnly) {
// For stroked painting, we have to change the text drawing mode. It's probably dangerous to leave that mutated as a side
......
......@@ -70,10 +70,11 @@ public:
void setHasHyphen(bool hasHyphen) { m_hasEllipsisBoxOrHyphen = hasHyphen; }
static inline bool compareByStart(const InlineTextBox* first, const InlineTextBox* second) { return first->start() < second->start(); }
virtual int baselinePosition(FontBaseline) const;
virtual int lineHeight() const;
bool getEmphasisMarkPosition(RenderStyle*, TextEmphasisPosition&) const;
private:
int selectionTop();
int selectionBottom();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment