Skip to content
Permalink
Browse files
https://bugs.webkit.org/show_bug.cgi?id=48001
Reviewed by Dan Bernstein.

Make boxes place themselves properly in the block direction.  Get basic painting working for spans and add a test that
verifies that span painting and replaced element painting (like images) works correctly.

Added fast/blockflow/basic-vertical-line.html

WebCore:

* rendering/InlineBox.cpp:
(WebCore::InlineBox::logicalHeight):
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::placeBoxesInInlineDirection):
(WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
(WebCore::verticalPositionForBox):
(WebCore::InlineFlowBox::computeLogicalBoxHeights):
(WebCore::InlineFlowBox::placeBoxesInBlockDirection):
(WebCore::InlineFlowBox::flipLinesInBlockDirection):
(WebCore::InlineFlowBox::paintBoxDecorations):
(WebCore::InlineFlowBox::paintMask):
* rendering/InlineFlowBox.h:
* rendering/style/RenderStyle.h:
(WebCore::InheritedFlags::isFlippedLinesWritingMode):

LayoutTests:

* fast/blockflow/basic-vertical-line.html: Added.
* platform/mac/fast/blockflow/basic-vertical-line-expected.checksum: Added.
* platform/mac/fast/blockflow/basic-vertical-line-expected.png: Added.
* platform/mac/fast/blockflow/basic-vertical-line-expected.txt: Added.



Canonical link: https://commits.webkit.org/60723@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@70172 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
David Hyatt committed Oct 20, 2010
1 parent a233a42 commit e7cf193ed9850f8e3eef86b56621437c1980cbde
Showing 10 changed files with 140 additions and 41 deletions.
@@ -1,3 +1,19 @@
2010-10-20 David Hyatt <hyatt@apple.com>

Reviewed by Dan Bernstein.

https://bugs.webkit.org/show_bug.cgi?id=48001

Make boxes place themselves properly in the block direction. Get basic painting working for spans and add a test that
verifies that span painting and replaced element painting (like images) works correctly.

Added fast/blockflow/basic-vertical-line.html

* fast/blockflow/basic-vertical-line.html: Added.
* platform/mac/fast/blockflow/basic-vertical-line-expected.checksum: Added.
* platform/mac/fast/blockflow/basic-vertical-line-expected.png: Added.
* platform/mac/fast/blockflow/basic-vertical-line-expected.txt: Added.

2010-10-20 Beth Dakin <bdakin@apple.com>

Reviewed by Dave Hyatt.
@@ -0,0 +1,8 @@
<div style="-webkit-writing-mode: vertical-lr; height:300px; border:2px solid maroon">
<span style="border-top: 5px solid black; border-bottom:5px solid black; padding-top:5px; padding-bottom:5px"><img style="height:200px;width:100px;background-color:green"></span>
<br>
<span style="border-top: 5px solid black; border-bottom:5px solid black; padding-top:5px; padding-bottom:5px"><img style="height:200px;width:100px;background-color:green"></span>
<br>
<span style="border-top: 5px solid black; border-bottom:5px solid black; padding-top:5px; padding-bottom:5px"><img style="height:200px;width:100px;background-color:green"></span>
</div>

@@ -0,0 +1 @@
f149a6f8dd8b17bffdc42eb7cbd66e40
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,19 @@
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 316x304 [border: (2px solid #800000)]
RenderInline {SPAN} at (0,0) size 220x18 [border: (5px solid #000000) none (5px solid #000000) none]
RenderImage {IMG} at (6,12) size 100x200 [bgcolor=#008000]
RenderText {#text} at (2,222) size 4x18
text run at (2,222) width 4: " "
RenderBR {BR} at (6,226) size 0x0
RenderInline {SPAN} at (0,0) size 220x18 [border: (5px solid #000000) none (5px solid #000000) none]
RenderImage {IMG} at (110,12) size 100x200 [bgcolor=#008000]
RenderText {#text} at (106,222) size 4x18
text run at (106,222) width 4: " "
RenderBR {BR} at (110,226) size 0x0
RenderInline {SPAN} at (0,0) size 220x18 [border: (5px solid #000000) none (5px solid #000000) none]
RenderImage {IMG} at (214,12) size 100x200 [bgcolor=#008000]
RenderText {#text} at (0,0) size 0x0
@@ -1,3 +1,29 @@
2010-10-20 David Hyatt <hyatt@apple.com>

Reviewed by Dan Bernstein.

https://bugs.webkit.org/show_bug.cgi?id=48001

Make boxes place themselves properly in the block direction. Get basic painting working for spans and add a test that
verifies that span painting and replaced element painting (like images) works correctly.

Added fast/blockflow/basic-vertical-line.html

* rendering/InlineBox.cpp:
(WebCore::InlineBox::logicalHeight):
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::placeBoxesInInlineDirection):
(WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
(WebCore::verticalPositionForBox):
(WebCore::InlineFlowBox::computeLogicalBoxHeights):
(WebCore::InlineFlowBox::placeBoxesInBlockDirection):
(WebCore::InlineFlowBox::flipLinesInBlockDirection):
(WebCore::InlineFlowBox::paintBoxDecorations):
(WebCore::InlineFlowBox::paintMask):
* rendering/InlineFlowBox.h:
* rendering/style/RenderStyle.h:
(WebCore::InheritedFlags::isFlippedLinesWritingMode):

2010-10-20 Beth Dakin <bdakin@apple.com>

Reviewed by Dave Hyatt.
@@ -95,14 +95,14 @@ int InlineBox::logicalHeight() const
if (renderer()->isText())
return m_isText ? renderer()->style(m_firstLine)->font().height() : 0;
if (renderer()->isBox() && parent())
return toRenderBox(m_renderer)->height();
return m_isVertical ? toRenderBox(m_renderer)->width() : toRenderBox(m_renderer)->height();

ASSERT(isInlineFlowBox());
RenderBoxModelObject* flowObject = boxModelObject();
const Font& font = renderer()->style(m_firstLine)->font();
int result = font.height();
if (parent())
result += flowObject->borderAndPaddingHeight();
result += flowObject->borderAndPaddingLogicalHeight();
return result;
}

@@ -332,7 +332,7 @@ int InlineFlowBox::placeBoxesInInlineDirection(int logicalLeft, bool& needsWordS
int logicalRightMargin = !isVertical() ? curr->boxModelObject()->marginRight() : curr->boxModelObject()->marginBottom();

logicalLeft += logicalLeftMargin;
curr->setX(logicalLeft);
curr->setLogicalLeft(logicalLeft);

RenderBox* box = toRenderBox(curr->renderer());

@@ -367,9 +367,9 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
// positioned elements
if (curr->renderer()->isPositioned())
continue; // Positioned placeholders don't affect calculations.
if (curr->y() == PositionTop || curr->y() == PositionBottom) {
if (curr->logicalTop() == PositionTop || curr->logicalTop() == PositionBottom) {
int lineHeight = curr->lineHeight();
if (curr->y() == PositionTop) {
if (curr->logicalTop() == PositionTop) {
if (maxAscent + maxDescent < lineHeight)
maxDescent = lineHeight - maxAscent;
}
@@ -390,7 +390,7 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
static int verticalPositionForBox(InlineBox* curr, bool firstLine)
{
if (curr->renderer()->isText())
return curr->parent()->y();
return curr->parent()->logicalTop();
if (curr->renderer()->isBox())
return toRenderBox(curr->renderer())->verticalPosition(firstLine);
return toRenderInline(curr->renderer())->verticalPositionFromCache(firstLine);
@@ -459,15 +459,15 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
baseline = curr->baselinePosition();
}

curr->setY(verticalPositionForBox(curr, m_firstLine));
if (curr->y() == PositionTop) {
curr->setLogicalTop(verticalPositionForBox(curr, m_firstLine));
if (curr->logicalTop() == PositionTop) {
if (maxPositionTop < lineHeight)
maxPositionTop = lineHeight;
} else if (curr->y() == PositionBottom) {
} else if (curr->logicalTop() == PositionBottom) {
if (maxPositionBottom < lineHeight)
maxPositionBottom = lineHeight;
} else if ((!isInlineFlow || static_cast<InlineFlowBox*>(curr)->hasTextChildren()) || curr->boxModelObject()->hasInlineDirectionBordersOrPadding() || strictMode) {
int ascent = baseline - curr->y();
int ascent = baseline - curr->logicalTop();
int descent = lineHeight - ascent;
if (maxAscent < ascent)
maxAscent = ascent;
@@ -480,10 +480,10 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
}
}

void InlineFlowBox::placeBoxesInBlockDirection(int yPos, int maxHeight, int maxAscent, bool strictMode, int& selectionTop, int& selectionBottom)
void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom)
{
if (isRootInlineBox())
setY(yPos + maxAscent - baselinePosition()); // Place our root box.
setLogicalTop(top + maxAscent - baselinePosition()); // Place our root box.

for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
if (curr->renderer()->isPositioned())
@@ -493,47 +493,70 @@ void InlineFlowBox::placeBoxesInBlockDirection(int yPos, int maxHeight, int maxA
// line-height).
bool isInlineFlow = curr->isInlineFlowBox();
if (isInlineFlow)
static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(yPos, maxHeight, maxAscent, strictMode, selectionTop, selectionBottom);
static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom);

bool childAffectsTopBottomPos = true;
if (curr->y() == PositionTop)
curr->setY(yPos);
else if (curr->y() == PositionBottom)
curr->setY(yPos + maxHeight - curr->lineHeight());
if (curr->logicalTop() == PositionTop)
curr->setLogicalTop(top);
else if (curr->logicalTop() == PositionBottom)
curr->setLogicalTop(top + maxHeight - curr->lineHeight());
else {
if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !strictMode)
childAffectsTopBottomPos = false;
int posAdjust = maxAscent - curr->baselinePosition();
curr->setY(curr->y() + yPos + posAdjust);
curr->setLogicalTop(curr->logicalTop() + top + posAdjust);
}

int newY = curr->y();
int newLogicalTop = curr->logicalTop();
if (curr->isText() || curr->isInlineFlowBox()) {
const Font& font = curr->renderer()->style(m_firstLine)->font();
newY += curr->baselinePosition() - font.ascent();
if (curr->isInlineFlowBox())
newY -= curr->boxModelObject()->borderTop() + curr->boxModelObject()->paddingTop();
newLogicalTop += curr->baselinePosition() - font.ascent();
if (curr->isInlineFlowBox()) {
RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer());
newLogicalTop -= boxObject->style(m_firstLine)->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() :
boxObject->borderRight() + boxObject->paddingRight();
}
} else if (!curr->renderer()->isBR()) {
RenderBox* box = toRenderBox(curr->renderer());
newY += box->marginTop();
newLogicalTop += box->style(m_firstLine)->isHorizontalWritingMode() ? box->marginTop() : box->marginRight();
}

curr->setY(newY);
curr->setLogicalTop(newLogicalTop);

if (childAffectsTopBottomPos) {
int boxHeight = curr->logicalHeight();
selectionTop = min(selectionTop, newY);
selectionBottom = max(selectionBottom, newY + boxHeight);
lineTop = min(lineTop, newLogicalTop);
lineBottom = max(lineBottom, newLogicalTop + boxHeight);
}
}

if (isRootInlineBox()) {
const Font& font = renderer()->style(m_firstLine)->font();
setY(y() + baselinePosition() - font.ascent());
setLogicalTop(logicalTop() + baselinePosition() - font.ascent());

if (hasTextChildren() || strictMode) {
selectionTop = min(selectionTop, y());
selectionBottom = max(selectionBottom, y() + logicalHeight());
lineTop = min(lineTop, logicalTop());
lineBottom = max(lineBottom, logicalTop() + logicalHeight());
}

if (renderer()->style()->isFlippedLinesWritingMode())
flipLinesInBlockDirection(lineTop, lineBottom);
}
}

void InlineFlowBox::flipLinesInBlockDirection(int lineTop, int lineBottom)
{
// Flip the box on the line such that the top is now relative to the lineBottom instead of the lineTop.
setLogicalTop(lineBottom - (logicalTop() - lineTop) - logicalHeight());

for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
if (curr->renderer()->isPositioned())
continue; // Positioned placeholders aren't affected here.

if (curr->isInlineFlowBox())
static_cast<InlineFlowBox*>(curr)->flipLinesInBlockDirection(lineTop, lineBottom);
else
curr->setLogicalTop(lineBottom - (curr->logicalTop() - lineTop) - curr->logicalHeight());
}
}

@@ -762,16 +785,18 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)

int x = m_x;
int y = m_y;
int w = logicalWidth();
int h = logicalHeight();
int w = m_isVertical ? logicalHeight() : logicalWidth();
int h = m_isVertical ? logicalWidth() : logicalHeight();

// Constrain our background/border painting to the line top and bottom if necessary.
bool noQuirksMode = renderer()->document()->inNoQuirksMode();
if (!hasTextChildren() && !noQuirksMode) {
RootInlineBox* rootBox = root();
int bottom = min(rootBox->lineBottom(), y + h);
y = max(rootBox->lineTop(), y);
h = bottom - y;
int& top = m_isVertical ? x : y;
int& logicalHeight = m_isVertical ? w : h;
int bottom = min(rootBox->lineBottom(), top + logicalHeight);
top = max(rootBox->lineTop(), top);
logicalHeight = bottom - top;
}

// Move x/y to our coordinates.
@@ -838,16 +863,18 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, int tx, int ty)

int x = m_x;
int y = m_y;
int w = logicalWidth();
int h = logicalHeight();
int w = m_isVertical ? logicalHeight() : logicalWidth();
int h = m_isVertical ? logicalWidth() : logicalHeight();

// Constrain our background/border painting to the line top and bottom if necessary.
bool noQuirksMode = renderer()->document()->inNoQuirksMode();
if (!hasTextChildren() && !noQuirksMode) {
RootInlineBox* rootBox = root();
int bottom = min(rootBox->lineBottom(), y + h);
y = max(rootBox->lineTop(), y);
h = bottom - y;
int& top = m_isVertical ? x : y;
int& logicalHeight = m_isVertical ? w : h;
int bottom = min(rootBox->lineBottom(), top + logicalHeight);
top = max(rootBox->lineTop(), top);
logicalHeight = bottom - top;
}

// Move x/y to our coordinates.
@@ -154,12 +154,13 @@ class InlineFlowBox : public InlineBox {
void determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject);
int getFlowSpacingLogicalWidth();
bool onEndChain(RenderObject* endObject);
int placeBoxesInInlineDirection(int x, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
int placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
int& maxAscent, int& maxDescent, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
int maxPositionTop, int maxPositionBottom);
void placeBoxesInBlockDirection(int y, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom);
void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom);
void flipLinesInBlockDirection(int lineTop, int lineBottom);
void computeBlockDirectionOverflow(int lineTop, int lineBottom, bool strictMode, GlyphOverflowAndFallbackFontsMap&);

void removeChild(InlineBox* child);
@@ -751,6 +751,7 @@ class RenderStyle: public RefCounted<RenderStyle> {

WritingMode writingMode() const { return static_cast<WritingMode>(inherited_flags.m_writingMode); }
bool isHorizontalWritingMode() const { return writingMode() == TopToBottomWritingMode || writingMode() == BottomToTopWritingMode; }
bool isFlippedLinesWritingMode() const { return writingMode() == LeftToRightWritingMode || writingMode() == BottomToTopWritingMode; }

ESpeak speak() { return static_cast<ESpeak>(rareInheritedData->speak); }

0 comments on commit e7cf193

Please sign in to comment.