WebCore/ChangeLog

 12010-10-20 David Hyatt <hyatt@apple.com>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 https://bugs.webkit.org/show_bug.cgi?id=48001
 6
 7 Make boxes place themselves properly in the block direction. Get basic painting working for spans and add a test that
 8 verifies that span painting and replaced element painting (like images) works correctly.
 9
 10 Added fast/blockflow/basic-vertical-line.html
 11
 12 * rendering/InlineBox.cpp:
 13 (WebCore::InlineBox::logicalHeight):
 14 * rendering/InlineFlowBox.cpp:
 15 (WebCore::InlineFlowBox::placeBoxesInInlineDirection):
 16 (WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
 17 (WebCore::verticalPositionForBox):
 18 (WebCore::InlineFlowBox::computeLogicalBoxHeights):
 19 (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
 20 (WebCore::InlineFlowBox::flipLinesInBlockDirection):
 21 (WebCore::InlineFlowBox::paintBoxDecorations):
 22 (WebCore::InlineFlowBox::paintMask):
 23 * rendering/InlineFlowBox.h:
 24 * rendering/style/RenderStyle.h:
 25 (WebCore::InheritedFlags::isFlippedLinesWritingMode):
 26
1272010-10-20 Peter Rybin <peter.rybin@gmail.com>
228
329 Reviewed by Adam Barth.
70166

WebCore/rendering/InlineBox.cpp

@@int InlineBox::logicalHeight() const
9595 if (renderer()->isText())
9696 return m_isText ? renderer()->style(m_firstLine)->font().height() : 0;
9797 if (renderer()->isBox() && parent())
98  return toRenderBox(m_renderer)->height();
 98 return m_isVertical ? toRenderBox(m_renderer)->width() : toRenderBox(m_renderer)->height();
9999
100100 ASSERT(isInlineFlowBox());
101101 RenderBoxModelObject* flowObject = boxModelObject();
102102 const Font& font = renderer()->style(m_firstLine)->font();
103103 int result = font.height();
104104 if (parent())
105  result += flowObject->borderAndPaddingHeight();
 105 result += flowObject->borderAndPaddingLogicalHeight();
106106 return result;
107107}
108108
70066

WebCore/rendering/InlineFlowBox.cpp

@@int InlineFlowBox::placeBoxesInInlineDir
332332 int logicalRightMargin = !isVertical() ? curr->boxModelObject()->marginRight() : curr->boxModelObject()->marginBottom();
333333
334334 logicalLeft += logicalLeftMargin;
335  curr->setX(logicalLeft);
 335 curr->setLogicalLeft(logicalLeft);
336336
337337 RenderBox* box = toRenderBox(curr->renderer());
338338

@@void InlineFlowBox::adjustMaxAscentAndDe
367367 // positioned elements
368368 if (curr->renderer()->isPositioned())
369369 continue; // Positioned placeholders don't affect calculations.
370  if (curr->y() == PositionTop || curr->y() == PositionBottom) {
 370 if (curr->logicalTop() == PositionTop || curr->logicalTop() == PositionBottom) {
371371 int lineHeight = curr->lineHeight();
372  if (curr->y() == PositionTop) {
 372 if (curr->logicalTop() == PositionTop) {
373373 if (maxAscent + maxDescent < lineHeight)
374374 maxDescent = lineHeight - maxAscent;
375375 }

@@void InlineFlowBox::adjustMaxAscentAndDe
390390static int verticalPositionForBox(InlineBox* curr, bool firstLine)
391391{
392392 if (curr->renderer()->isText())
393  return curr->parent()->y();
 393 return curr->parent()->logicalTop();
394394 if (curr->renderer()->isBox())
395395 return toRenderBox(curr->renderer())->verticalPosition(firstLine);
396396 return toRenderInline(curr->renderer())->verticalPositionFromCache(firstLine);

@@void InlineFlowBox::computeLogicalBoxHei
459459 baseline = curr->baselinePosition();
460460 }
461461
462  curr->setY(verticalPositionForBox(curr, m_firstLine));
463  if (curr->y() == PositionTop) {
 462 curr->setLogicalTop(verticalPositionForBox(curr, m_firstLine));
 463 if (curr->logicalTop() == PositionTop) {
464464 if (maxPositionTop < lineHeight)
465465 maxPositionTop = lineHeight;
466  } else if (curr->y() == PositionBottom) {
 466 } else if (curr->logicalTop() == PositionBottom) {
467467 if (maxPositionBottom < lineHeight)
468468 maxPositionBottom = lineHeight;
469469 } else if ((!isInlineFlow || static_cast<InlineFlowBox*>(curr)->hasTextChildren()) || curr->boxModelObject()->hasInlineDirectionBordersOrPadding() || strictMode) {
470  int ascent = baseline - curr->y();
 470 int ascent = baseline - curr->logicalTop();
471471 int descent = lineHeight - ascent;
472472 if (maxAscent < ascent)
473473 maxAscent = ascent;

@@void InlineFlowBox::computeLogicalBoxHei
480480 }
481481}
482482
483 void InlineFlowBox::placeBoxesInBlockDirection(int yPos, int maxHeight, int maxAscent, bool strictMode, int& selectionTop, int& selectionBottom)
 483void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom)
484484{
485485 if (isRootInlineBox())
486  setY(yPos + maxAscent - baselinePosition()); // Place our root box.
 486 setLogicalTop(top + maxAscent - baselinePosition()); // Place our root box.
487487
488488 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
489489 if (curr->renderer()->isPositioned())

@@void InlineFlowBox::placeBoxesInBlockDir
493493 // line-height).
494494 bool isInlineFlow = curr->isInlineFlowBox();
495495 if (isInlineFlow)
496  static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(yPos, maxHeight, maxAscent, strictMode, selectionTop, selectionBottom);
 496 static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom);
497497
498498 bool childAffectsTopBottomPos = true;
499  if (curr->y() == PositionTop)
500  curr->setY(yPos);
501  else if (curr->y() == PositionBottom)
502  curr->setY(yPos + maxHeight - curr->lineHeight());
 499 if (curr->logicalTop() == PositionTop)
 500 curr->setLogicalTop(top);
 501 else if (curr->logicalTop() == PositionBottom)
 502 curr->setLogicalTop(top + maxHeight - curr->lineHeight());
503503 else {
504504 if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !strictMode)
505505 childAffectsTopBottomPos = false;
506506 int posAdjust = maxAscent - curr->baselinePosition();
507  curr->setY(curr->y() + yPos + posAdjust);
 507 curr->setLogicalTop(curr->logicalTop() + top + posAdjust);
508508 }
509509
510  int newY = curr->y();
 510 int newLogicalTop = curr->logicalTop();
511511 if (curr->isText() || curr->isInlineFlowBox()) {
512512 const Font& font = curr->renderer()->style(m_firstLine)->font();
513  newY += curr->baselinePosition() - font.ascent();
514  if (curr->isInlineFlowBox())
515  newY -= curr->boxModelObject()->borderTop() + curr->boxModelObject()->paddingTop();
 513 newLogicalTop += curr->baselinePosition() - font.ascent();
 514 if (curr->isInlineFlowBox()) {
 515 RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer());
 516 newLogicalTop -= boxObject->style(m_firstLine)->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() :
 517 boxObject->borderRight() + boxObject->paddingRight();
 518 }
516519 } else if (!curr->renderer()->isBR()) {
517520 RenderBox* box = toRenderBox(curr->renderer());
518  newY += box->marginTop();
 521 newLogicalTop += box->style(m_firstLine)->isHorizontalWritingMode() ? box->marginTop() : box->marginRight();
519522 }
520523
521  curr->setY(newY);
 524 curr->setLogicalTop(newLogicalTop);
522525
523526 if (childAffectsTopBottomPos) {
524527 int boxHeight = curr->logicalHeight();
525  selectionTop = min(selectionTop, newY);
526  selectionBottom = max(selectionBottom, newY + boxHeight);
 528 lineTop = min(lineTop, newLogicalTop);
 529 lineBottom = max(lineBottom, newLogicalTop + boxHeight);
527530 }
528531 }
529532
530533 if (isRootInlineBox()) {
531534 const Font& font = renderer()->style(m_firstLine)->font();
532  setY(y() + baselinePosition() - font.ascent());
 535 setLogicalTop(logicalTop() + baselinePosition() - font.ascent());
 536
533537 if (hasTextChildren() || strictMode) {
534  selectionTop = min(selectionTop, y());
535  selectionBottom = max(selectionBottom, y() + logicalHeight());
 538 lineTop = min(lineTop, logicalTop());
 539 lineBottom = max(lineBottom, logicalTop() + logicalHeight());
536540 }
 541
 542 if (renderer()->style()->isFlippedLinesWritingMode())
 543 flipLinesInBlockDirection(lineTop, lineBottom);
 544 }
 545}
 546
 547void InlineFlowBox::flipLinesInBlockDirection(int lineTop, int lineBottom)
 548{
 549 // Flip the box on the line such that the top is now relative to the lineBottom instead of the lineTop.
 550 setLogicalTop(lineBottom - (logicalTop() - lineTop) - logicalHeight());
 551
 552 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
 553 if (curr->renderer()->isPositioned())
 554 continue; // Positioned placeholders aren't affected here.
 555
 556 if (curr->isInlineFlowBox())
 557 static_cast<InlineFlowBox*>(curr)->flipLinesInBlockDirection(lineTop, lineBottom);
 558 else
 559 curr->setLogicalTop(lineBottom - (curr->logicalTop() - lineTop) - curr->logicalHeight());
537560 }
538561}
539562

@@void InlineFlowBox::paintBoxDecorations(
762785
763786 int x = m_x;
764787 int y = m_y;
765  int w = logicalWidth();
766  int h = logicalHeight();
 788 int w = m_isVertical ? logicalHeight() : logicalWidth();
 789 int h = m_isVertical ? logicalWidth() : logicalHeight();
767790
768791 // Constrain our background/border painting to the line top and bottom if necessary.
769792 bool noQuirksMode = renderer()->document()->inNoQuirksMode();
770793 if (!hasTextChildren() && !noQuirksMode) {
771794 RootInlineBox* rootBox = root();
772  int bottom = min(rootBox->lineBottom(), y + h);
773  y = max(rootBox->lineTop(), y);
774  h = bottom - y;
 795 int& top = m_isVertical ? x : y;
 796 int& logicalHeight = m_isVertical ? w : h;
 797 int bottom = min(rootBox->lineBottom(), top + logicalHeight);
 798 top = max(rootBox->lineTop(), top);
 799 logicalHeight = bottom - top;
775800 }
776801
777802 // Move x/y to our coordinates.

@@void InlineFlowBox::paintMask(PaintInfo&
838863
839864 int x = m_x;
840865 int y = m_y;
841  int w = logicalWidth();
842  int h = logicalHeight();
 866 int w = m_isVertical ? logicalHeight() : logicalWidth();
 867 int h = m_isVertical ? logicalWidth() : logicalHeight();
843868
844869 // Constrain our background/border painting to the line top and bottom if necessary.
845870 bool noQuirksMode = renderer()->document()->inNoQuirksMode();
846871 if (!hasTextChildren() && !noQuirksMode) {
847872 RootInlineBox* rootBox = root();
848  int bottom = min(rootBox->lineBottom(), y + h);
849  y = max(rootBox->lineTop(), y);
850  h = bottom - y;
 873 int& top = m_isVertical ? x : y;
 874 int& logicalHeight = m_isVertical ? w : h;
 875 int bottom = min(rootBox->lineBottom(), top + logicalHeight);
 876 top = max(rootBox->lineTop(), top);
 877 logicalHeight = bottom - top;
851878 }
852879
853880 // Move x/y to our coordinates.
70072

WebCore/rendering/InlineFlowBox.h

@@public:
154154 void determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject);
155155 int getFlowSpacingLogicalWidth();
156156 bool onEndChain(RenderObject* endObject);
157  int placeBoxesInInlineDirection(int x, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
 157 int placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
158158 void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
159159 int& maxAscent, int& maxDescent, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
160160 void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
161161 int maxPositionTop, int maxPositionBottom);
162  void placeBoxesInBlockDirection(int y, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom);
 162 void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom);
 163 void flipLinesInBlockDirection(int lineTop, int lineBottom);
163164 void computeBlockDirectionOverflow(int lineTop, int lineBottom, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
164165
165166 void removeChild(InlineBox* child);
70066

WebCore/rendering/style/RenderStyle.h

@@public:
751751
752752 WritingMode writingMode() const { return static_cast<WritingMode>(inherited_flags.m_writingMode); }
753753 bool isHorizontalWritingMode() const { return writingMode() == TopToBottomWritingMode || writingMode() == BottomToTopWritingMode; }
 754 bool isFlippedLinesWritingMode() const { return writingMode() == LeftToRightWritingMode || writingMode() == BottomToTopWritingMode; }
754755
755756 ESpeak speak() { return static_cast<ESpeak>(rareInheritedData->speak); }
756757
70066

LayoutTests/ChangeLog

 12010-10-20 David Hyatt <hyatt@apple.com>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 https://bugs.webkit.org/show_bug.cgi?id=48001
 6
 7 Make boxes place themselves properly in the block direction. Get basic painting working for spans and add a test that
 8 verifies that span painting and replaced element painting (like images) works correctly.
 9
 10 Added fast/blockflow/basic-vertical-line.html
 11
 12 * fast/blockflow/basic-vertical-line.html: Added.
 13 * platform/mac/fast/blockflow/basic-vertical-line-expected.checksum: Added.
 14 * platform/mac/fast/blockflow/basic-vertical-line-expected.png: Added.
 15 * platform/mac/fast/blockflow/basic-vertical-line-expected.txt: Added.
 16
1172010-10-20 Sheriff Bot <webkit.review.bot@gmail.com>
218
319 Unreviewed, rolling out r70151.
70167

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

 1<div style="-webkit-writing-mode: vertical-lr; height:300px; border:2px solid maroon">
 2<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>
 3<br>
 4<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>
 5<br>
 6<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>
 7</div>
 8
0

LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.checksum

 1f149a6f8dd8b17bffdc42eb7cbd66e40
02\ No newline at end of file
0

LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.txt

 1layer at (0,0) size 800x600
 2 RenderView at (0,0) size 800x600
 3layer at (0,0) size 800x600
 4 RenderBlock {HTML} at (0,0) size 800x600
 5 RenderBody {BODY} at (8,8) size 784x584
 6 RenderBlock {DIV} at (0,0) size 316x304 [border: (2px solid #800000)]
 7 RenderInline {SPAN} at (0,0) size 220x18 [border: (5px solid #000000) none (5px solid #000000) none]
 8 RenderImage {IMG} at (6,12) size 100x200 [bgcolor=#008000]
 9 RenderText {#text} at (2,222) size 4x18
 10 text run at (2,222) width 4: " "
 11 RenderBR {BR} at (6,226) size 0x0
 12 RenderInline {SPAN} at (0,0) size 220x18 [border: (5px solid #000000) none (5px solid #000000) none]
 13 RenderImage {IMG} at (110,12) size 100x200 [bgcolor=#008000]
 14 RenderText {#text} at (106,222) size 4x18
 15 text run at (106,222) width 4: " "
 16 RenderBR {BR} at (110,226) size 0x0
 17 RenderInline {SPAN} at (0,0) size 220x18 [border: (5px solid #000000) none (5px solid #000000) none]
 18 RenderImage {IMG} at (214,12) size 100x200 [bgcolor=#008000]
 19 RenderText {#text} at (0,0) size 0x0
0

LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.png

INVALID: Image lacks a checksum. This will fail with a MISSING error in run-webkit-tests. Always generate new png files using run-webkit-tests.