diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/rendering')
147 files changed, 5349 insertions, 3730 deletions
diff --git a/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp b/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp index afb72cf55..3749782ff 100644 --- a/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp @@ -60,9 +60,9 @@ void AutoTableLayout::recalcColumn(int effCol) while (child) { if (child->isTableCol()) - static_cast<RenderTableCol*>(child)->calcPrefWidths(); + toRenderTableCol(child)->calcPrefWidths(); else if (child->isTableSection()) { - RenderTableSection* section = static_cast<RenderTableSection*>(child); + RenderTableSection* section = toRenderTableSection(child); int numRows = section->numRows(); RenderTableCell* last = 0; for (int i = 0; i < numRows; i++) { @@ -169,7 +169,7 @@ void AutoTableLayout::fullRecalc() int cCol = 0; while (child) { if (child->isTableCol()) { - RenderTableCol *col = static_cast<RenderTableCol*>(child); + RenderTableCol *col = toRenderTableCol(child); int span = col->span(); if (col->firstChild()) { grpWidth = col->style()->width(); @@ -227,7 +227,7 @@ static bool shouldScaleColumns(RenderTable* table) if (tw.isPercent()) scale = false; else { - RenderTableCell* cell = static_cast<RenderTableCell*>(cb); + RenderTableCell* cell = toRenderTableCell(cb); if (cell->colSpan() > 1 || cell->table()->style()->width().isAuto()) scale = false; else diff --git a/src/3rdparty/webkit/WebCore/rendering/CounterNode.cpp b/src/3rdparty/webkit/WebCore/rendering/CounterNode.cpp index c30ca9add..f546abb11 100644 --- a/src/3rdparty/webkit/WebCore/rendering/CounterNode.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/CounterNode.cpp @@ -63,11 +63,17 @@ void CounterNode::recount() for (CounterNode* c = this; c; c = c->m_nextSibling) { int oldCount = c->m_countInParent; int newCount = c->computeCountInParent(); - c->m_countInParent = newCount; if (oldCount == newCount) break; - if (c->m_renderer->isCounter()) - c->m_renderer->setNeedsLayoutAndPrefWidthsRecalc(); + c->m_countInParent = newCount; + // m_renderer contains the parent of the render node + // corresponding to a CounterNode. Let's find the counter + // child and make this re-layout. + for (RenderObject* o = c->m_renderer->firstChild(); o; o = o->nextSibling()) + if (!o->documentBeingDestroyed() && o->isCounter()) { + o->setNeedsLayoutAndPrefWidthsRecalc(); + break; + } } } @@ -167,13 +173,13 @@ static void showTreeAndMark(const CounterNode* node) for (const CounterNode* c = root; c; c = nextInPreOrder(c)) { if (c == node) - fprintf(stderr, "*"); + fprintf(stderr, "*"); for (const CounterNode* d = c; d && d != root; d = d->parent()) fprintf(stderr, "\t"); if (c->isReset()) - fprintf(stderr, "reset: %d\n", c->value()); + fprintf(stderr, "reset: %d %d\n", c->value(), c->countInParent()); else - fprintf(stderr, "increment: %d\n", c->value()); + fprintf(stderr, "increment: %d %d\n", c->value(), c->countInParent()); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp index 63a4f5439..4852708eb 100644 --- a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp @@ -93,7 +93,7 @@ int FixedTableLayout::calcWidthArray(int) Length grpWidth; while (child) { if (child->isTableCol()) { - RenderTableCol* col = static_cast<RenderTableCol*>(child); + RenderTableCol* col = toRenderTableCol(child); if (col->firstChild()) grpWidth = col->style()->width(); else { @@ -128,7 +128,7 @@ int FixedTableLayout::calcWidthArray(int) currentEffectiveColumn++; } } - static_cast<RenderTableCol*>(child)->calcPrefWidths(); + toRenderTableCol(child)->calcPrefWidths(); } else break; @@ -156,7 +156,7 @@ int FixedTableLayout::calcWidthArray(int) child = firstRow->firstChild(); while (child) { if (child->isTableCell()) { - RenderTableCell* cell = static_cast<RenderTableCell*>(child); + RenderTableCell* cell = toRenderTableCell(child); if (cell->prefWidthsDirty()) cell->calcPrefWidths(); @@ -188,6 +188,11 @@ int FixedTableLayout::calcWidthArray(int) return usedWidth; } +// Use a very large value (in effect infinite). But not too large! +// numeric_limits<int>::max() will too easily overflow widths. +// Keep this in synch with BLOCK_MAX_WIDTH in RenderBlock.cpp +#define TABLE_MAX_WIDTH 15000 + void FixedTableLayout::calcPrefWidths(int& minWidth, int& maxWidth) { // FIXME: This entire calculation is incorrect for both minwidth and maxwidth. @@ -206,6 +211,24 @@ void FixedTableLayout::calcPrefWidths(int& minWidth, int& maxWidth) minWidth = max(mw, tableWidth); maxWidth = minWidth; + + // This quirk is very similar to one that exists in RenderBlock::calcBlockPrefWidths(). + // Here's the example for this one: + /* + <table style="width:100%; background-color:red"><tr><td> + <table style="background-color:blue"><tr><td> + <table style="width:100%; background-color:green; table-layout:fixed"><tr><td> + Content + </td></tr></table> + </td></tr></table> + </td></tr></table> + */ + // In this example, the two inner tables should be as large as the outer table. + // We can achieve this effect by making the maxwidth of fixed tables with percentage + // widths be infinite. + if (m_table->style()->htmlHacks() && m_table->style()->width().isPercent() + && maxWidth < TABLE_MAX_WIDTH) + maxWidth = TABLE_MAX_WIDTH; } void FixedTableLayout::layout() diff --git a/src/3rdparty/webkit/WebCore/rendering/HitTestResult.cpp b/src/3rdparty/webkit/WebCore/rendering/HitTestResult.cpp index b7de46be5..50933c6d4 100644 --- a/src/3rdparty/webkit/WebCore/rendering/HitTestResult.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/HitTestResult.cpp @@ -123,17 +123,6 @@ Frame* HitTestResult::targetFrame() const return frame->tree()->find(m_innerURLElement->target()); } -IntRect HitTestResult::boundingBox() const -{ - if (m_innerNonSharedNode) { - RenderObject* renderer = m_innerNonSharedNode->renderer(); - if (renderer) - return renderer->absoluteBoundingBoxRect(); - } - - return IntRect(); -} - bool HitTestResult::isSelected() const { if (!m_innerNonSharedNode) @@ -209,7 +198,7 @@ String HitTestResult::altDisplayString() const if (m_innerNonSharedNode->hasTagName(imgTag)) { HTMLImageElement* image = static_cast<HTMLImageElement*>(m_innerNonSharedNode.get()); - return displayString(image->alt(), m_innerNonSharedNode.get()); + return displayString(image->getAttribute(altAttr), m_innerNonSharedNode.get()); } if (m_innerNonSharedNode->hasTagName(inputTag)) { @@ -246,7 +235,7 @@ IntRect HitTestResult::imageRect() const { if (!image()) return IntRect(); - return m_innerNonSharedNode->renderBox()->absoluteContentBox(); + return m_innerNonSharedNode->renderBox()->absoluteContentQuad().enclosingBoundingBox(); } KURL HitTestResult::absoluteImageURL() const diff --git a/src/3rdparty/webkit/WebCore/rendering/HitTestResult.h b/src/3rdparty/webkit/WebCore/rendering/HitTestResult.h index f29ca4195..25e10585c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/HitTestResult.h +++ b/src/3rdparty/webkit/WebCore/rendering/HitTestResult.h @@ -63,7 +63,6 @@ public: void setIsOverWidget(bool b) { m_isOverWidget = b; } Frame* targetFrame() const; - IntRect boundingBox() const; bool isSelected() const; String spellingToolTip(TextDirection&) const; String replacedString() const; diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineBox.cpp b/src/3rdparty/webkit/WebCore/rendering/InlineBox.cpp index bbf11b344..2575fb7d1 100644 --- a/src/3rdparty/webkit/WebCore/rendering/InlineBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/InlineBox.cpp @@ -98,18 +98,11 @@ int InlineBox::height() const return toRenderBox(m_renderer)->height(); ASSERT(isInlineFlowBox()); - const InlineFlowBox* flowBox = static_cast<const InlineFlowBox*>(this); RenderBoxModelObject* flowObject = boxModelObject(); const Font& font = renderer()->style(m_firstLine)->font(); int result = font.height(); - bool strictMode = renderer()->document()->inStrictMode(); if (parent()) result += flowObject->borderTop() + flowObject->paddingTop() + flowObject->borderBottom() + flowObject->paddingBottom(); - if (strictMode || flowBox->hasTextChildren() || flowObject->hasHorizontalBordersOrPadding()) - return result; - int bottom = root()->bottomOverflow(); - if (y() + result > bottom) - result = bottom - y(); return result; } diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineBox.h b/src/3rdparty/webkit/WebCore/rendering/InlineBox.h index 0f66edd59..e165f0ccd 100644 --- a/src/3rdparty/webkit/WebCore/rendering/InlineBox.h +++ b/src/3rdparty/webkit/WebCore/rendering/InlineBox.h @@ -208,11 +208,6 @@ public: inline int baselinePosition(bool isRootLineBox) const { return renderer()->baselinePosition(m_firstLine, isRootLineBox); } inline int lineHeight(bool isRootLineBox) const { return renderer()->lineHeight(m_firstLine, isRootLineBox); } - virtual int topOverflow() const { return y(); } - virtual int bottomOverflow() const { return y() + height(); } - virtual int leftOverflow() const { return x(); } - virtual int rightOverflow() const { return x() + width(); } - virtual int caretMinOffset() const; virtual int caretMaxOffset() const; virtual unsigned caretMaxRenderedOffset() const; @@ -246,7 +241,7 @@ public: RenderBoxModelObject* boxModelObject() const { if (!m_renderer->isText()) - return static_cast<RenderBoxModelObject*>(m_renderer); + return toRenderBoxModelObject(m_renderer); return 0; } diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp index b397bce60..baea956bc 100644 --- a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp @@ -29,6 +29,7 @@ #include "RootInlineBox.h" #include "RenderBlock.h" #include "RenderInline.h" +#include "RenderLayer.h" #include "RenderListMarker.h" #include "RenderTableCell.h" #include "RootInlineBox.h" @@ -167,6 +168,8 @@ void InlineFlowBox::adjustPosition(int dx, int dy) InlineRunBox::adjustPosition(dx, dy); for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) child->adjustPosition(dx, dy); + if (m_overflow) + m_overflow->move(dx, dy); } RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const @@ -248,18 +251,21 @@ void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* en } } -int InlineFlowBox::placeBoxesHorizontally(int xPos, int& leftPosition, int& rightPosition, bool& needsWordSpacing) +int InlineFlowBox::placeBoxesHorizontally(int xPos, bool& needsWordSpacing) { // Set our x position. setX(xPos); - int boxShadowLeft = 0; - int boxShadowRight = 0; - for (ShadowData* boxShadow = renderer()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - boxShadowLeft = min(boxShadow->x - boxShadow->blur - boxShadow->spread, boxShadowLeft); - boxShadowRight = max(boxShadow->x + boxShadow->blur + boxShadow->spread, boxShadowRight); - } - leftPosition = min(xPos + boxShadowLeft, leftPosition); + int leftLayoutOverflow = xPos; + int rightLayoutOverflow = xPos; + int leftVisualOverflow = xPos; + int rightVisualOverflow = xPos; + + int boxShadowLeft; + int boxShadowRight; + renderer()->style(m_firstLine)->getBoxShadowHorizontalExtent(boxShadowLeft, boxShadowRight); + + leftVisualOverflow = min(xPos + boxShadowLeft, leftVisualOverflow); int startX = xPos; xPos += borderLeft() + paddingLeft(); @@ -277,23 +283,24 @@ int InlineFlowBox::placeBoxesHorizontally(int xPos, int& leftPosition, int& righ int strokeOverflow = static_cast<int>(ceilf(rt->style()->textStrokeWidth() / 2.0f)); - // If letter-spacing is negative, we should factor that into right overflow. (Even in RTL, letter-spacing is + // If letter-spacing is negative, we should factor that into right layout overflow. (Even in RTL, letter-spacing is // applied to the right, so this is not an issue with left overflow. int letterSpacing = min(0, (int)rt->style(m_firstLine)->font().letterSpacing()); - + rightLayoutOverflow = max(xPos + text->width() - letterSpacing, rightLayoutOverflow); + int leftGlyphOverflow = -strokeOverflow; int rightGlyphOverflow = strokeOverflow - letterSpacing; - int visualOverflowLeft = leftGlyphOverflow; - int visualOverflowRight = rightGlyphOverflow; + int childOverflowLeft = leftGlyphOverflow; + int childOverflowRight = rightGlyphOverflow; for (ShadowData* shadow = rt->style()->textShadow(); shadow; shadow = shadow->next) { - visualOverflowLeft = min(visualOverflowLeft, shadow->x - shadow->blur + leftGlyphOverflow); - visualOverflowRight = max(visualOverflowRight, shadow->x + shadow->blur + rightGlyphOverflow); + childOverflowLeft = min(childOverflowLeft, shadow->x - shadow->blur + leftGlyphOverflow); + childOverflowRight = max(childOverflowRight, shadow->x + shadow->blur + rightGlyphOverflow); } - leftPosition = min(xPos + visualOverflowLeft, leftPosition); - rightPosition = max(xPos + text->width() + visualOverflowRight, rightPosition); - m_maxHorizontalVisualOverflow = max(max(visualOverflowRight, -visualOverflowLeft), (int)m_maxHorizontalVisualOverflow); + leftVisualOverflow = min(xPos + childOverflowLeft, leftVisualOverflow); + rightVisualOverflow = max(xPos + text->width() + childOverflowRight, rightVisualOverflow); + xPos += text->width(); } else { if (curr->renderer()->isPositioned()) { @@ -309,13 +316,26 @@ int InlineFlowBox::placeBoxesHorizontally(int xPos, int& leftPosition, int& righ if (curr->renderer()->isRenderInline()) { InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr); xPos += flow->marginLeft(); - xPos = flow->placeBoxesHorizontally(xPos, leftPosition, rightPosition, needsWordSpacing); + xPos = flow->placeBoxesHorizontally(xPos, needsWordSpacing); xPos += flow->marginRight(); - } else if (!curr->renderer()->isListMarker() || static_cast<RenderListMarker*>(curr->renderer())->isInside()) { + leftLayoutOverflow = min(leftLayoutOverflow, flow->leftLayoutOverflow()); + rightLayoutOverflow = max(rightLayoutOverflow, flow->rightLayoutOverflow()); + leftVisualOverflow = min(leftVisualOverflow, flow->leftVisualOverflow()); + rightVisualOverflow = max(rightVisualOverflow, flow->rightVisualOverflow()); + } else if (!curr->renderer()->isListMarker() || toRenderListMarker(curr->renderer())->isInside()) { xPos += curr->boxModelObject()->marginLeft(); curr->setX(xPos); - leftPosition = min(xPos + toRenderBox(curr->renderer())->overflowLeft(false), leftPosition); - rightPosition = max(xPos + toRenderBox(curr->renderer())->overflowWidth(false), rightPosition); + + RenderBox* box = toRenderBox(curr->renderer()); + int childLeftOverflow = box->hasOverflowClip() ? 0 : box->leftLayoutOverflow(); + int childRightOverflow = box->hasOverflowClip() ? curr->width() : box->rightLayoutOverflow(); + + leftLayoutOverflow = min(xPos + childLeftOverflow, leftLayoutOverflow); + rightLayoutOverflow = max(xPos + childRightOverflow, rightLayoutOverflow); + + leftVisualOverflow = min(xPos + box->leftVisualOverflow(), leftVisualOverflow); + rightVisualOverflow = max(xPos + box->rightVisualOverflow(), rightVisualOverflow); + xPos += curr->width() + curr->boxModelObject()->marginRight(); } } @@ -323,45 +343,13 @@ int InlineFlowBox::placeBoxesHorizontally(int xPos, int& leftPosition, int& righ xPos += borderRight() + paddingRight(); setWidth(xPos - startX); - rightPosition = max(x() + width() + boxShadowRight, rightPosition); + rightVisualOverflow = max(x() + width() + boxShadowRight, rightVisualOverflow); + rightLayoutOverflow = max(x() + width(), rightLayoutOverflow); + setHorizontalOverflowPositions(leftLayoutOverflow, rightLayoutOverflow, leftVisualOverflow, rightVisualOverflow); return xPos; } -int InlineFlowBox::verticallyAlignBoxes(int heightOfBlock) -{ - int maxPositionTop = 0; - int maxPositionBottom = 0; - int maxAscent = 0; - int maxDescent = 0; - - // Figure out if we're in strict mode. Note that we can't simply use !style()->htmlHacks(), - // because that would match almost strict mode as well. - RenderObject* curr = renderer(); - while (curr && !curr->node()) - curr = curr->container(); - bool strictMode = (curr && curr->document()->inStrictMode()); - - computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode); - - if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom)) - adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom); - - int maxHeight = maxAscent + maxDescent; - int topPosition = heightOfBlock; - int bottomPosition = heightOfBlock; - int selectionTop = heightOfBlock; - int selectionBottom = heightOfBlock; - placeBoxesVertically(heightOfBlock, maxHeight, maxAscent, strictMode, topPosition, bottomPosition, selectionTop, selectionBottom); - - setVerticalOverflowPositions(topPosition, bottomPosition); - setVerticalSelectionPositions(selectionTop, selectionBottom); - - heightOfBlock += maxHeight; - - return heightOfBlock; -} - void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent, int maxPositionTop, int maxPositionBottom) { @@ -441,7 +429,7 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi } lineHeight = baseline + baselineToBottom; } else if (parentLineHeight.isPercent()) { - lineHeight = parentLineHeight.calcMinValue(curr->renderer()->style()->fontSize()); + lineHeight = parentLineHeight.calcMinValue(curr->renderer()->style()->fontSize(), true); baseline = 0; for (size_t i = 0; i < usedFonts.size(); ++i) { int halfLeading = (lineHeight - usedFonts[i]->ascent() - usedFonts[i]->descent()) / 2; @@ -481,11 +469,10 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi } } -void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, bool strictMode, - int& topPosition, int& bottomPosition, int& selectionTop, int& selectionBottom) +void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, bool strictMode, int& selectionTop, int& selectionBottom) { if (isRootInlineBox()) - setY(yPos + max(0, maxAscent - baselinePosition(true))); // Place our root box. + setY(yPos + maxAscent - baselinePosition(true)); // Place our root box. for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { if (curr->renderer()->isPositioned()) @@ -495,7 +482,7 @@ void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, // line-height). bool isInlineFlow = curr->isInlineFlowBox(); if (isInlineFlow) - static_cast<InlineFlowBox*>(curr)->placeBoxesVertically(yPos, maxHeight, maxAscent, strictMode, topPosition, bottomPosition, selectionTop, selectionBottom); + static_cast<InlineFlowBox*>(curr)->placeBoxesVertically(yPos, maxHeight, maxAscent, strictMode, selectionTop, selectionBottom); bool childAffectsTopBottomPos = true; if (curr->y() == PositionTop) @@ -506,51 +493,18 @@ void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasHorizontalBordersOrPadding() && !strictMode) childAffectsTopBottomPos = false; int posAdjust = maxAscent - curr->baselinePosition(false); - if (!childAffectsTopBottomPos) - posAdjust = max(0, posAdjust); curr->setY(curr->y() + yPos + posAdjust); } - // FIXME: By only considering overflow as part of the root line box, we can't get an accurate picture regarding what the line - // actually needs to paint. A line box that is part of a self-painting layer technically shouldn't contribute to the overflow - // of the line, but in order to not do this and paint accurately, we have to track the overflow somewhere else (either by storing overflow - // in each InlineFlowBox up the chain or in the layer itself). Relative positioned objects on a line will cause scrollbars - // to appear when they shouldn't until we fix this issue. int newY = curr->y(); - int overflowTop = 0; - int overflowBottom = 0; if (curr->isText() || curr->isInlineFlowBox()) { const Font& font = curr->renderer()->style(m_firstLine)->font(); newY += curr->baselinePosition(false) - font.ascent(); - - for (ShadowData* shadow = curr->renderer()->style()->textShadow(); shadow; shadow = shadow->next) { - overflowTop = min(overflowTop, shadow->y - shadow->blur); - overflowBottom = max(overflowBottom, shadow->y + shadow->blur); - } - - for (ShadowData* boxShadow = curr->renderer()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - overflowTop = min(overflowTop, boxShadow->y - boxShadow->blur - boxShadow->spread); - overflowBottom = max(overflowBottom, boxShadow->y + boxShadow->blur + boxShadow->spread); - } - - for (ShadowData* textShadow = curr->renderer()->style(m_firstLine)->textShadow(); textShadow; textShadow = textShadow->next) { - overflowTop = min(overflowTop, textShadow->y - textShadow->blur); - overflowBottom = max(overflowBottom, textShadow->y + textShadow->blur); - } - - if (curr->renderer()->hasReflection()) { - RenderBox* box = toRenderBox(curr->renderer()); - overflowTop = min(overflowTop, box->reflectionBox().y()); - overflowBottom = max(overflowBottom, box->reflectionBox().bottom()); - } - if (curr->isInlineFlowBox()) newY -= curr->boxModelObject()->borderTop() + curr->boxModelObject()->paddingTop(); } else if (!curr->renderer()->isBR()) { RenderBox* box = toRenderBox(curr->renderer()); newY += box->marginTop(); - overflowTop = box->overflowTop(false); - overflowBottom = box->overflowHeight(false) - box->height(); } curr->setY(newY); @@ -559,8 +513,6 @@ void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, int boxHeight = curr->height(); selectionTop = min(selectionTop, newY); selectionBottom = max(selectionBottom, newY + boxHeight); - topPosition = min(topPosition, newY + overflowTop); - bottomPosition = max(bottomPosition, newY + boxHeight + overflowBottom); } } @@ -574,8 +526,88 @@ void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, } } +void InlineFlowBox::computeVerticalOverflow(int lineTop, int lineBottom, bool strictMode) +{ + int boxHeight = height(); + + // Any spillage outside of the line top and bottom is not considered overflow. We just ignore this, since it only happens + // from the "your ascent/descent don't affect the line" quirk. + // FIXME: Technically this means there can be repaint errors in the case where a line box has a shadow or background that spills + // outside of the block. We should consider making any line box that has anything to render just stop respecting the quirk or making + // boxes that render something set visual overflow. + int topOverflow = max(y(), lineTop); + int bottomOverflow = min(y() + boxHeight, lineBottom); + + int topLayoutOverflow = topOverflow; + int bottomLayoutOverflow = bottomOverflow; + + int topVisualOverflow = topOverflow; + int bottomVisualOverflow = bottomOverflow; + + // box-shadow on root line boxes is applying to the block and not to the lines. + if (parent()) { + int boxShadowTop; + int boxShadowBottom; + renderer()->style(m_firstLine)->getBoxShadowVerticalExtent(boxShadowTop, boxShadowBottom); + + topVisualOverflow = min(y() + boxShadowTop, topVisualOverflow); + bottomVisualOverflow = max(y() + boxHeight + boxShadowBottom, bottomVisualOverflow); + } + + for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { + if (curr->renderer()->isPositioned()) + continue; // Positioned placeholders don't affect calculations. + + if (curr->renderer()->isText()) { + InlineTextBox* text = static_cast<InlineTextBox*>(curr); + RenderText* rt = toRenderText(text->renderer()); + if (rt->isBR()) + continue; + + int strokeOverflow = static_cast<int>(ceilf(rt->style()->textStrokeWidth() / 2.0f)); + + int topGlyphOverflow = -strokeOverflow; + int bottomGlyphOverflow = strokeOverflow; + + int childOverflowTop = topGlyphOverflow; + int childOverflowBottom = bottomGlyphOverflow; + for (ShadowData* shadow = rt->style()->textShadow(); shadow; shadow = shadow->next) { + childOverflowTop = min(childOverflowTop, shadow->y - shadow->blur + topGlyphOverflow); + childOverflowBottom = max(childOverflowBottom, shadow->y + shadow->blur + bottomGlyphOverflow); + } + + topVisualOverflow = min(curr->y() + childOverflowTop, topVisualOverflow); + bottomVisualOverflow = max(curr->y() + text->height() + childOverflowBottom, bottomVisualOverflow); + } else if (curr->renderer()->isRenderInline()) { + InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr); + flow->computeVerticalOverflow(lineTop, lineBottom, strictMode); + topLayoutOverflow = min(topLayoutOverflow, flow->topLayoutOverflow()); + bottomLayoutOverflow = max(bottomLayoutOverflow, flow->bottomLayoutOverflow()); + topVisualOverflow = min(topVisualOverflow, flow->topVisualOverflow()); + bottomVisualOverflow = max(bottomVisualOverflow, flow->bottomVisualOverflow()); + } else if (!curr->boxModelObject()->hasSelfPaintingLayer()){ + // Only include overflow from replaced inlines if they do not paint themselves. + RenderBox* box = toRenderBox(curr->renderer()); + int boxY = curr->y(); + int childTopOverflow = box->hasOverflowClip() ? 0 : box->topLayoutOverflow(); + int childBottomOverflow = box->hasOverflowClip() ? curr->height() : box->bottomLayoutOverflow(); + topLayoutOverflow = min(boxY + childTopOverflow, topLayoutOverflow); + bottomLayoutOverflow = max(boxY + childBottomOverflow, bottomLayoutOverflow); + topVisualOverflow = min(boxY + box->topVisualOverflow(), topVisualOverflow); + bottomVisualOverflow = max(boxY + box->bottomVisualOverflow(), bottomVisualOverflow); + } + } + + setVerticalOverflowPositions(topLayoutOverflow, bottomLayoutOverflow, topVisualOverflow, bottomVisualOverflow, boxHeight); +} + bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty) { + IntRect overflowRect(visibleOverflowRect()); + overflowRect.move(tx, ty); + if (!overflowRect.contains(x, y)) + return false; + // Check children first. for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) { if ((curr->renderer()->isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) && curr->nodeAtPoint(request, result, x, y, tx, ty)) { @@ -596,23 +628,14 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re void InlineFlowBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty) { - int xPos = tx + m_x - renderer()->maximalOutlineSize(paintInfo.phase); - int w = width() + 2 * renderer()->maximalOutlineSize(paintInfo.phase); - int shadowLeft = 0; - int shadowRight = 0; - for (ShadowData* boxShadow = renderer()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - shadowLeft = min(boxShadow->x - boxShadow->blur - boxShadow->spread, shadowLeft); - shadowRight = max(boxShadow->x + boxShadow->blur + boxShadow->spread, shadowRight); - } - for (ShadowData* textShadow = renderer()->style(m_firstLine)->textShadow(); textShadow; textShadow = textShadow->next) { - shadowLeft = min(textShadow->x - textShadow->blur, shadowLeft); - shadowRight = max(textShadow->x + textShadow->blur, shadowRight); - } - xPos += shadowLeft; - w += -shadowLeft + shadowRight; - bool intersectsDamageRect = xPos < paintInfo.rect.right() && xPos + w > paintInfo.rect.x(); + IntRect overflowRect(visibleOverflowRect()); + overflowRect.inflate(renderer()->maximalOutlineSize(paintInfo.phase)); + overflowRect.move(tx, ty); + + if (!paintInfo.rect.intersects(overflowRect)) + return; - if (intersectsDamageRect && paintInfo.phase != PaintPhaseChildOutlines) { + if (paintInfo.phase != PaintPhaseChildOutlines) { if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) { // Add ourselves to the paint info struct's list of inlines that need to paint their // outlines. @@ -655,7 +678,7 @@ void InlineFlowBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty) } // 4. Paint our strike-through - if (intersectsDamageRect && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) + if (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection) paintTextDecorations(paintInfo, tx, ty, true); } @@ -784,18 +807,23 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty int w = width(); int h = height(); - // Figure out if we need to push a transparency layer to render our mask. - bool pushTransparencyLayer = false; const NinePieceImage& maskNinePieceImage = renderer()->style()->maskBoxImage(); StyleImage* maskBoxImage = renderer()->style()->maskBoxImage().image(); - if ((maskBoxImage && renderer()->style()->maskLayers()->hasImage()) || renderer()->style()->maskLayers()->next()) - pushTransparencyLayer = true; - - CompositeOperator compositeOp = CompositeDestinationIn; - if (pushTransparencyLayer) { - paintInfo.context->setCompositeOperation(CompositeDestinationIn); - paintInfo.context->beginTransparencyLayer(1.0f); - compositeOp = CompositeSourceOver; + + // Figure out if we need to push a transparency layer to render our mask. + bool pushTransparencyLayer = false; + bool compositedMask = renderer()->hasLayer() && boxModelObject()->layer()->hasCompositedMask(); + CompositeOperator compositeOp = CompositeSourceOver; + if (!compositedMask) { + if ((maskBoxImage && renderer()->style()->maskLayers()->hasImage()) || renderer()->style()->maskLayers()->next()) + pushTransparencyLayer = true; + + compositeOp = CompositeDestinationIn; + if (pushTransparencyLayer) { + paintInfo.context->setCompositeOperation(CompositeDestinationIn); + paintInfo.context->beginTransparencyLayer(1.0f); + compositeOp = CompositeSourceOver; + } } paintFillLayers(paintInfo, Color(), renderer()->style()->maskLayers(), tx, ty, w, h, compositeOp); diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h index 809fd54cb..23b5cc99e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h +++ b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h @@ -22,6 +22,7 @@ #define InlineFlowBox_h #include "InlineRunBox.h" +#include "RenderOverflow.h" namespace WebCore { @@ -35,10 +36,8 @@ public: : InlineRunBox(obj) , m_firstChild(0) , m_lastChild(0) - , m_maxHorizontalVisualOverflow(0) , m_includeLeftEdge(false) , m_includeRightEdge(false) - , m_hasTextChildren(true) #ifndef NDEBUG , m_hasBadChildList(false) #endif @@ -121,18 +120,13 @@ public: void determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject); int getFlowSpacingWidth(); bool onEndChain(RenderObject* endObject); - virtual int placeBoxesHorizontally(int x, int& leftPosition, int& rightPosition, bool& needsWordSpacing); - virtual int verticallyAlignBoxes(int heightOfBlock); + virtual int placeBoxesHorizontally(int x, bool& needsWordSpacing); void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom, int& maxAscent, int& maxDescent, bool strictMode); void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent, int maxPositionTop, int maxPositionBottom); - void placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode, - int& topPosition, int& bottomPosition, int& selectionTop, int& selectionBottom); - - virtual void setVerticalOverflowPositions(int /*top*/, int /*bottom*/) { } - virtual void setVerticalSelectionPositions(int /*top*/, int /*bottom*/) { } - short maxHorizontalVisualOverflow() const { return m_maxHorizontalVisualOverflow; } + void placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom); + void computeVerticalOverflow(int lineTop, int lineBottom, bool strictMode); void removeChild(InlineBox* child); @@ -146,12 +140,35 @@ public: void checkConsistency() const; void setHasBadChildList(); + int topVisibleOverflow() const { return std::min(topLayoutOverflow(), topVisualOverflow()); } + int bottomVisibleOverflow() const { return std::max(bottomLayoutOverflow(), bottomVisualOverflow()); } + int leftVisibleOverflow() const { return std::min(leftLayoutOverflow(), leftVisualOverflow()); } + int rightVisibleOverflow() const { return std::max(rightLayoutOverflow(), rightVisualOverflow()); } + IntRect visibleOverflowRect() const { return m_overflow ? m_overflow->visibleOverflowRect() : IntRect(m_x, m_y, m_width, height()); } + + int topLayoutOverflow() const { return m_overflow ? m_overflow->topLayoutOverflow() : m_y; } + int bottomLayoutOverflow() const { return m_overflow ? m_overflow->bottomLayoutOverflow() : m_y + height(); } + int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : m_x; } + int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : m_x + m_width; } + IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : IntRect(m_x, m_y, m_width, height()); } + + int topVisualOverflow() const { return m_overflow ? m_overflow->topVisualOverflow() : m_y; } + int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : m_y + height(); } + int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : m_x; } + int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : m_x + m_width; } + IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : IntRect(m_x, m_y, m_width, height()); } + + void setHorizontalOverflowPositions(int leftLayoutOverflow, int rightLayoutOverflow, int leftVisualOverflow, int rightVisualOverflow); + void setVerticalOverflowPositions(int topLayoutOverflow, int bottomLayoutOverflow, int topVisualOverflow, int bottomVisualOverflow, int boxHeight); + +protected: + OwnPtr<RenderOverflow> m_overflow; + private: virtual bool isInlineFlowBox() const { return true; } InlineBox* m_firstChild; InlineBox* m_lastChild; - short m_maxHorizontalVisualOverflow; bool m_includeLeftEdge : 1; bool m_includeRightEdge : 1; @@ -162,6 +179,34 @@ private: #endif }; +inline void InlineFlowBox::setHorizontalOverflowPositions(int leftLayoutOverflow, int rightLayoutOverflow, int leftVisualOverflow, int rightVisualOverflow) +{ + if (!m_overflow) { + if (leftLayoutOverflow == m_x && rightLayoutOverflow == m_x + m_width && leftVisualOverflow == m_x && rightVisualOverflow == m_x + m_width) + return; + m_overflow.set(new RenderOverflow(IntRect(m_x, m_y, m_width, m_renderer->style(m_firstLine)->font().height()))); + } + + m_overflow->setLeftLayoutOverflow(leftLayoutOverflow); + m_overflow->setRightLayoutOverflow(rightLayoutOverflow); + m_overflow->setLeftVisualOverflow(leftVisualOverflow); + m_overflow->setRightVisualOverflow(rightVisualOverflow); +} + +inline void InlineFlowBox::setVerticalOverflowPositions(int topLayoutOverflow, int bottomLayoutOverflow, int topVisualOverflow, int bottomVisualOverflow, int boxHeight) +{ + if (!m_overflow) { + if (topLayoutOverflow == m_y && bottomLayoutOverflow == m_y + boxHeight && topVisualOverflow == m_y && bottomVisualOverflow == m_y + boxHeight) + return; + m_overflow.set(new RenderOverflow(IntRect(m_x, m_y, m_width, boxHeight))); + } + + m_overflow->setTopLayoutOverflow(topLayoutOverflow); + m_overflow->setBottomLayoutOverflow(bottomLayoutOverflow); + m_overflow->setTopVisualOverflow(topVisualOverflow); + m_overflow->setBottomVisualOverflow(bottomVisualOverflow); +} + #ifdef NDEBUG inline void InlineFlowBox::checkConsistency() const { diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp b/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp index 619fb952b..751340d5f 100644 --- a/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp @@ -312,8 +312,12 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty) ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines); - int xPos = tx + m_x - parent()->maxHorizontalVisualOverflow(); - int w = width() + 2 * parent()->maxHorizontalVisualOverflow(); + // FIXME: Technically we're potentially incorporating other visual overflow that had nothing to do with us. + // Would it be simpler to just check our own shadow and stroke overflow by hand here? + int leftOverflow = parent()->x() - parent()->leftVisualOverflow(); + int rightOverflow = parent()->rightVisualOverflow() - (parent()->x() + parent()->width()); + int xPos = tx + m_x - leftOverflow; + int w = width() + leftOverflow + rightOverflow; if (xPos >= paintInfo.rect.right() || xPos + w <= paintInfo.rect.x()) return; diff --git a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp index d0af9811d..961166042 100644 --- a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp @@ -32,28 +32,37 @@ #include "MediaControlElements.h" -#include "LocalizedStrings.h" #include "EventNames.h" #include "FloatConversion.h" #include "Frame.h" #include "HTMLNames.h" +#include "LocalizedStrings.h" #include "MouseEvent.h" #include "RenderMedia.h" #include "RenderSlider.h" #include "RenderTheme.h" -#include "CString.h" namespace WebCore { using namespace HTMLNames; -// FIXME: These constants may need to be tweaked to better match the seeking in the QT plugin +HTMLMediaElement* toParentMediaElement(RenderObject* o) +{ + Node* node = o->node(); + Node* mediaNode = node ? node->shadowAncestorNode() : 0; + if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag))) + return 0; + + return static_cast<HTMLMediaElement*>(mediaNode); +} + +// FIXME: These constants may need to be tweaked to better match the seeking in the QuickTime plug-in. static const float cSeekRepeatDelay = 0.1f; static const float cStepTime = 0.07f; static const float cSeekTime = 0.2f; -MediaControlShadowRootElement::MediaControlShadowRootElement(Document* doc, HTMLMediaElement* mediaElement) - : HTMLDivElement(divTag, doc) +MediaControlShadowRootElement::MediaControlShadowRootElement(Document* document, HTMLMediaElement* mediaElement) + : HTMLDivElement(divTag, document) , m_mediaElement(mediaElement) { RefPtr<RenderStyle> rootStyle = RenderStyle::create(); @@ -76,14 +85,36 @@ void MediaControlShadowRootElement::updateStyle() } // ---------------------------- - -MediaControlElement::MediaControlElement(Document* doc, PseudoId pseudo, HTMLMediaElement* mediaElement) - : HTMLDivElement(divTag, doc) +MediaControlElement::MediaControlElement(Document* document, PseudoId pseudo, HTMLMediaElement* mediaElement) + : HTMLDivElement(divTag, document) , m_mediaElement(mediaElement) , m_pseudoStyleId(pseudo) { setInDocument(true); + switch (pseudo) { + case MEDIA_CONTROLS_CURRENT_TIME_DISPLAY: + m_displayType = MediaCurrentTimeDisplay; + break; + case MEDIA_CONTROLS_TIME_REMAINING_DISPLAY: + m_displayType = MediaTimeRemainingDisplay; + break; + case MEDIA_CONTROLS_TIMELINE_CONTAINER: + m_displayType = MediaTimelineContainer; + break; + case MEDIA_CONTROLS_STATUS_DISPLAY: + m_displayType = MediaStatusDisplay; + break; + case MEDIA_CONTROLS_PANEL: + m_displayType = MediaControlsPanel; + break; + case MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER: + m_displayType = MediaVolumeSliderContainer; + break; + default: + ASSERT_NOT_REACHED(); + break; + } } void MediaControlElement::attachToParent(Element* parent) @@ -114,7 +145,10 @@ PassRefPtr<RenderStyle> MediaControlElement::styleForElement() bool MediaControlElement::rendererIsNeeded(RenderStyle* style) { - return HTMLDivElement::rendererIsNeeded(style) && parent() && parent()->renderer(); + ASSERT(document()->page()); + + return HTMLDivElement::rendererIsNeeded(style) && parent() && parent()->renderer() + && (!style->hasAppearance() || document()->page()->theme()->shouldRenderMediaControlPart(style->appearance(), m_mediaElement)); } void MediaControlElement::attach() @@ -165,8 +199,8 @@ void MediaControlElement::updateStyle() // ---------------------------- -MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(Document* doc, HTMLMediaElement* element) -: MediaControlElement(doc, MEDIA_CONTROLS_TIMELINE_CONTAINER, element) +MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(Document* document, HTMLMediaElement* element) + : MediaControlElement(document, MEDIA_CONTROLS_TIMELINE_CONTAINER, element) { } @@ -185,12 +219,54 @@ bool MediaControlTimelineContainerElement::rendererIsNeeded(RenderStyle* style) return !isnan(duration) && !isinf(duration); } - // ---------------------------- -MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(Document* doc, HTMLMediaElement* element) -: MediaControlElement(doc, MEDIA_CONTROLS_STATUS_DISPLAY, element) -, m_stateBeingDisplayed(Nothing) +MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(Document* doc, HTMLMediaElement* element) + : MediaControlElement(doc, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER, element) + , m_isVisible(false) + , m_x(0) + , m_y(0) +{ +} + +PassRefPtr<RenderStyle> MediaControlVolumeSliderContainerElement::styleForElement() +{ + RefPtr<RenderStyle> style = MediaControlElement::styleForElement(); + style->setPosition(AbsolutePosition); + style->setLeft(Length(m_x, Fixed)); + style->setTop(Length(m_y, Fixed)); + style->setDisplay(m_isVisible ? BLOCK : NONE); + return style; +} + +void MediaControlVolumeSliderContainerElement::setVisible(bool visible) +{ + if (visible == m_isVisible) + return; + m_isVisible = visible; +} + +void MediaControlVolumeSliderContainerElement::setPosition(int x, int y) +{ + if (x == m_x && y == m_y) + return; + m_x = x; + m_y = y; +} + +bool MediaControlVolumeSliderContainerElement::hitTest(const IntPoint& absPoint) +{ + if (renderer() && renderer()->style()->hasAppearance()) + return renderer()->theme()->hitTestMediaControlPart(renderer(), absPoint); + + return false; +} + +// ---------------------------- + +MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(Document* document, HTMLMediaElement* element) + : MediaControlElement(document, MEDIA_CONTROLS_STATUS_DISPLAY, element) + , m_stateBeingDisplayed(Nothing) { } @@ -235,14 +311,46 @@ bool MediaControlStatusDisplayElement::rendererIsNeeded(RenderStyle* style) // ---------------------------- -MediaControlInputElement::MediaControlInputElement(Document* doc, PseudoId pseudo, const String& type, HTMLMediaElement* mediaElement, MediaControlElementType displayType) - : HTMLInputElement(inputTag, doc) +MediaControlInputElement::MediaControlInputElement(Document* document, PseudoId pseudo, const String& type, HTMLMediaElement* mediaElement) + : HTMLInputElement(inputTag, document) , m_mediaElement(mediaElement) , m_pseudoStyleId(pseudo) - , m_displayType(displayType) { setInputType(type); setInDocument(true); + + switch (pseudo) { + case MEDIA_CONTROLS_MUTE_BUTTON: + m_displayType = MediaMuteButton; + break; + case MEDIA_CONTROLS_PLAY_BUTTON: + m_displayType = MediaPlayButton; + break; + case MEDIA_CONTROLS_SEEK_FORWARD_BUTTON: + m_displayType = MediaSeekForwardButton; + break; + case MEDIA_CONTROLS_SEEK_BACK_BUTTON: + m_displayType = MediaSeekBackButton; + break; + case MEDIA_CONTROLS_FULLSCREEN_BUTTON: + m_displayType = MediaFullscreenButton; + break; + case MEDIA_CONTROLS_TIMELINE: + m_displayType = MediaSlider; + break; + case MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON: + m_displayType = MediaReturnToRealtimeButton; + break; + case MEDIA_CONTROLS_REWIND_BUTTON: + m_displayType = MediaRewindButton; + break; + case MEDIA_CONTROLS_VOLUME_SLIDER: + m_displayType = MediaVolumeSlider; + break; + default: + ASSERT_NOT_REACHED(); + break; + } } void MediaControlInputElement::attachToParent(Element* parent) @@ -265,7 +373,10 @@ PassRefPtr<RenderStyle> MediaControlInputElement::styleForElement() bool MediaControlInputElement::rendererIsNeeded(RenderStyle* style) { - return HTMLInputElement::rendererIsNeeded(style) && parent() && parent()->renderer(); + ASSERT(document()->page()); + + return HTMLInputElement::rendererIsNeeded(style) && parent() && parent()->renderer() + && (!style->hasAppearance() || document()->page()->theme()->shouldRenderMediaControlPart(style->appearance(), m_mediaElement)); } void MediaControlInputElement::attach() @@ -324,14 +435,14 @@ void MediaControlInputElement::setDisplayType(MediaControlElementType displayTyp return; m_displayType = displayType; - if (RenderObject* o = renderer()) - o->repaint(); + if (RenderObject* object = renderer()) + object->repaint(); } // ---------------------------- -MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document* doc, HTMLMediaElement* element) - : MediaControlInputElement(doc, MEDIA_CONTROLS_MUTE_BUTTON, "button", element, element->muted() ? MediaUnMuteButton : MediaMuteButton) +MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document* document, HTMLMediaElement* element) + : MediaControlInputElement(document, MEDIA_CONTROLS_MUTE_BUTTON, "button", element) { } @@ -351,8 +462,8 @@ void MediaControlMuteButtonElement::updateDisplayType() // ---------------------------- -MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document* doc, HTMLMediaElement* element) - : MediaControlInputElement(doc, MEDIA_CONTROLS_PLAY_BUTTON, "button", element, element->canPlay() ? MediaPlayButton : MediaPauseButton) +MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document* document, HTMLMediaElement* element) + : MediaControlInputElement(document, MEDIA_CONTROLS_PLAY_BUTTON, "button", element) { } @@ -372,9 +483,9 @@ void MediaControlPlayButtonElement::updateDisplayType() // ---------------------------- -MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document* doc, HTMLMediaElement* element, bool forward) - : MediaControlInputElement(doc, forward ? MEDIA_CONTROLS_SEEK_FORWARD_BUTTON : MEDIA_CONTROLS_SEEK_BACK_BUTTON, - "button", element, forward ? MediaSeekForwardButton : MediaSeekBackButton) +MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document* document, HTMLMediaElement* element, bool forward) + : MediaControlInputElement(document, forward ? MEDIA_CONTROLS_SEEK_FORWARD_BUTTON : MEDIA_CONTROLS_SEEK_BACK_BUTTON, + "button", element) , m_forward(forward) , m_seeking(false) , m_capturing(false) @@ -432,8 +543,8 @@ void MediaControlSeekButtonElement::detach() // ---------------------------- -MediaControlRewindButtonElement::MediaControlRewindButtonElement(Document* doc, HTMLMediaElement* element) -: MediaControlInputElement(doc, MEDIA_CONTROLS_REWIND_BUTTON, "button", element, MediaRewindButton) +MediaControlRewindButtonElement::MediaControlRewindButtonElement(Document* document, HTMLMediaElement* element) + : MediaControlInputElement(document, MEDIA_CONTROLS_REWIND_BUTTON, "button", element) { } @@ -446,16 +557,11 @@ void MediaControlRewindButtonElement::defaultEventHandler(Event* event) HTMLInputElement::defaultEventHandler(event); } -bool MediaControlRewindButtonElement::rendererIsNeeded(RenderStyle* style) -{ - return MediaControlInputElement::rendererIsNeeded(style) && m_mediaElement->movieLoadType() != MediaPlayer::LiveStream; -} - // ---------------------------- -MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(Document* doc, HTMLMediaElement* element) -: MediaControlInputElement(doc, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, "button", element, MediaReturnToRealtimeButton) +MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(Document* document, HTMLMediaElement* element) + : MediaControlInputElement(document, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, "button", element) { } @@ -468,28 +574,27 @@ void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event HTMLInputElement::defaultEventHandler(event); } -bool MediaControlReturnToRealtimeButtonElement::rendererIsNeeded(RenderStyle* style) -{ - return MediaControlInputElement::rendererIsNeeded(style) && m_mediaElement->movieLoadType() == MediaPlayer::LiveStream; -} // ---------------------------- MediaControlTimelineElement::MediaControlTimelineElement(Document* document, HTMLMediaElement* element) - : MediaControlInputElement(document, MEDIA_CONTROLS_TIMELINE, "range", element, MediaTimelineContainer) -{ + : MediaControlInputElement(document, MEDIA_CONTROLS_TIMELINE, "range", element) +{ } void MediaControlTimelineElement::defaultEventHandler(Event* event) { + // Left button is 0. Rejects mouse events not from left button. + if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button()) + return; + if (event->type() == eventNames().mousedownEvent) m_mediaElement->beginScrubbing(); MediaControlInputElement::defaultEventHandler(event); - if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent) { + if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent) return; - } float time = narrowPrecisionToFloat(value().toDouble()); if (time != m_mediaElement->currentTime()) { @@ -497,9 +602,9 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event) m_mediaElement->setCurrentTime(time, ec); } - RenderSlider* slider = static_cast<RenderSlider*>(renderer()); + RenderSlider* slider = toRenderSlider(renderer()); if (slider && slider->inDragMode()) - static_cast<RenderMedia*>(m_mediaElement->renderer())->updateTimeDisplay(); + toRenderMedia(m_mediaElement->renderer())->updateTimeDisplay(); if (event->type() == eventNames().mouseupEvent) m_mediaElement->endScrubbing(); @@ -517,29 +622,60 @@ void MediaControlTimelineElement::update(bool updateDuration) // ---------------------------- -MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document* doc, HTMLMediaElement* element) - : MediaControlInputElement(doc, MEDIA_CONTROLS_FULLSCREEN_BUTTON, "button", element, MediaFullscreenButton) +MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document* document, HTMLMediaElement* element) + : MediaControlInputElement(document, MEDIA_CONTROLS_VOLUME_SLIDER, "range", element) { } -void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event) +void MediaControlVolumeSliderElement::defaultEventHandler(Event* event) { - if (event->type() == eventNames().clickEvent) { - event->setDefaultHandled(); + // Left button is 0. Rejects mouse events not from left button. + if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button()) + return; + + MediaControlInputElement::defaultEventHandler(event); + + if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent) + return; + + float volume = narrowPrecisionToFloat(value().toDouble()); + if (volume != m_mediaElement->volume()) { + ExceptionCode ec = 0; + m_mediaElement->setVolume(volume, ec); + ASSERT(!ec); } - HTMLInputElement::defaultEventHandler(event); } -bool MediaControlFullscreenButtonElement::rendererIsNeeded(RenderStyle* style) +void MediaControlVolumeSliderElement::update() { - return MediaControlInputElement::rendererIsNeeded(style) && m_mediaElement->supportsFullscreen(); + float volume = m_mediaElement->volume(); + if (value().toFloat() != volume) { + setValue(String::number(volume)); + MediaControlInputElement::update(); + } } +// ---------------------------- + +MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document* document, HTMLMediaElement* element) + : MediaControlInputElement(document, MEDIA_CONTROLS_FULLSCREEN_BUTTON, "button", element) +{ +} + +void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event) +{ + if (event->type() == eventNames().clickEvent) { + m_mediaElement->enterFullscreen(); + event->setDefaultHandled(); + } + HTMLInputElement::defaultEventHandler(event); +} // ---------------------------- -MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document* doc, PseudoId pseudo, HTMLMediaElement* element) - : MediaControlElement(doc, pseudo, element) +MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document* document, PseudoId pseudo, HTMLMediaElement* element) + : MediaControlElement(document, pseudo, element) + , m_currentValue(0) , m_isVisible(true) { } @@ -569,6 +705,32 @@ void MediaControlTimeDisplayElement::setVisible(bool visible) renderer()->setStyle(style.get()); } +String MediaControlTimeDisplayElement::formatTime(float time) +{ + if (!isfinite(time)) + time = 0; + int seconds = (int)fabsf(time); + int hours = seconds / (60 * 60); + int minutes = (seconds / 60) % 60; + seconds %= 60; + if (hours) { + if (hours > 9) + return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds); + + return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds); + } + + return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds); +} + +void MediaControlTimeDisplayElement::setCurrentValue(float time) +{ + m_currentValue = time; + + ExceptionCode ec; + setInnerText(formatTime(m_currentValue), ec); +} + } //namespace WebCore #endif // enable(video) diff --git a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h index d5fa5d2fe..8b297733f 100644 --- a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h +++ b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h @@ -57,12 +57,17 @@ enum MediaControlElementType { MediaUnMuteButton, MediaPauseButton, MediaTimelineContainer, - MediaCurrentTimeDisplay, + MediaCurrentTimeDisplay, MediaTimeRemainingDisplay, MediaStatusDisplay, - MediaControlsPanel + MediaControlsPanel, + MediaVolumeSliderContainer, + MediaVolumeSlider, + MediaVolumeSliderThumb }; +HTMLMediaElement* toParentMediaElement(RenderObject*); + class MediaControlShadowRootElement : public HTMLDivElement { public: MediaControlShadowRootElement(Document*, HTMLMediaElement*); @@ -89,9 +94,15 @@ public: void update(); virtual void updateStyle(); + MediaControlElementType displayType() const { return m_displayType; } + + HTMLMediaElement* mediaElement() const { return m_mediaElement; } + virtual bool isMediaControlElement() const { return true; } + protected: HTMLMediaElement* m_mediaElement; PseudoId m_pseudoStyleId; + MediaControlElementType m_displayType; // some elements can show multiple types (e.g. play/pause) }; // ---------------------------- @@ -104,6 +115,22 @@ public: // ---------------------------- +class MediaControlVolumeSliderContainerElement : public MediaControlElement { +public: + MediaControlVolumeSliderContainerElement(Document*, HTMLMediaElement*); + virtual PassRefPtr<RenderStyle> styleForElement(); + void setVisible(bool); + bool isVisible() { return m_isVisible; } + void setPosition(int x, int y); + bool hitTest(const IntPoint& absPoint); + +private: + bool m_isVisible; + int m_x, m_y; +}; + +// ---------------------------- + class MediaControlStatusDisplayElement : public MediaControlElement { public: MediaControlStatusDisplayElement(Document*, HTMLMediaElement*); @@ -118,7 +145,7 @@ private: class MediaControlInputElement : public HTMLInputElement { public: - MediaControlInputElement(Document*, PseudoId, const String& type, HTMLMediaElement*, MediaControlElementType); + MediaControlInputElement(Document*, PseudoId, const String& type, HTMLMediaElement*); virtual void attach(); virtual bool rendererIsNeeded(RenderStyle*); @@ -130,13 +157,16 @@ public: bool hitTest(const IntPoint& absPoint); MediaControlElementType displayType() const { return m_displayType; } + HTMLMediaElement* mediaElement() const { return m_mediaElement; } + virtual bool isMediaControlElement() const { return true; } + protected: virtual void updateDisplayType() { } void setDisplayType(MediaControlElementType); HTMLMediaElement* m_mediaElement; PseudoId m_pseudoStyleId; - MediaControlElementType m_displayType; // some elements can show multiple types (e.g. play/pause) + MediaControlElementType m_displayType; }; // ---------------------------- @@ -179,7 +209,6 @@ class MediaControlRewindButtonElement : public MediaControlInputElement { public: MediaControlRewindButtonElement(Document*, HTMLMediaElement*); virtual void defaultEventHandler(Event*); - virtual bool rendererIsNeeded(RenderStyle*); }; // ---------------------------- @@ -188,7 +217,6 @@ class MediaControlReturnToRealtimeButtonElement : public MediaControlInputElemen public: MediaControlReturnToRealtimeButtonElement(Document*, HTMLMediaElement*); virtual void defaultEventHandler(Event*); - virtual bool rendererIsNeeded(RenderStyle*); }; // ---------------------------- @@ -202,11 +230,19 @@ public: // ---------------------------- +class MediaControlVolumeSliderElement : public MediaControlInputElement { +public: + MediaControlVolumeSliderElement(Document*, HTMLMediaElement*); + virtual void defaultEventHandler(Event*); + virtual void update(); +}; + +// ---------------------------- + class MediaControlFullscreenButtonElement : public MediaControlInputElement { public: MediaControlFullscreenButtonElement(Document*, HTMLMediaElement*); virtual void defaultEventHandler(Event*); - virtual bool rendererIsNeeded(RenderStyle*); }; // ---------------------------- @@ -217,7 +253,13 @@ public: void setVisible(bool); virtual PassRefPtr<RenderStyle> styleForElement(); + void setCurrentValue(float); + float currentValue() const { return m_currentValue; } + private: + String formatTime(float time); + + float m_currentValue; bool m_isVisible; }; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderApplet.h b/src/3rdparty/webkit/WebCore/rendering/RenderApplet.h index b481d87b6..343421eb0 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderApplet.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderApplet.h @@ -46,6 +46,15 @@ namespace WebCore { HashMap<String, String> m_args; }; + inline RenderApplet* toRenderApplet(RenderObject* object) + { + ASSERT(!object || object->isApplet()); + return static_cast<RenderApplet*>(object); + } + + // This will catch anyone doing an unnecessary cast. + void toRenderApplet(const RenderApplet*); + } // namespace WebCore #endif // RenderApplet_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBR.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBR.cpp index f40709912..e05c8b473 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBR.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBR.cpp @@ -64,7 +64,7 @@ int RenderBR::lineHeight(bool firstLine, bool /*isRootLineBox*/) const return s->font().lineSpacing(); } if (lh.isPercent()) - return lh.calcMinValue(s->fontSize()); + return lh.calcMinValue(s->fontSize(), true); return lh.value(); } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp index be1bab3e3..d5bb7787c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp @@ -33,6 +33,7 @@ #include "HTMLNames.h" #include "HitTestResult.h" #include "InlineTextBox.h" +#include "RenderFlexibleBox.h" #include "RenderImage.h" #include "RenderInline.h" #include "RenderMarquee.h" @@ -114,8 +115,6 @@ RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int top, int bottom) m_posMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(true) : 0; m_negMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(false) : 0; - - m_selfCollapsingBlockClearedFloat = false; m_topQuirk = m_bottomQuirk = m_determinedTopQuirk = false; } @@ -128,10 +127,6 @@ RenderBlock::RenderBlock(Node* node) , m_positionedObjects(0) , m_inlineContinuation(0) , m_maxMargin(0) - , m_overflowHeight(0) - , m_overflowWidth(0) - , m_overflowLeft(0) - , m_overflowTop(0) , m_lineHeight(-1) { setChildrenInline(true); @@ -168,15 +163,18 @@ RenderBlock::~RenderBlock() void RenderBlock::destroy() { - // Detach our continuation first. - if (m_inlineContinuation) - m_inlineContinuation->destroy(); - m_inlineContinuation = 0; - // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will - // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise. + // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise. children()->destroyLeftoverChildren(); + // Destroy our continuation before anything other than anonymous children. + // The reason we don't destroy it before anonymous children is that they may + // have continuations of their own that are anonymous children of our continuation. + if (m_inlineContinuation) { + m_inlineContinuation->destroy(); + m_inlineContinuation = 0; + } + if (!documentBeingDestroyed()) { if (firstLineBox()) { // We can't wait for RenderBox::destroy to clear the selection, @@ -550,104 +548,6 @@ void RenderBlock::removeChild(RenderObject* oldChild) } } -int RenderBlock::overflowHeight(bool includeInterior) const -{ - if (!includeInterior && hasOverflowClip()) { - int shadowHeight = 0; - for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) - shadowHeight = max(boxShadow->y + boxShadow->blur + boxShadow->spread, shadowHeight); - int inflatedHeight = height() + shadowHeight; - if (hasReflection()) - inflatedHeight = max(inflatedHeight, reflectionBox().bottom()); - return inflatedHeight; - } - return m_overflowHeight; -} - -int RenderBlock::overflowWidth(bool includeInterior) const -{ - if (!includeInterior && hasOverflowClip()) { - int shadowWidth = 0; - for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) - shadowWidth = max(boxShadow->x + boxShadow->blur + boxShadow->spread, shadowWidth); - int inflatedWidth = width() + shadowWidth; - if (hasReflection()) - inflatedWidth = max(inflatedWidth, reflectionBox().right()); - return inflatedWidth; - } - return m_overflowWidth; -} - -int RenderBlock::overflowLeft(bool includeInterior) const -{ - if (!includeInterior && hasOverflowClip()) { - int shadowLeft = 0; - for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) - shadowLeft = min(boxShadow->x - boxShadow->blur - boxShadow->spread, shadowLeft); - int left = shadowLeft; - if (hasReflection()) - left = min(left, reflectionBox().x()); - return left; - } - return m_overflowLeft; -} - -int RenderBlock::overflowTop(bool includeInterior) const -{ - if (!includeInterior && hasOverflowClip()) { - int shadowTop = 0; - for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) - shadowTop = min(boxShadow->y - boxShadow->blur - boxShadow->spread, shadowTop); - int top = shadowTop; - if (hasReflection()) - top = min(top, reflectionBox().y()); - return top; - } - return m_overflowTop; -} - -IntRect RenderBlock::overflowRect(bool includeInterior) const -{ - if (!includeInterior && hasOverflowClip()) { - IntRect box = borderBoxRect(); - int shadowLeft = 0; - int shadowRight = 0; - int shadowTop = 0; - int shadowBottom = 0; - - for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - shadowLeft = min(boxShadow->x - boxShadow->blur - boxShadow->spread, shadowLeft); - shadowRight = max(boxShadow->x + boxShadow->blur + boxShadow->spread, shadowRight); - shadowTop = min(boxShadow->y - boxShadow->blur - boxShadow->spread, shadowTop); - shadowBottom = max(boxShadow->y + boxShadow->blur + boxShadow->spread, shadowBottom); - } - - box.move(shadowLeft, shadowTop); - box.setWidth(box.width() - shadowLeft + shadowRight); - box.setHeight(box.height() - shadowTop + shadowBottom); - - if (hasReflection()) { - IntRect reflection(reflectionBox()); - int reflectTop = min(box.y(), reflection.y()); - int reflectBottom = max(box.bottom(), reflection.bottom()); - box.setHeight(reflectBottom - reflectTop); - box.setY(reflectTop); - - int reflectLeft = min(box.x(), reflection.x()); - int reflectRight = max(box.right(), reflection.right()); - box.setWidth(reflectRight - reflectLeft); - box.setX(reflectLeft); - } - return box; - } - - if (!includeInterior && hasOverflowClip()) - return borderBoxRect(); - int l = overflowLeft(includeInterior); - int t = overflowTop(includeInterior); - return IntRect(l, t, overflowWidth(includeInterior) - l, max(overflowHeight(includeInterior), height()) - t); -} - bool RenderBlock::isSelfCollapsingBlock() const { // We are not self-collapsing if we @@ -741,13 +641,9 @@ void RenderBlock::layout() layoutBlock(false); // It's safe to check for control clip here, since controls can never be table cells. - if (hasControlClip()) { - // Because of the lightweight clip, there can never be any overflow from children. - m_overflowWidth = width(); - m_overflowHeight = height(); - m_overflowLeft = 0; - m_overflowTop = 0; - } + // If we have a lightweight clip, there can never be any overflow from children. + if (hasControlClip() && m_overflow) + clearLayoutOverflow(); } void RenderBlock::layoutBlock(bool relayoutChildren) @@ -769,8 +665,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren) calcWidth(); calcColumnWidth(); - m_overflowWidth = width(); - m_overflowLeft = 0; + m_overflow.clear(); if (oldWidth != width() || oldColumnWidth != desiredColumnWidth()) relayoutChildren = true; @@ -780,8 +675,6 @@ void RenderBlock::layoutBlock(bool relayoutChildren) int previousHeight = height(); setHeight(0); - m_overflowHeight = 0; - // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track // our current maximal positive and negative margins. These values are used when we // are collapsed with adjacent blocks, so for example, if you have block A and B @@ -846,43 +739,35 @@ void RenderBlock::layoutBlock(bool relayoutChildren) } } } + // We have to rebalance columns to the new height. layoutColumns(singleColumnBottom); - - // If the block got expanded in size, then increase our overflowheight to match. - if (m_overflowHeight > height()) - m_overflowHeight -= toAdd; - if (m_overflowHeight < height()) - m_overflowHeight = height(); } + if (previousHeight != height()) relayoutChildren = true; - if ((isCell || isInline() || isFloatingOrPositioned() || isRoot()) && !hasOverflowClip() && !hasControlClip()) - addVisualOverflow(floatRect()); + // It's weird that we're treating float information as normal flow overflow, but we do this because floatRect() isn't + // able to be propagated up the render tree yet. Overflow information is however. This check is designed to catch anyone + // who wasn't going to propagate float information up to the parent and yet could potentially be painted by its ancestor. + if (isRoot() || expandsToEncloseOverhangingFloats()) + addOverflowFromFloats(); - layoutPositionedObjects(relayoutChildren || isRoot()); - - positionListMarker(); + // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway). + if (!hasColumns()) { + if (childrenInline()) + addOverflowFromInlineChildren(); + else + addOverflowFromBlockChildren(); + } - // Always ensure our overflow width/height are at least as large as our width/height. - m_overflowWidth = max(m_overflowWidth, width()); - m_overflowHeight = max(m_overflowHeight, height()); + // Add visual overflow from box-shadow and reflections. + addShadowOverflow(); - if (!hasOverflowClip()) { - for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - m_overflowLeft = min(m_overflowLeft, boxShadow->x - boxShadow->blur - boxShadow->spread); - m_overflowWidth = max(m_overflowWidth, width() + boxShadow->x + boxShadow->blur + boxShadow->spread); - m_overflowTop = min(m_overflowTop, boxShadow->y - boxShadow->blur - boxShadow->spread); - m_overflowHeight = max(m_overflowHeight, height() + boxShadow->y + boxShadow->blur + boxShadow->spread); - } - - if (hasReflection()) { - m_overflowTop = min(m_overflowTop, reflectionBox().y()); - m_overflowHeight = max(m_overflowHeight, reflectionBox().bottom()); - } - } + layoutPositionedObjects(relayoutChildren || isRoot()); + positionListMarker(); + statePusher.pop(); // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if @@ -892,7 +777,9 @@ void RenderBlock::layoutBlock(bool relayoutChildren) // Repaint with our new bounds if they are different from our old bounds. bool didFullRepaint = repainter.repaintAfterLayout(); if (!didFullRepaint && repaintTop != repaintBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) { - IntRect repaintRect(m_overflowLeft, repaintTop, m_overflowWidth - m_overflowLeft, repaintBottom - repaintTop); + int repaintLeft = min(leftVisualOverflow(), leftLayoutOverflow()); + int repaintRight = max(rightVisualOverflow(), rightLayoutOverflow()); + IntRect repaintRect(repaintLeft, repaintTop, repaintRight - repaintLeft, repaintBottom - repaintTop); // FIXME: Deal with multiple column repainting. We have to split the repaint // rect up into multiple rects if it spans columns. @@ -921,6 +808,28 @@ void RenderBlock::layoutBlock(bool relayoutChildren) setNeedsLayout(false); } +void RenderBlock::addOverflowFromBlockChildren() +{ + for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { + if (!child->isFloatingOrPositioned()) + addOverflowFromChild(child); + } +} + +void RenderBlock::addOverflowFromFloats() +{ + IntRect result; + if (!m_floatingObjects) + return; + FloatingObject* r; + DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); + for (; (r = it.current()); ++it) { + if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) + addOverflowFromChild(r->m_renderer, IntSize(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop())); + } + return; +} + bool RenderBlock::expandsToEncloseOverhangingFloats() const { return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox()) || hasColumns() || isTableCell() || isFieldset(); @@ -1010,7 +919,10 @@ bool RenderBlock::handleRunInChild(RenderBox* child) // See if we have a run-in element with inline children. If the // children aren't inline, then just treat the run-in as a normal // block. - if (!child->isRunIn() || !child->childrenInline() && !child->isReplaced()) + if (!child->isRunIn() || !child->childrenInline()) + return false; + // FIXME: We don't handle non-block elements with run-in for now. + if (!child->isRenderBlock()) return false; // Get the next non-positioned/non-floating RenderBlock. @@ -1144,8 +1056,6 @@ int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo) if (marginInfo.margin()) marginInfo.setBottomQuirk(child->isBottomMarginQuirk() || style()->marginBottomCollapse() == MDISCARD); - - marginInfo.setSelfCollapsingBlockClearedFloat(false); } return ypos; @@ -1161,16 +1071,26 @@ int RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, i // For self-collapsing blocks that clear, they can still collapse their // margins with following siblings. Reset the current margins to represent // the self-collapsing block's margins only. - marginInfo.setPosMargin(max(child->maxTopMargin(true), child->maxBottomMargin(true))); - marginInfo.setNegMargin(max(child->maxTopMargin(false), child->maxBottomMargin(false))); + // CSS2.1 states: + // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin. + // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the + // self-collapsing block's bottom margin. + bool atBottomOfBlock = true; + for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) { + if (!curr->isFloatingOrPositioned()) + atBottomOfBlock = false; + } + if (atBottomOfBlock) { + marginInfo.setPosMargin(child->maxBottomMargin(true)); + marginInfo.setNegMargin(child->maxBottomMargin(false)); + } else { + marginInfo.setPosMargin(max(child->maxTopMargin(true), child->maxBottomMargin(true))); + marginInfo.setNegMargin(max(child->maxTopMargin(false), child->maxBottomMargin(false))); + } - // Adjust our height such that we are ready to be collapsed with subsequent siblings. + // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom + // of the parent block). setHeight(child->y() - max(0, marginInfo.margin())); - - // Set a flag that we cleared a float so that we know both to increase the height of the block - // to compensate for the clear and to avoid collapsing our margins with the parent block's - // bottom margin. - marginInfo.setSelfCollapsingBlockClearedFloat(true); } else // Increase our height by the amount we had to clear. setHeight(height() + heightIncrease); @@ -1274,17 +1194,7 @@ void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo) void RenderBlock::handleBottomOfBlock(int top, int bottom, MarginInfo& marginInfo) { - // If our last flow was a self-collapsing block that cleared a float, then we don't - // collapse it with the bottom of the block. - if (!marginInfo.selfCollapsingBlockClearedFloat()) - marginInfo.setAtBottomOfBlock(true); - else { - // We have to special case the negative margin situation (where the collapsed - // margin of the self-collapsing block is negative), since there's no need - // to make an adjustment in that case. - if (marginInfo.margin() < 0) - marginInfo.clearMargin(); - } + marginInfo.setAtBottomOfBlock(true); // If we can't collapse with children then go ahead and add in the bottom margin. if (!marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop() @@ -1298,9 +1208,6 @@ void RenderBlock::handleBottomOfBlock(int top, int bottom, MarginInfo& marginInf // If this happens, ensure that the computed height is increased to the minimal height. setHeight(max(height(), top + bottom)); - // Always make sure our overflow height is at least our height. - m_overflowHeight = max(height(), m_overflowHeight); - // Update our bottom collapsed margin info. setCollapsedBottomMargin(marginInfo); } @@ -1328,8 +1235,7 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom int top = borderTop() + paddingTop(); int bottom = borderBottom() + paddingBottom() + horizontalScrollbarHeight(); - m_overflowHeight = top; - setHeight(m_overflowHeight); + setHeight(top); // The margin struct caches all our current margin collapsing state. The compact struct caches state when we encounter compacts, MarginInfo marginInfo(this, top, bottom); @@ -1350,9 +1256,6 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom if (legend == child) continue; // Skip the legend, since it has already been positioned up in the fieldset's border. - int oldTopPosMargin = maxTopPosMargin(); - int oldTopNegMargin = maxTopNegMargin(); - // Make sure we layout children if they need it. // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into // an auto value. Add a method to determine this, so that we can avoid the relayout. @@ -1368,127 +1271,127 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom if (handleSpecialChild(child, marginInfo)) continue; - // The child is a normal flow object. Compute its vertical margins now. - child->calcVerticalMargins(); + // Lay out the child. + layoutBlockChild(child, marginInfo, previousFloatBottom, maxFloatBottom); + } + + // Now do the handling of the bottom of the block, adding in our bottom border/padding and + // determining the correct collapsed bottom margin information. + handleBottomOfBlock(top, bottom, marginInfo); +} - // Do not allow a collapse if the margin top collapse style is set to SEPARATE. - if (child->style()->marginTopCollapse() == MSEPARATE) { - marginInfo.setAtTopOfBlock(false); - marginInfo.clearMargin(); - } +void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatBottom, int& maxFloatBottom) +{ + int oldTopPosMargin = maxTopPosMargin(); + int oldTopNegMargin = maxTopNegMargin(); - // Try to guess our correct y position. In most cases this guess will - // be correct. Only if we're wrong (when we compute the real y position) - // will we have to potentially relayout. - int yPosEstimate = estimateVerticalPosition(child, marginInfo); + // The child is a normal flow object. Compute its vertical margins now. + child->calcVerticalMargins(); - // Cache our old rect so that we can dirty the proper repaint rects if the child moves. - IntRect oldRect(child->x(), child->y() , child->width(), child->height()); + // Do not allow a collapse if the margin top collapse style is set to SEPARATE. + if (child->style()->marginTopCollapse() == MSEPARATE) { + marginInfo.setAtTopOfBlock(false); + marginInfo.clearMargin(); + } + + // Try to guess our correct y position. In most cases this guess will + // be correct. Only if we're wrong (when we compute the real y position) + // will we have to potentially relayout. + int yPosEstimate = estimateVerticalPosition(child, marginInfo); + + // Cache our old rect so that we can dirty the proper repaint rects if the child moves. + IntRect oldRect(child->x(), child->y() , child->width(), child->height()); #ifndef NDEBUG - IntSize oldLayoutDelta = view()->layoutDelta(); + IntSize oldLayoutDelta = view()->layoutDelta(); #endif - // Go ahead and position the child as though it didn't collapse with the top. - view()->addLayoutDelta(IntSize(0, child->y() - yPosEstimate)); - child->setLocation(child->x(), yPosEstimate); - - bool markDescendantsWithFloats = false; - if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats()) + // Go ahead and position the child as though it didn't collapse with the top. + view()->addLayoutDelta(IntSize(0, child->y() - yPosEstimate)); + child->setLocation(child->x(), yPosEstimate); + + bool markDescendantsWithFloats = false; + if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats()) + markDescendantsWithFloats = true; + else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) { + // If an element might be affected by the presence of floats, then always mark it for + // layout. + int fb = max(previousFloatBottom, floatBottom()); + if (fb > yPosEstimate) markDescendantsWithFloats = true; - else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) { - // If an element might be affected by the presence of floats, then always mark it for - // layout. - int fb = max(previousFloatBottom, floatBottom()); - if (fb > yPosEstimate) - markDescendantsWithFloats = true; - } + } - if (child->isRenderBlock()) { - if (markDescendantsWithFloats) - toRenderBlock(child)->markAllDescendantsWithFloatsForLayout(); + if (child->isRenderBlock()) { + if (markDescendantsWithFloats) + toRenderBlock(child)->markAllDescendantsWithFloatsForLayout(); - previousFloatBottom = max(previousFloatBottom, oldRect.y() + toRenderBlock(child)->floatBottom()); - } + previousFloatBottom = max(previousFloatBottom, oldRect.y() + toRenderBlock(child)->floatBottom()); + } - bool childHadLayout = child->m_everHadLayout; - bool childNeededLayout = child->needsLayout(); - if (childNeededLayout) - child->layout(); + bool childHadLayout = child->m_everHadLayout; + bool childNeededLayout = child->needsLayout(); + if (childNeededLayout) + child->layout(); - // Now determine the correct ypos based off examination of collapsing margin - // values. - int yBeforeClear = collapseMargins(child, marginInfo); + // Now determine the correct ypos based off examination of collapsing margin + // values. + int yBeforeClear = collapseMargins(child, marginInfo); - // Now check for clear. - int yAfterClear = clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin, yBeforeClear); - - view()->addLayoutDelta(IntSize(0, yPosEstimate - yAfterClear)); - child->setLocation(child->x(), yAfterClear); + // Now check for clear. + int yAfterClear = clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin, yBeforeClear); - // Now we have a final y position. See if it really does end up being different from our estimate. - if (yAfterClear != yPosEstimate) { - if (child->shrinkToAvoidFloats()) { - // The child's width depends on the line width. - // When the child shifts to clear an item, its width can - // change (because it has more available line width). - // So go ahead and mark the item as dirty. - child->setChildNeedsLayout(true, false); - } - if (!child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats()) - toRenderBlock(child)->markAllDescendantsWithFloatsForLayout(); - // Our guess was wrong. Make the child lay itself out again. - child->layoutIfNeeded(); + view()->addLayoutDelta(IntSize(0, yPosEstimate - yAfterClear)); + child->setLocation(child->x(), yAfterClear); + + // Now we have a final y position. See if it really does end up being different from our estimate. + if (yAfterClear != yPosEstimate) { + if (child->shrinkToAvoidFloats()) { + // The child's width depends on the line width. + // When the child shifts to clear an item, its width can + // change (because it has more available line width). + // So go ahead and mark the item as dirty. + child->setChildNeedsLayout(true, false); } + if (!child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats()) + toRenderBlock(child)->markAllDescendantsWithFloatsForLayout(); + // Our guess was wrong. Make the child lay itself out again. + child->layoutIfNeeded(); + } - // We are no longer at the top of the block if we encounter a non-empty child. - // This has to be done after checking for clear, so that margins can be reset if a clear occurred. - if (marginInfo.atTopOfBlock() && !child->isSelfCollapsingBlock()) - marginInfo.setAtTopOfBlock(false); - - // Now place the child in the correct horizontal position - determineHorizontalPosition(child); + // We are no longer at the top of the block if we encounter a non-empty child. + // This has to be done after checking for clear, so that margins can be reset if a clear occurred. + if (marginInfo.atTopOfBlock() && !child->isSelfCollapsingBlock()) + marginInfo.setAtTopOfBlock(false); - // Update our height now that the child has been placed in the correct position. - setHeight(height() + child->height()); - if (child->style()->marginBottomCollapse() == MSEPARATE) { - setHeight(height() + child->marginBottom()); - marginInfo.clearMargin(); - } - // If the child has overhanging floats that intrude into following siblings (or possibly out - // of this block), then the parent gets notified of the floats now. - if (child->isBlockFlow() && toRenderBlock(child)->containsFloats()) - maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout)); - - // Update our visual overflow in case the child spills out the block, but only if we were going to paint - // the child block ourselves. - if (!child->hasSelfPaintingLayer()) { - m_overflowTop = min(m_overflowTop, child->y() + child->overflowTop(false)); - m_overflowHeight = max(m_overflowHeight, height() + child->overflowHeight(false) - child->height()); - m_overflowWidth = max(child->x() + child->overflowWidth(false), m_overflowWidth); - m_overflowLeft = min(child->x() + child->overflowLeft(false), m_overflowLeft); - } + // Now place the child in the correct horizontal position + determineHorizontalPosition(child); - IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y()); - if (childOffset.width() || childOffset.height()) { - view()->addLayoutDelta(childOffset); + // Update our height now that the child has been placed in the correct position. + setHeight(height() + child->height()); + if (child->style()->marginBottomCollapse() == MSEPARATE) { + setHeight(height() + child->marginBottom()); + marginInfo.clearMargin(); + } + // If the child has overhanging floats that intrude into following siblings (or possibly out + // of this block), then the parent gets notified of the floats now. + if (child->isBlockFlow() && toRenderBlock(child)->containsFloats()) + maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout)); - // If the child moved, we have to repaint it as well as any floating/positioned - // descendants. An exception is if we need a layout. In this case, we know we're going to - // repaint ourselves (and the child) anyway. - if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout()) - child->repaintDuringLayoutIfMoved(oldRect); - } + IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y()); + if (childOffset.width() || childOffset.height()) { + view()->addLayoutDelta(childOffset); - if (!childHadLayout && child->checkForRepaintDuringLayout()) { - child->repaint(); - child->repaintOverhangingFloats(true); - } + // If the child moved, we have to repaint it as well as any floating/positioned + // descendants. An exception is if we need a layout. In this case, we know we're going to + // repaint ourselves (and the child) anyway. + if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout()) + child->repaintDuringLayoutIfMoved(oldRect); + } - ASSERT(oldLayoutDelta == view()->layoutDelta()); + if (!childHadLayout && child->checkForRepaintDuringLayout()) { + child->repaint(); + child->repaintOverhangingFloats(true); } - // Now do the handling of the bottom of the block, adding in our bottom border/padding and - // determining the correct collapsed bottom margin information. - handleBottomOfBlock(top, bottom, marginInfo); + ASSERT(oldLayoutDelta == view()->layoutDelta()); } bool RenderBlock::layoutOnlyPositionedObjects() @@ -1594,7 +1497,7 @@ void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty) // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView // paints the root's background. if (!isRoot()) { - IntRect overflowBox = overflowRect(false); + IntRect overflowBox = visibleOverflowRect(); overflowBox.inflate(maximalOutlineSize(paintInfo.phase)); overflowBox.move(tx, ty); if (!overflowBox.intersects(paintInfo.rect)) @@ -2131,9 +2034,9 @@ GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) { // Go ahead and update our lastY to be the bottom of the last selected line. - lastTop = (ty - blockY) + lastSelectedLine->bottomOverflow(); - lastLeft = leftSelectionOffset(rootBlock, lastSelectedLine->bottomOverflow()); - lastRight = rightSelectionOffset(rootBlock, lastSelectedLine->bottomOverflow()); + lastTop = (ty - blockY) + lastSelectedLine->selectionBottom(); + lastLeft = leftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); + lastRight = rightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); } return result; } @@ -2684,13 +2587,13 @@ RenderBlock::floatBottom() const IntRect RenderBlock::floatRect() const { IntRect result; - if (!m_floatingObjects || hasOverflowClip()) + if (!m_floatingObjects || hasOverflowClip() || hasColumns()) return result; FloatingObject* r; DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); for (; (r = it.current()); ++it) { if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) { - IntRect childRect = r->m_renderer->overflowRect(false); + IntRect childRect = r->m_renderer->visibleOverflowRect(); childRect.move(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop()); result.unite(childRect); } @@ -2701,10 +2604,11 @@ IntRect RenderBlock::floatRect() const int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) const { + int bottom = includeSelf && width() > 0 ? height() : 0; + if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip())) - return includeSelf && width() > 0 ? overflowHeight(false) : 0; + return bottom; - int bottom = includeSelf && width() > 0 ? height() : 0; if (!hasColumns()) { // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. // For now, we have to descend into all the children, since we may have a huge abs div inside @@ -2728,7 +2632,7 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetY() : 0; if (includeSelf) - bottom = max(bottom, m_overflowHeight + relativeOffset); + bottom = max(bottom, bottomLayoutOverflow() + relativeOffset); if (m_positionedObjects) { RenderBox* r; @@ -2770,8 +2674,8 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) if (!includeSelf) { bottom = max(bottom, borderTop() + paddingTop() + paddingBottom() + relativeOffset); if (childrenInline()) { - if (lastLineBox()) { - int childBottomEdge = lastLineBox()->y() + lastLineBox()->height(); + if (lastRootBox()) { + int childBottomEdge = lastRootBox()->selectionBottom(); bottom = max(bottom, childBottomEdge + paddingBottom() + relativeOffset); } } else { @@ -2791,11 +2695,11 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const { - if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip())) - return includeSelf && height() > 0 ? overflowWidth(false) : 0; - int right = includeSelf && height() > 0 ? width() : 0; + if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip())) + return right; + if (!hasColumns()) { // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. // For now, we have to descend into all the children, since we may have a huge abs div inside @@ -2818,7 +2722,7 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetX() : 0; if (includeSelf) - right = max(right, m_overflowWidth + relativeOffset); + right = max(right, rightLayoutOverflow() + relativeOffset); if (m_positionedObjects) { RenderBox* r; @@ -2885,10 +2789,11 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const { + int left = includeSelf && height() > 0 ? 0 : width(); + if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip())) - return includeSelf && height() > 0 ? overflowLeft(false) : width(); + return left; - int left = includeSelf && height() > 0 ? 0 : width(); if (!hasColumns()) { // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. // For now, we have to descend into all the children, since we may have a huge abs div inside @@ -2911,7 +2816,7 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetX() : 0; if (includeSelf) - left = min(left, m_overflowLeft + relativeOffset); + left = min(left, leftLayoutOverflow() + relativeOffset); if (m_positionedObjects) { RenderBox* r; @@ -3105,9 +3010,8 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bo int lowestFloatBottom = 0; - // Floats that will remain the child's responsiblity to paint should factor into its - // visual overflow. - IntRect floatsOverflowRect; + // Floats that will remain the child's responsibility to paint should factor into its + // overflow. DeprecatedPtrListIterator<FloatingObject> it(*child->m_floatingObjects); for (FloatingObject* r; (r = it.current()); ++it) { int bottom = child->y() + r->m_bottom; @@ -3148,13 +3052,9 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bo // it should paint. r->m_shouldPaint = true; - if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) { - IntRect floatOverflowRect = r->m_renderer->overflowRect(false); - floatOverflowRect.move(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop()); - floatsOverflowRect.unite(floatOverflowRect); - } + if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) + child->addOverflowFromChild(r->m_renderer, IntSize(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop())); } - child->addVisualOverflow(floatsOverflowRect); return lowestFloatBottom; } @@ -3269,26 +3169,20 @@ int RenderBlock::getClearDelta(RenderBox* child, int yPos) // We also clear floats if we are too big to sit on the same line as a float (and wish to avoid floats by default). // FIXME: Note that the remaining space checks aren't quite accurate, since you should be able to clear only some floats (the minimum # needed // to fit) and not all (we should be using nextFloatBottomBelow and looping). - // Do not allow tables to wrap in quirks or even in almost strict mode - // (ebay on the PLT, finance.yahoo.com in the real world, versiontracker.com forces even almost strict mode not to work) int result = clearSet ? max(0, bottom - yPos) : 0; - if (!result && child->avoidsFloats() && child->style()->width().isFixed() && - child->minPrefWidth() > lineWidth(yPos, false) && child->minPrefWidth() <= availableWidth() && - document()->inStrictMode()) - result = max(0, floatBottom() - yPos); + if (!result && child->avoidsFloats()) { + int oldYPos = child->y(); + int oldWidth = child->width(); + child->setY(yPos); + child->calcWidth(); + if (child->width() > lineWidth(yPos, false) && child->minPrefWidth() <= availableWidth()) + result = max(0, floatBottom() - yPos); + child->setY(oldYPos); + child->setWidth(oldWidth); + } return result; } -void RenderBlock::addVisualOverflow(const IntRect& r) -{ - if (r.isEmpty()) - return; - m_overflowLeft = min(m_overflowLeft, r.x()); - m_overflowWidth = max(m_overflowWidth, r.right()); - m_overflowTop = min(m_overflowTop, r.y()); - m_overflowHeight = max(m_overflowHeight, r.bottom()); -} - bool RenderBlock::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty) { if (!scrollsOverflow()) @@ -3304,7 +3198,7 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu if (!isRenderView()) { // Check if we need to do anything at all. - IntRect overflowBox = overflowRect(false); + IntRect overflowBox = visibleOverflowRect(); overflowBox.move(tx, ty); if (!overflowBox.contains(_x, _y)) return false; @@ -3513,9 +3407,9 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& if (root->nextRootBox()) { // FIXME: We would prefer to make the break point halfway between the bottom // of the previous root box and the top of the next root box. - bottom = root->nextRootBox()->topOverflow(); + bottom = root->nextRootBox()->lineTop(); } else - bottom = root->bottomOverflow() + verticalLineClickFudgeFactor; + bottom = root->lineBottom() + verticalLineClickFudgeFactor; // check if this root line box is located at this y coordinate if (pointInContents.y() < bottom) { @@ -3534,7 +3428,7 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& } if (closestBox) { - if (!useWindowsBehavior && pointInContents.y() < firstRootBoxWithChildren->topOverflow() - verticalLineClickFudgeFactor) { + if (!useWindowsBehavior && pointInContents.y() < firstRootBoxWithChildren->lineTop() - verticalLineClickFudgeFactor) { // y coordinate is above first root line box, so return the start of the first return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM); } @@ -3670,7 +3564,7 @@ void RenderBlock::calcColumnWidth() void RenderBlock::setDesiredColumnCountAndWidth(int count, int width) { - if (count == 1) { + if (count == 1 && style()->hasAutoColumnWidth()) { if (hasColumns()) { delete gColumnInfoMap->take(this); setHasColumns(false); @@ -3807,14 +3701,16 @@ int RenderBlock::layoutColumns(int endOfContent) colCount++; } - m_overflowWidth = max(width(), currX - colGap); - m_overflowLeft = min(0, currX + desiredColumnWidth + colGap); - - m_overflowHeight = maxColBottom; + int overflowRight = max(width(), currX - colGap); + int overflowLeft = min(0, currX + desiredColumnWidth + colGap); + int overflowHeight = maxColBottom; int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight(); if (computeIntrinsicHeight) - setHeight(m_overflowHeight + toAdd); + setHeight(maxColBottom + toAdd); + + m_overflow.clear(); + addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight)); v->setPrintRect(IntRect()); v->setTruncatedAt(0); @@ -3918,7 +3814,7 @@ void RenderBlock::calcPrefWidths() } if (isTableCell()) { - Length w = static_cast<const RenderTableCell*>(this)->styleOrColWidth(); + Length w = toRenderTableCell(this)->styleOrColWidth(); if (w.isFixed() && w.value() > 0) m_maxPrefWidth = max(m_minPrefWidth, calcContentBoxWidth(w.value())); } @@ -4734,7 +4630,7 @@ static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, if (block->childrenInline()) { for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) { if (++count == l) - return box->bottomOverflow() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0); + return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0); } } else { @@ -5065,8 +4961,11 @@ void RenderBlock::addFocusRingRects(GraphicsContext* graphicsContext, int tx, in graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height())); if (!hasOverflowClip() && !hasControlClip()) { - for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) - graphicsContext->addFocusRingRect(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height())); + for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { + int top = max(curr->lineTop(), curr->y()); + int bottom = min(curr->lineBottom(), curr->y() + curr->height()); + graphicsContext->addFocusRingRect(IntRect(tx + curr->x(), ty + top, curr->width(), bottom - top)); + } for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { if (!curr->isText() && !curr->isListMarker() && curr->isBox()) { @@ -5088,13 +4987,20 @@ void RenderBlock::addFocusRingRects(GraphicsContext* graphicsContext, int tx, in ty - y() + inlineContinuation()->containingBlock()->y()); } -RenderBlock* RenderBlock::createAnonymousBlock() const +RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const { RefPtr<RenderStyle> newStyle = RenderStyle::create(); newStyle->inheritFrom(style()); - newStyle->setDisplay(BLOCK); - RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */); + RenderBlock* newBox = 0; + if (isFlexibleBox) { + newStyle->setDisplay(BOX); + newBox = new (renderArena()) RenderFlexibleBox(document() /* anonymous box */); + } else { + newStyle->setDisplay(BLOCK); + newBox = new (renderArena()) RenderBlock(document() /* anonymous box */); + } + newBox->setStyle(newStyle.release()); return newBox; } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h index 871e4398c..7ba5fcedc 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h @@ -1,10 +1,8 @@ /* - * This file is part of the render object implementation for KHTML. - * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2007 David Smith (catfish.man@gmail.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -52,26 +50,15 @@ public: RenderBlock(Node*); virtual ~RenderBlock(); - virtual RenderObjectChildList* virtualChildren() { return children(); } - virtual const RenderObjectChildList* virtualChildren() const { return children(); } const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } virtual void destroy(); - virtual const char* renderName() const; - // These two functions are overridden for inline-block. virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const; virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const; - virtual bool isRenderBlock() const { return true; } - virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); } - virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); } - - void makeChildrenNonInline(RenderObject* insertionPoint = 0); - virtual void removeLeftoverAnonymousBlock(RenderBlock* child); - RenderLineBoxList* lineBoxes() { return &m_lineBoxes; } const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; } @@ -79,26 +66,80 @@ public: InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); } void deleteLineBoxTree(); - virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); } - // The height (and width) of a block when you include overflow spillage out of the bottom - // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside - // it would have an overflow height of borderTop() + paddingTop() + 100px. - virtual int overflowHeight(bool includeInterior = true) const; - virtual int overflowWidth(bool includeInterior = true) const; - virtual int overflowLeft(bool includeInterior = true) const; - virtual int overflowTop(bool includeInterior = true) const; - virtual IntRect overflowRect(bool includeInterior = true) const; - virtual void setOverflowHeight(int h) { m_overflowHeight = h; } - virtual void setOverflowWidth(int w) { m_overflowWidth = w; } + virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0); + virtual void removeChild(RenderObject*); + + virtual void layoutBlock(bool relayoutChildren); - void addVisualOverflow(const IntRect&); + void insertPositionedObject(RenderBox*); + void removePositionedObject(RenderBox*); + void removePositionedObjects(RenderBlock*); - virtual bool isSelfCollapsingBlock() const; + void addPercentHeightDescendant(RenderBox*); + static void removePercentHeightDescendant(RenderBox*); + HashSet<RenderBox*>* percentHeightDescendants() const; - virtual int maxTopMargin(bool positive) const { return positive ? maxTopPosMargin() : maxTopNegMargin(); } - virtual int maxBottomMargin(bool positive) const { return positive ? maxBottomPosMargin() : maxBottomNegMargin(); } + RootInlineBox* createAndAppendRootInlineBox(); + bool generatesLineBoxesForInlineChild(RenderObject*, bool isLineEmpty = true, bool previousLineBrokeCleanly = true); + + void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true); + void markPositionedObjectsForLayout(); + + bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); } + bool containsFloat(RenderObject*); + + IntRect floatRect() const; + + int lineWidth(int y, bool firstLine) const; + + virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; + virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; + virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; + + int rightOffset(int y, bool firstLine) const { return rightRelOffset(y, rightOffset(), firstLine); } + int leftOffset(int y, bool firstLine) const { return leftRelOffset(y, leftOffset(), firstLine); } + + virtual VisiblePosition positionForPoint(const IntPoint&); + + // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.) + virtual int availableWidth() const; + + RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); } + RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); } + + bool containsNonZeroBidiLevel() const; + + virtual void setSelectionState(SelectionState s); + + GapRects selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer); + IntRect fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, + int blockX, int blockY, int tx, int ty, const PaintInfo*); + IntRect fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, + int blockX, int blockY, int tx, int ty, const PaintInfo*); + IntRect fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo*); + + void getHorizontalSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap); + + // Helper methods for computing line counts and heights for line counts. + RootInlineBox* lineAtIndex(int); + int lineCount(); + int heightForLineCount(int); + void clearTruncation(); + + void adjustRectForColumns(IntRect&) const; + + void addContinuationWithOutline(RenderInline*); + + RenderInline* inlineContinuation() const { return m_inlineContinuation; } + void setInlineContinuation(RenderInline* c) { m_inlineContinuation = c; } + + // This function is a convenience helper for creating an anonymous block that inherits its + // style from this RenderBlock. + RenderBlock* createAnonymousBlock(bool isFlexibleBox = false) const; + +protected: int maxTopPosMargin() const { return m_maxMargin ? m_maxMargin->m_topPos : MaxMargin::topPosDefault(this); } int maxTopNegMargin() const { return m_maxMargin ? m_maxMargin->m_topNeg : MaxMargin::topNegDefault(this); } int maxBottomPosMargin() const { return m_maxMargin ? m_maxMargin->m_bottomPos : MaxMargin::bottomPosDefault(this); } @@ -116,32 +157,72 @@ public: } } - virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0); - virtual void removeChild(RenderObject*); + virtual void layout(); + + void layoutPositionedObjects(bool relayoutChildren); + + virtual void paint(PaintInfo&, int tx, int ty); + virtual void paintObject(PaintInfo&, int tx, int ty); + + int rightRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const; + int leftRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const; + + virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); + + virtual void calcPrefWidths(); + + virtual int firstLineBoxBaseline() const; + virtual int lastLineBoxBaseline() const; + + virtual void updateFirstLetter(); + + virtual void updateHitTestResult(HitTestResult&, const IntPoint&); + + // Delay update scrollbar until finishDelayRepaint() will be + // called. This function is used when a flexbox is laying out its + // descendant. If multiple calls are made to startDelayRepaint(), + // finishDelayRepaint() will do nothing until finishDelayRepaint() + // is called the same number of times. + static void startDelayUpdateScrollInfo(); + static void finishDelayUpdateScrollInfo(); + + virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + + virtual bool hasLineIfEmpty() const; + bool layoutOnlyPositionedObjects(); + +private: + virtual RenderObjectChildList* virtualChildren() { return children(); } + virtual const RenderObjectChildList* virtualChildren() const { return children(); } + + virtual const char* renderName() const; + + virtual bool isRenderBlock() const { return true; } + virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); } + virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); } + + void makeChildrenNonInline(RenderObject* insertionPoint = 0); + virtual void removeLeftoverAnonymousBlock(RenderBlock* child); + + virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); } + + virtual bool isSelfCollapsingBlock() const; + + virtual int maxTopMargin(bool positive) const { return positive ? maxTopPosMargin() : maxTopNegMargin(); } + virtual int maxBottomMargin(bool positive) const { return positive ? maxBottomPosMargin() : maxBottomNegMargin(); } virtual void repaintOverhangingFloats(bool paintAllDescendants); - virtual void layout(); - virtual void layoutBlock(bool relayoutChildren); void layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom); void layoutInlineChildren(bool relayoutChildren, int& repaintTop, int& repaintBottom); - void layoutPositionedObjects(bool relayoutChildren); - void insertPositionedObject(RenderBox*); - void removePositionedObject(RenderBox*); - void removePositionedObjects(RenderBlock*); - - void addPercentHeightDescendant(RenderBox*); - static void removePercentHeightDescendant(RenderBox*); - HashSet<RenderBox*>* percentHeightDescendants() const; - virtual void positionListMarker() { } virtual void borderFitAdjust(int& x, int& w) const; // Shrink the box in which the border paints if border-fit is set. virtual void updateBeforeAfterContent(PseudoId); - RootInlineBox* createAndAppendRootInlineBox(); virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby. // Called to lay out the legend for a fieldset. @@ -169,7 +250,7 @@ public: int& yPos); bool matchedEndLine(const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus, RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop); - bool generatesLineBoxesForInlineChild(RenderObject*, bool isLineEmpty = true, bool previousLineBrokeCleanly = true); + void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly); int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly); void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth); @@ -178,13 +259,14 @@ public: InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine); void computeHorizontalPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd); void computeVerticalPositionsForLine(RootInlineBox*, BidiRun*); - void checkLinesForOverflow(); void deleteEllipsisLineBoxes(); void checkLinesForTextOverflow(); + void addOverflowFromInlineChildren(); // End of functions defined in RenderBlockLineLayout.cpp. - virtual void paint(PaintInfo&, int tx, int ty); - virtual void paintObject(PaintInfo&, int tx, int ty); + void addOverflowFromBlockChildren(); + void addOverflowFromFloats(); + void paintFloats(PaintInfo&, int tx, int ty, bool preservePhase = false); void paintContents(PaintInfo&, int tx, int ty); void paintColumnContents(PaintInfo&, int tx, int ty, bool paintFloats = false); @@ -202,11 +284,6 @@ public: bool positionNewFloats(); void clearFloats(); int getClearDelta(RenderBox* child, int yPos); - void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true); - void markPositionedObjectsForLayout(); - - bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); } - bool containsFloat(RenderObject*); virtual bool avoidsFloats() const; @@ -218,49 +295,20 @@ public: int floatBottom() const; inline int leftBottom(); inline int rightBottom(); - IntRect floatRect() const; - - int lineWidth(int y, bool firstLine) const; - virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; - virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; - virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; int rightOffset() const; - int rightRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const; - int rightOffset(int y, bool firstLine) const { return rightRelOffset(y, rightOffset(), firstLine); } - int leftOffset() const; - int leftRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const; - int leftOffset(int y, bool firstLine) const { return leftRelOffset(y, leftOffset(), firstLine); } - - virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); virtual bool hitTestColumns(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); virtual bool isPointInOverflowControl(HitTestResult&, int x, int y, int tx, int ty); - virtual VisiblePosition positionForPoint(const IntPoint&); - - // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.) - virtual int availableWidth() const; - - virtual void calcPrefWidths(); void calcInlinePrefWidths(); void calcBlockPrefWidths(); - virtual int firstLineBoxBaseline() const; - virtual int lastLineBoxBaseline() const; - - RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); } - RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); } - - bool containsNonZeroBidiLevel() const; - // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline // children. virtual RenderBlock* firstLineBlock() const; - virtual void updateFirstLetter(); - bool inRootBlockContext() const; virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth); @@ -268,17 +316,12 @@ public: virtual RenderObject* hoverAncestor() const; virtual void updateDragState(bool dragOn); - virtual void updateHitTestResult(HitTestResult&, const IntPoint&); - virtual void childBecameNonInline(RenderObject* child); - virtual void setSelectionState(SelectionState s); - virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool /*clipToVisibleContent*/) { return selectionGapRectsForRepaint(repaintContainer); } - GapRects selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer); virtual bool shouldPaintSelectionGaps() const; bool isSelectionRoot() const; GapRects fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, @@ -289,71 +332,31 @@ public: int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*); IntRect fillVerticalSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock, int blockX, int blockY, const PaintInfo*); - IntRect fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, - int blockX, int blockY, int tx, int ty, const PaintInfo*); - IntRect fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, - int blockX, int blockY, int tx, int ty, const PaintInfo*); - IntRect fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo*); - - void getHorizontalSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap); int leftSelectionOffset(RenderBlock* rootBlock, int y); int rightSelectionOffset(RenderBlock* rootBlock, int y); virtual void absoluteRects(Vector<IntRect>&, int tx, int ty); virtual void absoluteQuads(Vector<FloatQuad>&); - // Helper methods for computing line counts and heights for line counts. - RootInlineBox* lineAtIndex(int); - int lineCount(); - int heightForLineCount(int); - void clearTruncation(); - int desiredColumnWidth() const; unsigned desiredColumnCount() const; Vector<IntRect>* columnRects() const; void setDesiredColumnCountAndWidth(int count, int width); int columnGap() const; - void adjustRectForColumns(IntRect&) const; - - void addContinuationWithOutline(RenderInline*); void paintContinuationOutlines(PaintInfo&, int tx, int ty); - RenderInline* inlineContinuation() const { return m_inlineContinuation; } - void setInlineContinuation(RenderInline* c) { m_inlineContinuation = c; } - virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0); virtual void addFocusRingRects(GraphicsContext*, int tx, int ty); - // This function is a convenience helper for creating an anonymous block that inherits its - // style from this RenderBlock. - RenderBlock* createAnonymousBlock() const; - - // Delay update scrollbar until finishDelayRepaint() will be - // called. This function is used when a flexbox is layouting its - // descendant. If multiple startDelayRepaint() is called, - // finishDelayRepaint() will do nothing until finishDelayRepaint() - // is called same times. - static void startDelayUpdateScrollInfo(); - static void finishDelayUpdateScrollInfo(); - -private: void adjustPointToColumnContents(IntPoint&) const; void adjustForBorderFit(int x, int& left, int& right) const; // Helper function for borderFitAdjust void markLinesDirtyInVerticalRange(int top, int bottom); -protected: - virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); - virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); - void newLine(EClear); - virtual bool hasLineIfEmpty() const; - bool layoutOnlyPositionedObjects(); - -private: Position positionForBox(InlineBox*, bool start = true) const; Position positionForRenderer(RenderObject*, bool start = true) const; VisiblePosition positionForPointWithInlineChildren(const IntPoint&); @@ -368,7 +371,6 @@ private: void updateScrollInfoAfterLayout(); -protected: struct FloatingObject { enum Type { FloatLeft, @@ -419,10 +421,6 @@ protected: // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block. bool m_atBottomOfBlock : 1; - // If our last normal flow child was a self-collapsing block that cleared a float, - // we track it in this variable. - bool m_selfCollapsingBlockClearedFloat : 1; - // These variables are used to detect quirky margins that we need to collapse away (in table cells // and in the body element). bool m_topQuirk : 1; @@ -439,7 +437,6 @@ protected: void setAtTopOfBlock(bool b) { m_atTopOfBlock = b; } void setAtBottomOfBlock(bool b) { m_atBottomOfBlock = b; } void clearMargin() { m_posMargin = m_negMargin = 0; } - void setSelfCollapsingBlockClearedFloat(bool b) { m_selfCollapsingBlockClearedFloat = b; } void setTopQuirk(bool b) { m_topQuirk = b; } void setBottomQuirk(bool b) { m_bottomQuirk = b; } void setDeterminedTopQuirk(bool b) { m_determinedTopQuirk = b; } @@ -455,7 +452,6 @@ protected: bool canCollapseWithBottom() const { return m_atBottomOfBlock && m_canCollapseBottomWithChildren; } bool canCollapseTopWithChildren() const { return m_canCollapseTopWithChildren; } bool canCollapseBottomWithChildren() const { return m_canCollapseBottomWithChildren; } - bool selfCollapsingBlockClearedFloat() const { return m_selfCollapsingBlockClearedFloat; } bool quirkContainer() const { return m_quirkContainer; } bool determinedTopQuirk() const { return m_determinedTopQuirk; } bool topQuirk() const { return m_topQuirk; } @@ -465,6 +461,7 @@ protected: int margin() const { return m_posMargin - m_negMargin; } }; + void layoutBlockChild(RenderBox* child, MarginInfo&, int& previousFloatBottom, int& maxFloatBottom); void adjustPositionedBlock(RenderBox* child, const MarginInfo&); void adjustFloatingBlock(const MarginInfo&); bool handleSpecialChild(RenderBox* child, const MarginInfo&); @@ -479,7 +476,6 @@ protected: void setCollapsedBottomMargin(const MarginInfo&); // End helper functions and structs used by layoutBlockChildren. -private: typedef ListHashSet<RenderBox*>::const_iterator Iterator; DeprecatedPtrList<FloatingObject>* m_floatingObjects; ListHashSet<RenderBox*>* m_positionedObjects; @@ -513,33 +509,26 @@ private: MaxMargin* m_maxMargin; -protected: RenderObjectChildList m_children; RenderLineBoxList m_lineBoxes; // All of the root line boxes created for this block flow. For example, <div>Hello<br>world.</div> will have two total lines for the <div>. - // How much content overflows out of our block vertically or horizontally. - int m_overflowHeight; - int m_overflowWidth; - int m_overflowLeft; - int m_overflowTop; - mutable int m_lineHeight; }; -inline RenderBlock* toRenderBlock(RenderObject* o) +inline RenderBlock* toRenderBlock(RenderObject* object) { - ASSERT(!o || o->isRenderBlock()); - return static_cast<RenderBlock*>(o); + ASSERT(!object || object->isRenderBlock()); + return static_cast<RenderBlock*>(object); } -inline const RenderBlock* toRenderBlock(const RenderObject* o) +inline const RenderBlock* toRenderBlock(const RenderObject* object) { - ASSERT(!o || o->isRenderBlock()); - return static_cast<const RenderBlock*>(o); + ASSERT(!object || object->isRenderBlock()); + return static_cast<const RenderBlock*>(object); } // This will catch anyone doing an unnecessary cast. -void toRenderBlock(const RenderBlock* o); +void toRenderBlock(const RenderBlock*); } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp index c243dc12e..19923f15c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp @@ -763,11 +763,8 @@ void RenderBlock::computeHorizontalPositionsForLine(RootInlineBox* lineBox, bool // The widths of all runs are now known. We can now place every inline box (and // compute accurate widths for the inline flow boxes). - int leftPosition = x; - int rightPosition = x; needsWordSpacing = false; - lineBox->placeBoxesHorizontally(x, leftPosition, rightPosition, needsWordSpacing); - lineBox->setHorizontalOverflowPositions(leftPosition, rightPosition); + lineBox->placeBoxesHorizontally(x, needsWordSpacing); } void RenderBlock::computeVerticalPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun) @@ -775,11 +772,6 @@ void RenderBlock::computeVerticalPositionsForLine(RootInlineBox* lineBox, BidiRu setHeight(lineBox->verticallyAlignBoxes(height())); lineBox->setBlockHeight(height()); - // See if the line spilled out. If so set overflow height accordingly. - int bottomOfLine = lineBox->bottomOverflow(); - if (bottomOfLine > height() && bottomOfLine > m_overflowHeight) - m_overflowHeight = bottomOfLine; - // Now make sure we place replaced render objects correctly. for (BidiRun* r = firstRun; r; r = r->next()) { ASSERT(r->m_box); @@ -824,7 +816,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i { bool useRepaintBounds = false; - m_overflowHeight = 0; + m_overflow.clear(); setHeight(borderTop() + paddingTop()); int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight(); @@ -921,8 +913,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i RenderArena* arena = renderArena(); RootInlineBox* box = startLine; while (box) { - repaintTop = min(repaintTop, box->topOverflow()); - repaintBottom = max(repaintBottom, box->bottomOverflow()); + repaintTop = min(repaintTop, box->topVisibleOverflow()); + repaintBottom = max(repaintBottom, box->bottomVisibleOverflow()); RootInlineBox* next = box->nextRootBox(); box->deleteLine(arena); box = next; @@ -1058,8 +1050,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i if (lineBox) { lineBox->setLineBreakInfo(end.obj, end.pos, resolver.status()); if (useRepaintBounds) { - repaintTop = min(repaintTop, lineBox->topOverflow()); - repaintBottom = max(repaintBottom, lineBox->bottomOverflow()); + repaintTop = min(repaintTop, lineBox->topVisibleOverflow()); + repaintBottom = max(repaintBottom, lineBox->bottomVisibleOverflow()); } } @@ -1098,8 +1090,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i for (RootInlineBox* line = endLine; line; line = line->nextRootBox()) { line->attachLine(); if (delta) { - repaintTop = min(repaintTop, line->topOverflow() + min(delta, 0)); - repaintBottom = max(repaintBottom, line->bottomOverflow() + max(delta, 0)); + repaintTop = min(repaintTop, line->topVisibleOverflow() + min(delta, 0)); + repaintBottom = max(repaintBottom, line->bottomVisibleOverflow() + max(delta, 0)); line->adjustPosition(0, delta); } if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) { @@ -1115,12 +1107,12 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i setHeight(lastRootBox()->blockHeight()); } else { // Delete all the remaining lines. - InlineRunBox* line = endLine; + RootInlineBox* line = endLine; RenderArena* arena = renderArena(); while (line) { - repaintTop = min(repaintTop, line->topOverflow()); - repaintBottom = max(repaintBottom, line->bottomOverflow()); - InlineRunBox* next = line->nextLineBox(); + repaintTop = min(repaintTop, line->topVisibleOverflow()); + repaintBottom = max(repaintBottom, line->bottomVisibleOverflow()); + RootInlineBox* next = line->nextRootBox(); line->deleteLine(arena); line = next; } @@ -1158,12 +1150,6 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i // Now add in the bottom border/padding. setHeight(height() + toAdd); - // Always make sure this is at least our height. - m_overflowHeight = max(height(), m_overflowHeight); - - // See if any lines spill out of the block. If so, we need to update our overflow width. - checkLinesForOverflow(); - if (!firstLineBox() && hasLineIfEmpty()) setHeight(height() + lineHeight(true, true)); @@ -1390,8 +1376,8 @@ bool RenderBlock::matchedEndLine(const InlineBidiResolver& resolver, const Inlin RootInlineBox* boxToDelete = endLine; RenderArena* arena = renderArena(); while (boxToDelete && boxToDelete != result) { - repaintTop = min(repaintTop, boxToDelete->topOverflow()); - repaintBottom = max(repaintBottom, boxToDelete->bottomOverflow()); + repaintTop = min(repaintTop, boxToDelete->topVisibleOverflow()); + repaintBottom = max(repaintBottom, boxToDelete->bottomVisibleOverflow()); RootInlineBox* next = boxToDelete->nextRootBox(); boxToDelete->deleteLine(arena); boxToDelete = next; @@ -1786,7 +1772,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool // Optimize for a common case. If we can't find whitespace after the list // item, then this is all moot. -dwh - if (o->isListMarker() && !static_cast<RenderListMarker*>(o)->isInside()) { + if (o->isListMarker() && !toRenderListMarker(o)->isInside()) { if (style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) { // Like with inline flows, we start ignoring spaces to make sure that any // additional spaces we see will be discarded. @@ -2106,7 +2092,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool if (!o->isFloatingOrPositioned()) { last = o; - if (last->isReplaced() && autoWrap && (!last->isImage() || allowImagesToBreak) && (!last->isListMarker() || static_cast<RenderListMarker*>(last)->isInside())) { + if (last->isReplaced() && autoWrap && (!last->isImage() || allowImagesToBreak) && (!last->isListMarker() || toRenderListMarker(last)->isInside())) { w += tmpW; tmpW = 0; lBreak.obj = next; @@ -2211,14 +2197,12 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool return lBreak; } -void RenderBlock::checkLinesForOverflow() +void RenderBlock::addOverflowFromInlineChildren() { - m_overflowWidth = width(); for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { - m_overflowLeft = min(curr->leftOverflow(), m_overflowLeft); - m_overflowTop = min(curr->topOverflow(), m_overflowTop); - m_overflowWidth = max(curr->rightOverflow(), m_overflowWidth); - m_overflowHeight = max(curr->bottomOverflow(), m_overflowHeight); + addLayoutOverflow(curr->layoutOverflowRect()); + if (!hasOverflowClip()) + addVisualOverflow(curr->visualOverflowRect()); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp index 19a2167d5..1df82a409 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp @@ -139,6 +139,8 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl markContainingBlocksForLayout(); if (style()->position() == StaticPosition) repaint(); + else if (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition) + parent()->setChildNeedsLayout(true); if (isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition)) removeFloatingOrPositionedChildFromBlockLists(); } @@ -400,16 +402,28 @@ int RenderBox::horizontalScrollbarHeight() const return includeHorizontalScrollbarSize() ? layer()->horizontalScrollbarHeight() : 0; } -bool RenderBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier) +bool RenderBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier, Node** stopNode) { RenderLayer* l = layer(); - if (l && l->scroll(direction, granularity, multiplier)) + if (l && l->scroll(direction, granularity, multiplier)) { + if (stopNode) + *stopNode = node(); return true; + } + + if (stopNode && *stopNode && *stopNode == node()) + return true; + RenderBlock* b = containingBlock(); if (b && !b->isRenderView()) - return b->scroll(direction, granularity, multiplier); + return b->scroll(direction, granularity, multiplier, stopNode); return false; } + +bool RenderBox::canBeScrolledAndHasScrollableArea() const +{ + return canBeProgramaticallyScrolled(false) && (scrollHeight() != clientHeight() || scrollWidth() != clientWidth()); +} bool RenderBox::canBeProgramaticallyScrolled(bool) const { @@ -647,31 +661,36 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, int tx, int ty, int { // Figure out if we need to push a transparency layer to render our mask. bool pushTransparencyLayer = false; - StyleImage* maskBoxImage = style()->maskBoxImage().image(); - if (maskBoxImage && style()->maskLayers()->hasImage()) { - pushTransparencyLayer = true; - } else { - // We have to use an extra image buffer to hold the mask. Multiple mask images need - // to composite together using source-over so that they can then combine into a single unified mask that - // can be composited with the content using destination-in. SVG images need to be able to set compositing modes - // as they draw images contained inside their sub-document, so we paint all our images into a separate buffer - // and composite that buffer as the mask. - // We have to check that the mask images to be rendered contain at least one image that can be actually used in rendering - // before pushing the transparency layer. - for (const FillLayer* fillLayer = style()->maskLayers()->next(); fillLayer; fillLayer = fillLayer->next()) { - if (fillLayer->hasImage() && fillLayer->image()->canRender(style()->effectiveZoom())) { - pushTransparencyLayer = true; - // We found one image that can be used in rendering, exit the loop - break; + bool compositedMask = hasLayer() && layer()->hasCompositedMask(); + CompositeOperator compositeOp = CompositeSourceOver; + + if (!compositedMask) { + StyleImage* maskBoxImage = style()->maskBoxImage().image(); + if (maskBoxImage && style()->maskLayers()->hasImage()) { + pushTransparencyLayer = true; + } else { + // We have to use an extra image buffer to hold the mask. Multiple mask images need + // to composite together using source-over so that they can then combine into a single unified mask that + // can be composited with the content using destination-in. SVG images need to be able to set compositing modes + // as they draw images contained inside their sub-document, so we paint all our images into a separate buffer + // and composite that buffer as the mask. + // We have to check that the mask images to be rendered contain at least one image that can be actually used in rendering + // before pushing the transparency layer. + for (const FillLayer* fillLayer = style()->maskLayers()->next(); fillLayer; fillLayer = fillLayer->next()) { + if (fillLayer->hasImage() && fillLayer->image()->canRender(style()->effectiveZoom())) { + pushTransparencyLayer = true; + // We found one image that can be used in rendering, exit the loop + break; + } } } - } - - CompositeOperator compositeOp = CompositeDestinationIn; - if (pushTransparencyLayer) { - paintInfo.context->setCompositeOperation(CompositeDestinationIn); - paintInfo.context->beginTransparencyLayer(1.0f); - compositeOp = CompositeSourceOver; + + compositeOp = CompositeDestinationIn; + if (pushTransparencyLayer) { + paintInfo.context->setCompositeOperation(CompositeDestinationIn); + paintInfo.context->beginTransparencyLayer(1.0f); + compositeOp = CompositeSourceOver; + } } paintFillLayers(paintInfo, Color(), style()->maskLayers(), tx, ty, w, h, compositeOp); @@ -924,7 +943,8 @@ void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool if (style()->position() == FixedPosition) fixed = true; - RenderObject* o = container(); + bool containerSkipped; + RenderObject* o = container(repaintContainer, &containerSkipped); if (!o) return; @@ -942,6 +962,14 @@ void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool } else transformState.move(containerOffset.width(), containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); + if (containerSkipped) { + // There can't be a transform between repaintContainer and o, because transforms create containers, so it should be safe + // to just subtract the delta between the repaintContainer and o. + IntSize containerOffset = repaintContainer->offsetFromAncestorContainer(o); + transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); + return; + } + o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState); } @@ -1062,7 +1090,7 @@ IntRect RenderBox::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintCo if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent()) return IntRect(); - IntRect r = overflowRect(false); + IntRect r = visibleOverflowRect(); RenderView* v = view(); if (v) { @@ -1114,7 +1142,8 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, In if (repaintContainer == this) return; - RenderObject* o = container(); + bool containerSkipped; + RenderObject* o = container(repaintContainer, &containerSkipped); if (!o) return; @@ -1171,6 +1200,13 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, In return; } else rect.setLocation(topLeft); + + if (containerSkipped) { + // If the repaintContainer is below o, then we need to map the rect into repaintContainer's coordinates. + IntSize containerOffset = repaintContainer->offsetFromAncestorContainer(o); + rect.move(-containerOffset); + return; + } o->computeRectForRepaint(repaintContainer, rect, fixed); } @@ -1469,7 +1505,7 @@ int RenderBox::calcHeightUsing(const Length& h) int RenderBox::calcPercentageHeight(const Length& height) { int result = -1; - bool includeBorderPadding = isTable(); + bool skippedAutoHeightContainingBlock = false; RenderBlock* cb = containingBlock(); if (style()->htmlHacks()) { // In quirks mode, blocks with auto height are skipped, and we keep looking for an enclosing @@ -1477,6 +1513,7 @@ int RenderBox::calcPercentageHeight(const Length& height) // specification, which states that percentage heights just revert to auto if the containing // block has an auto height. while (!cb->isRenderView() && !cb->isBody() && !cb->isTableCell() && !cb->isPositioned() && cb->style()->height().isAuto()) { + skippedAutoHeightContainingBlock = true; cb = cb->containingBlock(); cb->addPercentHeightDescendant(this); } @@ -1486,25 +1523,29 @@ int RenderBox::calcPercentageHeight(const Length& height) // explicitly specified that can be used for any percentage computations. bool isPositionedWithSpecifiedHeight = cb->isPositioned() && (!cb->style()->height().isAuto() || (!cb->style()->top().isAuto() && !cb->style()->bottom().isAuto())); + bool includeBorderPadding = isTable(); + // Table cells violate what the CSS spec says to do with heights. Basically we // don't care if the cell specified a height or not. We just always make ourselves // be a percentage of the cell's current content height. if (cb->isTableCell()) { - result = cb->overrideSize(); - if (result == -1) { - // Normally we would let the cell size intrinsically, but scrolling overflow has to be - // treated differently, since WinIE lets scrolled overflow regions shrink as needed. - // While we can't get all cases right, we can at least detect when the cell has a specified - // height or when the table has a specified height. In these cases we want to initially have - // no size and allow the flexing of the table or the cell to its specified height to cause us - // to grow to fill the space. This could end up being wrong in some cases, but it is - // preferable to the alternative (sizing intrinsically and making the row end up too big). - RenderTableCell* cell = static_cast<RenderTableCell*>(cb); - if (scrollsOverflowY() && (!cell->style()->height().isAuto() || !cell->table()->style()->height().isAuto())) - return 0; - return -1; + if (!skippedAutoHeightContainingBlock) { + result = cb->overrideSize(); + if (result == -1) { + // Normally we would let the cell size intrinsically, but scrolling overflow has to be + // treated differently, since WinIE lets scrolled overflow regions shrink as needed. + // While we can't get all cases right, we can at least detect when the cell has a specified + // height or when the table has a specified height. In these cases we want to initially have + // no size and allow the flexing of the table or the cell to its specified height to cause us + // to grow to fill the space. This could end up being wrong in some cases, but it is + // preferable to the alternative (sizing intrinsically and making the row end up too big). + RenderTableCell* cell = toRenderTableCell(cb); + if (scrollsOverflowY() && (!cell->style()->height().isAuto() || !cell->table()->style()->height().isAuto())) + return 0; + return -1; + } + includeBorderPadding = true; } - includeBorderPadding = true; } // Otherwise we only use our percentage height if our containing block had a specified // height. @@ -2434,7 +2475,7 @@ void RenderBox::calcAbsoluteHorizontalReplaced() // positioned, inline containing block because right now, it is using the xPos // of the first line box when really it should use the last line box. When // this is fixed elsewhere, this block should be removed. - if (containerBlock->isInline() && containerBlock->style()->direction() == RTL) { + if (containerBlock->isRenderInline() && containerBlock->style()->direction() == RTL) { const RenderInline* flow = toRenderInline(containerBlock); InlineFlowBox* firstLine = flow->firstLineBox(); InlineFlowBox* lastLine = flow->lastLineBox(); @@ -2595,9 +2636,9 @@ IntRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, int* extraWid if (box) { RootInlineBox* rootBox = box->root(); - int top = rootBox->topOverflow(); + int top = rootBox->lineTop(); rect.setY(top); - rect.setHeight(rootBox->bottomOverflow() - top); + rect.setHeight(rootBox->lineBottom() - top); } // If height of box is smaller than font height, use the latter one, @@ -2650,11 +2691,6 @@ int RenderBox::leftmostPosition(bool /*includeOverflowInterior*/, bool includeSe return left; } -bool RenderBox::isAfterContent(RenderObject* child) const -{ - return (child && child->style()->styleType() == AFTER && (!child->isText() || child->isBR())); -} - VisiblePosition RenderBox::positionForPoint(const IntPoint& point) { // no children...return this render object's element, if there is one, and offset 0 @@ -2762,6 +2798,81 @@ bool RenderBox::avoidsFloats() const return isReplaced() || hasOverflowClip() || isHR(); } +void RenderBox::addShadowOverflow() +{ + int shadowLeft; + int shadowRight; + int shadowTop; + int shadowBottom; + style()->getBoxShadowExtent(shadowTop, shadowRight, shadowBottom, shadowLeft); + IntRect borderBox = borderBoxRect(); + int overflowLeft = borderBox.x() + shadowLeft; + int overflowRight = borderBox.right() + shadowRight; + int overflowTop = borderBox.y() + shadowTop; + int overflowBottom = borderBox.bottom() + shadowBottom; + addVisualOverflow(IntRect(overflowLeft, overflowTop, overflowRight - overflowLeft, overflowBottom - overflowTop)); +} + +void RenderBox::addOverflowFromChild(RenderBox* child, const IntSize& delta) +{ + // Update our overflow in case the child spills out the block, but only if we were going to paint + // the child block ourselves. + if (child->hasSelfPaintingLayer()) + return; + + // Only propagate layout overflow from the child if the child isn't clipping its overflow. If it is, then + // its overflow is internal to it, and we don't care about it. + IntRect childLayoutOverflowRect = child->hasOverflowClip() ? child->borderBoxRect() : child->layoutOverflowRect(); + childLayoutOverflowRect.move(delta); + addLayoutOverflow(childLayoutOverflowRect); + + // Add in visual overflow from the child. Even if the child clips its overflow, it may still + // have visual overflow of its own set from box shadows or reflections. It is unnecessary to propagate this + // overflow if we are clipping our own overflow. + if (hasOverflowClip()) + return; + IntRect childVisualOverflowRect = child->visualOverflowRect(); + childVisualOverflowRect.move(delta); + addVisualOverflow(childVisualOverflowRect); +} + +void RenderBox::addLayoutOverflow(const IntRect& rect) +{ + IntRect borderBox = borderBoxRect(); + if (borderBox.contains(rect)) + return; + + if (!m_overflow) + m_overflow.set(new RenderOverflow(borderBox)); + + m_overflow->addLayoutOverflow(rect); +} + +void RenderBox::addVisualOverflow(const IntRect& rect) +{ + IntRect borderBox = borderBoxRect(); + if (borderBox.contains(rect)) + return; + + if (!m_overflow) + m_overflow.set(new RenderOverflow(borderBox)); + + m_overflow->addVisualOverflow(rect); +} + +void RenderBox::clearLayoutOverflow() +{ + if (!m_overflow) + return; + + if (visualOverflowRect() == borderBoxRect()) { + m_overflow.clear(); + return; + } + + m_overflow->resetLayoutOverflow(borderBoxRect()); +} + #if ENABLE(SVG) TransformationMatrix RenderBox::localTransform() const diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBox.h b/src/3rdparty/webkit/WebCore/rendering/RenderBox.h index 95c0637fa..9050dcbe1 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBox.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBox.h @@ -24,6 +24,7 @@ #define RenderBox_h #include "RenderBoxModelObject.h" +#include "RenderOverflow.h" #include "ScrollTypes.h" namespace WebCore { @@ -80,16 +81,31 @@ public: RenderBox* nextSiblingBox() const; RenderBox* parentBox() const; - // The height of a block when you include normal flow overflow spillage out of the bottom - // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside - // it would have an overflow height of borderTop() + paddingTop() + 100px. - virtual int overflowHeight(bool /*includeInterior*/ = true) const { return height(); } - virtual int overflowWidth(bool /*includeInterior*/ = true) const { return width(); } - virtual void setOverflowHeight(int) { } - virtual void setOverflowWidth(int) { } - virtual int overflowLeft(bool /*includeInterior*/ = true) const { return 0; } - virtual int overflowTop(bool /*includeInterior*/ = true) const { return 0; } - virtual IntRect overflowRect(bool /*includeInterior*/ = true) const { return borderBoxRect(); } + IntRect visibleOverflowRect() const { return hasOverflowClip() ? visualOverflowRect() : (m_overflow ? m_overflow->visibleOverflowRect() : borderBoxRect()); } + int topVisibleOverflow() const { return hasOverflowClip() ? topVisualOverflow() : std::min(topLayoutOverflow(), topVisualOverflow()); } + int bottomVisibleOverflow() const { return hasOverflowClip() ? bottomVisualOverflow() : std::max(bottomLayoutOverflow(), bottomVisualOverflow()); } + int leftVisibleOverflow() const { return hasOverflowClip() ? leftVisualOverflow() : std::min(leftLayoutOverflow(), leftVisualOverflow()); } + int rightVisibleOverflow() const { return hasOverflowClip() ? rightVisualOverflow() : std::max(rightLayoutOverflow(), rightVisualOverflow()); } + + IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : borderBoxRect(); } + int topLayoutOverflow() const { return m_overflow? m_overflow->topLayoutOverflow() : 0; } + int bottomLayoutOverflow() const { return m_overflow ? m_overflow->bottomLayoutOverflow() : height(); } + int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : 0; } + int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : width(); } + + IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : borderBoxRect(); } + int topVisualOverflow() const { return m_overflow? m_overflow->topVisualOverflow() : 0; } + int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : height(); } + int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : 0; } + int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : width(); } + + void addLayoutOverflow(const IntRect&); + void addVisualOverflow(const IntRect&); + + void addShadowOverflow(); + void addOverflowFromChild(RenderBox* child) { addOverflowFromChild(child, IntSize(child->x(), child->y())); } + void addOverflowFromChild(RenderBox* child, const IntSize& delta); + void clearLayoutOverflow(); int contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); } int contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); } @@ -229,7 +245,8 @@ public: virtual int verticalScrollbarWidth() const; int horizontalScrollbarHeight() const; - virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f); + virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0); + bool canBeScrolledAndHasScrollableArea() const; virtual bool canBeProgramaticallyScrolled(bool) const; virtual void autoscroll(); virtual void stopAutoscroll() { } @@ -251,7 +268,7 @@ public: virtual void paintObject(PaintInfo&, int /*tx*/, int /*ty*/) { ASSERT_NOT_REACHED(); } virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); - virtual void paintMask(PaintInfo& paintInfo, int tx, int ty); + virtual void paintMask(PaintInfo&, int tx, int ty); virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); // Called when a positioned object moves but doesn't change size. A simplified layout is done @@ -301,7 +318,7 @@ protected: virtual bool shouldCalculateSizeAsReplaced() const { return isReplaced() && !isInlineBlockOrInlineTable(); } - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const; + virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState&) const; virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const; private: @@ -333,9 +350,6 @@ private: // These include tables, positioned objects, floats and flexible boxes. virtual void calcPrefWidths() { setPrefWidthsDirty(false); } -protected: - bool isAfterContent(RenderObject* child) const; - private: // The width/height of the contents + borders + padding. The x/y location is relative to our container (which is not always our parent). IntRect m_frameRect; @@ -355,21 +369,24 @@ protected: // For inline replaced elements, the inline box that owns us. InlineBox* m_inlineBoxWrapper; + // Our overflow information. + OwnPtr<RenderOverflow> m_overflow; + private: // Used to store state between styleWillChange and styleDidChange static bool s_hadOverflowClip; }; -inline RenderBox* toRenderBox(RenderObject* o) +inline RenderBox* toRenderBox(RenderObject* object) { - ASSERT(!o || o->isBox()); - return static_cast<RenderBox*>(o); + ASSERT(!object || object->isBox()); + return static_cast<RenderBox*>(object); } -inline const RenderBox* toRenderBox(const RenderObject* o) +inline const RenderBox* toRenderBox(const RenderObject* object) { - ASSERT(!o || o->isBox()); - return static_cast<const RenderBox*>(o); + ASSERT(!object || object->isBox()); + return static_cast<const RenderBox*>(object); } // This will catch anyone doing an unnecessary cast. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp index c22462509..23dad2d50 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp @@ -316,10 +316,14 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co bool clippedToBorderRadius = false; if (style()->hasBorderRadius() && (includeLeftEdge || includeRightEdge)) { + IntRect borderRect(tx, ty, w, h); + + if (borderRect.isEmpty()) + return; + context->save(); IntSize topLeft, topRight, bottomLeft, bottomRight; - IntRect borderRect(tx, ty, w, h); style()->getBorderRadiiForRect(borderRect, topLeft, topRight, bottomLeft, bottomRight); context->addRoundedRectClip(borderRect, includeLeftEdge ? topLeft : IntSize(), @@ -358,7 +362,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co maskRect.intersect(paintInfo.rect); // Now create the mask. - OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), false); + OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size()); if (!maskImage) return; @@ -489,153 +493,130 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co context->restore(); } -IntSize RenderBoxModelObject::calculateBackgroundSize(const FillLayer* bgLayer, int scaledWidth, int scaledHeight) const +IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer, IntSize positioningAreaSize) const { - StyleImage* bg = bgLayer->image(); - bg->setImageContainerSize(IntSize(scaledWidth, scaledHeight)); // Use the box established by background-origin. - - if (bgLayer->isSizeSet()) { - int w = scaledWidth; - int h = scaledHeight; - Length bgWidth = bgLayer->size().width(); - Length bgHeight = bgLayer->size().height(); - - if (bgWidth.isFixed()) - w = bgWidth.value(); - else if (bgWidth.isPercent()) - w = bgWidth.calcValue(scaledWidth); - - if (bgHeight.isFixed()) - h = bgHeight.value(); - else if (bgHeight.isPercent()) - h = bgHeight.calcValue(scaledHeight); - - // If one of the values is auto we have to use the appropriate - // scale to maintain our aspect ratio. - if (bgWidth.isAuto() && !bgHeight.isAuto()) - w = bg->imageSize(this, style()->effectiveZoom()).width() * h / bg->imageSize(this, style()->effectiveZoom()).height(); - else if (!bgWidth.isAuto() && bgHeight.isAuto()) - h = bg->imageSize(this, style()->effectiveZoom()).height() * w / bg->imageSize(this, style()->effectiveZoom()).width(); - else if (bgWidth.isAuto() && bgHeight.isAuto()) { - // If both width and height are auto, we just want to use the image's - // intrinsic size. - w = bg->imageSize(this, style()->effectiveZoom()).width(); - h = bg->imageSize(this, style()->effectiveZoom()).height(); + StyleImage* image = fillLayer->image(); + image->setImageContainerSize(positioningAreaSize); // Use the box established by background-origin. + + EFillSizeType type = fillLayer->size().type; + + switch (type) { + case SizeLength: { + int w = positioningAreaSize.width(); + int h = positioningAreaSize.height(); + Length layerWidth = fillLayer->size().size.width(); + Length layerHeight = fillLayer->size().size.height(); + + if (layerWidth.isFixed()) + w = layerWidth.value(); + else if (layerWidth.isPercent()) + w = layerWidth.calcValue(positioningAreaSize.width()); + + if (layerHeight.isFixed()) + h = layerHeight.value(); + else if (layerHeight.isPercent()) + h = layerHeight.calcValue(positioningAreaSize.height()); + + // If one of the values is auto we have to use the appropriate + // scale to maintain our aspect ratio. + if (layerWidth.isAuto() && !layerHeight.isAuto()) + w = image->imageSize(this, style()->effectiveZoom()).width() * h / image->imageSize(this, style()->effectiveZoom()).height(); + else if (!layerWidth.isAuto() && layerHeight.isAuto()) + h = image->imageSize(this, style()->effectiveZoom()).height() * w / image->imageSize(this, style()->effectiveZoom()).width(); + else if (layerWidth.isAuto() && layerHeight.isAuto()) { + // If both width and height are auto, we just want to use the image's + // intrinsic size. + w = image->imageSize(this, style()->effectiveZoom()).width(); + h = image->imageSize(this, style()->effectiveZoom()).height(); + } + + return IntSize(max(1, w), max(1, h)); } - - return IntSize(max(1, w), max(1, h)); - } else - return bg->imageSize(this, style()->effectiveZoom()); + case Contain: + case Cover: { + IntSize imageIntrinsicSize = image->imageSize(this, 1); + float horizontalScaleFactor = static_cast<float>(positioningAreaSize.width()) / imageIntrinsicSize.width(); + float verticalScaleFactor = static_cast<float>(positioningAreaSize.height()) / imageIntrinsicSize.height(); + float scaleFactor = type == Contain ? min(horizontalScaleFactor, verticalScaleFactor) : max(horizontalScaleFactor, verticalScaleFactor); + + return IntSize(max<int>(1, imageIntrinsicSize.width() * scaleFactor), max<int>(1, imageIntrinsicSize.height() * scaleFactor)); + } + case SizeNone: + break; + } + return image->imageSize(this, style()->effectiveZoom()); } -void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* bgLayer, int tx, int ty, int w, int h, +void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fillLayer, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize) { - int pw; - int ph; int left = 0; - int right = 0; int top = 0; - int bottom = 0; - int cx; - int cy; - int rw = 0; - int rh = 0; - - // CSS2 chapter 14.2.1 - bool fixedAttachment = bgLayer->attachment() == FixedBackgroundAttachment; + IntSize positioningAreaSize; + + // Determine the background positioning area and set destRect to the background painting area. + // destRect will be adjusted later if the background is non-repeating. + bool fixedAttachment = fillLayer->attachment() == FixedBackgroundAttachment; if (!fixedAttachment) { - // Scroll and Local - if (bgLayer->origin() != BorderFillBox) { + destRect = IntRect(tx, ty, w, h); + + int right = 0; + int bottom = 0; + // Scroll and Local. + if (fillLayer->origin() != BorderFillBox) { left = borderLeft(); right = borderRight(); top = borderTop(); bottom = borderBottom(); - if (bgLayer->origin() == ContentFillBox) { + if (fillLayer->origin() == ContentFillBox) { left += paddingLeft(); right += paddingRight(); top += paddingTop(); bottom += paddingBottom(); } } - + // The background of the box generated by the root element covers the entire canvas including - // its margins. Since those were added in already, we have to factor them out when computing the - // box used by background-origin/size/position. + // its margins. Since those were added in already, we have to factor them out when computing + // the background positioning area. if (isRoot()) { - rw = toRenderBox(this)->width() - left - right; - rh = toRenderBox(this)->height() - top - bottom; + positioningAreaSize = IntSize(toRenderBox(this)->width() - left - right, toRenderBox(this)->height() - top - bottom); left += marginLeft(); - right += marginRight(); top += marginTop(); - bottom += marginBottom(); - } - cx = tx; - cy = ty; - pw = w - left - right; - ph = h - top - bottom; + } else + positioningAreaSize = IntSize(w - left - right, h - top - bottom); } else { - // Fixed background attachment. - IntRect vr = viewRect(); - cx = vr.x(); - cy = vr.y(); - pw = vr.width(); - ph = vr.height(); + destRect = viewRect(); + positioningAreaSize = destRect.size(); } - int sx = 0; - int sy = 0; - int cw; - int ch; + tileSize = calculateFillTileSize(fillLayer, positioningAreaSize); - IntSize scaledImageSize; - if (isRoot() && !fixedAttachment) - scaledImageSize = calculateBackgroundSize(bgLayer, rw, rh); - else - scaledImageSize = calculateBackgroundSize(bgLayer, pw, ph); - - int scaledImageWidth = scaledImageSize.width(); - int scaledImageHeight = scaledImageSize.height(); + EFillRepeat backgroundRepeatX = fillLayer->repeatX(); + EFillRepeat backgroundRepeatY = fillLayer->repeatY(); - EFillRepeat backgroundRepeat = bgLayer->repeat(); - - int xPosition; - if (isRoot() && !fixedAttachment) - xPosition = bgLayer->xPosition().calcMinValue(rw - scaledImageWidth, true); - else - xPosition = bgLayer->xPosition().calcMinValue(pw - scaledImageWidth, true); - if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatXFill) { - cw = pw + left + right; - sx = scaledImageWidth ? scaledImageWidth - (xPosition + left) % scaledImageWidth : 0; - } else { - cx += max(xPosition + left, 0); - sx = -min(xPosition + left, 0); - cw = scaledImageWidth + min(xPosition + left, 0); - } - - int yPosition; - if (isRoot() && !fixedAttachment) - yPosition = bgLayer->yPosition().calcMinValue(rh - scaledImageHeight, true); - else - yPosition = bgLayer->yPosition().calcMinValue(ph - scaledImageHeight, true); - if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatYFill) { - ch = ph + top + bottom; - sy = scaledImageHeight ? scaledImageHeight - (yPosition + top) % scaledImageHeight : 0; - } else { - cy += max(yPosition + top, 0); - sy = -min(yPosition + top, 0); - ch = scaledImageHeight + min(yPosition + top, 0); + int xPosition = fillLayer->xPosition().calcMinValue(positioningAreaSize.width() - tileSize.width(), true); + if (backgroundRepeatX == RepeatFill) + phase.setX(tileSize.width() ? tileSize.width() - (xPosition + left) % tileSize.width() : 0); + else { + destRect.move(max(xPosition + left, 0), 0); + phase.setX(-min(xPosition + left, 0)); + destRect.setWidth(tileSize.width() + min(xPosition + left, 0)); } - if (fixedAttachment) { - sx += max(tx - cx, 0); - sy += max(ty - cy, 0); + int yPosition = fillLayer->yPosition().calcMinValue(positioningAreaSize.height() - tileSize.height(), true); + if (backgroundRepeatY == RepeatFill) + phase.setY(tileSize.height() ? tileSize.height() - (yPosition + top) % tileSize.height() : 0); + else { + destRect.move(0, max(yPosition + top, 0)); + phase.setY(-min(yPosition + top, 0)); + destRect.setHeight(tileSize.height() + min(yPosition + top, 0)); } - destRect = IntRect(cx, cy, cw, ch); + if (fixedAttachment) + phase.move(max(tx - destRect.x(), 0), max(ty - destRect.y(), 0)); + destRect.intersect(IntRect(tx, ty, w, h)); - phase = IntPoint(sx, sy); - tileSize = IntSize(scaledImageWidth, scaledImageHeight); } int RenderBoxModelObject::verticalPosition(bool firstLine) const diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h index c67477808..c9a4a0a0e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h @@ -100,10 +100,12 @@ public: protected: void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize); - IntSize calculateBackgroundSize(const FillLayer*, int scaledWidth, int scaledHeight) const; private: virtual bool isBoxModelObject() const { return true; } + + IntSize calculateFillTileSize(const FillLayer*, IntSize scaledSize) const; + friend class RenderView; RenderLayer* m_layer; @@ -114,16 +116,16 @@ private: static bool s_layerWasSelfPainting; }; -inline RenderBoxModelObject* toRenderBoxModelObject(RenderObject* o) +inline RenderBoxModelObject* toRenderBoxModelObject(RenderObject* object) { - ASSERT(!o || o->isBoxModelObject()); - return static_cast<RenderBoxModelObject*>(o); + ASSERT(!object || object->isBoxModelObject()); + return static_cast<RenderBoxModelObject*>(object); } -inline const RenderBoxModelObject* toRenderBoxModelObject(const RenderObject* o) +inline const RenderBoxModelObject* toRenderBoxModelObject(const RenderObject* object) { - ASSERT(!o || o->isBoxModelObject()); - return static_cast<const RenderBoxModelObject*>(o); + ASSERT(!object || object->isBoxModelObject()); + return static_cast<const RenderBoxModelObject*>(object); } // This will catch anyone doing an unnecessary cast. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderButton.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderButton.cpp index 6d36a0f8a..f3ae5580f 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderButton.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderButton.cpp @@ -52,7 +52,8 @@ void RenderButton::addChild(RenderObject* newChild, RenderObject* beforeChild) if (!m_inner) { // Create an anonymous block. ASSERT(!firstChild()); - m_inner = createAnonymousBlock(); + bool isFlexibleBox = style()->display() == BOX || style()->display() == INLINE_BOX; + m_inner = createAnonymousBlock(isFlexibleBox); setupInnerStyle(m_inner->style()); RenderFlexibleBox::addChild(m_inner); } @@ -108,6 +109,7 @@ void RenderButton::setupInnerStyle(RenderStyle* innerStyle) // RenderBlock::createAnonymousBlock creates a new RenderStyle, so this is // safe to modify. innerStyle->setBoxFlex(1.0f); + innerStyle->setBoxOrient(style()->boxOrient()); innerStyle->setPaddingTop(Length(theme()->buttonInternalPaddingTop(), Fixed)); innerStyle->setPaddingRight(Length(theme()->buttonInternalPaddingRight(), Fixed)); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderButton.h b/src/3rdparty/webkit/WebCore/rendering/RenderButton.h index 3b4ff3f4e..3a7458967 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderButton.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderButton.h @@ -74,16 +74,16 @@ protected: bool m_default; }; -inline RenderButton* toRenderButton(RenderObject* o) +inline RenderButton* toRenderButton(RenderObject* object) { - ASSERT(!o || o->isRenderButton()); - return static_cast<RenderButton*>(o); + ASSERT(!object || object->isRenderButton()); + return static_cast<RenderButton*>(object); } -inline const RenderButton* toRenderButton(const RenderObject* o) +inline const RenderButton* toRenderButton(const RenderObject* object) { - ASSERT(!o || o->isRenderButton()); - return static_cast<const RenderButton*>(o); + ASSERT(!object || object->isRenderButton()); + return static_cast<const RenderButton*>(object); } // This will catch anyone doing an unnecessary cast. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderCounter.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderCounter.cpp index fd6d80dbc..17c6dad21 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderCounter.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderCounter.cpp @@ -107,8 +107,8 @@ static bool planCounter(RenderObject* object, const AtomicString& counterName, b if (counterName == "list-item") { if (object->isListItem()) { - if (static_cast<RenderListItem*>(object)->hasExplicitValue()) { - value = static_cast<RenderListItem*>(object)->explicitValue(); + if (toRenderListItem(object)->hasExplicitValue()) { + value = toRenderListItem(object)->explicitValue(); isReset = true; return true; } @@ -143,13 +143,19 @@ static bool findPlaceForCounter(RenderObject* object, const AtomicString& counte RenderObject* resetCandidate = isReset ? object->parent() : previousSiblingOrParent(object); RenderObject* prevCounterCandidate = object; CounterNode* candidateCounter = 0; + // When a reset counter is chosen as candidateCounter, we'll + // decide the new node should be a child of the reset node or a + // sibling or the reset node. This flag controls it. + bool createChildForReset = true; while ((prevCounterCandidate = prevCounterCandidate->previousInPreOrder())) { CounterNode* c = counter(prevCounterCandidate, counterName, false); if (prevCounterCandidate == resetCandidate) { - if (!candidateCounter) + if (!candidateCounter) { candidateCounter = c; + createChildForReset = true; + } if (candidateCounter) { - if (candidateCounter->isReset()) { + if (createChildForReset && candidateCounter->isReset()) { parent = candidateCounter; previousSibling = 0; } else { @@ -160,10 +166,19 @@ static bool findPlaceForCounter(RenderObject* object, const AtomicString& counte } resetCandidate = previousSiblingOrParent(resetCandidate); } else if (c) { - if (c->isReset()) - candidateCounter = 0; - else if (!candidateCounter) + if (c->isReset()) { + if (c->parent()) { + // The new node may be the next sibling of this reset node. + createChildForReset = false; + candidateCounter = c; + } else { + createChildForReset = true; + candidateCounter = 0; + } + } else if (!candidateCounter) { + createChildForReset = true; candidateCounter = c; + } } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderCounter.h b/src/3rdparty/webkit/WebCore/rendering/RenderCounter.h index 55aab7300..961968e16 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderCounter.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderCounter.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -33,21 +33,30 @@ class RenderCounter : public RenderText { public: RenderCounter(Document*, const CounterContent&); + void invalidate(); + + static void destroyCounterNodes(RenderObject*); + +private: virtual const char* renderName() const; virtual bool isCounter() const; virtual PassRefPtr<StringImpl> originalText() const; virtual void calcPrefWidths(int leadWidth); - void invalidate(); - - static void destroyCounterNodes(RenderObject*); - -private: CounterContent m_counter; mutable CounterNode* m_counterNode; }; +inline RenderCounter* toRenderCounter(RenderObject* object) +{ + ASSERT(!object || object->isCounter()); + return static_cast<RenderCounter*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderCounter(const RenderCounter*); + } // namespace WebCore #endif // RenderCounter_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp index 437991acd..8618d11c0 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp @@ -108,10 +108,11 @@ RenderBox* RenderFieldset::findLegend() const { for (RenderObject* legend = firstChild(); legend; legend = legend->nextSibling()) { if (!legend->isFloatingOrPositioned() && legend->node() && - legend->node()->hasTagName(legendTag) + (legend->node()->hasTagName(legendTag) #if ENABLE(WML) || legend->node()->hasTagName(WMLNames::insertedLegendTag) #endif + ) ) return toRenderBox(legend); } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.h b/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.h index ed57d3a50..df6a1daf3 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.h @@ -1,10 +1,8 @@ /* - * This file is part of the DOM implementation for KDE. - * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2004, 2006 Apple Computer, Inc. + * Copyright (C) 2004, 2006, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -34,6 +32,9 @@ class RenderFieldset : public RenderBlock { public: RenderFieldset(Node*); + RenderBox* findLegend() const; + +private: virtual const char* renderName() const { return "RenderFieldSet"; } virtual bool isFieldset() const { return true; } @@ -43,17 +44,23 @@ public: virtual bool avoidsFloats() const { return true; } virtual bool stretchesToMinIntrinsicWidth() const { return true; } - RenderBox* findLegend() const; - -protected: virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); -private: virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); - virtual void paintMask(PaintInfo& paintInfo, int tx, int ty); + virtual void paintMask(PaintInfo&, int tx, int ty); + void paintBorderMinusLegend(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, int lx, int lw, int lb); }; +inline RenderFieldset* toRenderFieldset(RenderObject* object) +{ + ASSERT(!object || object->isFieldset()); + return static_cast<RenderFieldset*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderFieldset(const RenderFieldset*); + } // namespace WebCore #endif // RenderFieldset_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.h b/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.h index 85bc09f1c..bd7d62a49 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. + * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -35,13 +35,7 @@ class HTMLInputElement; class RenderFileUploadControl : public RenderBlock, private FileChooserClient { public: RenderFileUploadControl(HTMLInputElement*); - ~RenderFileUploadControl(); - - virtual const char* renderName() const { return "RenderFileUploadControl"; } - - virtual void updateFromElement(); - virtual void calcPrefWidths(); - virtual void paintObject(PaintInfo&, int tx, int ty); + virtual ~RenderFileUploadControl(); void click(); @@ -54,10 +48,15 @@ public: bool allowsMultipleFiles(); -protected: +private: + virtual const char* renderName() const { return "RenderFileUploadControl"; } + + virtual void updateFromElement(); + virtual void calcPrefWidths(); + virtual void paintObject(PaintInfo&, int tx, int ty); + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); -private: int maxFilenameWidth() const; PassRefPtr<RenderStyle> createButtonStyle(const RenderStyle* parentStyle) const; @@ -65,6 +64,15 @@ private: RefPtr<FileChooser> m_fileChooser; }; +inline RenderFileUploadControl* toRenderFileUploadControl(RenderObject* object) +{ + ASSERT(!object || !strcmp(object->renderName(), "RenderFileUploadControl")); + return static_cast<RenderFileUploadControl*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderFileUploadControl(const RenderFileUploadControl*); + } // namespace WebCore #endif // RenderFileUploadControl_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFlexibleBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderFlexibleBox.cpp index e9fc7aa60..63c72fd0d 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderFlexibleBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderFlexibleBox.cpp @@ -216,7 +216,8 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren) calcWidth(); calcHeight(); - m_overflowWidth = width(); + + m_overflow.clear(); if (previousWidth != width() || previousHeight != height() || (parent()->isFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL && @@ -224,7 +225,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren) relayoutChildren = true; setHeight(0); - m_overflowHeight = 0; + m_flexingChildren = m_stretchingChildren = false; initMaxMarginValues(); @@ -242,15 +243,8 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren) else layoutVerticalBox(relayoutChildren); - int oldHeight = height(); calcHeight(); - if (oldHeight != height()) { - // If the block got expanded in size, then increase our overflowheight to match. - if (m_overflowHeight > height()) - m_overflowHeight -= (borderBottom() + paddingBottom() + horizontalScrollbarHeight()); - if (m_overflowHeight < height()) - m_overflowHeight = height(); - } + if (previousHeight != height()) relayoutChildren = true; @@ -273,27 +267,14 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren) setMaxTopMargins(pos, neg); setMaxBottomMargins(0, 0); } + + // Add in the overflow from children. + FlexBoxIterator iterator(this); + for (RenderBox* child = iterator.first(); child; child = iterator.next()) + addOverflowFromChild(child); - // Always ensure our overflow width is at least as large as our width. - if (m_overflowWidth < width()) - m_overflowWidth = width(); - - if (!hasOverflowClip()) { - for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - m_overflowLeft = min(m_overflowLeft, boxShadow->x - boxShadow->blur - boxShadow->spread); - m_overflowWidth = max(m_overflowWidth, width() + boxShadow->x + boxShadow->blur + boxShadow->spread); - m_overflowTop = min(m_overflowTop, boxShadow->y - boxShadow->blur - boxShadow->spread); - m_overflowHeight = max(m_overflowHeight, height() + boxShadow->y + boxShadow->blur + boxShadow->spread); - } - - if (hasReflection()) { - IntRect reflection(reflectionBox()); - m_overflowTop = min(m_overflowTop, reflection.y()); - m_overflowHeight = max(m_overflowHeight, reflection.bottom()); - m_overflowLeft = min(m_overflowLeft, reflection.x()); - m_overflowHeight = max(m_overflowWidth, reflection.right()); - } - } + // Add visual overflow from box-shadow and reflections. + addShadowOverflow(); statePusher.pop(); @@ -308,23 +289,10 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren) setNeedsLayout(false); } -void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) +// The first walk over our kids is to find out if we have any flexible children. +static void gatherFlexChildrenInfo(FlexBoxIterator& iterator, bool relayoutChildren, unsigned int& highestFlexGroup, unsigned int& lowestFlexGroup, bool& haveFlex) { - int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight(); - int yPos = borderTop() + paddingTop(); - int xPos = borderLeft() + paddingLeft(); - bool heightSpecified = false; - int oldHeight = 0; - - unsigned int highestFlexGroup = 0; - unsigned int lowestFlexGroup = 0; - bool haveFlex = false; - int remainingSpace = 0; - m_overflowHeight = height(); - - // The first walk over our kids is to find out if we have any flexible children. - FlexBoxIterator iterator(this); - RenderBox* child = iterator.next(); + RenderBox* child = iterator.first(); while (child) { // Check to see if this child flexes. if (!child->isPositioned() && child->style()->boxFlex() > 0.0f) { @@ -344,6 +312,26 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) } child = iterator.next(); } +} + +void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) +{ + int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight(); + int yPos = borderTop() + paddingTop(); + int xPos = borderLeft() + paddingLeft(); + bool heightSpecified = false; + int oldHeight = 0; + + int remainingSpace = 0; + + + FlexBoxIterator iterator(this); + unsigned int highestFlexGroup = 0; + unsigned int lowestFlexGroup = 0; + bool haveFlex = false; + gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex); + + RenderBox* child; RenderBlock::startDelayUpdateScrollInfo(); @@ -352,7 +340,7 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) do { // Reset our height. setHeight(yPos); - m_overflowHeight = height(); + xPos = borderLeft() + paddingLeft(); // Our first pass is done without flexing. We simply lay the children @@ -403,10 +391,6 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) setHeight(height() + lineHeight(true, true)); setHeight(height() + toAdd); - - // Always make sure our overflowheight is at least our height. - if (m_overflowHeight < height()) - m_overflowHeight = height(); oldHeight = height(); calcHeight(); @@ -465,12 +449,6 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) } placeChild(child, xPos, childY); - - if (child->isRenderBlock()) - toRenderBlock(child)->addVisualOverflow(toRenderBlock(child)->floatRect()); - - m_overflowHeight = max(m_overflowHeight, childY + child->overflowHeight(false)); - m_overflowTop = min(m_overflowTop, child->y() + child->overflowTop(false)); xPos += child->width() + child->marginRight(); @@ -634,22 +612,6 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) } } - child = iterator.first(); - while (child && child->isPositioned()) { - child = iterator.next(); - } - - if (child) { - m_overflowLeft = min(child->x() + child->overflowLeft(false), m_overflowLeft); - - RenderBox* lastChild = child; - while ((child = iterator.next())) { - if (!child->isPositioned()) - lastChild = child; - } - m_overflowWidth = max(lastChild->x() + lastChild->overflowWidth(false), m_overflowWidth); - } - // So that the calcHeight in layoutBlock() knows to relayout positioned objects because of // a height change, we revert our height back to the intrinsic height before returning. if (heightSpecified) @@ -665,34 +627,16 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight(); bool heightSpecified = false; int oldHeight = 0; - + + int remainingSpace = 0; + + FlexBoxIterator iterator(this); unsigned int highestFlexGroup = 0; unsigned int lowestFlexGroup = 0; bool haveFlex = false; - int remainingSpace = 0; - - // The first walk over our kids is to find out if we have any flexible children. - FlexBoxIterator iterator(this); - RenderBox* child = iterator.next(); - while (child) { - // Check to see if this child flexes. - if (!child->isPositioned() && child->style()->boxFlex() > 0.0f) { - // We always have to lay out flexible objects again, since the flex distribution - // may have changed, and we need to reallocate space. - child->setOverrideSize(-1); - if (!relayoutChildren) - child->setChildNeedsLayout(true, false); - haveFlex = true; - unsigned int flexGroup = child->style()->boxFlexGroup(); - if (lowestFlexGroup == 0) - lowestFlexGroup = flexGroup; - if (flexGroup < lowestFlexGroup) - lowestFlexGroup = flexGroup; - if (flexGroup > highestFlexGroup) - highestFlexGroup = flexGroup; - } - child = iterator.next(); - } + gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex); + + RenderBox* child; // We confine the line clamp ugliness to vertical flexible boxes (thus keeping it out of // mainstream block layout); this is not really part of the XUL box model. @@ -810,7 +754,6 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) do { setHeight(borderTop() + paddingTop()); int minHeight = height() + toAdd; - m_overflowHeight = height(); child = iterator.first(); while (child) { @@ -818,8 +761,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) if (!haveLineClamp && (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())))) child->setChildNeedsLayout(true, false); - if (child->isPositioned()) - { + if (child->isPositioned()) { child->containingBlock()->insertPositionedObject(child); if (child->style()->hasStaticX()) { if (style()->direction() == LTR) @@ -866,14 +808,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) // Place the child. placeChild(child, childX, height()); setHeight(height() + child->height() + child->marginBottom()); - - if (child->isRenderBlock()) - toRenderBlock(child)->addVisualOverflow(toRenderBlock(child)->floatRect()); - // See if this child has made our overflow need to grow. - m_overflowWidth = max(child->x() + child->overflowWidth(false), m_overflowWidth); - m_overflowLeft = min(child->x() + child->overflowLeft(false), m_overflowLeft); - child = iterator.next(); } @@ -889,10 +824,6 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) if (height() < minHeight) setHeight(minHeight); - // Always make sure our overflowheight is at least our height. - if (m_overflowHeight < height()) - m_overflowHeight = height(); - // Now we have to calc our height, so we know how much space we have remaining. oldHeight = height(); calcHeight(); @@ -1050,22 +981,6 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) } } } - - child = iterator.first(); - while (child && child->isPositioned()) { - child = iterator.next(); - } - - if (child) { - m_overflowTop = min(child->y() + child->overflowTop(false), m_overflowTop); - - RenderBox* lastChild = child; - while ((child = iterator.next())) { - if (!child->isPositioned()) - lastChild = child; - } - m_overflowHeight = max(lastChild->y() + lastChild->overflowHeight(false), m_overflowHeight); - } // So that the calcHeight in layoutBlock() knows to relayout positioned objects because of // a height change, we revert our height back to the intrinsic height before returning. @@ -1151,6 +1066,8 @@ const char *RenderFlexibleBox::renderName() const return "RenderFlexibleBox (floating)"; if (isPositioned()) return "RenderFlexibleBox (positioned)"; + if (isAnonymous()) + return "RenderFlexibleBox (generated)"; if (isRelPositioned()) return "RenderFlexibleBox (relative positioned)"; return "RenderFlexibleBox"; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h index 8fdb81678..e014f22a5 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h @@ -49,6 +49,7 @@ public: virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction); virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); + virtual bool isSVGForeignObject() const { return true; } private: TransformationMatrix translationForAttributes() const; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFrame.h b/src/3rdparty/webkit/WebCore/rendering/RenderFrame.h index 2716e14fb..587a8bd6e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderFrame.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderFrame.h @@ -43,6 +43,15 @@ private: virtual void viewCleared(); }; +inline RenderFrame* toRenderFrame(RenderObject* object) +{ + ASSERT(!object || object->isFrame()); + return static_cast<RenderFrame*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderFrame(const RenderFrame*); + } // namespace WebCore #endif // RenderFrame_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.cpp index 57c8a2f01..2fe1ddbf1 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.cpp @@ -416,9 +416,9 @@ void RenderFrameSet::computeEdgeInfo() for (int c = 0; c < cols; ++c) { FrameEdgeInfo edgeInfo; if (child->isFrameSet()) - edgeInfo = static_cast<RenderFrameSet*>(child)->edgeInfo(); + edgeInfo = toRenderFrameSet(child)->edgeInfo(); else - edgeInfo = static_cast<RenderFrame*>(child)->edgeInfo(); + edgeInfo = toRenderFrame(child)->edgeInfo(); fillFromEdgeInfo(edgeInfo, r, c); child = child->nextSibling(); if (!child) @@ -590,9 +590,10 @@ bool RenderFrameSet::userResize(MouseEvent* evt) void RenderFrameSet::setIsResizing(bool isResizing) { m_isResizing = isResizing; - for (RenderObject* p = parent(); p; p = p->parent()) - if (p->isFrameSet()) - static_cast<RenderFrameSet*>(p)->m_isChildResizing = isResizing; + for (RenderObject* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { + if (ancestor->isFrameSet()) + toRenderFrameSet(ancestor)->m_isChildResizing = isResizing; + } if (Frame* frame = document()->frame()) frame->eventHandler()->setResizingFrameSet(isResizing ? frameSet() : 0); } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.h b/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.h index 9f905023b..26bf73281 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.h @@ -57,19 +57,9 @@ public: RenderFrameSet(HTMLFrameSetElement*); virtual ~RenderFrameSet(); - virtual RenderObjectChildList* virtualChildren() { return children(); } - virtual const RenderObjectChildList* virtualChildren() const { return children(); } const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } - virtual const char* renderName() const { return "RenderFrameSet"; } - virtual bool isFrameSet() const { return true; } - - virtual void layout(); - virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); - virtual void paint(PaintInfo& paintInfo, int tx, int ty); - virtual bool isChildAllowed(RenderObject*, RenderStyle*) const; - FrameEdgeInfo edgeInfo() const; bool userResize(MouseEvent*); @@ -95,6 +85,17 @@ private: int m_splitResizeOffset; }; + virtual RenderObjectChildList* virtualChildren() { return children(); } + virtual const RenderObjectChildList* virtualChildren() const { return children(); } + + virtual const char* renderName() const { return "RenderFrameSet"; } + virtual bool isFrameSet() const { return true; } + + virtual void layout(); + virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); + virtual void paint(PaintInfo&, int tx, int ty); + virtual bool isChildAllowed(RenderObject*, RenderStyle*) const; + inline HTMLFrameSetElement* frameSet() const; void setIsResizing(bool); @@ -110,8 +111,8 @@ private: void startResizing(GridAxis&, int position); void continueResizing(GridAxis&, int position); - void paintRowBorder(const PaintInfo& paintInfo, const IntRect& rect); - void paintColumnBorder(const PaintInfo& paintInfo, const IntRect& rect); + void paintRowBorder(const PaintInfo&, const IntRect&); + void paintColumnBorder(const PaintInfo&, const IntRect&); RenderObjectChildList m_children; @@ -122,6 +123,16 @@ private: bool m_isChildResizing; }; + +inline RenderFrameSet* toRenderFrameSet(RenderObject* object) +{ + ASSERT(!object || object->isFrameSet()); + return static_cast<RenderFrameSet*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderFrameSet(const RenderFrameSet*); + } // namespace WebCore #endif // RenderFrameSet_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderHTMLCanvas.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderHTMLCanvas.cpp index 1fc07f034..8c17a0e0e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderHTMLCanvas.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderHTMLCanvas.cpp @@ -43,6 +43,19 @@ RenderHTMLCanvas::RenderHTMLCanvas(HTMLCanvasElement* element) view()->frameView()->setIsVisuallyNonEmpty(); } +bool RenderHTMLCanvas::requiresLayer() const +{ + if (RenderReplaced::requiresLayer()) + return true; + +#if ENABLE(3D_CANVAS) + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(node()); + return canvas && canvas->is3D(); +#else + return false; +#endif +} + void RenderHTMLCanvas::paintReplaced(PaintInfo& paintInfo, int tx, int ty) { IntRect rect = contentBoxRect(); @@ -55,10 +68,13 @@ void RenderHTMLCanvas::canvasSizeChanged() IntSize canvasSize = static_cast<HTMLCanvasElement*>(node())->size(); IntSize zoomedSize(canvasSize.width() * style()->effectiveZoom(), canvasSize.height() * style()->effectiveZoom()); - if (canvasSize == intrinsicSize()) + if (zoomedSize == intrinsicSize()) return; - setIntrinsicSize(canvasSize); + setIntrinsicSize(zoomedSize); + + if (!parent()) + return; if (!prefWidthsDirty()) setPrefWidthsDirty(true); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderHTMLCanvas.h b/src/3rdparty/webkit/WebCore/rendering/RenderHTMLCanvas.h index ad6c5051e..473dad5da 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderHTMLCanvas.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderHTMLCanvas.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,17 +36,26 @@ class RenderHTMLCanvas : public RenderReplaced { public: RenderHTMLCanvas(HTMLCanvasElement*); - virtual const char* renderName() const { return "RenderHTMLCanvas"; } - - virtual void paintReplaced(PaintInfo& paintInfo, int tx, int ty); + virtual bool isCanvas() const { return true; } + virtual bool requiresLayer() const; void canvasSizeChanged(); -protected: +private: + virtual const char* renderName() const { return "RenderHTMLCanvas"; } + virtual void paintReplaced(PaintInfo&, int tx, int ty); virtual void intrinsicSizeChanged() { canvasSizeChanged(); } - }; +inline RenderHTMLCanvas* toRenderHTMLCanvas(RenderObject* object) +{ + ASSERT(!object || !strcmp(object->renderName(), "RenderHTMLCanvas")); + return static_cast<RenderHTMLCanvas*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderHTMLCanvas(const RenderHTMLCanvas*); + } // namespace WebCore #endif // RenderHTMLCanvas_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp index 559406b64..4206b1cf1 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp @@ -26,9 +26,6 @@ #include "config.h" #include "RenderImage.h" -#include "BitmapImage.h" -#include "Document.h" -#include "FrameView.h" #include "GraphicsContext.h" #include "HTMLImageElement.h" #include "HTMLInputElement.h" @@ -230,7 +227,7 @@ bool RenderImage::setImageSizeForAltText(CachedImage* newImage /* = 0 */) imageHeight = paddingHeight; } - if (newImage) { + if (newImage && newImage->image()) { // imageSize() returns 0 for the error image. We need the true size of the // error image, so we have to get it by grabbing image() directly. imageWidth += newImage->image()->width() * style()->effectiveZoom(); @@ -439,20 +436,21 @@ int RenderImage::minimumReplacedHeight() const HTMLMapElement* RenderImage::imageMap() { HTMLImageElement* i = node() && node()->hasTagName(imgTag) ? static_cast<HTMLImageElement*>(node()) : 0; - return i ? i->document()->getImageMap(i->useMap()) : 0; + return i ? i->document()->getImageMap(i->getAttribute(usemapAttr)) : 0; } -bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction) +bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) { HitTestResult tempResult(result.point()); - bool inside = RenderReplaced::nodeAtPoint(request, tempResult, _x, _y, _tx, _ty, hitTestAction); + bool inside = RenderReplaced::nodeAtPoint(request, tempResult, x, y, tx, ty, hitTestAction); if (inside && node()) { - int tx = _tx + x(); - int ty = _ty + y(); - if (HTMLMapElement* map = imageMap()) { - if (map->mapMouseEvent(_x - tx, _y - ty, IntSize(contentWidth(), contentHeight()), tempResult)) + IntRect contentBox = contentBoxRect(); + float zoom = style()->effectiveZoom(); + int mapX = lroundf((x - tx - this->x() - contentBox.x()) / zoom); + int mapY = lroundf((y - ty - this->y() - contentBox.y()) / zoom); + if (map->mapMouseEvent(mapX, mapY, contentBox.size(), tempResult)) tempResult.setInnerNonSharedNode(node()); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderImage.h b/src/3rdparty/webkit/WebCore/rendering/RenderImage.h index 042452f9b..2224412ae 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderImage.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderImage.h @@ -3,7 +3,7 @@ * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com) * (C) 2006 Samuel Weinig (sam.weinig@gmail.com) - * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,8 +25,6 @@ #ifndef RenderImage_h #define RenderImage_h -#include "CachedImage.h" -#include "CachedResourceHandle.h" #include "RenderReplaced.h" namespace WebCore { @@ -38,18 +36,6 @@ public: RenderImage(Node*); virtual ~RenderImage(); - virtual const char* renderName() const { return "RenderImage"; } - - virtual bool isImage() const { return true; } - virtual bool isRenderImage() const { return true; } - - virtual void paintReplaced(PaintInfo& paintInfo, int tx, int ty); - - virtual int minimumReplacedHeight() const; - - virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); - virtual void notifyFinished(CachedResource*); - bool setImageSizeForAltText(CachedImage* newImage = 0); void updateAltText(); @@ -57,13 +43,6 @@ public: void setCachedImage(CachedImage*); CachedImage* cachedImage() const { return m_cachedImage.get(); } - virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); - - virtual int calcReplacedWidth(bool includeMaxWidth = true) const; - virtual int calcReplacedHeight() const; - - virtual void calcPrefWidths(); - HTMLMapElement* imageMap(); void resetAnimation(); @@ -73,8 +52,29 @@ public: void highQualityRepaintTimerFired(Timer<RenderImage>*); protected: - virtual Image* image(int /*w*/ = 0, int /*h*/ = 0) { return m_cachedImage ? m_cachedImage->image() : nullImage(); } + virtual Image* image(int /* width */ = 0, int /* height */ = 0) { return m_cachedImage ? m_cachedImage->image() : nullImage(); } virtual bool errorOccurred() const { return m_cachedImage && m_cachedImage->errorOccurred(); } + + virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); + +private: + virtual const char* renderName() const { return "RenderImage"; } + + virtual bool isImage() const { return true; } + virtual bool isRenderImage() const { return true; } + + virtual void paintReplaced(PaintInfo&, int tx, int ty); + + virtual int minimumReplacedHeight() const; + + virtual void notifyFinished(CachedResource*); + virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); + + virtual int calcReplacedWidth(bool includeMaxWidth = true) const; + virtual int calcReplacedHeight() const; + + virtual void calcPrefWidths(); + virtual bool usesImageContainerSize() const { return m_cachedImage ? m_cachedImage->usesImageContainerSize() : false; } virtual void setImageContainerSize(const IntSize& size) const { if (m_cachedImage) m_cachedImage->setImageContainerSize(size); } virtual bool imageHasRelativeWidth() const { return m_cachedImage ? m_cachedImage->imageHasRelativeWidth() : false; } @@ -84,7 +84,6 @@ protected: virtual void intrinsicSizeChanged() { imageChanged(imagePtr()); } -private: int calcAspectRatioWidth() const; int calcAspectRatioHeight() const; @@ -95,6 +94,7 @@ protected: // The image we are rendering. CachedResourceHandle<CachedImage> m_cachedImage; +private: // Text to display as long as the image isn't available. String m_altText; @@ -103,16 +103,16 @@ protected: friend class RenderImageScaleObserver; }; -inline RenderImage* toRenderImage(RenderObject* o) +inline RenderImage* toRenderImage(RenderObject* object) { - ASSERT(!o || o->isRenderImage()); - return static_cast<RenderImage*>(o); + ASSERT(!object || object->isRenderImage()); + return static_cast<RenderImage*>(object); } -inline const RenderImage* toRenderImage(const RenderObject* o) +inline const RenderImage* toRenderImage(const RenderObject* object) { - ASSERT(!o || o->isRenderImage()); - return static_cast<const RenderImage*>(o); + ASSERT(!object || object->isRenderImage()); + return static_cast<const RenderImage*>(object); } // This will catch anyone doing an unnecessary cast. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderInline.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderInline.cpp index f798a5606..2f9a247a5 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderInline.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderInline.cpp @@ -1,9 +1,7 @@ /* - * This file is part of the render object implementation for KHTML. - * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -32,6 +30,7 @@ #include "RenderArena.h" #include "RenderBlock.h" #include "RenderView.h" +#include "TransformState.h" #include "VisiblePosition.h" #if ENABLE(DASHBOARD_SUPPORT) @@ -51,21 +50,20 @@ RenderInline::RenderInline(Node* node) setChildrenInline(true); } -RenderInline::~RenderInline() -{ -} - void RenderInline::destroy() { - // Detach our continuation first. - if (m_continuation) - m_continuation->destroy(); - m_continuation = 0; - // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise. children()->destroyLeftoverChildren(); + // Destroy our continuation before anything other than anonymous children. + // The reason we don't destroy it before anonymous children is that they may + // have continuations of their own that are anonymous children of our continuation. + if (m_continuation) { + m_continuation->destroy(); + m_continuation = 0; + } + if (!documentBeingDestroyed()) { if (firstLineBox()) { // We can't wait for RenderBoxModelObject::destroy to clear the selection, @@ -137,18 +135,6 @@ void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt } } -static inline bool isAfterContent(RenderObject* child) -{ - if (!child) - return false; - if (child->style()->styleType() != AFTER) - return false; - // Text nodes don't have their own styles, so ignore the style on a text node. - if (child->isText() && !child->isBR()) - return false; - return true; -} - void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild) { if (continuation()) @@ -258,7 +244,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock, // We have been reparented and are now under the fromBlock. We need // to walk up our inline parent chain until we hit the containing block. // Once we hit the containing block we're done. - RenderBoxModelObject* curr = static_cast<RenderBoxModelObject*>(parent()); + RenderBoxModelObject* curr = toRenderBoxModelObject(parent()); RenderBoxModelObject* currChild = this; // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone. @@ -302,7 +288,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock, // Keep walking up the chain. currChild = curr; - curr = static_cast<RenderBoxModelObject*>(curr->parent()); + curr = toRenderBoxModelObject(curr->parent()); splitDepth++; } @@ -384,7 +370,7 @@ void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject* ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock() || beforeChild->parent()->isRenderInline()); RenderBoxModelObject* beforeChildParent = 0; if (beforeChild) - beforeChildParent = static_cast<RenderBoxModelObject*>(beforeChild->parent()); + beforeChildParent = toRenderBoxModelObject(beforeChild->parent()); else { RenderBoxModelObject* cont = nextContinuation(flow); if (cont) @@ -562,6 +548,23 @@ IntRect RenderInline::linesBoundingBox() const return result; } +IntRect RenderInline::linesVisibleOverflowBoundingBox() const +{ + if (!firstLineBox() || !lastLineBox()) + return IntRect(); + + // Return the width of the minimal left side and the maximal right side. + int leftSide = numeric_limits<int>::max(); + int rightSide = numeric_limits<int>::min(); + for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextFlowBox()) { + leftSide = min(leftSide, curr->leftVisibleOverflow()); + rightSide = max(rightSide, curr->rightVisibleOverflow()); + } + + return IntRect(leftSide, firstLineBox()->topVisibleOverflow(), rightSide - leftSide, + lastLineBox()->bottomVisibleOverflow() - firstLineBox()->topVisibleOverflow()); +} + IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) { // Only run-ins are allowed in here during layout. @@ -571,7 +574,7 @@ IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repain return IntRect(); // Find our leftmost position. - IntRect boundingBox(linesBoundingBox()); + IntRect boundingBox(linesVisibleOverflowBoundingBox()); int left = boundingBox.x(); int top = boundingBox.y(); @@ -653,7 +656,8 @@ void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer, if (repaintContainer == this) return; - RenderObject* o = container(); + bool containerSkipped; + RenderObject* o = container(repaintContainer, &containerSkipped); if (!o) return; @@ -694,10 +698,103 @@ void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer, return; } else rect.setLocation(topLeft); + + if (containerSkipped) { + // If the repaintContainer is below o, then we need to map the rect into repaintContainer's coordinates. + IntSize containerOffset = repaintContainer->offsetFromAncestorContainer(o); + rect.move(-containerOffset); + return; + } o->computeRectForRepaint(repaintContainer, rect, fixed); } +IntSize RenderInline::offsetFromContainer(RenderObject* container) const +{ + ASSERT(container == this->container()); + + IntSize offset; + if (isRelPositioned()) + offset += relativePositionOffset(); + + if (!isInline() || isReplaced()) { + RenderBlock* cb; + if (container->isBlockFlow() && (cb = toRenderBlock(container))->hasColumns()) { + IntRect rect(0, 0, 1, 1); + cb->adjustRectForColumns(rect); + } + } + + if (container->hasOverflowClip()) + offset -= toRenderBox(container)->layer()->scrolledContentOffset(); + + return offset; +} + +void RenderInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const +{ + if (repaintContainer == this) + return; + + if (RenderView *v = view()) { + if (v->layoutStateEnabled() && !repaintContainer) { + LayoutState* layoutState = v->layoutState(); + IntSize offset = layoutState->m_offset; + if (style()->position() == RelativePosition && layer()) + offset += layer()->relativePositionOffset(); + transformState.move(offset); + return; + } + } + + bool containerSkipped; + RenderObject* o = container(repaintContainer, &containerSkipped); + if (!o) + return; + + IntSize containerOffset = offsetFromContainer(o); + + bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D()); + if (useTransforms && shouldUseTransformFromContainer(o)) { + TransformationMatrix t; + getTransformFromContainer(o, containerOffset, t); + transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); + } else + transformState.move(containerOffset.width(), containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); + + if (containerSkipped) { + // There can't be a transform between repaintContainer and o, because transforms create containers, so it should be safe + // to just subtract the delta between the repaintContainer and o. + IntSize containerOffset = repaintContainer->offsetFromAncestorContainer(o); + transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); + return; + } + + o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState); +} + +void RenderInline::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const +{ + // We don't expect this function to be called during layout. + ASSERT(!view() || !view()->layoutStateEnabled()); + + RenderObject* o = container(); + if (!o) + return; + + o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState); + + IntSize containerOffset = offsetFromContainer(o); + + bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D()); + if (useTransforms && shouldUseTransformFromContainer(o)) { + TransformationMatrix t; + getTransformFromContainer(o, containerOffset, t); + transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); + } else + transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); +} + void RenderInline::updateDragState(bool dragOn) { RenderBoxModelObject::updateDragState(dragOn); @@ -836,8 +933,12 @@ void RenderInline::imageChanged(WrappedImagePtr, const IntRect*) void RenderInline::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty) { - for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) - graphicsContext->addFocusRingRect(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height())); + for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { + RootInlineBox* root = curr->root(); + int top = max(root->lineTop(), curr->y()); + int bottom = min(root->lineBottom(), curr->y() + curr->height()); + graphicsContext->addFocusRingRect(IntRect(tx + curr->x(), ty + top, curr->width(), bottom - top)); + } for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { if (!curr->isText() && !curr->isListMarker()) { @@ -889,9 +990,12 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty Vector<IntRect> rects; rects.append(IntRect()); - for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) - rects.append(IntRect(curr->x(), curr->y(), curr->width(), curr->height())); - + for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { + RootInlineBox* root = curr->root(); + int top = max(root->lineTop(), curr->y()); + int bottom = min(root->lineBottom(), curr->y() + curr->height()); + rects.append(IntRect(curr->x(), top, curr->width(), bottom - top)); + } rects.append(IntRect()); for (unsigned i = 1; i < rects.size() - 1; i++) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderInline.h b/src/3rdparty/webkit/WebCore/rendering/RenderInline.h index 5a10068fb..8e9715ccb 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderInline.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderInline.h @@ -1,9 +1,7 @@ /* - * This file is part of the render object implementation for KHTML. - * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003 Apple Computer, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -35,20 +33,54 @@ class Position; class RenderInline : public RenderBoxModelObject { public: RenderInline(Node*); - virtual ~RenderInline(); + virtual void destroy(); + + virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0); + + virtual int marginLeft() const; + virtual int marginRight() const; + + virtual void absoluteRects(Vector<IntRect>&, int tx, int ty); + virtual void absoluteQuads(Vector<FloatQuad>&); + + virtual IntSize offsetFromContainer(RenderObject*) const; + + IntRect linesBoundingBox() const; + IntRect linesVisibleOverflowBoundingBox() const; + + InlineFlowBox* createAndAppendInlineFlowBox(); + + void dirtyLineBoxes(bool fullLayout); + + RenderLineBoxList* lineBoxes() { return &m_lineBoxes; } + const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; } + + InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); } + InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); } + + RenderBoxModelObject* continuation() const { return m_continuation; } + + virtual void updateDragState(bool dragOn); + + IntSize relativePositionedInlineOffset(const RenderBox* child) const; + + virtual void addFocusRingRects(GraphicsContext*, int tx, int ty); + void paintOutline(GraphicsContext*, int tx, int ty); + + int verticalPositionFromCache(bool firstLine) const; + void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; } + +private: virtual RenderObjectChildList* virtualChildren() { return children(); } virtual const RenderObjectChildList* virtualChildren() const { return children(); } const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } - virtual void destroy(); - virtual const char* renderName() const; virtual bool isRenderInline() const { return true; } - virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0); void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild); virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0); @@ -73,95 +105,67 @@ public: // Just ignore top/bottom margins on RenderInlines. virtual int marginTop() const { return 0; } virtual int marginBottom() const { return 0; } - virtual int marginLeft() const; - virtual int marginRight() const; - - virtual void absoluteRects(Vector<IntRect>&, int tx, int ty); - virtual void absoluteQuads(Vector<FloatQuad>&); - virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer); virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth); virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed); + virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState&) const; + virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const; + virtual VisiblePosition positionForPoint(const IntPoint&); - IntRect linesBoundingBox() const; - virtual IntRect borderBoundingBox() const { IntRect boundingBox = linesBoundingBox(); return IntRect(0, 0, boundingBox.width(), boundingBox.height()); } - InlineFlowBox* createAndAppendInlineFlowBox(); virtual InlineFlowBox* createInlineFlowBox(); // Subclassed by SVG and Ruby - void dirtyLineBoxes(bool fullLayout); virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); } - RenderLineBoxList* lineBoxes() { return &m_lineBoxes; } - const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; } - - InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); } - InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); } - virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const; - RenderBoxModelObject* continuation() const { return m_continuation; } RenderInline* inlineContinuation() const; void setContinuation(RenderBoxModelObject* c) { m_continuation = c; } - virtual void updateDragState(bool dragOn); - virtual void childBecameNonInline(RenderObject* child); virtual void updateHitTestResult(HitTestResult&, const IntPoint&); - IntSize relativePositionedInlineOffset(const RenderBox* child) const; - - virtual void addFocusRingRects(GraphicsContext*, int tx, int ty); - void paintOutline(GraphicsContext*, int tx, int ty); - virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); - int verticalPositionFromCache(bool firstLine) const; - void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; } - #if ENABLE(DASHBOARD_SUPPORT) virtual void addDashboardRegions(Vector<DashboardRegionValue>&); #endif -protected: virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); virtual void updateBoxModelInfoFromStyle(); static RenderInline* cloneInline(RenderInline* src); -private: void paintOutlineForLine(GraphicsContext*, int tx, int ty, const IntRect& prevLine, const IntRect& thisLine, const IntRect& nextLine); RenderBoxModelObject* continuationBefore(RenderObject* beforeChild); -protected: RenderObjectChildList m_children; RenderLineBoxList m_lineBoxes; // All of the line boxes created for this inline flow. For example, <i>Hello<br>world.</i> will have two <i> line boxes. -private: RenderBoxModelObject* m_continuation; // Can be either a block or an inline. <b><i><p>Hello</p></i></b>. In this example the <i> will have a block as its continuation but the // <b> will just have an inline as its continuation. mutable int m_lineHeight; mutable int m_verticalPosition; }; -inline RenderInline* toRenderInline(RenderObject* o) +inline RenderInline* toRenderInline(RenderObject* object) { - ASSERT(!o || o->isRenderInline()); - return static_cast<RenderInline*>(o); + ASSERT(!object || object->isRenderInline()); + return static_cast<RenderInline*>(object); } -inline const RenderInline* toRenderInline(const RenderObject* o) +inline const RenderInline* toRenderInline(const RenderObject* object) { - ASSERT(!o || o->isRenderInline()); - return static_cast<const RenderInline*>(o); + ASSERT(!object || object->isRenderInline()); + return static_cast<const RenderInline*>(object); } // This will catch anyone doing an unnecessary cast. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp index 4b6d291d0..fea61c9fe 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp @@ -207,12 +207,8 @@ RenderLayer::~RenderLayer() // Make sure we have no lingering clip rects. ASSERT(!m_clipRects); - if (m_reflection) { - if (!m_reflection->documentBeingDestroyed()) - m_reflection->removeLayers(this); - m_reflection->setParent(0); - m_reflection->destroy(); - } + if (m_reflection) + removeReflection(); if (m_scrollCorner) m_scrollCorner->destroy(); @@ -315,12 +311,19 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags) if (m_reflection) m_reflection->layout(); +#if USE(ACCELERATED_COMPOSITING) + // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update. + bool isUpdateRoot = (flags & IsCompositingUpdateRoot); + if (isComposited()) + flags &= ~IsCompositingUpdateRoot; +#endif + for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) child->updateLayerPositions(flags); #if USE(ACCELERATED_COMPOSITING) if ((flags & UpdateCompositingLayers) && isComposited()) - backing()->updateAfterLayout(RenderLayerBacking::CompositingChildren); + backing()->updateAfterLayout(RenderLayerBacking::CompositingChildren, isUpdateRoot); #endif // With all our children positioned, now update our marquee if we need to. @@ -584,10 +587,10 @@ void RenderLayer::updateLayerPosition() setHeight(box->height()); if (!box->hasOverflowClip()) { - if (box->overflowWidth() > box->width()) - setWidth(box->overflowWidth()); - if (box->overflowHeight() > box->height()) - setHeight(box->overflowHeight()); + if (box->rightLayoutOverflow() > box->width()) + setWidth(box->rightLayoutOverflow()); + if (box->bottomLayoutOverflow() > box->height()) + setHeight(box->bottomLayoutOverflow()); } } } @@ -642,37 +645,44 @@ RenderLayer* RenderLayer::stackingContext() const return layer; } +static inline bool isPositionedContainer(RenderLayer* layer) +{ + RenderObject* o = layer->renderer(); + return o->isRenderView() || o->isPositioned() || o->isRelPositioned() || layer->hasTransform(); +} + RenderLayer* RenderLayer::enclosingPositionedAncestor() const { RenderLayer* curr = parent(); - for ( ; curr && !curr->renderer()->isRenderView() && !curr->renderer()->isPositioned() && !curr->renderer()->isRelPositioned() && !curr->hasTransform(); - curr = curr->parent()) { } + while (curr && !isPositionedContainer(curr)) + curr = curr->parent(); + return curr; } RenderLayer* RenderLayer::enclosingTransformedAncestor() const { RenderLayer* curr = parent(); - for ( ; curr && !curr->renderer()->isRenderView() && !curr->transform(); curr = curr->parent()) - { } + while (curr && !curr->renderer()->isRenderView() && !curr->transform()) + curr = curr->parent(); + return curr; } +static inline const RenderLayer* compositingContainer(const RenderLayer* layer) +{ + return layer->isNormalFlowOnly() ? layer->parent() : layer->stackingContext(); +} + #if USE(ACCELERATED_COMPOSITING) RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const { if (includeSelf && isComposited()) return const_cast<RenderLayer*>(this); - // Compositing layers are parented according to stacking order and overflow list, - // so we have to check whether the parent is a stacking context, or whether - // the child is overflow-only. - bool inNormalFlowList = isNormalFlowOnly(); - for (RenderLayer* curr = parent(); curr; curr = curr->parent()) { - if (curr->isComposited() && (inNormalFlowList || curr->isStackingContext())) - return curr; - - inNormalFlowList = curr->isNormalFlowOnly(); + for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) { + if (curr->isComposited()) + return const_cast<RenderLayer*>(curr); } return 0; @@ -760,6 +770,19 @@ static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransfor } } + // If we have a reflection, then we need to account for that when we push the clip. Reflect our entire + // current transparencyClipBox to catch all child layers. + // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this + // size into the parent layer. + if (l->renderer()->hasReflection()) { + int deltaX = 0; + int deltaY = 0; + l->convertToLayerCoords(rootLayer, deltaX, deltaY); + clipRect.move(-deltaX, -deltaY); + clipRect.unite(l->renderBox()->reflectedRect(clipRect)); + clipRect.move(deltaX, deltaY); + } + // Now map the clipRect via the enclosing transform return enclosingTransform.mapRect(clipRect); } @@ -946,12 +969,44 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i } RenderLayer* parentLayer; - if (renderer()->style()->position() == AbsolutePosition) - parentLayer = enclosingPositionedAncestor(); - else + if (renderer()->style()->position() == AbsolutePosition) { + // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way + parentLayer = parent(); + bool foundAncestorFirst = false; + while (parentLayer) { + if (isPositionedContainer(parentLayer)) + break; + + if (parentLayer == ancestorLayer) { + foundAncestorFirst = true; + break; + } + + parentLayer = parentLayer->parent(); + } + + if (foundAncestorFirst) { + // Found ancestorLayer before the abs. positioned container, so compute offset of both relative + // to enclosingPositionedAncestor and subtract. + RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor(); + + int thisX = 0; + int thisY = 0; + convertToLayerCoords(positionedAncestor, thisX, thisY); + + int ancestorX = 0; + int ancestorY = 0; + ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorX, ancestorY); + + xPos += (thisX - ancestorX); + yPos += (thisY - ancestorY); + return; + } + } else parentLayer = parent(); - if (!parentLayer) return; + if (!parentLayer) + return; parentLayer->convertToLayerCoords(ancestorLayer, xPos, yPos); @@ -959,12 +1014,22 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i yPos += y(); } +static inline int adjustedScrollDelta(int beginningDelta) { + // This implemention matches Firefox's. + // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#856. + const int speedReducer = 12; + + int adjustedDelta = beginningDelta / speedReducer; + if (adjustedDelta > 1) + adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(adjustedDelta))) - 1; + else if (adjustedDelta < -1) + adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(-adjustedDelta))) + 1; + + return adjustedDelta; +} + void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint) { - // We want to reduce the speed if we're close from the original point to improve the handleability of the scroll - const int shortDistanceLimit = 100; // We delimit a 200 pixels long square enclosing the original point - const int speedReducer = 2; // Within this square we divide the scrolling speed by 2 - Frame* frame = renderer()->document()->frame(); if (!frame) return; @@ -981,22 +1046,19 @@ void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint) int xDelta = currentMousePosition.x() - sourcePoint.x(); int yDelta = currentMousePosition.y() - sourcePoint.y(); - if (abs(xDelta) < ScrollView::noPanScrollRadius) // at the center we let the space for the icon + if (abs(xDelta) <= ScrollView::noPanScrollRadius) // at the center we let the space for the icon xDelta = 0; - if (abs(yDelta) < ScrollView::noPanScrollRadius) + if (abs(yDelta) <= ScrollView::noPanScrollRadius) yDelta = 0; - // Let's attenuate the speed for the short distances - if (abs(xDelta) < shortDistanceLimit) - xDelta /= speedReducer; - if (abs(yDelta) < shortDistanceLimit) - yDelta /= speedReducer; - - scrollByRecursively(xDelta, yDelta); + scrollByRecursively(adjustedScrollDelta(xDelta), adjustedScrollDelta(yDelta)); } void RenderLayer::scrollByRecursively(int xDelta, int yDelta) { + if (!xDelta && !yDelta) + return; + bool restrictedByLineClamp = false; if (renderer()->parent()) restrictedByLineClamp = renderer()->parent()->style()->lineClamp() >= 0; @@ -1006,17 +1068,30 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta) int newOffsetY = scrollYOffset() + yDelta; scrollToOffset(newOffsetX, newOffsetY); - // If this layer can't do the scroll we ask its parent + // If this layer can't do the scroll we ask the next layer up that can scroll to try int leftToScrollX = newOffsetX - scrollXOffset(); int leftToScrollY = newOffsetY - scrollYOffset(); if ((leftToScrollX || leftToScrollY) && renderer()->parent()) { - renderer()->parent()->enclosingLayer()->scrollByRecursively(leftToScrollX, leftToScrollY); + RenderObject* nextRenderer = renderer()->parent(); + while (nextRenderer) { + if (nextRenderer->isBox() && toRenderBox(nextRenderer)->canBeScrolledAndHasScrollableArea()) { + nextRenderer->enclosingLayer()->scrollByRecursively(leftToScrollX, leftToScrollY); + break; + } + nextRenderer = nextRenderer->parent(); + } + Frame* frame = renderer()->document()->frame(); if (frame) frame->eventHandler()->updateAutoscrollRenderer(); } - } else if (renderer()->view()->frameView()) + } else if (renderer()->view()->frameView()) { + // If we are here, we were called on a renderer that can be programatically scrolled, but doesn't + // have an overflow clip. Which means that it is a document node that can be scrolled. renderer()->view()->frameView()->scrollBy(IntSize(xDelta, yDelta)); + // FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement? + // https://bugs.webkit.org/show_bug.cgi?id=28237 + } } @@ -1071,8 +1146,10 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai #if USE(ACCELERATED_COMPOSITING) if (compositor()->inCompositingMode()) { - if (RenderLayer* compositingAncestor = ancestorCompositingLayer()) - compositingAncestor->backing()->updateAfterLayout(RenderLayerBacking::AllDescendants); + if (RenderLayer* compositingAncestor = ancestorCompositingLayer()) { + bool isUpdateRoot = true; + compositingAncestor->backing()->updateAfterLayout(RenderLayerBacking::AllDescendants, isUpdateRoot); + } } #endif @@ -1275,7 +1352,9 @@ void RenderLayer::autoscroll() if (!frameView) return; +#if ENABLE(DRAG_SUPPORT) frame->eventHandler()->updateSelectionForMouseDrag(); +#endif IntPoint currentDocumentPosition = frameView->windowToContents(frame->eventHandler()->currentMousePosition()); scrollRectToVisible(IntRect(currentDocumentPosition, IntSize(1, 1)), false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded); @@ -2056,9 +2135,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, // Make sure the parent's clip rects have been calculated. IntRect clipRect = paintDirtyRect; if (parent()) { - ClipRects parentRects; - parentClipRects(rootLayer, parentRects, paintFlags & PaintLayerTemporaryClipRects); - clipRect = parentRects.overflowClipRect(); + clipRect = backgroundClipRect(rootLayer, paintFlags & PaintLayerTemporaryClipRects); clipRect.intersect(paintDirtyRect); } @@ -2363,9 +2440,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont if (transform() && !appliedTransform) { // Make sure the parent's clip rects have been calculated. if (parent()) { - ClipRects parentRects; - parentClipRects(rootLayer, parentRects, useTemporaryClipRects); - IntRect clipRect = parentRects.overflowClipRect(); + IntRect clipRect = backgroundClipRect(rootLayer, useTemporaryClipRects); // Go ahead and test the enclosing clip now. if (!clipRect.contains(hitTestPoint)) return 0; @@ -2663,10 +2738,10 @@ void RenderLayer::parentClipRects(const RenderLayer* rootLayer, ClipRects& clipR clipRects = *parent()->clipRects(); } -void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds, - IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects) const +IntRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, bool temporaryClipRects) const { - if (rootLayer != this && parent()) { + IntRect backgroundRect; + if (parent()) { ClipRects parentRects; parentClipRects(rootLayer, parentRects, temporaryClipRects); backgroundRect = renderer()->style()->position() == FixedPosition ? parentRects.fixedClipRect() : @@ -2676,7 +2751,15 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa ASSERT(view); if (view && parentRects.fixed() && rootLayer->renderer() == view) backgroundRect.move(view->frameView()->scrollX(), view->frameView()->scrollY()); + } + return backgroundRect; +} +void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds, + IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects) const +{ + if (rootLayer != this && parent()) { + backgroundRect = backgroundClipRect(rootLayer, temporaryClipRects); backgroundRect.intersect(paintDirtyRect); } else backgroundRect = paintDirtyRect; @@ -2707,10 +2790,13 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa if (ShadowData* boxShadow = renderer()->style()->boxShadow()) { IntRect overflow = layerBounds; do { - IntRect shadowRect = layerBounds; - shadowRect.move(boxShadow->x, boxShadow->y); - shadowRect.inflate(boxShadow->blur + boxShadow->spread); - overflow.unite(shadowRect); + if (boxShadow->style == Normal) { + IntRect shadowRect = layerBounds; + shadowRect.move(boxShadow->x, boxShadow->y); + shadowRect.inflate(boxShadow->blur + boxShadow->spread); + overflow.unite(shadowRect); + } + boxShadow = boxShadow->next; } while (boxShadow); backgroundRect.intersect(overflow); @@ -2763,7 +2849,7 @@ IntRect RenderLayer::localBoundingBox() const { // There are three special cases we need to consider. // (1) Inline Flows. For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the - // inline. In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the root + // inline. In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the // line boxes of all three lines (including overflow on those lines). // (2) Left/Top Overflow. The width/height of layers already includes right/bottom overflow. However, in the case of left/top // overflow, we have to create a bounding box that will extend to include this overflow. @@ -2777,8 +2863,8 @@ IntRect RenderLayer::localBoundingBox() const InlineFlowBox* firstBox = inlineFlow->firstLineBox(); if (!firstBox) return result; - int top = firstBox->root()->topOverflow(); - int bottom = inlineFlow->lastLineBox()->root()->bottomOverflow(); + int top = firstBox->topVisibleOverflow(); + int bottom = inlineFlow->lastLineBox()->bottomVisibleOverflow(); int left = firstBox->x(); for (InlineRunBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox()) left = min(left, curr->x()); @@ -2789,7 +2875,7 @@ IntRect RenderLayer::localBoundingBox() const if (child->isTableCell()) { IntRect bbox = toRenderBox(child)->borderBoxRect(); result.unite(bbox); - IntRect overflowRect = renderBox()->overflowRect(false); + IntRect overflowRect = renderBox()->visibleOverflowRect(); if (bbox != overflowRect) result.unite(overflowRect); } @@ -2802,7 +2888,7 @@ IntRect RenderLayer::localBoundingBox() const else { IntRect bbox = box->borderBoxRect(); result = bbox; - IntRect overflowRect = box->overflowRect(false); + IntRect overflowRect = box->visibleOverflowRect(); if (bbox != overflowRect) result.unite(overflowRect); } @@ -2865,6 +2951,11 @@ void RenderLayer::clearBacking() { m_backing.clear(); } + +bool RenderLayer::hasCompositedMask() const +{ + return m_backing && m_backing->hasMaskLayer(); +} #endif void RenderLayer::setParent(RenderLayer* parent) @@ -3175,10 +3266,9 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*) m_marquee = 0; } - if (!hasReflection() && m_reflection) { - m_reflection->destroy(); - m_reflection = 0; - } else if (hasReflection()) { + if (!hasReflection() && m_reflection) + removeReflection(); + else if (hasReflection()) { if (!m_reflection) createReflection(); updateReflectionStyle(); @@ -3252,6 +3342,16 @@ void RenderLayer::createReflection() m_reflection->setParent(renderer()); // We create a 1-way connection. } +void RenderLayer::removeReflection() +{ + if (!m_reflection->documentBeingDestroyed()) + m_reflection->removeLayers(this); + + m_reflection->setParent(0); + m_reflection->destroy(); + m_reflection = 0; +} + void RenderLayer::updateReflectionStyle() { RefPtr<RenderStyle> newStyle = RenderStyle::create(); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h index 1772c66c9..a27463858 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h @@ -298,10 +298,11 @@ public: enum UpdateLayerPositionsFlag { DoFullRepaint = 1, CheckForRepaint = 1 << 1, - UpdateCompositingLayers = 1 << 2, + IsCompositingUpdateRoot = 1 << 2, + UpdateCompositingLayers = 1 << 3, }; typedef unsigned UpdateLayerPositionsFlags; - void updateLayerPositions(UpdateLayerPositionsFlags = DoFullRepaint | UpdateCompositingLayers); + void updateLayerPositions(UpdateLayerPositionsFlags = DoFullRepaint | IsCompositingUpdateRoot | UpdateCompositingLayers); void updateTransform(); @@ -327,6 +328,7 @@ public: Vector<RenderLayer*>* normalFlowList() const { return m_normalFlowList; } bool hasVisibleContent() const { return m_hasVisibleContent; } + bool hasVisibleDescendant() const { return m_hasVisibleDescendant; } void setHasVisibleContent(bool); void dirtyVisibleContentStatus(); @@ -415,11 +417,13 @@ public: #if USE(ACCELERATED_COMPOSITING) bool isComposited() const { return m_backing != 0; } + bool hasCompositedMask() const; RenderLayerBacking* backing() const { return m_backing.get(); } RenderLayerBacking* ensureBacking(); void clearBacking(); #else bool isComposited() const { return false; } + bool hasCompositedMask() const { return false; } #endif bool paintsWithTransparency() const @@ -507,11 +511,14 @@ private: Node* enclosingElement() const; void createReflection(); + void removeReflection(); + void updateReflectionStyle(); bool paintingInsideReflection() const { return m_paintingInsideReflection; } void setPaintingInsideReflection(bool b) { m_paintingInsideReflection = b; } void parentClipRects(const RenderLayer* rootLayer, ClipRects&, bool temporaryClipRects = false) const; + IntRect backgroundClipRect(const RenderLayer* rootLayer, bool temporaryClipRects) const; RenderLayer* enclosingTransformedAncestor() const; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp index ce0ffb13b..d7248d49f 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp @@ -28,11 +28,13 @@ #if USE(ACCELERATED_COMPOSITING) #include "AnimationController.h" +#include "CanvasRenderingContext3D.h" #include "CSSPropertyNames.h" #include "CSSStyleSelector.h" #include "FrameView.h" #include "GraphicsContext.h" #include "GraphicsLayer.h" +#include "HTMLCanvasElement.h" #include "HTMLElement.h" #include "HTMLNames.h" #include "RenderBox.h" @@ -47,17 +49,16 @@ using namespace std; namespace WebCore { +using namespace HTMLNames; + static bool hasBorderOutlineOrShadow(const RenderStyle*); static bool hasBoxDecorations(const RenderStyle*); static bool hasBoxDecorationsWithBackgroundImage(const RenderStyle*); RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) : m_owningLayer(layer) - , m_ancestorClippingLayer(0) - , m_graphicsLayer(0) - , m_contentsLayer(0) - , m_clippingLayer(0) , m_hasDirectlyCompositedContent(false) + , m_artificiallyInflatedBounds(false) { createGraphicsLayer(); } @@ -65,13 +66,14 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) RenderLayerBacking::~RenderLayerBacking() { updateClippingLayers(false, false); - updateContentsLayer(false); + updateForegroundLayer(false); + updateMaskLayer(false); destroyGraphicsLayer(); } void RenderLayerBacking::createGraphicsLayer() { - m_graphicsLayer = GraphicsLayer::createGraphicsLayer(this); + m_graphicsLayer = GraphicsLayer::create(this); #ifndef NDEBUG if (renderer()->node()) { @@ -79,7 +81,7 @@ void RenderLayerBacking::createGraphicsLayer() m_graphicsLayer->setName("Document Node"); else { if (renderer()->node()->isHTMLElement() && renderer()->node()->hasID()) - m_graphicsLayer->setName(renderer()->renderName() + String(" ") + static_cast<HTMLElement*>(renderer()->node())->id()); + m_graphicsLayer->setName(renderer()->renderName() + String(" ") + static_cast<HTMLElement*>(renderer()->node())->getAttribute(idAttr)); else m_graphicsLayer->setName(renderer()->renderName()); } @@ -87,8 +89,8 @@ void RenderLayerBacking::createGraphicsLayer() m_graphicsLayer->setName("Anonymous Node"); #endif // NDEBUG - updateLayerOpacity(); - updateLayerTransform(); + updateLayerOpacity(renderer()->style()); + updateLayerTransform(renderer()->style()); } void RenderLayerBacking::destroyGraphicsLayer() @@ -96,25 +98,19 @@ void RenderLayerBacking::destroyGraphicsLayer() if (m_graphicsLayer) m_graphicsLayer->removeFromParent(); - delete m_graphicsLayer; m_graphicsLayer = 0; - - delete m_contentsLayer; - m_contentsLayer = 0; - - delete m_clippingLayer; + m_foregroundLayer = 0; m_clippingLayer = 0; + m_maskLayer = 0; } -void RenderLayerBacking::updateLayerOpacity() +void RenderLayerBacking::updateLayerOpacity(const RenderStyle* style) { - m_graphicsLayer->setOpacity(compositingOpacity(renderer()->opacity()), 0, 0); + m_graphicsLayer->setOpacity(compositingOpacity(style->opacity())); } -void RenderLayerBacking::updateLayerTransform() +void RenderLayerBacking::updateLayerTransform(const RenderStyle* style) { - RenderStyle* style = renderer()->style(); - // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin // baked into it, and we don't want that. TransformationMatrix t; @@ -126,7 +122,31 @@ void RenderLayerBacking::updateLayerTransform() m_graphicsLayer->setTransform(t); } -void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth) +static bool hasNonZeroTransformOrigin(const RenderObject* renderer) +{ + RenderStyle* style = renderer->style(); + return (style->transformOriginX().type() == Fixed && style->transformOriginX().value()) + || (style->transformOriginY().type() == Fixed && style->transformOriginY().value()); +} + +void RenderLayerBacking::updateCompositedBounds() +{ + IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); + + // If the element has a transform-origin that has fixed lengths, and the renderer has zero size, + // then we need to ensure that the compositing layer has non-zero size so that we can apply + // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value). + if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) { + layerBounds.setWidth(1); + layerBounds.setHeight(1); + m_artificiallyInflatedBounds = true; + } else + m_artificiallyInflatedBounds = false; + + setCompositedBounds(layerBounds); +} + +void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth, bool isUpdateRoot) { RenderLayerCompositor* layerCompositor = compositor(); if (!layerCompositor->compositingLayersNeedRebuild()) { @@ -137,10 +157,10 @@ void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth) // // The solution is to update compositing children of this layer here, // via updateCompositingChildrenGeometry(). - setCompositedBounds(layerCompositor->calculateCompositedBounds(m_owningLayer, m_owningLayer)); + updateCompositedBounds(); layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, updateDepth); - if (!m_owningLayer->parent()) { + if (isUpdateRoot) { updateGraphicsLayerGeometry(); layerCompositor->updateRootLayerPosition(); } @@ -152,12 +172,15 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() RenderLayerCompositor* compositor = this->compositor(); bool layerConfigChanged = false; - if (updateContentsLayer(compositor->needsContentsCompositingLayer(m_owningLayer))) + if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer))) layerConfigChanged = true; if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), compositor->clipsCompositingDescendants(m_owningLayer))) layerConfigChanged = true; + if (updateMaskLayer(m_owningLayer->renderer()->hasMask())) + m_graphicsLayer->setMaskLayer(m_maskLayer.get()); + m_hasDirectlyCompositedContent = false; if (canUseDirectCompositing()) { if (renderer()->isImage()) { @@ -165,6 +188,16 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() m_hasDirectlyCompositedContent = true; m_graphicsLayer->setDrawsContent(false); } +#if ENABLE(3D_CANVAS) + else if (renderer()->isCanvas()) { + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node()); + if (canvas->is3D()) { + CanvasRenderingContext3D* context = static_cast<CanvasRenderingContext3D*>(canvas->renderingContext()); + if (context->graphicsContext3D()->platformGraphicsContext3D()) + m_graphicsLayer->setContentsToGraphicsContext3D(context->graphicsContext3D()); + } + } +#endif if (rendererHasBackground()) m_graphicsLayer->setBackgroundColor(rendererBackgroundColor()); @@ -184,11 +217,11 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() // Set transform property, if it is not animating. We have to do this here because the transform // is affected by the layer dimensions. if (!renderer()->animation()->isAnimatingPropertyOnRenderer(renderer(), CSSPropertyWebkitTransform)) - updateLayerTransform(); + updateLayerTransform(renderer()->style()); // Set opacity, if it is not animating. if (!renderer()->animation()->isAnimatingPropertyOnRenderer(renderer(), CSSPropertyOpacity)) - updateLayerOpacity(); + updateLayerOpacity(renderer()->style()); RenderStyle* style = renderer()->style(); m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D); @@ -222,10 +255,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects // for a compositing layer, rootLayer is the layer itself. - ClipRects parentRects; - m_owningLayer->parentClipRects(compAncestor, parentRects, true); - IntRect parentClipRect = parentRects.overflowClipRect(); - + IntRect parentClipRect = m_owningLayer->backgroundClipRect(compAncestor, true); m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation)); m_ancestorClippingLayer->setSize(parentClipRect.size()); @@ -251,13 +281,19 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() } // If we have a layer that clips children, position it. + IntRect clippingBox; if (m_clippingLayer) { - IntRect clippingBox = toRenderBox(renderer())->overflowClipRect(0, 0); + clippingBox = toRenderBox(renderer())->overflowClipRect(0, 0); m_clippingLayer->setPosition(FloatPoint() + (clippingBox.location() - localCompositingBounds.location())); m_clippingLayer->setSize(clippingBox.size()); m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - IntPoint()); } + if (m_maskLayer) { + m_maskLayer->setSize(m_graphicsLayer->size()); + m_maskLayer->setPosition(FloatPoint()); + } + if (m_owningLayer->hasTransform()) { const IntRect borderBox = toRenderBox(renderer())->borderBoxRect(); @@ -292,31 +328,41 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0)); } - if (m_contentsLayer) { - // The contents layer is always coincidental with the graphicsLayer for now. - m_contentsLayer->setPosition(IntPoint(0, 0)); - m_contentsLayer->setSize(newSize); - m_contentsLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer()); + if (m_foregroundLayer) { + FloatPoint foregroundPosition; + FloatSize foregroundSize = newSize; + IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer(); + // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it, + // so that it gets correctly sorted with children. In that case, position relative to the clipping layer. + if (m_clippingLayer) { + foregroundPosition = FloatPoint() + (localCompositingBounds.location() - clippingBox.location()); + foregroundSize = FloatSize(clippingBox.size()); + foregroundOffset = clippingBox.location() - IntPoint(); + } + + m_foregroundLayer->setPosition(foregroundPosition); + m_foregroundLayer->setSize(foregroundSize); + m_foregroundLayer->setOffsetFromRenderer(foregroundOffset); } - m_graphicsLayer->updateContentsRect(); + m_graphicsLayer->setContentsRect(contentsBox()); if (!m_hasDirectlyCompositedContent) - m_graphicsLayer->setDrawsContent(!isSimpleContainerCompositingLayer() && !paintingGoesToWindow()); + m_graphicsLayer->setDrawsContent(!isSimpleContainerCompositingLayer() && !paintingGoesToWindow() && !m_artificiallyInflatedBounds); } void RenderLayerBacking::updateInternalHierarchy() { - // m_contentsLayer has to be inserted in the correct order with child layers, + // m_foregroundLayer has to be inserted in the correct order with child layers, // so it's not inserted here. if (m_ancestorClippingLayer) { m_ancestorClippingLayer->removeAllChildren(); m_graphicsLayer->removeFromParent(); - m_ancestorClippingLayer->addChild(m_graphicsLayer); + m_ancestorClippingLayer->addChild(m_graphicsLayer.get()); } if (m_clippingLayer) { m_clippingLayer->removeFromParent(); - m_graphicsLayer->addChild(m_clippingLayer); + m_graphicsLayer->addChild(m_clippingLayer.get()); } } @@ -327,7 +373,7 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs if (needsAncestorClip) { if (!m_ancestorClippingLayer) { - m_ancestorClippingLayer = GraphicsLayer::createGraphicsLayer(this); + m_ancestorClippingLayer = GraphicsLayer::create(this); #ifndef NDEBUG m_ancestorClippingLayer->setName("Ancestor clipping Layer"); #endif @@ -336,14 +382,13 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs } } else if (m_ancestorClippingLayer) { m_ancestorClippingLayer->removeFromParent(); - delete m_ancestorClippingLayer; m_ancestorClippingLayer = 0; layersChanged = true; } if (needsDescendantClip) { if (!m_clippingLayer) { - m_clippingLayer = GraphicsLayer::createGraphicsLayer(0); + m_clippingLayer = GraphicsLayer::create(0); #ifndef NDEBUG m_clippingLayer->setName("Child clipping Layer"); #endif @@ -352,7 +397,6 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs } } else if (m_clippingLayer) { m_clippingLayer->removeFromParent(); - delete m_clippingLayer; m_clippingLayer = 0; layersChanged = true; } @@ -363,30 +407,66 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs return layersChanged; } -bool RenderLayerBacking::updateContentsLayer(bool needsContentsLayer) +bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer) { bool layerChanged = false; - if (needsContentsLayer) { - if (!m_contentsLayer) { - m_contentsLayer = GraphicsLayer::createGraphicsLayer(this); + if (needsForegroundLayer) { + if (!m_foregroundLayer) { + m_foregroundLayer = GraphicsLayer::create(this); #ifndef NDEBUG - m_contentsLayer->setName("Contents"); + m_foregroundLayer->setName("Foreground"); #endif - m_contentsLayer->setDrawsContent(true); - m_contentsLayer->setDrawingPhase(GraphicsLayerPaintForegroundMask); - m_graphicsLayer->setDrawingPhase(GraphicsLayerPaintBackgroundMask); + m_foregroundLayer->setDrawsContent(true); + m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground); layerChanged = true; } - } else if (m_contentsLayer) { - m_contentsLayer->removeFromParent(); - delete m_contentsLayer; - m_contentsLayer = 0; - m_graphicsLayer->setDrawingPhase(GraphicsLayerPaintAllMask); + } else if (m_foregroundLayer) { + m_foregroundLayer->removeFromParent(); + m_foregroundLayer = 0; layerChanged = true; } + + if (layerChanged) + m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer()); + return layerChanged; } +bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer) +{ + bool layerChanged = false; + if (needsMaskLayer) { + if (!m_maskLayer) { + m_maskLayer = GraphicsLayer::create(this); +#ifndef NDEBUG + m_maskLayer->setName("Mask"); +#endif + m_maskLayer->setDrawsContent(true); + m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask); + layerChanged = true; + } + } else if (m_maskLayer) { + m_maskLayer = 0; + layerChanged = true; + } + + if (layerChanged) + m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer()); + + return layerChanged; +} + +GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const +{ + unsigned phase = GraphicsLayerPaintBackground; + if (!m_foregroundLayer) + phase |= GraphicsLayerPaintForeground; + if (!m_maskLayer) + phase |= GraphicsLayerPaintMask; + + return static_cast<GraphicsLayerPaintingPhase>(phase); +} + float RenderLayerBacking::compositingOpacity(float rendererOpacity) const { float finalOpacity = rendererOpacity; @@ -500,7 +580,7 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const // Now look at the body's renderer. HTMLElement* body = renderObject->document()->body(); - RenderObject* bodyObject = (body && body->hasLocalName(HTMLNames::bodyTag)) ? body->renderer() : 0; + RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0; if (!bodyObject) return false; @@ -582,6 +662,14 @@ bool RenderLayerBacking::canUseDirectCompositing() const { RenderObject* renderObject = renderer(); + // Canvas3D is always direct composited +#if ENABLE(3D_CANVAS) + if (renderer()->isCanvas()) { + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node()); + return canvas->is3D(); + } +#endif + // Reject anything that isn't an image if (!renderObject->isImage() && !renderObject->isVideo()) return false; @@ -600,14 +688,25 @@ bool RenderLayerBacking::canUseDirectCompositing() const void RenderLayerBacking::rendererContentChanged() { - if (canUseDirectCompositing() && renderer()->isImage()) - updateImageContents(); + if (canUseDirectCompositing()) { + if (renderer()->isImage()) + updateImageContents(); + else { +#if ENABLE(3D_CANVAS) + if (renderer()->isCanvas()) { + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node()); + if (canvas->is3D()) + m_graphicsLayer->setGraphicsContext3DNeedsDisplay(); + } +#endif + } + } } void RenderLayerBacking::updateImageContents() { ASSERT(renderer()->isImage()); - RenderImage* imageRenderer = static_cast<RenderImage*>(renderer()); + RenderImage* imageRenderer = toRenderImage(renderer()); CachedImage* cachedImage = imageRenderer->cachedImage(); if (!cachedImage) @@ -657,12 +756,12 @@ FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox } // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted. -IntSize RenderLayerBacking::contentOffsetInCompostingLayer() +IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const { return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y()); } -IntRect RenderLayerBacking::contentsBox(const GraphicsLayer*) +IntRect RenderLayerBacking::contentsBox() const { if (!renderer()->isBox()) return IntRect(); @@ -670,7 +769,7 @@ IntRect RenderLayerBacking::contentsBox(const GraphicsLayer*) IntRect contentsRect; #if ENABLE(VIDEO) if (renderer()->isVideo()) { - RenderVideo* videoRenderer = static_cast<RenderVideo*>(renderer()); + RenderVideo* videoRenderer = toRenderVideo(renderer()); contentsRect = videoRenderer->videoBox(); } else #endif @@ -700,47 +799,36 @@ bool RenderLayerBacking::paintingGoesToWindow() const void RenderLayerBacking::setContentsNeedDisplay() { - bool needViewUpdate = false; - - if (m_graphicsLayer && m_graphicsLayer->drawsContent()) { + if (m_graphicsLayer && m_graphicsLayer->drawsContent()) m_graphicsLayer->setNeedsDisplay(); - needViewUpdate = true; - } - if (m_contentsLayer && m_contentsLayer->drawsContent()) { - m_contentsLayer->setNeedsDisplay(); - needViewUpdate = true; - } - - // Make sure layout happens before we get rendered again. - if (needViewUpdate) - compositor()->scheduleViewUpdate(); + if (m_foregroundLayer && m_foregroundLayer->drawsContent()) + m_foregroundLayer->setNeedsDisplay(); + + if (m_maskLayer && m_maskLayer->drawsContent()) + m_maskLayer->setNeedsDisplay(); } // r is in the coordinate space of the layer's render object void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r) { - bool needViewUpdate = false; - if (m_graphicsLayer && m_graphicsLayer->drawsContent()) { - FloatPoint dirtyOrigin = contentsToGraphicsLayerCoordinates(m_graphicsLayer, FloatPoint(r.x(), r.y())); + FloatPoint dirtyOrigin = contentsToGraphicsLayerCoordinates(m_graphicsLayer.get(), FloatPoint(r.x(), r.y())); FloatRect dirtyRect(dirtyOrigin, r.size()); FloatRect bounds(FloatPoint(), m_graphicsLayer->size()); - if (bounds.intersects(dirtyRect)) { + if (bounds.intersects(dirtyRect)) m_graphicsLayer->setNeedsDisplayInRect(dirtyRect); - needViewUpdate = true; - } } - if (m_contentsLayer && m_contentsLayer->drawsContent()) { + if (m_foregroundLayer && m_foregroundLayer->drawsContent()) { // FIXME: do incremental repaint - m_contentsLayer->setNeedsDisplay(); - needViewUpdate = true; + m_foregroundLayer->setNeedsDisplay(); } - // Make sure layout happens before we get rendered again. - if (needViewUpdate) - compositor()->scheduleViewUpdate(); + if (m_maskLayer && m_maskLayer->drawsContent()) { + // FIXME: do incremental repaint + m_maskLayer->setNeedsDisplay(); + } } static void setClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect) @@ -796,9 +884,9 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* if (paintingRoot && !renderer()->isDescendantOf(paintingRoot)) paintingRootForRenderer = paintingRoot; - bool shouldPaint = m_owningLayer->hasVisibleContent() && m_owningLayer->isSelfPaintingLayer(); + bool shouldPaint = (m_owningLayer->hasVisibleContent() || m_owningLayer->hasVisibleDescendant()) && m_owningLayer->isSelfPaintingLayer(); - if (shouldPaint && (paintingPhase & GraphicsLayerPaintBackgroundMask)) { + if (shouldPaint && (paintingPhase & GraphicsLayerPaintBackground)) { // If this is the root then we need to send in a bigger bounding box // because we'll be painting the background as well (see RenderBox::paintRootBoxDecorations()). IntRect paintBox = clipRectToApply; @@ -842,7 +930,10 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* restoreClip(context, paintDirtyRect, damageRect); } - if (shouldPaint && (paintingPhase & GraphicsLayerPaintForegroundMask)) { + bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText; + bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText; + + if (shouldPaint && (paintingPhase & GraphicsLayerPaintForeground)) { // Now walk the sorted list of children with negative z-indices. Only RenderLayers without compositing layers will paint. // FIXME: should these be painted as background? Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList(); @@ -851,9 +942,6 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot); } - bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText; - bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText; - // Set up the clip used when painting our children. setClip(context, paintDirtyRect, clipRectToApply); RenderObject::PaintInfo paintInfo(context, clipRectToApply, @@ -896,7 +984,9 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot); } - + } + + if (shouldPaint && (paintingPhase & GraphicsLayerPaintMask)) { if (renderer()->hasMask() && !selectionOnly && !damageRect.isEmpty()) { setClip(context, paintDirtyRect, damageRect); @@ -913,7 +1003,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* } // Up-call from compositing layer drawing callback. -void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase drawingPhase, const IntRect& clip) +void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip) { // We have to use the same root as for hit testing, because both methods // can compute and cache clipRects. @@ -931,7 +1021,7 @@ void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& co IntRect dirtyRect = enclosingBBox; dirtyRect.intersect(clipRect); - paintIntoLayer(m_owningLayer, &context, dirtyRect, PaintRestrictionNone, drawingPhase, renderer()); + paintIntoLayer(m_owningLayer, &context, dirtyRect, PaintRestrictionNone, paintingPhase, renderer()); } bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes) @@ -942,8 +1032,8 @@ bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim, if (!hasOpacity && !hasTransform) return false; - GraphicsLayer::TransformValueList transformVector; - GraphicsLayer::FloatValueList opacityVector; + KeyframeValueList transformVector(AnimatedPropertyWebkitTransform); + KeyframeValueList opacityVector(AnimatedPropertyOpacity); for (Vector<KeyframeValue>::const_iterator it = keyframes.beginKeyframes(); it != keyframes.endKeyframes(); ++it) { const RenderStyle* keyframeStyle = it->style(); @@ -956,19 +1046,19 @@ bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim, const TimingFunction* tf = keyframeStyle->hasAnimations() ? &((*keyframeStyle->animations()).animation(0)->timingFunction()) : 0; if (hasTransform) - transformVector.insert(key, &(keyframeStyle->transform()), tf); - + transformVector.insert(new TransformAnimationValue(key, &(keyframeStyle->transform()), tf)); + if (hasOpacity) - opacityVector.insert(key, keyframeStyle->opacity(), tf); + opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf)); } bool didAnimateTransform = !hasTransform; bool didAnimateOpacity = !hasOpacity; - if (hasTransform && m_graphicsLayer->animateTransform(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, beginTime, false)) + if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), beginTime)) didAnimateTransform = true; - if (hasOpacity && m_graphicsLayer->animateFloat(AnimatedPropertyOpacity, opacityVector, anim, beginTime)) + if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), beginTime)) didAnimateOpacity = true; bool runningAcceleratedAnimation = didAnimateTransform && didAnimateOpacity; @@ -986,27 +1076,29 @@ bool RenderLayerBacking::startTransition(double beginTime, int property, const R if (property == (int)CSSPropertyOpacity) { const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity); if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) { - // If beginTime is not 0, we are restarting this transition, so first set the from value - // in case it was smashed by a previous animation. - if (beginTime > 0) - m_graphicsLayer->setOpacity(compositingOpacity(fromStyle->opacity()), 0, 0); - - if (m_graphicsLayer->setOpacity(compositingOpacity(toStyle->opacity()), opacityAnim, beginTime)) + KeyframeValueList opacityVector(AnimatedPropertyOpacity); + opacityVector.insert(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity()))); + opacityVector.insert(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity()))); + // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here. + if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, String(), beginTime)) { + // To ensure that the correct opacity is visible when the animation ends, also set the final opacity. + updateLayerOpacity(toStyle); didAnimate = true; + } } } if (property == (int)CSSPropertyWebkitTransform && m_owningLayer->hasTransform()) { - // We get a TransformOperation, which is a linked list of primitive operations and their arguments. - // Arguments can be floats or Length values, which need to be converted to numbers using - // val.calcFloatValue(renderer()->width()) (or height()). const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform); if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) { - GraphicsLayer::TransformValueList transformVector; - transformVector.insert(0, &fromStyle->transform(), 0); - transformVector.insert(1, &toStyle->transform(), 0); - if (m_graphicsLayer->animateTransform(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, beginTime, true)) + KeyframeValueList transformVector(AnimatedPropertyWebkitTransform); + transformVector.insert(new TransformAnimationValue(0, &fromStyle->transform())); + transformVector.insert(new TransformAnimationValue(1, &toStyle->transform())); + if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, String(), beginTime)) { + // To ensure that the correct transform is visible when the animation ends, also set the final opacity. + updateLayerTransform(toStyle); didAnimate = true; + } } } @@ -1021,21 +1113,32 @@ void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double tim renderer()->animation()->notifyAnimationStarted(renderer(), time); } -void RenderLayerBacking::animationFinished(const String& name, int index, bool reset) +void RenderLayerBacking::notifySyncRequired(const GraphicsLayer*) +{ + if (!renderer()->documentBeingDestroyed()) + compositor()->scheduleSync(); +} + +void RenderLayerBacking::animationFinished(const String& animationName) +{ + m_graphicsLayer->removeAnimationsForKeyframes(animationName); +} + +void RenderLayerBacking::animationPaused(const String& animationName) { - m_graphicsLayer->removeFinishedAnimations(name, index, reset); + m_graphicsLayer->pauseAnimation(animationName); } void RenderLayerBacking::transitionFinished(int property) { AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property); if (animatedProperty != AnimatedPropertyInvalid) - m_graphicsLayer->removeFinishedTransitions(animatedProperty); + m_graphicsLayer->removeAnimationsForProperty(animatedProperty); } -void RenderLayerBacking::suspendAnimations() +void RenderLayerBacking::suspendAnimations(double time) { - m_graphicsLayer->suspendAnimations(); + m_graphicsLayer->suspendAnimations(time); } void RenderLayerBacking::resumeAnimations() diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h index 25b1a31b5..17bcaf707 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h @@ -54,7 +54,7 @@ public: RenderLayer* owningLayer() const { return m_owningLayer; } enum UpdateDepth { CompositingChildren, AllDescendants }; - void updateAfterLayout(UpdateDepth); + void updateAfterLayout(UpdateDepth, bool isUpdateRoot); // Returns true if layer configuration changed. bool updateGraphicsLayerConfiguration(); @@ -63,21 +63,23 @@ public: // Update contents and clipping structure. void updateInternalHierarchy(); // make private - GraphicsLayer* graphicsLayer() const { return m_graphicsLayer; } + GraphicsLayer* graphicsLayer() const { return m_graphicsLayer.get(); } // Layer to clip children bool hasClippingLayer() const { return m_clippingLayer != 0; } - GraphicsLayer* clippingLayer() const { return m_clippingLayer; } + GraphicsLayer* clippingLayer() const { return m_clippingLayer.get(); } // Layer to get clipped by ancestor bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer != 0; } - GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer; } + GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer.get(); } - bool hasContentsLayer() const { return m_contentsLayer != 0; } - GraphicsLayer* contentsLayer() const { return m_contentsLayer; } + bool hasContentsLayer() const { return m_foregroundLayer != 0; } + GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); } - GraphicsLayer* parentForSublayers() const { return m_clippingLayer ? m_clippingLayer : m_graphicsLayer; } - GraphicsLayer* childForSuperlayers() const { return m_ancestorClippingLayer ? m_ancestorClippingLayer : m_graphicsLayer; } + bool hasMaskLayer() const { return m_maskLayer != 0; } + + GraphicsLayer* parentForSublayers() const { return m_clippingLayer ? m_clippingLayer.get() : m_graphicsLayer.get(); } + GraphicsLayer* childForSuperlayers() const { return m_ancestorClippingLayer ? m_ancestorClippingLayer.get() : m_graphicsLayer.get(); } // RenderLayers with backing normally short-circuit paintLayer() because // their content is rendered via callbacks from GraphicsLayer. However, the document @@ -97,24 +99,27 @@ public: // Interface to start, finish, suspend and resume animations and transitions bool startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes); bool startTransition(double beginTime, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle); - void animationFinished(const String& name, int index, bool reset); + void animationFinished(const String& name); + void animationPaused(const String& name); void transitionFinished(int property); - void suspendAnimations(); + void suspendAnimations(double time = 0); void resumeAnimations(); IntRect compositedBounds() const; void setCompositedBounds(const IntRect&); + void updateCompositedBounds(); FloatPoint graphicsLayerToContentsCoordinates(const GraphicsLayer*, const FloatPoint&); FloatPoint contentsToGraphicsLayerCoordinates(const GraphicsLayer*, const FloatPoint&); // GraphicsLayerClient interface virtual void notifyAnimationStarted(const GraphicsLayer*, double startTime); + virtual void notifySyncRequired(const GraphicsLayer*); virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip); - virtual IntRect contentsBox(const GraphicsLayer*); + IntRect contentsBox() const; private: void createGraphicsLayer(); @@ -124,16 +129,19 @@ private: RenderLayerCompositor* compositor() const { return m_owningLayer->compositor(); } bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip); - bool updateContentsLayer(bool needsContentsLayer); + bool updateForegroundLayer(bool needsForegroundLayer); + bool updateMaskLayer(bool needsMaskLayer); - IntSize contentOffsetInCompostingLayer(); + GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const; + + IntSize contentOffsetInCompostingLayer() const; // Result is transform origin in pixels. FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const; // Result is perspective origin in pixels. FloatPoint computePerspectiveOrigin(const IntRect& borderBox) const; - void updateLayerOpacity(); - void updateLayerTransform(); + void updateLayerOpacity(const RenderStyle*); + void updateLayerTransform(const RenderStyle*); // Return the opacity value that this layer should use for compositing. float compositingOpacity(float rendererOpacity) const; @@ -160,14 +168,16 @@ private: private: RenderLayer* m_owningLayer; - GraphicsLayer* m_ancestorClippingLayer; // only used if we are clipped by an ancestor which is not a stacking context - GraphicsLayer* m_graphicsLayer; - GraphicsLayer* m_contentsLayer; // only used in cases where we need to draw the foreground separately - GraphicsLayer* m_clippingLayer; // only used if we have clipping on a stacking context, with compositing children + OwnPtr<GraphicsLayer> m_ancestorClippingLayer; // only used if we are clipped by an ancestor which is not a stacking context + OwnPtr<GraphicsLayer> m_graphicsLayer; + OwnPtr<GraphicsLayer> m_foregroundLayer; // only used in cases where we need to draw the foreground separately + OwnPtr<GraphicsLayer> m_clippingLayer; // only used if we have clipping on a stacking context, with compositing children + OwnPtr<GraphicsLayer> m_maskLayer; // only used if we have a mask IntRect m_compositedBounds; bool m_hasDirectlyCompositedContent; + bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp index b7bccaac3..5201287eb 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp @@ -34,8 +34,8 @@ #include "Frame.h" #include "FrameView.h" #include "GraphicsLayer.h" -#include "HitTestRequest.h" #include "HitTestResult.h" +#include "HTMLCanvasElement.h" #include "Page.h" #include "RenderLayerBacking.h" #include "RenderVideo.h" @@ -92,7 +92,6 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView) RenderLayerCompositor::~RenderLayerCompositor() { ASSERT(!m_rootLayerAttached); - delete m_rootPlatformLayer; } void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */) @@ -124,22 +123,18 @@ void RenderLayerCompositor::cacheAcceleratedCompositingEnabledFlag() void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild) { - if (inCompositingMode()) { - if (!m_compositingLayersNeedRebuild && needRebuild) - scheduleViewUpdate(); - + if (inCompositingMode()) m_compositingLayersNeedRebuild = needRebuild; - } } -void RenderLayerCompositor::scheduleViewUpdate() +void RenderLayerCompositor::scheduleSync() { Frame* frame = m_renderView->frameView()->frame(); Page* page = frame ? frame->page() : 0; if (!page) return; - page->chrome()->client()->scheduleViewUpdate(); + page->chrome()->client()->scheduleCompositingLayerSync(); } void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot) @@ -236,7 +231,7 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR #if ENABLE(VIDEO) if (layerChanged && layer->renderer()->isVideo()) { // If it's a video, give the media player a chance to hook up to the layer. - RenderVideo* video = static_cast<RenderVideo*>(layer->renderer()); + RenderVideo* video = toRenderVideo(layer->renderer()); video->acceleratedRenderingStateChanged(); } #endif @@ -257,6 +252,10 @@ bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, Comp void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer) { + // If the renderer is not attached yet, no need to repaint. + if (!layer->renderer()->parent()) + return; + RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint(); if (!repaintContainer) repaintContainer = m_renderView; @@ -287,6 +286,13 @@ IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* laye return boundingBoxRect; } + if (RenderLayer* reflection = layer->reflectionLayer()) { + if (!reflection->isComposited()) { + IntRect childUnionBounds = calculateCompositedBounds(reflection, layer); + unionBounds.unite(childUnionBounds); + } + } + ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0)); if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { @@ -425,11 +431,11 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O bool haveComputedBounds = false; IntRect absBounds; - if (overlapMap && mustOverlapCompositedLayers) { + if (overlapMap && !overlapMap->isEmpty()) { // If we're testing for overlap, we only need to composite if we overlap something that is already composited. absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox(); haveComputedBounds = true; - mustOverlapCompositedLayers &= overlapsCompositedLayers(*overlapMap, absBounds); + mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds); } layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers); @@ -503,8 +509,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O // If we have a software transform, and we have layers under us, we need to also // be composited. Also, if we have opacity < 1, then we need to be a layer so that // the child layers are opaque, then rendered with opacity on this layer. - if (childState.m_subtreeIsCompositing && - (layer->renderer()->hasTransform() || layer->renderer()->style()->opacity() < 1)) { + if (childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) { layer->setMustOverlapCompositedLayers(true); if (overlapMap) addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); @@ -530,6 +535,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer) { + ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer); ASSERT(childLayer->isComposited()); // It's possible to be called with a parent that isn't yet composited when we're doing @@ -573,7 +579,7 @@ bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const { // FIXME: ideally we need to look at all ancestors for mask or video. But for now, // just bail on the obvious cases. - if (o->hasMask() || o->hasReflection() || !m_hasAcceleratedCompositing) + if (o->hasReflection() || !m_hasAcceleratedCompositing) return false; return o->supportsAcceleratedRendering(); @@ -589,8 +595,7 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru if (layerBacking) { // The compositing state of all our children has been updated already, so now // we can compute and cache the composited bounds for this layer. - layerBacking->setCompositedBounds(calculateCompositedBounds(layer, layer)); - + layerBacking->updateCompositedBounds(); layerBacking->updateGraphicsLayerConfiguration(); layerBacking->updateGraphicsLayerGeometry(); @@ -631,12 +636,12 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru } } - if (updateHierarchy && layerBacking && layerBacking->contentsLayer()) { - // we only have a contents layer if we have an m_layer - layerBacking->contentsLayer()->removeFromParent(); - - GraphicsLayer* hostingLayer = layerBacking->clippingLayer() ? layerBacking->clippingLayer() : layerBacking->graphicsLayer(); - hostingLayer->addChild(layerBacking->contentsLayer()); + if (updateHierarchy && layerBacking && layerBacking->foregroundLayer()) { + layerBacking->foregroundLayer()->removeFromParent(); + + // The foreground layer has to be correctly sorted with child layers, so needs to become a child of the clipping layer. + GraphicsLayer* hostingLayer = layerBacking->parentForSublayers(); + hostingLayer->addChild(layerBacking->foregroundLayer()); } } @@ -670,7 +675,7 @@ void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* com { if (layer != compositingAncestor) { if (RenderLayerBacking* layerBacking = layer->backing()) { - layerBacking->setCompositedBounds(calculateCompositedBounds(layer, layer)); + layerBacking->updateCompositedBounds(); layerBacking->updateGraphicsLayerGeometry(); if (updateDepth == RenderLayerBacking::CompositingChildren) return; @@ -759,7 +764,7 @@ RenderLayer* RenderLayerCompositor::rootRenderLayer() const GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const { - return m_rootPlatformLayer; + return m_rootPlatformLayer.get(); } void RenderLayerCompositor::didMoveOnscreen() @@ -772,7 +777,7 @@ void RenderLayerCompositor::didMoveOnscreen() if (!page) return; - page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer); + page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer.get()); m_rootLayerAttached = true; } @@ -793,7 +798,7 @@ void RenderLayerCompositor::willMoveOffscreen() void RenderLayerCompositor::updateRootLayerPosition() { if (m_rootPlatformLayer) - m_rootPlatformLayer->setSize(FloatSize(m_renderView->overflowWidth(), m_renderView->overflowHeight())); + m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow())); } void RenderLayerCompositor::didStartAcceleratedAnimation() @@ -821,11 +826,12 @@ bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. // static bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const -{ +{ // The root layer always has a compositing layer, but it may not have backing. return (inCompositingMode() && layer->isRootLayer()) || requiresCompositingForTransform(layer->renderer()) || requiresCompositingForVideo(layer->renderer()) || + requiresCompositingForCanvas(layer->renderer()) || layer->renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden || clipsCompositingDescendants(layer) || requiresCompositingForAnimation(layer->renderer()); @@ -862,10 +868,8 @@ bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const if (!computeClipRoot || computeClipRoot == layer) return false; - ClipRects parentRects; - layer->parentClipRects(computeClipRoot, parentRects, true); - - return parentRects.overflowClipRect() != ClipRects::infiniteRect(); + IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true); + return backgroundRect != ClipRects::infiniteRect(); } // Return true if the given layer is a stacking context and has compositing child @@ -890,13 +894,26 @@ bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) { #if ENABLE(VIDEO) if (renderer->isVideo()) { - RenderVideo* video = static_cast<RenderVideo*>(renderer); + RenderVideo* video = toRenderVideo(renderer); return canAccelerateVideoRendering(video); } #endif return false; } +bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const +{ +#if ENABLE(3D_CANVAS) + if (renderer->isCanvas()) { + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node()); + return canvas->is3D(); + } +#else + UNUSED_PARAM(renderer); +#endif + return false; +} + bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const { if (AnimationController* animController = renderer->animation()) { @@ -906,6 +923,11 @@ bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* render return false; } +bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const +{ + return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask(); +} + // If an element has negative z-index children, those children render in front of the // layer background, so we need an extra 'contents' layer for the foreground of the layer // object. @@ -919,8 +941,8 @@ void RenderLayerCompositor::ensureRootPlatformLayer() if (m_rootPlatformLayer) return; - m_rootPlatformLayer = GraphicsLayer::createGraphicsLayer(0); - m_rootPlatformLayer->setSize(FloatSize(m_renderView->overflowWidth(), m_renderView->overflowHeight())); + m_rootPlatformLayer = GraphicsLayer::create(0); + m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow())); m_rootPlatformLayer->setPosition(FloatPoint(0, 0)); // The root layer does flipping if we need it on this platform. m_rootPlatformLayer->setGeometryOrientation(GraphicsLayer::compositingCoordinatesOrientation()); @@ -937,7 +959,6 @@ void RenderLayerCompositor::destroyRootPlatformLayer() return; willMoveOffscreen(); - delete m_rootPlatformLayer; m_rootPlatformLayer = 0; } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h index 778eccca6..a809a7077 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h @@ -64,7 +64,7 @@ public: // Copy the acceleratedCompositingEnabledFlag from Settings void cacheAcceleratedCompositingEnabledFlag(); - // Called when the layer hierarchy needs to be udpated (compositing layers have been + // Called when the layer hierarchy needs to be updated (compositing layers have been // created, destroyed or re-parented). void setCompositingLayersNeedRebuild(bool needRebuild = true); bool compositingLayersNeedRebuild() const { return m_compositingLayersNeedRebuild; } @@ -74,7 +74,7 @@ public: void setCompositingConsultsOverlap(bool b) { m_compositingConsultsOverlap = b; } bool compositingConsultsOverlap() const { return m_compositingConsultsOverlap; } - void scheduleViewUpdate(); + void scheduleSync(); // Rebuild the tree of compositing layers void updateCompositingLayers(RenderLayer* updateRoot = 0); @@ -164,10 +164,12 @@ private: bool requiresCompositingForAnimation(RenderObject*) const; bool requiresCompositingForTransform(RenderObject*) const; bool requiresCompositingForVideo(RenderObject*) const; + bool requiresCompositingForCanvas(RenderObject*) const; + bool requiresCompositingWhenDescendantsAreCompositing(RenderObject*) const; private: RenderView* m_renderView; - GraphicsLayer* m_rootPlatformLayer; + OwnPtr<GraphicsLayer> m_rootPlatformLayer; bool m_hasAcceleratedCompositing; bool m_compositingConsultsOverlap; bool m_compositing; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLineBoxList.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLineBoxList.cpp index 00566b87b..76a2e2f4e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLineBoxList.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLineBoxList.cpp @@ -162,8 +162,8 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::Pain // intersect. This is a quick short-circuit that we can take to avoid walking any lines. // FIXME: This check is flawed in the following extremely obscure way: // if some line in the middle has a huge overflow, it might actually extend below the last line. - int yPos = firstLineBox()->root()->topOverflow() - renderer->maximalOutlineSize(paintInfo.phase); - int h = renderer->maximalOutlineSize(paintInfo.phase) + lastLineBox()->root()->bottomOverflow() - yPos; + int yPos = firstLineBox()->topVisibleOverflow() - renderer->maximalOutlineSize(paintInfo.phase); + int h = renderer->maximalOutlineSize(paintInfo.phase) + lastLineBox()->bottomVisibleOverflow() - yPos; yPos += ty; if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y()) return; @@ -184,19 +184,19 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::Pain // The whole way objects break across pages needs to be redone. // Try to avoid splitting a line vertically, but only if it's less than the height // of the entire page. - if (curr->root()->bottomOverflow() - curr->root()->topOverflow() <= v->printRect().height()) { - if (ty + curr->root()->bottomOverflow() > v->printRect().bottom()) { - if (ty + curr->root()->topOverflow() < v->truncatedAt()) - v->setBestTruncatedAt(ty + curr->root()->topOverflow(), renderer); + if (curr->bottomVisibleOverflow() - curr->topVisibleOverflow() <= v->printRect().height()) { + if (ty + curr->bottomVisibleOverflow() > v->printRect().bottom()) { + if (ty + curr->topVisibleOverflow() < v->truncatedAt()) + v->setBestTruncatedAt(ty + curr->root()->topVisibleOverflow(), renderer); // If we were able to truncate, don't paint. - if (ty + curr->root()->topOverflow() >= v->truncatedAt()) + if (ty + curr->topVisibleOverflow() >= v->truncatedAt()) break; } } } - int top = min(curr->root()->topOverflow(), curr->root()->selectionTop()) - renderer->maximalOutlineSize(info.phase); - int bottom = curr->root()->bottomOverflow() + renderer->maximalOutlineSize(info.phase); + int top = min(curr->topVisibleOverflow(), curr->root()->selectionTop()) - renderer->maximalOutlineSize(info.phase); + int bottom = curr->bottomVisibleOverflow() + renderer->maximalOutlineSize(info.phase); h = bottom - top; yPos = ty + top; if (yPos < info.rect.bottom() && yPos + h > info.rect.y()) @@ -229,14 +229,14 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq // contain the point. This is a quick short-circuit that we can take to avoid walking any lines. // FIXME: This check is flawed in the following extremely obscure way: // if some line in the middle has a huge overflow, it might actually extend below the last line. - if ((y >= ty + lastLineBox()->root()->bottomOverflow()) || (y < ty + firstLineBox()->root()->topOverflow())) + if ((y >= ty + lastLineBox()->root()->bottomVisibleOverflow()) || (y < ty + firstLineBox()->root()->topVisibleOverflow())) return false; // See if our root lines contain the point. If so, then we hit test // them further. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevFlowBox()) { - if (y >= ty + curr->root()->topOverflow() && y < ty + curr->root()->bottomOverflow()) { + if (y >= ty + curr->root()->topVisibleOverflow() && y < ty + curr->root()->bottomVisibleOverflow()) { bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty); if (inside) { renderer->updateHitTestResult(result, IntPoint(x - tx, y - ty)); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp index e6c28f710..0edfdef31 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp @@ -508,7 +508,7 @@ bool RenderListBox::listIndexIsVisible(int index) return index >= m_indexOffset && index < m_indexOffset + numVisibleItems(); } -bool RenderListBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier) +bool RenderListBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier, Node**) { return m_vBar && m_vBar->scroll(direction, granularity, multiplier); } @@ -527,8 +527,7 @@ void RenderListBox::valueChanged(Scrollbar*) if (newOffset != m_indexOffset) { m_indexOffset = newOffset; repaint(); - // Fire the scroll DOM event. - node()->dispatchEvent(eventNames().scrollEvent, false, false); + node()->dispatchEvent(Event::create(eventNames().scrollEvent, false, false)); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListBox.h b/src/3rdparty/webkit/WebCore/rendering/RenderListBox.h index dd257a85c..aafb87e95 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderListBox.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderListBox.h @@ -1,7 +1,7 @@ /* * This file is part of the select element renderer in WebCore. * - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,8 +39,21 @@ namespace WebCore { class RenderListBox : public RenderBlock, private ScrollbarClient { public: RenderListBox(Element*); - ~RenderListBox(); + virtual ~RenderListBox(); + void selectionChanged(); + + void setOptionsChanged(bool changed) { m_optionsChanged = changed; } + + int listIndexAtOffset(int x, int y); + IntRect itemBoundingBoxRect(int tx, int ty, int index); + + bool scrollToRevealElementAtListIndex(int index); + bool listIndexIsVisible(int index); + + int scrollToward(const IntPoint&); // Returns the new index or -1 if no scroll occurred + +private: virtual const char* renderName() const { return "RenderListBox"; } virtual bool isListBox() const { return true; } @@ -55,7 +68,7 @@ public: virtual bool isPointInOverflowControl(HitTestResult&, int x, int y, int tx, int ty); - virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f); + virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0); virtual void calcPrefWidths(); virtual int baselinePosition(bool firstLine, bool isRootLineBox) const; @@ -63,16 +76,6 @@ public: virtual void layout(); - void selectionChanged(); - - void setOptionsChanged(bool changed) { m_optionsChanged = changed; } - - int listIndexAtOffset(int x, int y); - IntRect itemBoundingBoxRect(int tx, int ty, int index); - - bool scrollToRevealElementAtListIndex(int index); - bool listIndexIsVisible(int index); - virtual bool canBeProgramaticallyScrolled(bool) const { return true; } virtual void autoscroll(); virtual void stopAutoscroll(); @@ -80,8 +83,6 @@ public: virtual bool shouldPanScroll() const { return true; } virtual void panScroll(const IntPoint&); - int scrollToward(const IntPoint&); // Returns the new index or -1 if no scroll occurred - virtual int verticalScrollbarWidth() const; virtual int scrollLeft() const; virtual int scrollTop() const; @@ -92,10 +93,8 @@ public: virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); -protected: virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); -private: // ScrollbarClient interface. virtual void valueChanged(Scrollbar*); virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&); @@ -130,6 +129,15 @@ private: RefPtr<Scrollbar> m_vBar; }; +inline RenderListBox* toRenderListBox(RenderObject* object) +{ + ASSERT(!object || object->isListBox()); + return static_cast<RenderListBox*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderListBox(const RenderListBox*); + } // namepace WebCore #endif // RenderListBox_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListItem.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderListItem.cpp index fb965d2cc..e487c603e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderListItem.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderListItem.cpp @@ -91,20 +91,20 @@ static Node* enclosingList(Node* node) static RenderListItem* previousListItem(Node* list, const RenderListItem* item) { - for (Node* n = item->node()->traversePreviousNode(); n != list; n = n->traversePreviousNode()) { - RenderObject* o = n->renderer(); - if (o && o->isListItem()) { - Node* otherList = enclosingList(n); - // This item is part of our current list, so it's what we're looking for. - if (list == otherList) - return static_cast<RenderListItem*>(o); - // We found ourself inside another list; lets skip the rest of it. - // Use traverseNextNode() here because the other list itself may actually - // be a list item itself. We need to examine it, so we do this to counteract - // the traversePreviousNode() that will be done by the loop. - if (otherList) - n = otherList->traverseNextNode(); - } + for (Node* node = item->node()->traversePreviousNode(); node != list; node = node->traversePreviousNode()) { + RenderObject* renderer = node->renderer(); + if (!renderer || !renderer->isListItem()) + continue; + Node* otherList = enclosingList(node); + // This item is part of our current list, so it's what we're looking for. + if (list == otherList) + return toRenderListItem(renderer); + // We found ourself inside another list; lets skip the rest of it. + // Use traverseNextNode() here because the other list itself may actually + // be a list item itself. We need to examine it, so we do this to counteract + // the traversePreviousNode() that will be done by the loop. + if (otherList) + node = otherList->traverseNextNode(); } return 0; } @@ -247,21 +247,30 @@ void RenderListItem::positionListMarker() int markerXPos; RootInlineBox* root = m_marker->inlineBoxWrapper()->root(); + // FIXME: Inline flows in the line box hierarchy that have self-painting layers should act as cutoff points + // and really shouldn't keep propagating overflow up. This won't really break anything other than repainting + // not being as tight as it could be though. if (style()->direction() == LTR) { int leftLineOffset = leftRelOffset(yOffset, leftOffset(yOffset, false), false); markerXPos = leftLineOffset - xOffset - paddingLeft() - borderLeft() + m_marker->marginLeft(); m_marker->inlineBoxWrapper()->adjustPosition(markerXPos - markerOldX, 0); - if (markerXPos < root->leftOverflow()) { - root->setHorizontalOverflowPositions(markerXPos, root->rightOverflow()); - adjustOverflow = true; + for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) { + if (markerXPos < box->leftLayoutOverflow()) { + box->setHorizontalOverflowPositions(markerXPos, box->rightLayoutOverflow(), box->leftVisualOverflow(), box->rightVisualOverflow()); + if (box == root) + adjustOverflow = true; + } } } else { int rightLineOffset = rightRelOffset(yOffset, rightOffset(yOffset, false), false); markerXPos = rightLineOffset - xOffset + paddingRight() + borderRight() + m_marker->marginLeft(); m_marker->inlineBoxWrapper()->adjustPosition(markerXPos - markerOldX, 0); - if (markerXPos + m_marker->width() > root->rightOverflow()) { - root->setHorizontalOverflowPositions(root->leftOverflow(), markerXPos + m_marker->width()); - adjustOverflow = true; + for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) { + if (markerXPos + m_marker->width() > box->rightLayoutOverflow()) { + box->setHorizontalOverflowPositions(box->leftLayoutOverflow(), markerXPos + m_marker->width(), box->leftVisualOverflow(), box->rightVisualOverflow()); + if (box == root) + adjustOverflow = true; + } } } @@ -271,9 +280,9 @@ void RenderListItem::positionListMarker() do { o = o->parentBox(); if (o->isRenderBlock()) - toRenderBlock(o)->addVisualOverflow(markerRect); + toRenderBlock(o)->addLayoutOverflow(markerRect); markerRect.move(-o->x(), -o->y()); - } while (o != this); + } while (o != this && !o->hasSelfPaintingLayer()); } } } @@ -302,9 +311,9 @@ void RenderListItem::explicitValueChanged() RenderObject* listRenderer = 0; if (listNode) listRenderer = listNode->renderer(); - for (RenderObject* r = this; r; r = r->nextInPreOrder(listRenderer)) - if (r->isListItem()) { - RenderListItem* item = static_cast<RenderListItem*>(r); + for (RenderObject* renderer = this; renderer; renderer = renderer->nextInPreOrder(listRenderer)) + if (renderer->isListItem()) { + RenderListItem* item = toRenderListItem(renderer); if (!item->m_hasExplicitValue) { item->m_isValueUpToDate = false; if (RenderListMarker* marker = item->m_marker) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListItem.h b/src/3rdparty/webkit/WebCore/rendering/RenderListItem.h index 91844f716..c4c41dcbf 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderListItem.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderListItem.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -33,12 +33,6 @@ class RenderListItem : public RenderBlock { public: RenderListItem(Node*); - virtual const char* renderName() const { return "RenderListItem"; } - - virtual bool isListItem() const { return true; } - - virtual void destroy(); - int value() const { if (!m_isValueUpToDate) updateValueNow(); return m_value; } void updateValue(); @@ -47,6 +41,18 @@ public: void setExplicitValue(int value); void clearExplicitValue(); + void setNotInList(bool notInList) { m_notInList = notInList; } + bool notInList() const { return m_notInList; } + + const String& markerText() const; + +private: + virtual const char* renderName() const { return "RenderListItem"; } + + virtual bool isListItem() const { return true; } + + virtual void destroy(); + virtual bool isEmpty() const; virtual void paint(PaintInfo&, int tx, int ty); @@ -55,15 +61,8 @@ public: virtual void positionListMarker(); - void setNotInList(bool notInList) { m_notInList = notInList; } - bool notInList() const { return m_notInList; } - - const String& markerText() const; - -protected: virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); -private: void updateMarkerLocation(); inline int calcValue() const; void updateValueNow() const; @@ -78,6 +77,15 @@ private: bool m_notInList : 1; }; +inline RenderListItem* toRenderListItem(RenderObject* object) +{ + ASSERT(!object || object->isListItem()); + return static_cast<RenderListItem*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderListItem(const RenderListItem*); + } // namespace WebCore #endif // RenderListItem_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.h b/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.h index 57580a87b..5b46278da 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -36,8 +36,15 @@ String listMarkerText(EListStyleType, int value); class RenderListMarker : public RenderBox { public: RenderListMarker(RenderListItem*); - ~RenderListMarker(); + virtual ~RenderListMarker(); + virtual void calcPrefWidths(); + + const String& text() const { return m_text; } + + bool isInside() const; + +private: virtual const char* renderName() const { return "RenderListMarker"; } virtual bool isListMarker() const { return true; } @@ -45,7 +52,6 @@ public: virtual void paint(PaintInfo&, int tx, int ty); virtual void layout(); - virtual void calcPrefWidths(); virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); @@ -56,9 +62,6 @@ public: bool isImage() const; bool isText() const { return !isImage(); } - const String& text() const { return m_text; } - - bool isInside() const; virtual void setSelectionState(SelectionState); virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true); @@ -66,11 +69,9 @@ public: void updateMargins(); -protected: virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); -private: IntRect getRelativeMarkerRect(); String m_text; @@ -78,6 +79,21 @@ private: RenderListItem* m_listItem; }; +inline RenderListMarker* toRenderListMarker(RenderObject* object) +{ + ASSERT(!object || object->isListMarker()); + return static_cast<RenderListMarker*>(object); +} + +inline const RenderListMarker* toRenderListMarker(const RenderObject* object) +{ + ASSERT(!object || object->isListMarker()); + return static_cast<const RenderListMarker*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderListMarker(const RenderListMarker*); + } // namespace WebCore #endif // RenderListMarker_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMarquee.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMarquee.cpp index 31a8305f0..bb917f853 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMarquee.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMarquee.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * Portions are Copyright (C) 1998 Netscape Communications Corporation. * @@ -152,7 +153,11 @@ int RenderMarquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge void RenderMarquee::start() { - if (m_timer.isActive() || m_layer->renderer()->style()->marqueeIncrement().isZero()) + if (m_timer.isActive() || m_layer->renderer()->style()->marqueeIncrement().isZero() +#if ENABLE(WCSS) && ENABLE(XHTMLMP) + || (m_layer->renderer()->document()->isXHTMLMPDocument() && !m_layer->renderer()->style()->marqueeLoopCount()) +#endif + ) return; // We may end up propagating a scroll event. It is important that we suspend events until diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp index b87e99dce..1d4da2338 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp @@ -33,6 +33,7 @@ #include "HTMLNames.h" #include "MediaControlElements.h" #include "MouseEvent.h" +#include "RenderTheme.h" #include <wtf/CurrentTime.h> #include <wtf/MathExtras.h> @@ -132,6 +133,10 @@ void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldSty m_currentTimeDisplay->updateStyle(); if (m_timeRemainingDisplay) m_timeRemainingDisplay->updateStyle(); + if (m_volumeSliderContainer) + m_volumeSliderContainer->updateStyle(); + if (m_volumeSlider) + m_volumeSlider->updateStyle(); } } @@ -240,6 +245,23 @@ void RenderMedia::createTimeline() m_timeline->attachToParent(m_timelineContainer.get()); } +void RenderMedia::createVolumeSliderContainer() +{ + ASSERT(!m_volumeSliderContainer); + m_volumeSliderContainer = new MediaControlVolumeSliderContainerElement(document(), mediaElement()); + m_volumeSliderContainer->attachToParent(m_panel.get()); +} + +void RenderMedia::createVolumeSlider() +{ + ASSERT(!m_volumeSlider); + m_volumeSlider = new MediaControlVolumeSliderElement(document(), mediaElement()); + m_volumeSlider->setAttribute(precisionAttr, "float"); + m_volumeSlider->setAttribute(maxAttr, "1"); + m_volumeSlider->setAttribute(valueAttr, String::number(mediaElement()->volume())); + m_volumeSlider->attachToParent(m_volumeSliderContainer.get()); +} + void RenderMedia::createCurrentTimeDisplay() { ASSERT(!m_currentTimeDisplay); @@ -285,6 +307,8 @@ void RenderMedia::updateControls() m_currentTimeDisplay = 0; m_timeRemainingDisplay = 0; m_fullscreenButton = 0; + m_volumeSliderContainer = 0; + m_volumeSlider = 0; m_controlsShadowRoot = 0; } m_opacityAnimationTo = 1.0f; @@ -298,19 +322,22 @@ void RenderMedia::updateControls() createPanel(); if (m_panel) { createRewindButton(); - createMuteButton(); createPlayButton(); createReturnToRealtimeButton(); createStatusDisplay(); createTimelineContainer(); - createSeekBackButton(); - createSeekForwardButton(); - createFullscreenButton(); if (m_timelineContainer) { createCurrentTimeDisplay(); createTimeline(); createTimeRemainingDisplay(); } + createSeekBackButton(); + createSeekForwardButton(); + createFullscreenButton(); + createMuteButton(); + createVolumeSliderContainer(); + if (m_volumeSliderContainer) + createVolumeSlider(); m_panel->attach(); } } @@ -336,6 +363,8 @@ void RenderMedia::updateControls() m_playButton->update(); if (m_timelineContainer) m_timelineContainer->update(); + if (m_volumeSliderContainer) + m_volumeSliderContainer->update(); if (m_timeline) m_timeline->update(); if (m_currentTimeDisplay) @@ -354,6 +383,8 @@ void RenderMedia::updateControls() m_statusDisplay->update(); if (m_fullscreenButton) m_fullscreenButton->update(); + if (m_volumeSlider) + m_volumeSlider->update(); updateTimeDisplay(); updateControlVisibility(); @@ -366,24 +397,6 @@ void RenderMedia::timeUpdateTimerFired(Timer<RenderMedia>*) updateTimeDisplay(); } -String RenderMedia::formatTime(float time) -{ - if (!isfinite(time)) - time = 0; - int seconds = (int)fabsf(time); - int hours = seconds / (60 * 60); - int minutes = (seconds / 60) % 60; - seconds %= 60; - if (hours) { - if (hours > 9) - return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds); - else - return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds); - } - else - return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds); -} - void RenderMedia::updateTimeDisplay() { if (!m_currentTimeDisplay || !m_currentTimeDisplay->renderer() || m_currentTimeDisplay->renderer()->style()->display() == NONE || style()->visibility() != VISIBLE) @@ -391,12 +404,8 @@ void RenderMedia::updateTimeDisplay() float now = mediaElement()->currentTime(); float duration = mediaElement()->duration(); - String timeString = formatTime(now); - ExceptionCode ec; - m_currentTimeDisplay->setInnerText(timeString, ec); - - timeString = formatTime(now - duration); - m_timeRemainingDisplay->setInnerText(timeString, ec); + m_currentTimeDisplay->setCurrentValue(now); + m_timeRemainingDisplay->setCurrentValue(now - duration); } void RenderMedia::updateControlVisibility() @@ -463,13 +472,53 @@ void RenderMedia::opacityAnimationTimerFired(Timer<RenderMedia>*) changeOpacity(m_panel.get(), opacity); } +void RenderMedia::updateVolumeSliderContainer(bool visible) +{ + if (!mediaElement()->hasAudio() || !m_volumeSliderContainer || !m_volumeSlider) + return; + + if (visible && !m_volumeSliderContainer->isVisible()) { + if (!m_muteButton || !m_muteButton->renderer() || !m_muteButton->renderBox()) + return; + + RefPtr<RenderStyle> s = m_volumeSliderContainer->styleForElement(); + int height = s->height().isPercent() ? 0 : s->height().value(); + int x = m_muteButton->renderBox()->offsetLeft(); + int y = m_muteButton->renderBox()->offsetTop() - height; + FloatPoint absPoint = m_muteButton->renderer()->localToAbsolute(FloatPoint(x, y), true, true); + if (absPoint.y() < 0) + y = m_muteButton->renderBox()->offsetTop() + m_muteButton->renderBox()->height(); + m_volumeSliderContainer->setVisible(true); + m_volumeSliderContainer->setPosition(x, y); + m_volumeSliderContainer->update(); + m_volumeSlider->update(); + } else if (!visible && m_volumeSliderContainer->isVisible()) { + m_volumeSliderContainer->setVisible(false); + m_volumeSliderContainer->updateStyle(); + } +} + void RenderMedia::forwardEvent(Event* event) { if (event->isMouseEvent() && m_controlsShadowRoot) { MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); IntPoint point(mouseEvent->absoluteLocation()); - if (m_muteButton && m_muteButton->hitTest(point)) + bool showVolumeSlider = false; + if (m_muteButton && m_muteButton->hitTest(point)) { m_muteButton->defaultEventHandler(event); + if (event->type() != eventNames().mouseoutEvent) + showVolumeSlider = true; + } + + if (m_volumeSliderContainer && m_volumeSliderContainer->hitTest(point)) + showVolumeSlider = true; + + if (m_volumeSlider && m_volumeSlider->hitTest(point)) { + m_volumeSlider->defaultEventHandler(event); + showVolumeSlider = true; + } + + updateVolumeSliderContainer(showVolumeSlider); if (m_playButton && m_playButton->hitTest(point)) m_playButton->defaultEventHandler(event); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.h b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.h index e1149bb56..602cd2648 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,10 +41,12 @@ class MediaControlSeekButtonElement; class MediaControlRewindButtonElement; class MediaControlReturnToRealtimeButtonElement; class MediaControlTimelineElement; +class MediaControlVolumeSliderElement; class MediaControlFullscreenButtonElement; class MediaControlTimeDisplayElement; class MediaControlStatusDisplayElement; class MediaControlTimelineContainerElement; +class MediaControlVolumeSliderContainerElement; class MediaControlElement; class MediaPlayer; @@ -54,23 +56,12 @@ public: RenderMedia(HTMLMediaElement*, const IntSize& intrinsicSize); virtual ~RenderMedia(); - virtual RenderObjectChildList* virtualChildren() { return children(); } - virtual const RenderObjectChildList* virtualChildren() const { return children(); } const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } - virtual void destroy(); - - virtual void layout(); - - virtual const char* renderName() const { return "RenderMedia"; } - virtual bool isMedia() const { return true; } - HTMLMediaElement* mediaElement() const; MediaPlayer* player() const; - static String formatTime(float time); - bool shouldShowTimeDisplayControls() const; void updateFromElement(); @@ -80,11 +71,22 @@ public: void forwardEvent(Event*); +protected: + virtual void layout(); + +private: + virtual RenderObjectChildList* virtualChildren() { return children(); } + virtual const RenderObjectChildList* virtualChildren() const { return children(); } + + virtual void destroy(); + + virtual const char* renderName() const { return "RenderMedia"; } + virtual bool isMedia() const { return true; } + virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; -private: void createControlsShadowRoot(); void destroyControlsShadowRoot(); void createPanel(); @@ -97,6 +99,8 @@ private: void createStatusDisplay(); void createTimelineContainer(); void createTimeline(); + void createVolumeSliderContainer(); + void createVolumeSlider(); void createCurrentTimeDisplay(); void createTimeRemainingDisplay(); void createFullscreenButton(); @@ -107,6 +111,8 @@ private: void changeOpacity(HTMLElement*, float opacity); void opacityAnimationTimerFired(Timer<RenderMedia>*); + void updateVolumeSliderContainer(bool visible); + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); RefPtr<HTMLElement> m_controlsShadowRoot; @@ -118,8 +124,10 @@ private: RefPtr<MediaControlRewindButtonElement> m_rewindButton; RefPtr<MediaControlReturnToRealtimeButtonElement> m_returnToRealtimeButton; RefPtr<MediaControlTimelineElement> m_timeline; + RefPtr<MediaControlVolumeSliderElement> m_volumeSlider; RefPtr<MediaControlFullscreenButtonElement> m_fullscreenButton; RefPtr<MediaControlTimelineContainerElement> m_timelineContainer; + RefPtr<MediaControlVolumeSliderContainerElement> m_volumeSliderContainer; RefPtr<MediaControlTimeDisplayElement> m_currentTimeDisplay; RefPtr<MediaControlTimeDisplayElement> m_timeRemainingDisplay; RefPtr<MediaControlStatusDisplayElement> m_statusDisplay; @@ -136,6 +144,15 @@ private: float m_opacityAnimationTo; }; +inline RenderMedia* toRenderMedia(RenderObject* object) +{ + ASSERT(!object || object->isMedia()); + return static_cast<RenderMedia*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderMedia(const RenderMedia*); + } // namespace WebCore #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp index 06d901a7d..9cc1493f5 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp @@ -37,7 +37,7 @@ using namespace std; namespace WebCore { -#if !defined(NDEBUG) && defined(USE_DEBUG_SAFARI_THEME) +#ifdef DEBUG_ALL SOFT_LINK_DEBUG_LIBRARY(SafariTheme) #else SOFT_LINK_LIBRARY(SafariTheme) @@ -82,16 +82,6 @@ void RenderMediaControls::adjustMediaSliderThumbSize(RenderObject* o) o->style()->setHeight(Length(static_cast<int>(mediaSliderThumbHeight * zoomLevel), Fixed)); } -static HTMLMediaElement* parentMediaElement(RenderObject* o) -{ - Node* node = o->node(); - Node* mediaNode = node ? node->shadowAncestorNode() : 0; - if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag))) - return 0; - - return static_cast<HTMLMediaElement*>(mediaNode); -} - bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { ASSERT(SafariThemeLibrary()); @@ -110,8 +100,8 @@ bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, R case MediaPauseButton: case MediaPlayButton: if (MediaControlPlayButtonElement* btn = static_cast<MediaControlPlayButtonElement*>(o->node())) { - bool currentlyPlaying = btn->displayType() == MediaPlayButton; - paintThemePart(currentlyPlaying ? SafariTheme::MediaPauseButtonPart : SafariTheme::MediaPlayButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); + bool canPlay = btn->displayType() == MediaPlayButton; + paintThemePart(canPlay ? SafariTheme::MediaPlayButtonPart : SafariTheme::MediaPauseButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); } break; case MediaSeekBackButton: @@ -121,13 +111,25 @@ bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, R paintThemePart(SafariTheme::MediaSeekForwardButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); break; case MediaSlider: { - if (HTMLMediaElement* mediaElement = parentMediaElement(o)) + if (HTMLMediaElement* mediaElement = toParentMediaElement(o)) STPaintProgressIndicator(SafariTheme::MediaType, paintInfo.context->platformContext(), r, NSRegularControlSize, 0, mediaElement->percentLoaded()); break; } case MediaSliderThumb: paintThemePart(SafariTheme::MediaSliderThumbPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); break; + case MediaVolumeSliderContainer: + // FIXME: Implement volume slider. + ASSERT_NOT_REACHED(); + break; + case MediaVolumeSlider: + // FIXME: Implement volume slider. + ASSERT_NOT_REACHED(); + break; + case MediaVolumeSliderThumb: + // FIXME: Implement volume slider. + ASSERT_NOT_REACHED(); + break; case MediaTimelineContainer: ASSERT_NOT_REACHED(); break; @@ -147,4 +149,3 @@ bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, R #endif // #if ENABLE(VIDEO) } // namespace WebCore - diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.cpp new file mode 100644 index 000000000..56fbec43c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2009 Apple Inc. + * Copyright (C) 2009 Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RenderMediaControlsChromium.h" + +#include "Gradient.h" +#include "GraphicsContext.h" +#include "HTMLMediaElement.h" +#include "HTMLNames.h" + +namespace WebCore { + +#if ENABLE(VIDEO) + +typedef WTF::HashMap<const char*, Image*> MediaControlImageMap; +static MediaControlImageMap* gMediaControlImageMap = 0; + +static Image* platformResource(const char* name) +{ + if (!gMediaControlImageMap) + gMediaControlImageMap = new MediaControlImageMap(); + if (Image* image = gMediaControlImageMap->get(name)) + return image; + if (Image* image = Image::loadPlatformResource(name).releaseRef()) { + gMediaControlImageMap->set(name, image); + return image; + } + ASSERT_NOT_REACHED(); + return 0; +} + +static bool hasSource(const HTMLMediaElement* mediaElement) +{ + return mediaElement->networkState() != HTMLMediaElement::NETWORK_EMPTY + && mediaElement->networkState() != HTMLMediaElement::NETWORK_NO_SOURCE; +} + +static bool paintMediaButton(GraphicsContext* context, const IntRect& rect, Image* image) +{ + IntRect imageRect = image->rect(); + context->drawImage(image, rect); + return true; +} + +static bool paintMediaMuteButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ + HTMLMediaElement* mediaElement = toParentMediaElement(object); + if (!mediaElement) + return false; + + static Image* soundFull = platformResource("mediaSoundFull"); + static Image* soundNone = platformResource("mediaSoundNone"); + static Image* soundDisabled = platformResource("mediaSoundDisabled"); + + if (!hasSource(mediaElement) || !mediaElement->hasAudio()) + return paintMediaButton(paintInfo.context, rect, soundDisabled); + + return paintMediaButton(paintInfo.context, rect, mediaElement->muted() ? soundNone: soundFull); +} + +static bool paintMediaPlayButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ + HTMLMediaElement* mediaElement = toParentMediaElement(object); + if (!mediaElement) + return false; + + static Image* mediaPlay = platformResource("mediaPlay"); + static Image* mediaPause = platformResource("mediaPause"); + static Image* mediaPlayDisabled = platformResource("mediaPlayDisabled"); + + if (!hasSource(mediaElement)) + return paintMediaButton(paintInfo.context, rect, mediaPlayDisabled); + + return paintMediaButton(paintInfo.context, rect, mediaElement->paused() ? mediaPlay : mediaPause); +} + +static bool paintMediaSlider(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ + HTMLMediaElement* mediaElement = toParentMediaElement(object); + if (!mediaElement) + return false; + + RenderStyle* style = object->style(); + GraphicsContext* context = paintInfo.context; + + // Draw the border of the time bar. + // FIXME: this should be a rounded rect but need to fix GraphicsContextSkia first. + // https://bugs.webkit.org/show_bug.cgi?id=30143 + context->save(); + context->setShouldAntialias(true); + context->setStrokeStyle(SolidStroke); + context->setStrokeColor(style->borderLeftColor()); + context->setStrokeThickness(style->borderLeftWidth()); + context->setFillColor(style->backgroundColor()); + context->drawRect(rect); + context->restore(); + + // Draw the buffered ranges. + // FIXME: Draw multiple ranges if there are multiple buffered ranges. + IntRect bufferedRect = rect; + bufferedRect.inflate(-style->borderLeftWidth()); + bufferedRect.setWidth((bufferedRect.width() * mediaElement->percentLoaded())); + + // Don't bother drawing an empty area. + if (!bufferedRect.isEmpty()) { + IntPoint sliderTopLeft = bufferedRect.location(); + IntPoint sliderTopRight = sliderTopLeft; + sliderTopRight.move(0, bufferedRect.height()); + + RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight); + Color startColor = object->style()->color(); + gradient->addColorStop(0.0, startColor); + gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha())); + + context->save(); + context->setStrokeStyle(NoStroke); + context->setFillGradient(gradient); + context->fillRect(bufferedRect); + context->restore(); + } + + return true; +} + +static bool paintMediaSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ + if (!object->parent()->isSlider()) + return false; + + HTMLMediaElement* mediaElement = toParentMediaElement(object->parent()); + if (!mediaElement) + return false; + + if (!hasSource(mediaElement)) + return true; + + static Image* mediaSliderThumb = platformResource("mediaSliderThumb"); + return paintMediaButton(paintInfo.context, rect, mediaSliderThumb); +} + +static bool paintMediaVolumeSlider(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ + HTMLMediaElement* mediaElement = toParentMediaElement(object); + if (!mediaElement) + return false; + + GraphicsContext* context = paintInfo.context; + Color originalColor = context->strokeColor(); + if (originalColor != Color::white) + context->setStrokeColor(Color::white); + + int x = rect.x() + rect.width() / 2; + context->drawLine(IntPoint(x, rect.y()), IntPoint(x, rect.y() + rect.height())); + + if (originalColor != Color::white) + context->setStrokeColor(originalColor); + return true; +} + +static bool paintMediaVolumeSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ + if (!object->parent()->isSlider()) + return false; + + static Image* mediaVolumeSliderThumb = platformResource("mediaVolumeSliderThumb"); + return paintMediaButton(paintInfo.context, rect, mediaVolumeSliderThumb); +} + +static bool paintMediaTimelineContainer(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ + HTMLMediaElement* mediaElement = toParentMediaElement(object); + if (!mediaElement) + return false; + + if (!rect.isEmpty()) { + GraphicsContext* context = paintInfo.context; + Color originalColor = context->strokeColor(); + float originalThickness = context->strokeThickness(); + StrokeStyle originalStyle = context->strokeStyle(); + + context->setStrokeStyle(SolidStroke); + + // Draw the left border using CSS defined width and color. + context->setStrokeThickness(object->style()->borderLeftWidth()); + context->setStrokeColor(object->style()->borderLeftColor().rgb()); + context->drawLine(IntPoint(rect.x() + 1, rect.y()), + IntPoint(rect.x() + 1, rect.y() + rect.height())); + + // Draw the right border using CSS defined width and color. + context->setStrokeThickness(object->style()->borderRightWidth()); + context->setStrokeColor(object->style()->borderRightColor().rgb()); + context->drawLine(IntPoint(rect.x() + rect.width() - 1, rect.y()), + IntPoint(rect.x() + rect.width() - 1, rect.y() + rect.height())); + + context->setStrokeColor(originalColor); + context->setStrokeThickness(originalThickness); + context->setStrokeStyle(originalStyle); + } + return true; +} + +bool RenderMediaControlsChromium::shouldRenderMediaControlPart(ControlPart part, Element* e) +{ + UNUSED_PARAM(e); + + switch (part) { + case MediaMuteButtonPart: + case MediaPlayButtonPart: + case MediaSliderPart: + case MediaSliderThumbPart: + case MediaVolumeSliderContainerPart: + case MediaVolumeSliderPart: + case MediaVolumeSliderThumbPart: + case MediaControlsBackgroundPart: + case MediaCurrentTimePart: + case MediaTimeRemainingPart: + return true; + default: + ; + } + return false; +} + +bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType part, RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ + switch (part) { + case MediaMuteButton: + case MediaUnMuteButton: + return paintMediaMuteButton(object, paintInfo, rect); + case MediaPauseButton: + case MediaPlayButton: + return paintMediaPlayButton(object, paintInfo, rect); + case MediaSlider: + return paintMediaSlider(object, paintInfo, rect); + case MediaSliderThumb: + return paintMediaSliderThumb(object, paintInfo, rect); + case MediaVolumeSlider: + return paintMediaVolumeSlider(object, paintInfo, rect); + case MediaVolumeSliderThumb: + return paintMediaVolumeSliderThumb(object, paintInfo, rect); + case MediaTimelineContainer: + return paintMediaTimelineContainer(object, paintInfo, rect); + case MediaFullscreenButton: + case MediaSeekBackButton: + case MediaSeekForwardButton: + case MediaVolumeSliderContainer: + case MediaCurrentTimeDisplay: + case MediaTimeRemainingDisplay: + case MediaControlsPanel: + case MediaRewindButton: + case MediaReturnToRealtimeButton: + case MediaStatusDisplay: + ASSERT_NOT_REACHED(); + break; + } + return false; +} + +void RenderMediaControlsChromium::adjustMediaSliderThumbSize(RenderObject* object) +{ + static Image* mediaSliderThumb = platformResource("mediaSliderThumb"); + static Image* mediaVolumeSliderThumb = platformResource("mediaVolumeSliderThumb"); + + Image* thumbImage = 0; + if (object->style()->appearance() == MediaSliderThumbPart) + thumbImage = mediaSliderThumb; + else if (object->style()->appearance() == MediaVolumeSliderThumbPart) + thumbImage = mediaVolumeSliderThumb; + + float zoomLevel = object->style()->effectiveZoom(); + if (thumbImage) { + object->style()->setWidth(Length(static_cast<int>(thumbImage->width() * zoomLevel), Fixed)); + object->style()->setHeight(Length(static_cast<int>(thumbImage->height() * zoomLevel), Fixed)); + } +} + +#endif // #if ENABLE(VIDEO) + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.h b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.h new file mode 100644 index 000000000..d6d986cde --- /dev/null +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 Apple Inc. + * Copyright (C) 2009 Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RenderMediaControlsChromium_h +#define RenderMediaControlsChromium_h + +#include "RenderObject.h" +#include "MediaControlElements.h" + +namespace WebCore { + +class HTMLMediaElement; +class RenderMediaControlsChromium { +public: + static bool shouldRenderMediaControlPart(ControlPart, Element*); + static bool paintMediaControlsPart(MediaControlElementType, RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + static void adjustMediaSliderThumbSize(RenderObject*); +}; + +} // namespace WebCore + +#endif // RenderMediaControlsChromium_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp index ed8c8ba93..cbbc7cbad 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp @@ -292,7 +292,6 @@ void RenderMenuList::hidePopup() { if (m_popup) m_popup->hide(); - m_popupIsVisible = false; } void RenderMenuList::valueChanged(unsigned listIndex, bool fireOnChange) @@ -318,6 +317,13 @@ String RenderMenuList::itemText(unsigned listIndex) const return String(); } +String RenderMenuList::itemToolTip(unsigned listIndex) const +{ + SelectElement* select = toSelectElement(static_cast<Element*>(node())); + Element* element = select->listItems()[listIndex]; + return element->title(); +} + bool RenderMenuList::itemIsEnabled(unsigned listIndex) const { SelectElement* select = toSelectElement(static_cast<Element*>(node())); @@ -421,6 +427,11 @@ int RenderMenuList::selectedIndex() const return select->optionToListIndex(select->selectedIndex()); } +void RenderMenuList::popupDidHide() +{ + m_popupIsVisible = false; +} + bool RenderMenuList::itemIsSeparator(unsigned listIndex) const { SelectElement* select = toSelectElement(static_cast<Element*>(node())); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.h b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.h index 7966eff34..2d617c115 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.h @@ -40,7 +40,16 @@ class RenderText; class RenderMenuList : public RenderFlexibleBox, private PopupMenuClient { public: RenderMenuList(Element*); - ~RenderMenuList(); + virtual ~RenderMenuList(); + +public: + bool popupIsVisible() const { return m_popupIsVisible; } + void showPopup(); + void hidePopup(); + + void setOptionsChanged(bool changed) { m_optionsChanged = changed; } + + String text() const; private: virtual bool isMenuList() const { return true; } @@ -59,20 +68,11 @@ private: virtual void calcPrefWidths(); -public: - bool popupIsVisible() const { return m_popupIsVisible; } - void showPopup(); - void hidePopup(); - - void setOptionsChanged(bool changed) { m_optionsChanged = changed; } - - String text() const; - -private: virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); // PopupMenuClient methods virtual String itemText(unsigned listIndex) const; + virtual String itemToolTip(unsigned listIndex) const; virtual bool itemIsEnabled(unsigned listIndex) const; virtual PopupMenuStyle itemStyle(unsigned listIndex) const; virtual PopupMenuStyle menuStyle() const; @@ -82,6 +82,7 @@ private: virtual int clientPaddingRight() const; virtual int listSize() const; virtual int selectedIndex() const; + virtual void popupDidHide(); virtual bool itemIsSeparator(unsigned listIndex) const; virtual bool itemIsLabel(unsigned listIndex) const; virtual bool itemIsSelected(unsigned listIndex) const; @@ -113,6 +114,15 @@ private: bool m_popupIsVisible; }; +inline RenderMenuList* toRenderMenuList(RenderObject* object) +{ + ASSERT(!object || object->isMenuList()); + return static_cast<RenderMenuList*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderMenuList(const RenderMenuList*); + } #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp index df8c58a0e..a10ffd960 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp @@ -4,6 +4,7 @@ * (C) 2000 Dirk Mueller (mueller@kde.org) * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -46,6 +47,7 @@ #include "RenderTheme.h" #include "RenderView.h" #include "TransformState.h" +#include "htmlediting.h" #include <algorithm> #include <stdio.h> #include <wtf/RefCountedLeakCounter.h> @@ -142,6 +144,12 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style) o = new (arena) RenderTableCell(node); break; case TABLE_CAPTION: +#if ENABLE(WCSS) + // As per the section 17.1 of the spec WAP-239-WCSS-20011026-a.pdf, + // the marquee box inherits and extends the characteristics of the + // principal block box ([CSS2] section 9.2.1). + case WAP_MARQUEE: +#endif o = new (arena) RenderBlock(node); break; case BOX: @@ -197,7 +205,6 @@ RenderObject::RenderObject(Node* node) , m_selectionState(SelectionNone) , m_hasColumns(false) , m_cellWidthChanged(false) - , m_replacedHasOverflow(false) { #ifndef NDEBUG renderObjectCounter.increment(); @@ -247,9 +254,10 @@ bool RenderObject::isHTMLMarquee() const static void updateListMarkerNumbers(RenderObject* child) { - for (RenderObject* r = child; r; r = r->nextSibling()) - if (r->isListItem()) - static_cast<RenderListItem*>(r)->updateValue(); + for (RenderObject* sibling = child; sibling; sibling = sibling->nextSibling()) { + if (sibling->isListItem()) + toRenderListItem(sibling)->updateValue(); + } } void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild) @@ -285,7 +293,7 @@ void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild) RenderTable* table; RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : children->lastChild(); if (afterChild && afterChild->isAnonymous() && afterChild->isTable()) - table = static_cast<RenderTable*>(afterChild); + table = toRenderTable(afterChild); else { table = new (renderArena()) RenderTable(document() /* is anonymous */); RefPtr<RenderStyle> newStyle = RenderStyle::create(); @@ -595,7 +603,7 @@ void RenderObject::setLayerNeedsFullRepaint() RenderBlock* RenderObject::containingBlock() const { if (isTableCell()) { - const RenderTableCell* cell = static_cast<const RenderTableCell*>(this); + const RenderTableCell* cell = toRenderTableCell(this); if (parent() && cell->section()) return cell->table(); return 0; @@ -617,6 +625,11 @@ RenderBlock* RenderObject::containingBlock() const // inline directly. if (o->style()->position() == RelativePosition && o->isInline() && !o->isReplaced()) return o->containingBlock(); +#if ENABLE(SVG) + if (o->isSVGForeignObject()) //foreignObject is the containing block for contents inside it + break; +#endif + o = o->parent(); } } else { @@ -649,10 +662,10 @@ static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer* if (!layer->xPosition().isZero() || !layer->yPosition().isZero()) return true; - if (layer->isSizeSet()) { - if (layer->size().width().isPercent() || layer->size().height().isPercent()) + if (layer->size().type == SizeLength) { + if (layer->size().size.width().isPercent() || layer->size().size.height().isPercent()) return true; - } else if (img->usesImageContainerSize()) + } else if (layer->size().type == Contain || layer->size().type == Cover || img->usesImageContainerSize()) return true; return false; @@ -1213,12 +1226,11 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta // two rectangles (but typically only one). RenderStyle* outlineStyle = outlineStyleForRepaint(); int ow = outlineStyle->outlineSize(); - ShadowData* boxShadow = style()->boxShadow(); int width = abs(newOutlineBox.width() - oldOutlineBox.width()); if (width) { - int shadowRight = 0; - for (ShadowData* shadow = boxShadow; shadow; shadow = shadow->next) - shadowRight = max(shadow->x + shadow->blur + shadow->spread, shadowRight); + int shadowLeft; + int shadowRight; + style()->getBoxShadowHorizontalExtent(shadowLeft, shadowRight); int borderRight = isBox() ? toRenderBox(this)->borderRight() : 0; int borderWidth = max(-outlineStyle->outlineOffset(), max(borderRight, max(style()->borderTopRightRadius().width(), style()->borderBottomRightRadius().width()))) + max(ow, shadowRight); @@ -1234,9 +1246,9 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta } int height = abs(newOutlineBox.height() - oldOutlineBox.height()); if (height) { - int shadowBottom = 0; - for (ShadowData* shadow = boxShadow; shadow; shadow = shadow->next) - shadowBottom = max(shadow->y + shadow->blur + shadow->spread, shadowBottom); + int shadowTop; + int shadowBottom; + style()->getBoxShadowVerticalExtent(shadowTop, shadowBottom); int borderBottom = isBox() ? toRenderBox(this)->borderBottom() : 0; int borderHeight = max(-outlineStyle->outlineOffset(), max(borderBottom, max(style()->borderBottomLeftRadius().height(), style()->borderBottomRightRadius().height()))) + max(ow, shadowBottom); @@ -1362,6 +1374,7 @@ Color RenderObject::selectionForegroundColor() const return color; } +#if ENABLE(DRAG_SUPPORT) Node* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const { if (!dhtmlOK && !uaOK) @@ -1396,6 +1409,7 @@ Node* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& d } return 0; } +#endif // ENABLE(DRAG_SUPPORT) void RenderObject::selectionStartEnd(int& spos, int& epos) const { @@ -1554,7 +1568,7 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS // For changes in float styles, we need to conceivably remove ourselves // from the floating objects list. toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists(); - else if (isPositioned() && (newStyle->position() != AbsolutePosition && newStyle->position() != FixedPosition)) + else if (isPositioned() && (m_style->position() != newStyle->position())) // For changes in positioning styles, we need to conceivably remove ourselves // from the positioned objects list. toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists(); @@ -1609,15 +1623,20 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle*) void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers) { - // FIXME: This will be slow when a large number of images is used. Fix by using a dict. - for (const FillLayer* currOld = oldLayers; currOld; currOld = currOld->next()) { - if (currOld->image() && (!newLayers || !newLayers->containsImage(currOld->image()))) - currOld->image()->removeClient(this); - } + // Optimize the common case + if (oldLayers && !oldLayers->next() && newLayers && !newLayers->next() && (oldLayers->image() == newLayers->image())) + return; + + // Go through the new layers and addClients first, to avoid removing all clients of an image. for (const FillLayer* currNew = newLayers; currNew; currNew = currNew->next()) { - if (currNew->image() && (!oldLayers || !oldLayers->containsImage(currNew->image()))) + if (currNew->image()) currNew->image()->addClient(this); } + + for (const FillLayer* currOld = oldLayers; currOld; currOld = currOld->next()) { + if (currOld->image()) + currOld->image()->removeClient(this); + } } void RenderObject::updateImage(StyleImage* oldImage, StyleImage* newImage) @@ -1736,6 +1755,23 @@ IntSize RenderObject::offsetFromContainer(RenderObject* o) const return offset; } +IntSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const +{ + IntSize offset; + const RenderObject* currContainer = this; + do { + RenderObject* nextContainer = currContainer->container(); + ASSERT(nextContainer); // This means we reached the top without finding container. + if (!nextContainer) + break; + ASSERT(!currContainer->hasTransform()); + offset += currContainer->offsetFromContainer(nextContainer); + currContainer = nextContainer; + } while (currContainer != container); + + return offset; +} + IntRect RenderObject::localCaretRect(InlineBox*, int, int* extraWidthToEndOfLine) { if (extraWidthToEndOfLine) @@ -1769,8 +1805,11 @@ bool RenderObject::hasOutlineAnnotation() const return node() && node()->isLink() && document()->printing(); } -RenderObject* RenderObject::container() const +RenderObject* RenderObject::container(RenderBoxModelObject* repaintContainer, bool* repaintContainerSkipped) const { + if (repaintContainerSkipped) + *repaintContainerSkipped = false; + // This method is extremely similar to containingBlock(), but with a few notable // exceptions. // (1) It can be used on orphaned subtrees, i.e., it can be called safely even when @@ -1795,14 +1834,20 @@ RenderObject* RenderObject::container() const // we'll just return 0). // FIXME: The definition of view() has changed to not crawl up the render tree. It might // be safe now to use it. - while (o && o->parent() && !(o->hasTransform() && o->isRenderBlock())) + while (o && o->parent() && !(o->hasTransform() && o->isRenderBlock())) { + if (repaintContainerSkipped && o == repaintContainer) + *repaintContainerSkipped = true; o = o->parent(); + } } else if (pos == AbsolutePosition) { // Same goes here. We technically just want our containing block, but // we may not have one if we're part of an uninstalled subtree. We'll // climb as high as we can though. - while (o && o->style()->position() == StaticPosition && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) + while (o && o->style()->position() == StaticPosition && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) { + if (repaintContainerSkipped && o == repaintContainer) + *repaintContainerSkipped = true; o = o->parent(); + } } return o; @@ -1822,7 +1867,12 @@ void RenderObject::destroy() children->destroyLeftoverChildren(); // If this renderer is being autoscrolled, stop the autoscroll timer - if (document()->frame()->eventHandler()->autoscrollRenderer() == this) + + // FIXME: RenderObject::destroy should not get called with a renderar whose document + // has a null frame, so we assert this. However, we don't want release builds to crash which is why we + // check that the frame is not null. + ASSERT(document()->frame()); + if (document()->frame() && document()->frame()->eventHandler()->autoscrollRenderer() == this) document()->frame()->eventHandler()->stopAutoscrollTimer(true); if (m_hasCounterNodeMap) @@ -2240,10 +2290,12 @@ void RenderObject::adjustRectForOutlineAndShadow(IntRect& rect) const int shadowBottom = 0; do { - shadowLeft = min(boxShadow->x - boxShadow->blur - boxShadow->spread - outlineSize, shadowLeft); - shadowRight = max(boxShadow->x + boxShadow->blur + boxShadow->spread + outlineSize, shadowRight); - shadowTop = min(boxShadow->y - boxShadow->blur - boxShadow->spread - outlineSize, shadowTop); - shadowBottom = max(boxShadow->y + boxShadow->blur + boxShadow->spread + outlineSize, shadowBottom); + if (boxShadow->style == Normal) { + shadowLeft = min(boxShadow->x - boxShadow->blur - boxShadow->spread - outlineSize, shadowLeft); + shadowRight = max(boxShadow->x + boxShadow->blur + boxShadow->spread + outlineSize, shadowRight); + shadowTop = min(boxShadow->y - boxShadow->blur - boxShadow->spread - outlineSize, shadowTop); + shadowBottom = max(boxShadow->y + boxShadow->blur + boxShadow->spread + outlineSize, shadowBottom); + } boxShadow = boxShadow->next; } while (boxShadow); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderObject.h index 911169d75..e358c981a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderObject.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderObject.h @@ -278,6 +278,7 @@ public: virtual bool isTextField() const { return false; } virtual bool isVideo() const { return false; } virtual bool isWidget() const { return false; } + virtual bool isCanvas() const { return false; } bool isRoot() const { return document()->documentElement() == m_node; } bool isBody() const; @@ -285,6 +286,9 @@ public: bool isHTMLMarquee() const; + inline bool isAfterContent() const; + static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); } + bool childrenInline() const { return m_childrenInline; } void setChildrenInline(bool b = true) { m_childrenInline = b; } bool hasColumns() const { return m_hasColumns; } @@ -301,6 +305,7 @@ public: virtual bool isRenderPath() const { return false; } virtual bool isSVGText() const { return false; } virtual bool isSVGImage() const { return false; } + virtual bool isSVGForeignObject() const { return false; } // Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects, opacity and stroke-width. // This is used for all computation of objectBoundingBox relative units and by SVGLocateable::getBBox(). @@ -398,11 +403,11 @@ public: bool hasOutlineAnnotation() const; bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); } - /** - * returns the object containing this one. can be different from parent for - * positioned elements - */ - RenderObject* container() const; + // Returns the object containing this one. Can be different from parent for positioned elements. + // If repaintContainer and repaintContainerSkipped are not null, on return *repaintContainerSkipped + // is true if the renderer returned is an ancestor of repaintContainer. + RenderObject* container(RenderBoxModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const; + virtual RenderObject* hoverAncestor() const { return parent(); } // IE Extension that can be called on any RenderObject. See the implementation for the details. @@ -536,6 +541,8 @@ public: // Return the offset from the container() renderer (excluding transforms) virtual IntSize offsetFromContainer(RenderObject*) const; + // Return the offset from an object up the container() chain. Asserts that none of the intermediate objects have transforms. + IntSize offsetFromAncestorContainer(RenderObject*) const; virtual void absoluteRects(Vector<IntRect>&, int, int) { } // FIXME: useTransforms should go away eventually @@ -658,7 +665,9 @@ public: // Whether or not a given block needs to paint selection gaps. virtual bool shouldPaintSelectionGaps() const { return false; } +#if ENABLE(DRAG_SUPPORT) Node* draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const; +#endif /** * Returns the local coordinates of the caret within this render object. @@ -734,9 +743,6 @@ public: return outlineBoundsForRepaint(0); } - bool replacedHasOverflow() const { return m_replacedHasOverflow; } - void setReplacedHasOverflow(bool b = true) { m_replacedHasOverflow = b; } - protected: // Overrides should call the superclass at the end virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); @@ -845,9 +851,6 @@ private: // from RenderTableCell bool m_cellWidthChanged : 1; - // from RenderReplaced - bool m_replacedHasOverflow : 1; - private: // Store state between styleWillChange and styleDidChange static bool s_affectsParentBlock; @@ -858,6 +861,16 @@ inline bool RenderObject::documentBeingDestroyed() const return !document()->renderer(); } +inline bool RenderObject::isAfterContent() const +{ + if (style()->styleType() != AFTER) + return false; + // Text nodes don't have their own styles, so ignore the style on a text node. + if (isText() && !isBR()) + return false; + return true; +} + inline void RenderObject::setNeedsLayout(bool b, bool markParents) { bool alreadyNeededLayout = m_needsLayout; @@ -974,6 +987,42 @@ inline void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRenderi #endif } +inline int adjustForAbsoluteZoom(int value, RenderObject* renderer) +{ + float zoomFactor = renderer->style()->effectiveZoom(); + if (zoomFactor == 1) + return value; + // Needed because computeLengthInt truncates (rather than rounds) when scaling up. + if (zoomFactor > 1) + value++; + return static_cast<int>(value / zoomFactor); +} + +inline void adjustIntRectForAbsoluteZoom(IntRect& rect, RenderObject* renderer) +{ + rect.setX(adjustForAbsoluteZoom(rect.x(), renderer)); + rect.setY(adjustForAbsoluteZoom(rect.y(), renderer)); + rect.setWidth(adjustForAbsoluteZoom(rect.width(), renderer)); + rect.setHeight(adjustForAbsoluteZoom(rect.height(), renderer)); +} + +inline FloatPoint adjustFloatPointForAbsoluteZoom(const FloatPoint& point, RenderObject* renderer) +{ + // The result here is in floats, so we don't need the truncation hack from the integer version above. + float zoomFactor = renderer->style()->effectiveZoom(); + if (zoomFactor == 1) + return point; + return FloatPoint(point.x() / zoomFactor, point.y() / zoomFactor); +} + +inline void adjustFloatQuadForAbsoluteZoom(FloatQuad& quad, RenderObject* renderer) +{ + quad.setP1(adjustFloatPointForAbsoluteZoom(quad.p1(), renderer)); + quad.setP2(adjustFloatPointForAbsoluteZoom(quad.p2(), renderer)); + quad.setP3(adjustFloatPointForAbsoluteZoom(quad.p3(), renderer)); + quad.setP4(adjustFloatPointForAbsoluteZoom(quad.p4(), renderer)); +} + } // namespace WebCore #ifndef NDEBUG diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.cpp index 32e856f3d..23ab98f27 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.cpp @@ -41,13 +41,12 @@ namespace WebCore { static void updateListMarkerNumbers(RenderObject* child) { - for (RenderObject* r = child; r; r = r->nextSibling()) { - if (r->isListItem()) - static_cast<RenderListItem*>(r)->updateValue(); + for (RenderObject* sibling = child; sibling; sibling = sibling->nextSibling()) { + if (sibling->isListItem()) + toRenderListItem(sibling)->updateValue(); } } - void RenderObjectChildList::destroyLeftoverChildren() { while (firstChild()) { @@ -281,7 +280,7 @@ static void invalidateCountersInContainer(RenderObject* container) return; for (RenderObject* content = container->firstChild(); content; content = content->nextSibling()) { if (content->isCounter()) - static_cast<RenderCounter*>(content)->invalidate(); + toRenderCounter(content)->invalidate(); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderOverflow.h b/src/3rdparty/webkit/WebCore/rendering/RenderOverflow.h new file mode 100644 index 000000000..ed8976a5b --- /dev/null +++ b/src/3rdparty/webkit/WebCore/rendering/RenderOverflow.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef RenderOverflow_h +#define RenderOverflow_h + +#include "IntRect.h" + +namespace WebCore +{ +// RenderOverflow is a class for tracking content that spills out of a box. This class is used by RenderBox and +// InlineFlowBox. +// +// There are two types of overflow: layout overflow (which is expected to be reachable via scrolling mechanisms) and +// visual overflow (which is not expected to be reachable via scrolling mechanisms). +// +// Layout overflow examples include other boxes that spill out of our box, For example, in the inline case a tall image +// could spill out of a line box. + +// Examples of visual overflow are shadows, text stroke (and eventually outline and border-image). + +// This object is allocated only when some of these fields have non-default values in the owning box. +class RenderOverflow { +public: + RenderOverflow(const IntRect& defaultRect = IntRect()) + : m_topLayoutOverflow(defaultRect.y()) + , m_bottomLayoutOverflow(defaultRect.bottom()) + , m_leftLayoutOverflow(defaultRect.x()) + , m_rightLayoutOverflow(defaultRect.right()) + , m_topVisualOverflow(defaultRect.y()) + , m_bottomVisualOverflow(defaultRect.bottom()) + , m_leftVisualOverflow(defaultRect.x()) + , m_rightVisualOverflow(defaultRect.right()) + { + } + + int topLayoutOverflow() const { return m_topLayoutOverflow; } + int bottomLayoutOverflow() const { return m_bottomLayoutOverflow; } + int leftLayoutOverflow() const { return m_leftLayoutOverflow; } + int rightLayoutOverflow() const { return m_rightLayoutOverflow; } + IntRect layoutOverflowRect() const; + + int topVisualOverflow() const { return m_topVisualOverflow; } + int bottomVisualOverflow() const { return m_bottomVisualOverflow; } + int leftVisualOverflow() const { return m_leftVisualOverflow; } + int rightVisualOverflow() const { return m_rightVisualOverflow; } + IntRect visualOverflowRect() const; + + IntRect visibleOverflowRect() const; + + void setTopLayoutOverflow(int overflow) { m_topLayoutOverflow = overflow; } + void setBottomLayoutOverflow(int overflow) { m_bottomLayoutOverflow = overflow; } + void setLeftLayoutOverflow(int overflow) { m_leftLayoutOverflow = overflow; } + void setRightLayoutOverflow(int overflow) { m_rightLayoutOverflow = overflow; } + + void setTopVisualOverflow(int overflow) { m_topVisualOverflow = overflow; } + void setBottomVisualOverflow(int overflow) { m_bottomVisualOverflow = overflow; } + void setLeftVisualOverflow(int overflow) { m_leftVisualOverflow = overflow; } + void setRightVisualOverflow(int overflow) { m_rightVisualOverflow = overflow; } + + void move(int dx, int dy); + + void addLayoutOverflow(const IntRect&); + void addVisualOverflow(const IntRect&); + + void resetLayoutOverflow(const IntRect& defaultRect); + +private: + int m_topLayoutOverflow; + int m_bottomLayoutOverflow; + int m_leftLayoutOverflow; + int m_rightLayoutOverflow; + + int m_topVisualOverflow; + int m_bottomVisualOverflow; + int m_leftVisualOverflow; + int m_rightVisualOverflow; +}; + +inline IntRect RenderOverflow::layoutOverflowRect() const +{ + return IntRect(m_leftLayoutOverflow, m_topLayoutOverflow, m_rightLayoutOverflow - m_leftLayoutOverflow, m_bottomLayoutOverflow - m_topLayoutOverflow); +} + +inline IntRect RenderOverflow::visualOverflowRect() const +{ + return IntRect(m_leftVisualOverflow, m_topVisualOverflow, m_rightVisualOverflow - m_leftVisualOverflow, m_bottomVisualOverflow - m_topVisualOverflow); +} + +inline IntRect RenderOverflow::visibleOverflowRect() const +{ + IntRect combinedRect(layoutOverflowRect()); + combinedRect.unite(visualOverflowRect()); + return combinedRect; +} + +inline void RenderOverflow::move(int dx, int dy) +{ + m_topLayoutOverflow += dy; + m_bottomLayoutOverflow += dy; + m_leftLayoutOverflow += dx; + m_rightLayoutOverflow += dx; + + m_topVisualOverflow += dy; + m_bottomVisualOverflow += dy; + m_leftVisualOverflow += dx; + m_rightVisualOverflow += dx; +} + +inline void RenderOverflow::addLayoutOverflow(const IntRect& rect) +{ + m_topLayoutOverflow = std::min(rect.y(), m_topLayoutOverflow); + m_bottomLayoutOverflow = std::max(rect.bottom(), m_bottomLayoutOverflow); + m_leftLayoutOverflow = std::min(rect.x(), m_leftLayoutOverflow); + m_rightLayoutOverflow = std::max(rect.right(), m_rightLayoutOverflow); +} + +inline void RenderOverflow::addVisualOverflow(const IntRect& rect) +{ + m_topVisualOverflow = std::min(rect.y(), m_topVisualOverflow); + m_bottomVisualOverflow = std::max(rect.bottom(), m_bottomVisualOverflow); + m_leftVisualOverflow = std::min(rect.x(), m_leftVisualOverflow); + m_rightVisualOverflow = std::max(rect.right(), m_rightVisualOverflow); +} + +inline void RenderOverflow::resetLayoutOverflow(const IntRect& rect) +{ + m_topLayoutOverflow = rect.y(); + m_bottomLayoutOverflow = rect.bottom(); + m_leftLayoutOverflow = rect.x(); + m_rightLayoutOverflow = rect.right(); +} + +} // namespace WebCore + +#endif // RenderOverflow_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPart.h b/src/3rdparty/webkit/WebCore/rendering/RenderPart.h index a1d2e2b62..08abf9904 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderPart.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderPart.h @@ -45,6 +45,15 @@ private: virtual const char* renderName() const { return "RenderPart"; } }; +inline RenderPart* toRenderPart(RenderObject* object) +{ + ASSERT(!object || object->isRenderPart()); + return static_cast<RenderPart*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderPart(const RenderPart*); + } #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp index 7a3aa6456..e2c8e7d8a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp @@ -33,8 +33,8 @@ #include "HTMLParamElement.h" #include "MIMETypeRegistry.h" #include "Page.h" -#include "PluginData.h" #include "RenderView.h" +#include "RenderWidgetProtector.h" #include "Text.h" #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) @@ -72,7 +72,7 @@ static bool isURLAllowed(Document* doc, const String& url) KURL completeURL = doc->completeURL(url); bool foundSelfReference = false; for (Frame* frame = doc->frame(); frame; frame = frame->tree()->parent()) { - if (equalIgnoringRef(frame->loader()->url(), completeURL)) { + if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) { if (foundSelfReference) return false; foundSelfReference = true; @@ -90,25 +90,12 @@ static ClassIdToTypeMap* createClassIdToTypeMap() map->add("clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA", "audio/x-pn-realaudio-plugin"); map->add("clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B", "video/quicktime"); map->add("clsid:166B1BCA-3F9C-11CF-8075-444553540000", "application/x-director"); -#if ENABLE(ACTIVEX_TYPE_CONVERSION_WMPLAYER) map->add("clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6", "application/x-mplayer2"); map->add("clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95", "application/x-mplayer2"); -#endif return map; } -static const String& activeXType() -{ - DEFINE_STATIC_LOCAL(String, activeXType, ("application/x-oleobject")); - return activeXType; -} - -static inline bool havePlugin(const PluginData* pluginData, const String& type) -{ - return pluginData && !type.isEmpty() && pluginData->supportsMimeType(type); -} - -static String serviceTypeForClassId(const String& classId, const PluginData* pluginData) +static String serviceTypeForClassId(const String& classId) { // Return early if classId is empty (since we won't do anything below). // Furthermore, if classId is null, calling get() below will crash. @@ -116,30 +103,7 @@ static String serviceTypeForClassId(const String& classId, const PluginData* plu return String(); static ClassIdToTypeMap* map = createClassIdToTypeMap(); - String type = map->get(classId); - - // If we do have a plug-in that supports generic ActiveX content and don't have a plug-in - // for the MIME type we came up with, ignore the MIME type we came up with and just use - // the ActiveX type. - if (havePlugin(pluginData, activeXType()) && !havePlugin(pluginData, type)) - return activeXType(); - - return type; -} - -static inline bool shouldUseEmbedDescendant(HTMLObjectElement* objectElement, const PluginData* pluginData) -{ -#if PLATFORM(MAC) - UNUSED_PARAM(objectElement); - UNUSED_PARAM(pluginData); - // On Mac, we always want to use the embed descendant. - return true; -#else - // If we have both an <object> and <embed>, we always want to use the <embed> except when we have - // an ActiveX plug-in and plan to use it. - return !(havePlugin(pluginData, activeXType()) - && serviceTypeForClassId(objectElement->classId(), pluginData) == activeXType()); -#endif + return map->get(classId); } static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues) @@ -168,6 +132,12 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins) Vector<String> paramValues; Frame* frame = frameView()->frame(); + // The calls to FrameLoader::requestObject within this function can result in a plug-in being initialized. + // This can run cause arbitrary JavaScript to run and may result in this RenderObject being detached from + // the render tree and destroyed, causing a crash like <rdar://problem/6954546>. By extending our lifetime + // artifically to ensure that we remain alive for the duration of plug-in initialization. + RenderWidgetProtector protector(this); + if (node()->hasTagName(objectTag)) { HTMLObjectElement* o = static_cast<HTMLObjectElement*>(node()); @@ -177,17 +147,14 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins) // Check for a child EMBED tag. HTMLEmbedElement* embed = 0; - const PluginData* pluginData = frame->page()->pluginData(); - if (shouldUseEmbedDescendant(o, pluginData)) { - for (Node* child = o->firstChild(); child; ) { - if (child->hasTagName(embedTag)) { - embed = static_cast<HTMLEmbedElement*>(child); - break; - } else if (child->hasTagName(objectTag)) - child = child->nextSibling(); // Don't descend into nested OBJECT tags - else - child = child->traverseNextNode(o); // Otherwise descend (EMBEDs may be inside COMMENT tags) - } + for (Node* child = o->firstChild(); child; ) { + if (child->hasTagName(embedTag)) { + embed = static_cast<HTMLEmbedElement*>(child); + break; + } else if (child->hasTagName(objectTag)) + child = child->nextSibling(); // Don't descend into nested OBJECT tags + else + child = child->traverseNextNode(o); // Otherwise descend (EMBEDs may be inside COMMENT tags) } // Use the attributes from the EMBED tag instead of the OBJECT tag including WIDTH and HEIGHT. @@ -260,7 +227,7 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins) // If we still don't have a type, try to map from a specific CLASSID to a type. if (serviceType.isEmpty()) - serviceType = serviceTypeForClassId(o->classId(), pluginData); + serviceType = serviceTypeForClassId(o->classId()); if (!isURLAllowed(document(), url)) return; @@ -282,7 +249,8 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins) return; } - bool success = frame->loader()->requestObject(this, url, AtomicString(o->name()), serviceType, paramNames, paramValues); + bool success = o->dispatchBeforeLoadEvent(url) && + frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues); if (!success && m_hasFallbackContent) o->renderFallbackContent(); } else if (node()->hasTagName(embedTag)) { @@ -316,7 +284,8 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins) } - frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues); + if (o->dispatchBeforeLoadEvent(url)) + frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues); } #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) else if (node()->hasTagName(videoTag) || node()->hasTagName(audioTag)) { @@ -339,7 +308,9 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins) } serviceType = "application/x-media-element-proxy-plugin"; - frame->loader()->requestObject(this, url, nullAtom, serviceType, paramNames, paramValues); + + if (o->dispatchBeforeLoadEvent(url)) + frame->loader()->requestObject(this, url, nullAtom, serviceType, paramNames, paramValues); } #endif } @@ -350,10 +321,12 @@ void RenderPartObject::layout() calcWidth(); calcHeight(); - adjustOverflowForBoxShadowAndReflect(); RenderPart::layout(); + m_overflow.clear(); + addShadowOverflow(); + if (!widget() && frameView()) frameView()->addWidgetToUpdate(this); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.h index 2159d3c06..ad956bd1e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 2000 Simon Hausmann <hausmann@kde.org> - * Copyright (C) 2006, 2009 Apple Inc. + * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -42,6 +42,15 @@ private: virtual void viewCleared(); }; +inline RenderPartObject* toRenderPartObject(RenderObject* object) +{ + ASSERT(!object || !strcmp(object->renderName(), "RenderPartObject")); + return static_cast<RenderPartObject*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderPartObject(const RenderPartObject*); + } // namespace WebCore #endif // RenderPartObject_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPath.h b/src/3rdparty/webkit/WebCore/rendering/RenderPath.h index a4aefedc4..2ff179e24 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderPath.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderPath.h @@ -40,6 +40,9 @@ class RenderPath : public RenderSVGModelObject { public: RenderPath(SVGStyledTransformableElement*); + const Path& path() const; + +private: // Hit-detection seperated for the fill and the stroke bool fillContains(const FloatPoint&, bool requiresFill = true) const; bool strokeContains(const FloatPoint&, bool requiresStroke = true) const; @@ -49,7 +52,6 @@ public: virtual TransformationMatrix localToParentTransform() const; - const Path& path() const; void setPath(const Path&); virtual bool isRenderPath() const { return true; } @@ -73,6 +75,21 @@ private: TransformationMatrix m_localTransform; }; +inline RenderPath* toRenderPath(RenderObject* object) +{ + ASSERT(!object || object->isRenderPath()); + return static_cast<RenderPath*>(object); +} + +inline const RenderPath* toRenderPath(const RenderObject* object) +{ + ASSERT(!object || object->isRenderPath()); + return static_cast<const RenderPath*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderPath(const RenderPath*); + } #endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp index ba045eab3..27d2e72af 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp @@ -34,9 +34,6 @@ using namespace std; namespace WebCore { -typedef WTF::HashMap<const RenderReplaced*, IntRect> OverflowRectMap; -static OverflowRectMap* gOverflowRectMap = 0; - const int cDefaultWidth = 300; const int cDefaultHeight = 150; @@ -56,8 +53,6 @@ RenderReplaced::RenderReplaced(Node* node, const IntSize& intrinsicSize) RenderReplaced::~RenderReplaced() { - if (replacedHasOverflow()) - gOverflowRectMap->remove(this); } void RenderReplaced::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) @@ -66,7 +61,7 @@ void RenderReplaced::styleDidChange(StyleDifference diff, const RenderStyle* old bool hadStyle = (oldStyle != 0); float oldZoom = hadStyle ? oldStyle->effectiveZoom() : RenderStyle::initialZoom(); - if (hadStyle && style() && style()->effectiveZoom() != oldZoom) + if (style() && style()->effectiveZoom() != oldZoom) intrinsicSizeChanged(); } @@ -77,10 +72,12 @@ void RenderReplaced::layout() LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); setHeight(minimumReplacedHeight()); - + calcWidth(); calcHeight(); - adjustOverflowForBoxShadowAndReflect(); + + m_overflow.clear(); + addShadowOverflow(); repainter.repaintAfterLayout(); @@ -127,21 +124,29 @@ void RenderReplaced::paint(PaintInfo& paintInfo, int tx, int ty) drawSelectionTint = false; } + bool completelyClippedOut = false; if (style()->hasBorderRadius()) { - // Push a clip if we have a border radius, since we want to round the foreground content that gets painted. - paintInfo.context->save(); - - IntSize topLeft, topRight, bottomLeft, bottomRight; IntRect borderRect = IntRect(tx, ty, width(), height()); - style()->getBorderRadiiForRect(borderRect, topLeft, topRight, bottomLeft, bottomRight); - paintInfo.context->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight); + if (borderRect.isEmpty()) + completelyClippedOut = true; + else { + // Push a clip if we have a border radius, since we want to round the foreground content that gets painted. + paintInfo.context->save(); + + IntSize topLeft, topRight, bottomLeft, bottomRight; + style()->getBorderRadiiForRect(borderRect, topLeft, topRight, bottomLeft, bottomRight); + + paintInfo.context->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight); + } } - paintReplaced(paintInfo, tx, ty); + if (!completelyClippedOut) { + paintReplaced(paintInfo, tx, ty); - if (style()->hasBorderRadius()) - paintInfo.context->restore(); + if (style()->hasBorderRadius()) + paintInfo.context->restore(); + } // The selection tint never gets clipped by border-radius rounding, since we want it to run right up to the edges of // surrounding content. @@ -169,8 +174,8 @@ bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, int& tx, int& ty) int currentTY = ty + y(); // Early exit if the element touches the edges. - int top = currentTY + overflowTop(); - int bottom = currentTY + overflowHeight(); + int top = currentTY + topVisibleOverflow(); + int bottom = currentTY + bottomVisibleOverflow(); if (isSelected() && m_inlineBoxWrapper) { int selTop = ty + m_inlineBoxWrapper->root()->selectionTop(); int selBottom = ty + selTop + m_inlineBoxWrapper->root()->selectionHeight(); @@ -179,7 +184,7 @@ bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, int& tx, int& ty) } int os = 2 * maximalOutlineSize(paintInfo.phase); - if (currentTX + overflowLeft() >= paintInfo.rect.right() + os || currentTX + overflowWidth() <= paintInfo.rect.x() - os) + if (currentTX + leftVisibleOverflow() >= paintInfo.rect.right() + os || currentTX + rightVisibleOverflow() <= paintInfo.rect.x() - os) return false; if (top >= paintInfo.rect.bottom() + os || bottom <= paintInfo.rect.y() - os) return false; @@ -231,8 +236,8 @@ VisiblePosition RenderReplaced::positionForPoint(const IntPoint& point) RootInlineBox* root = box->root(); - int top = root->topOverflow(); - int bottom = root->nextRootBox() ? root->nextRootBox()->topOverflow() : root->bottomOverflow(); + int top = root->lineTop(); + int bottom = root->nextRootBox() ? root->nextRootBox()->lineTop() : root->lineBottom(); if (point.y() + y() < top) return createVisiblePosition(caretMinOffset(), DOWNSTREAM); // coordinates are above @@ -327,80 +332,6 @@ void RenderReplaced::setIntrinsicSize(const IntSize& size) m_intrinsicSize = size; } -void RenderReplaced::adjustOverflowForBoxShadowAndReflect() -{ - IntRect overflow; - for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - IntRect shadow = borderBoxRect(); - shadow.move(boxShadow->x, boxShadow->y); - shadow.inflate(boxShadow->blur + boxShadow->spread); - overflow.unite(shadow); - } - - // Now that we have an overflow rect including shadow, let's make sure that - // the reflection (which can also include the shadow) is also included. - if (hasReflection()) { - if (overflow.isEmpty()) - overflow = borderBoxRect(); - overflow.unite(reflectedRect(overflow)); - } - - if (!overflow.isEmpty()) { - if (!gOverflowRectMap) - gOverflowRectMap = new OverflowRectMap(); - overflow.unite(borderBoxRect()); - gOverflowRectMap->set(this, overflow); - setReplacedHasOverflow(true); - } else if (replacedHasOverflow()) { - gOverflowRectMap->remove(this); - setReplacedHasOverflow(false); - } -} - -int RenderReplaced::overflowHeight(bool) const -{ - if (replacedHasOverflow()) { - IntRect *r = &gOverflowRectMap->find(this)->second; - return r->height() + r->y(); - } - - return height(); -} - -int RenderReplaced::overflowWidth(bool) const -{ - if (replacedHasOverflow()) { - IntRect *r = &gOverflowRectMap->find(this)->second; - return r->width() + r->x(); - } - - return width(); -} - -int RenderReplaced::overflowLeft(bool) const -{ - if (replacedHasOverflow()) - return gOverflowRectMap->get(this).x(); - - return 0; -} - -int RenderReplaced::overflowTop(bool) const -{ - if (replacedHasOverflow()) - return gOverflowRectMap->get(this).y(); - - return 0; -} - -IntRect RenderReplaced::overflowRect(bool) const -{ - if (replacedHasOverflow()) - return gOverflowRectMap->find(this)->second; - - return borderBoxRect(); -} - IntRect RenderReplaced::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) { if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent()) @@ -408,7 +339,7 @@ IntRect RenderReplaced::clippedOverflowRectForRepaint(RenderBoxModelObject* repa // The selectionRect can project outside of the overflowRect, so take their union // for repainting to avoid selection painting glitches. - IntRect r = unionRect(localSelectionRect(false), overflowRect(false)); + IntRect r = unionRect(localSelectionRect(false), visibleOverflowRect()); RenderView* v = view(); if (v) { diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.h b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.h index 493744674..0ba6b8abc 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. + * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -32,6 +32,25 @@ public: RenderReplaced(Node*, const IntSize& intrinsicSize); virtual ~RenderReplaced(); +protected: + virtual void layout(); + + virtual IntSize intrinsicSize() const; + + virtual void setSelectionState(SelectionState); + + bool isSelected() const; + + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + + void setIntrinsicSize(const IntSize&); + virtual void intrinsicSizeChanged(); + + bool shouldPaint(PaintInfo&, int& tx, int& ty); + void adjustOverflowForBoxShadowAndReflect(); + IntRect localSelectionRect(bool checkWhetherSelected = true) const; + +private: virtual const char* renderName() const { return "RenderReplaced"; } virtual bool canHaveChildren() const { return false; } @@ -40,43 +59,21 @@ public: virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const; virtual void calcPrefWidths(); - - virtual void layout(); + virtual int minimumReplacedHeight() const { return 0; } virtual void paint(PaintInfo&, int tx, int ty); virtual void paintReplaced(PaintInfo&, int /*tx*/, int /*ty*/) { } - virtual IntSize intrinsicSize() const; - - virtual int overflowHeight(bool includeInterior = true) const; - virtual int overflowWidth(bool includeInterior = true) const; - virtual int overflowLeft(bool includeInterior = true) const; - virtual int overflowTop(bool includeInterior = true) const; - virtual IntRect overflowRect(bool includeInterior = true) const; - virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer); virtual unsigned caretMaxRenderedOffset() const; virtual VisiblePosition positionForPoint(const IntPoint&); virtual bool canBeSelectionLeaf() const { return true; } - virtual void setSelectionState(SelectionState); - virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true); - - bool isSelected() const; - -protected: - virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); - - void setIntrinsicSize(const IntSize&); - virtual void intrinsicSizeChanged(); - bool shouldPaint(PaintInfo&, int& tx, int& ty); - void adjustOverflowForBoxShadowAndReflect(); - IntRect localSelectionRect(bool checkWhetherSelected = true) const; + virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true); -private: IntSize m_intrinsicSize; }; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.h index f8afd0f6d..a4ececb3c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.h @@ -34,6 +34,8 @@ class SVGElement; class RenderSVGBlock : public RenderBlock, protected SVGRenderBase { public: RenderSVGBlock(SVGElement*); + +private: virtual void setStyle(PassRefPtr<RenderStyle>); }; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.cpp index 8a77d2edb..d7aec99df 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.cpp @@ -42,10 +42,6 @@ RenderSVGContainer::RenderSVGContainer(SVGStyledElement* node) { } -RenderSVGContainer::~RenderSVGContainer() -{ -} - bool RenderSVGContainer::drawsContents() const { return m_drawsContents; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.h index 4bb7e44d3..f2195e3fa 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.h @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2007 Rob Buis <buis@kde.org> Copyright (C) 2009 Google, Inc. All rights reserved. + Copyright (C) 2009 Apple Inc. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -33,10 +34,7 @@ class SVGElement; class RenderSVGContainer : public RenderSVGModelObject { public: RenderSVGContainer(SVGStyledElement*); - ~RenderSVGContainer(); - virtual RenderObjectChildList* virtualChildren() { return children(); } - virtual const RenderObjectChildList* virtualChildren() const { return children(); } const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } @@ -44,11 +42,18 @@ public: void setDrawsContents(bool); bool drawsContents() const; +protected: + virtual void paint(PaintInfo&, int parentX, int parentY); + +private: + virtual RenderObjectChildList* virtualChildren() { return children(); } + virtual const RenderObjectChildList* virtualChildren() const { return children(); } + virtual bool isSVGContainer() const { return true; } virtual const char* renderName() const { return "RenderSVGContainer"; } virtual void layout(); - virtual void paint(PaintInfo&, int parentX, int parentY); + virtual void addFocusRingRects(GraphicsContext*, int tx, int ty); virtual FloatRect objectBoundingBox() const; @@ -56,7 +61,6 @@ public: virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction); -protected: // Allow RenderSVGTransformableContainer to hook in at the right time in layout() virtual void calculateLocalTransform() { } @@ -65,13 +69,29 @@ protected: virtual void applyViewportClip(PaintInfo&) { } virtual bool pointIsInsideViewportClip(const FloatPoint& /*pointInParent*/) { return true; } -private: bool selfWillPaint() const; RenderObjectChildList m_children; bool m_drawsContents : 1; }; +inline RenderSVGContainer* toRenderSVGContainer(RenderObject* object) +{ + // Note: isSVGContainer is also true for RenderSVGViewportContainer, which is not derived from this. + ASSERT(!object || object->isSVGContainer() && strcmp(object->renderName(), "RenderSVGViewportContainer")); + return static_cast<RenderSVGContainer*>(object); +} + +inline const RenderSVGContainer* toRenderSVGContainer(const RenderObject* object) +{ + // Note: isSVGContainer is also true for RenderSVGViewportContainer, which is not derived from this. + ASSERT(!object || object->isSVGContainer() && strcmp(object->renderName(), "RenderSVGViewportContainer")); + return static_cast<const RenderSVGContainer*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderSVGContainer(const RenderSVGContainer*); + } // namespace WebCore #endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.cpp index f08c00808..d4b39d3a7 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.cpp @@ -35,10 +35,6 @@ RenderSVGHiddenContainer::RenderSVGHiddenContainer(SVGStyledElement* element) { } -RenderSVGHiddenContainer::~RenderSVGHiddenContainer() -{ -} - void RenderSVGHiddenContainer::layout() { ASSERT(needsLayout()); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.h index 5a208d0b2..0ef0a430e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.h @@ -36,9 +36,8 @@ namespace WebCore { class RenderSVGHiddenContainer : public RenderSVGContainer { public: RenderSVGHiddenContainer(SVGStyledElement*); - virtual ~RenderSVGHiddenContainer(); - virtual bool isSVGContainer() const { return true; } + private: virtual bool isSVGHiddenContainer() const { return true; } virtual const char* renderName() const { return "RenderSVGHiddenContainer"; } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.cpp index f4947092e..7e0b40d53 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.cpp @@ -47,10 +47,6 @@ RenderSVGImage::RenderSVGImage(SVGImageElement* impl) { } -RenderSVGImage::~RenderSVGImage() -{ -} - void RenderSVGImage::adjustRectsForAspectRatio(FloatRect& destRect, FloatRect& srcRect, SVGPreserveAspectRatio* aspectRatio) { float origDestWidth = destRect.width(); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.h index 01b8b6503..ef117191d 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.h @@ -1,6 +1,6 @@ /* Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> - Copyright (C) 2006 Apple Computer, Inc. + Copyright (C) 2006, 2009 Apple Inc. All rights reserved. Copyright (C) 2007 Rob Buis <buis@kde.org> Copyright (C) 2009 Google, Inc. @@ -38,8 +38,8 @@ namespace WebCore { class RenderSVGImage : public RenderImage, SVGRenderBase { public: RenderSVGImage(SVGImageElement*); - virtual ~RenderSVGImage(); + private: virtual const char* renderName() const { return "RenderSVGImage"; } virtual bool isSVGImage() const { return true; } @@ -63,12 +63,11 @@ namespace WebCore { virtual void layout(); virtual void paint(PaintInfo&, int parentX, int parentY); - bool requiresLayer() const { return false; } + virtual bool requiresLayer() const { return false; } virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction); - virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int _x, int _y, int _tx, int _ty, HitTestAction); + virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); - private: virtual TransformationMatrix localTransform() const { return m_localTransform; } TransformationMatrix m_localTransform; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.h index c4a096d46..e9c5d6e19 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.h @@ -33,6 +33,8 @@ namespace WebCore { class RenderSVGInlineText : public RenderText { public: RenderSVGInlineText(Node*, PassRefPtr<StringImpl>); + +private: virtual const char* renderName() const { return "RenderSVGInlineText"; } virtual void styleDidChange(StyleDifference, const RenderStyle*); @@ -49,7 +51,6 @@ public: virtual void destroy(); -private: virtual InlineTextBox* createTextBox(); IntRect computeRepaintRectForRange(RenderBoxModelObject* repaintContainer, int startPos, int endPos); FloatQuad computeRepaintQuadForRange(RenderBoxModelObject* repaintContainer, int startPos, int endPos); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.cpp index 80c29dd39..0a39bf472 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.cpp @@ -48,10 +48,6 @@ RenderSVGRoot::RenderSVGRoot(SVGStyledElement* node) setReplaced(true); } -RenderSVGRoot::~RenderSVGRoot() -{ -} - int RenderSVGRoot::lineHeight(bool, bool) const { return height() + marginTop() + marginBottom(); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.h index 50866d2fe..08c3058e7 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.h @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2007 Rob Buis <buis@kde.org> Copyright (C) 2009 Google, Inc. All rights reserved. + Copyright (C) 2009 Apple Inc. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -35,13 +36,14 @@ class TransformationMatrix; class RenderSVGRoot : public RenderBox, SVGRenderBase { public: RenderSVGRoot(SVGStyledElement*); - ~RenderSVGRoot(); - virtual RenderObjectChildList* virtualChildren() { return children(); } - virtual const RenderObjectChildList* virtualChildren() const { return children(); } const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } +private: + virtual RenderObjectChildList* virtualChildren() { return children(); } + virtual const RenderObjectChildList* virtualChildren() const { return children(); } + virtual bool isSVGRoot() const { return true; } virtual const char* renderName() const { return "RenderSVGRoot"; } @@ -70,7 +72,6 @@ public: virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const; -private: void calcViewport(); const FloatSize& viewportSize() const; @@ -85,6 +86,21 @@ private: FloatSize m_viewportSize; }; +inline RenderSVGRoot* toRenderSVGRoot(RenderObject* object) +{ + ASSERT(!object || object->isSVGRoot()); + return static_cast<RenderSVGRoot*>(object); +} + +inline const RenderSVGRoot* toRenderSVGRoot(const RenderObject* object) +{ + ASSERT(!object || object->isSVGRoot()); + return static_cast<const RenderSVGRoot*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderSVGRoot(const RenderSVGRoot*); + } // namespace WebCore #endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h index 088332ee4..9a2770ba3 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h @@ -37,6 +37,7 @@ class RenderSVGText : public RenderSVGBlock { public: RenderSVGText(SVGTextElement* node); +private: virtual const char* renderName() const { return "RenderSVGText"; } virtual bool isSVGText() const { return true; } @@ -61,7 +62,6 @@ public: virtual FloatRect objectBoundingBox() const; virtual FloatRect repaintRectInLocalCoordinates() const; -private: // FIXME: This can be removed when localTransform() is removed from RenderObject virtual TransformationMatrix localTransform() const { return m_localTransform; } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGTextPath.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGTextPath.h index efab659ae..8e6ff429a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGTextPath.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGTextPath.h @@ -2,6 +2,7 @@ * This file is part of the WebKit project. * * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -37,9 +38,9 @@ namespace WebCore { bool exactAlignment() const; bool stretchMethod() const; + private: virtual const char* renderName() const { return "RenderSVGTextPath"; } - private: float m_startOffset; bool m_exactAlignment : 1; @@ -47,6 +48,16 @@ namespace WebCore { Path m_layoutPath; }; + + inline RenderSVGTextPath* toRenderSVGTextPath(RenderObject* object) + { + ASSERT(!object || !strcmp(object->renderName(), "RenderSVGTextPath")); + return static_cast<RenderSVGTextPath*>(object); + } + + // This will catch anyone doing an unnecessary cast. + void toRenderSVGTextPath(const RenderSVGTextPath*); + } #endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.cpp index d20862146..a432ef3b7 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.cpp @@ -38,14 +38,14 @@ RenderSVGViewportContainer::RenderSVGViewportContainer(SVGStyledElement* node) { } -RenderSVGViewportContainer::~RenderSVGViewportContainer() -{ -} - void RenderSVGViewportContainer::paint(PaintInfo& paintInfo, int parentX, int parentY) { + // FIXME: The if statement here evaluates to false. isEmpty() is exactly the same + // as what is on the right side, so it's basically !isEmpty && isEmpty. So this + // function does nothing. + // A value of zero disables rendering of the element. - if (!viewport().isEmpty() && (viewport().width() <= 0. || viewport().height() <= 0.)) + if (!m_viewport.isEmpty() && (m_viewport.width() <= 0. || m_viewport.height() <= 0.)) return; RenderSVGContainer::paint(paintInfo, parentX, parentY); @@ -54,12 +54,7 @@ void RenderSVGViewportContainer::paint(PaintInfo& paintInfo, int parentX, int pa void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo) { if (style()->overflowX() != OVISIBLE) - paintInfo.context->clip(enclosingIntRect(viewport())); // FIXME: Eventually we'll want float-precision clipping -} - -FloatRect RenderSVGViewportContainer::viewport() const -{ - return m_viewport; + paintInfo.context->clip(enclosingIntRect(m_viewport)); // FIXME: Eventually we'll want float-precision clipping } void RenderSVGViewportContainer::calcViewport() @@ -91,10 +86,10 @@ TransformationMatrix RenderSVGViewportContainer::viewportTransform() const { if (node()->hasTagName(SVGNames::svgTag)) { SVGSVGElement* svg = static_cast<SVGSVGElement*>(node()); - return svg->viewBoxToViewTransform(viewport().width(), viewport().height()); + return svg->viewBoxToViewTransform(m_viewport.width(), m_viewport.height()); } else if (node()->hasTagName(SVGNames::markerTag)) { SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node()); - return marker->viewBoxToViewTransform(viewport().width(), viewport().height()); + return marker->viewBoxToViewTransform(m_viewport.width(), m_viewport.height()); } return TransformationMatrix(); @@ -103,7 +98,7 @@ TransformationMatrix RenderSVGViewportContainer::viewportTransform() const TransformationMatrix RenderSVGViewportContainer::localToParentTransform() const { TransformationMatrix viewportTranslation; - viewportTranslation.translate(viewport().x(), viewport().y()); + viewportTranslation.translate(m_viewport.x(), m_viewport.y()); return viewportTransform() * viewportTranslation; // If this class were ever given a localTransform(), then the above would read: // return viewportTransform() * localTransform() * viewportTranslation; @@ -121,7 +116,7 @@ bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& poi // Respect the viewport clip (which is in parent coords). SVG does not support separate x/y overflow rules. if (style()->overflowX() == OHIDDEN) { ASSERT(style()->overflowY() == OHIDDEN); - if (!viewport().contains(pointInParent)) + if (!m_viewport.contains(pointInParent)) return false; } return true; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.h index 8657af4c8..b8b30b550 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.h @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2007 Rob Buis <buis@kde.org> 2009 Google, Inc. + Copyright (C) 2009 Apple Inc. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -33,24 +34,21 @@ namespace WebCore { class RenderSVGViewportContainer : public RenderSVGContainer { public: RenderSVGViewportContainer(SVGStyledElement*); - ~RenderSVGViewportContainer(); - virtual bool isSVGContainer() const { return true; } - virtual const char* renderName() const { return "RenderSVGViewportContainer"; } + // FIXME: This is only public for SVGResourceMarker::draw, likely the callsite should be changed. + TransformationMatrix viewportTransform() const; virtual void paint(PaintInfo&, int parentX, int parentY); +private: + virtual bool isSVGContainer() const { return true; } + virtual const char* renderName() const { return "RenderSVGViewportContainer"; } + virtual TransformationMatrix localToParentTransform() const; // FIXME: This override should be removed once callers of RenderBox::absoluteTransform() can be removed. virtual TransformationMatrix absoluteTransform() const; - FloatRect viewport() const; - - // FIXME: This is only public for SVGResourceMarker::draw, likely the callsite should be changed. - TransformationMatrix viewportTransform() const; - -private: virtual void calcViewport(); virtual void applyViewportClip(PaintInfo&); @@ -59,6 +57,15 @@ private: FloatRect m_viewport; }; +inline RenderSVGViewportContainer* toRenderSVGViewportContainer(RenderObject* object) +{ + ASSERT(!object || !strcmp(object->renderName(), "RenderSVGViewportContainer")); + return static_cast<RenderSVGViewportContainer*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderSVGViewportContainer(const RenderSVGViewportContainer*); + } // namespace WebCore #endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.cpp index db24a060c..63fce8dbb 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,6 +25,7 @@ #include "config.h" #include "RenderScrollbar.h" + #include "RenderScrollbarPart.h" #include "RenderScrollbarTheme.h" @@ -39,6 +40,16 @@ RenderScrollbar::RenderScrollbar(ScrollbarClient* client, ScrollbarOrientation o : Scrollbar(client, orientation, RegularScrollbar, RenderScrollbarTheme::renderScrollbarTheme()) , m_owner(renderer) { + // FIXME: We need to do this because RenderScrollbar::styleChanged is called as soon as the scrollbar is created. + + // Update the scrollbar size. + updateScrollbarPart(ScrollbarBGPart); + RenderScrollbarPart* part = m_parts.get(ScrollbarBGPart); + if (!part) + return; + + part->layout(); + setFrameRect(IntRect(0, 0, part->width(), part->height())); } RenderScrollbar::~RenderScrollbar() @@ -173,9 +184,14 @@ static PseudoId pseudoForScrollbarPart(ScrollbarPart part) return SCROLLBAR_THUMB; case TrackBGPart: return SCROLLBAR_TRACK; - default: + case ScrollbarBGPart: return SCROLLBAR; + case NoPart: + case AllParts: + break; } + ASSERT_NOT_REACHED(); + return SCROLLBAR; } void RenderScrollbar::updateScrollbarPart(ScrollbarPart partType, bool destroy) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.h b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.h index 245d75099..b3c00efe3 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,7 +33,6 @@ namespace WebCore { class RenderBox; -class RenderStyle; class RenderScrollbarPart; class RenderStyle; @@ -46,21 +45,9 @@ public: static PassRefPtr<Scrollbar> createCustomScrollbar(ScrollbarClient*, ScrollbarOrientation, RenderBox*); virtual ~RenderScrollbar(); - virtual void setParent(ScrollView*); - virtual void setEnabled(bool); - - virtual void paint(GraphicsContext*, const IntRect& damageRect); - - virtual void setHoveredPart(ScrollbarPart); - virtual void setPressedPart(ScrollbarPart); - - void updateScrollbarParts(bool destroy = false); - static ScrollbarPart partForStyleResolve(); static RenderScrollbar* scrollbarForStyleResolve(); - virtual void styleChanged(); - RenderBox* owningRenderer() const { return m_owner; } void paintPart(GraphicsContext*, ScrollbarPart, const IntRect&); @@ -70,9 +57,22 @@ public: IntRect trackPieceRectWithMargins(ScrollbarPart, const IntRect&); int minimumThumbLength(); - virtual bool isCustomScrollbar() const { return true; } private: + virtual void setParent(ScrollView*); + virtual void setEnabled(bool); + + virtual void paint(GraphicsContext*, const IntRect& damageRect); + + virtual void setHoveredPart(ScrollbarPart); + virtual void setPressedPart(ScrollbarPart); + + virtual void styleChanged(); + + virtual bool isCustomScrollbar() const { return true; } + + void updateScrollbarParts(bool destroy = false); + PassRefPtr<RenderStyle> getScrollbarPseudoStyle(ScrollbarPart, PseudoId); void updateScrollbarPart(ScrollbarPart, bool destroy = false); @@ -80,6 +80,15 @@ private: HashMap<unsigned, RenderScrollbarPart*> m_parts; }; +inline RenderScrollbar* toRenderScrollbar(Scrollbar* scrollbar) +{ + ASSERT(!scrollbar || scrollbar->isCustomScrollbar()); + return static_cast<RenderScrollbar*>(scrollbar); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderScrollbar(const RenderScrollbar*); + } // namespace WebCore #endif // RenderScrollbar_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarPart.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarPart.cpp index 0f29aeb1f..c83248a11 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarPart.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarPart.cpp @@ -27,6 +27,7 @@ #include "RenderScrollbarPart.h" #include "RenderScrollbar.h" #include "RenderScrollbarTheme.h" +#include "RenderView.h" using namespace std; @@ -51,9 +52,6 @@ void RenderScrollbarPart::layout() else layoutVerticalPart(); - m_overflowWidth = max(width(), m_overflowWidth); - m_overflowHeight = max(height(), m_overflowHeight); - setNeedsLayout(false); } @@ -143,8 +141,16 @@ void RenderScrollbarPart::imageChanged(WrappedImagePtr image, const IntRect* rec { if (m_scrollbar && m_part != NoPart) m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part); - else + else { + if (FrameView* frameView = view()->frameView()) { + if (frameView->isFrameViewScrollCorner(this)) { + frameView->invalidateScrollCorner(); + return; + } + } + RenderBlock::imageChanged(image, rect); + } } void RenderScrollbarPart::paintIntoRect(GraphicsContext* graphicsContext, int tx, int ty, const IntRect& rect) @@ -153,8 +159,6 @@ void RenderScrollbarPart::paintIntoRect(GraphicsContext* graphicsContext, int tx setLocation(rect.x() - tx, rect.y() - ty); setWidth(rect.width()); setHeight(rect.height()); - setOverflowWidth(max(rect.width(), overflowWidth())); - setOverflowHeight(max(rect.height(), overflowHeight())); if (graphicsContext->paintingDisabled()) return; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarTheme.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarTheme.cpp index d7cfb2b3a..06ca32ad9 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarTheme.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarTheme.cpp @@ -66,17 +66,17 @@ bool RenderScrollbarTheme::hasThumb(Scrollbar* scrollbar) int RenderScrollbarTheme::minimumThumbLength(Scrollbar* scrollbar) { - return static_cast<RenderScrollbar*>(scrollbar)->minimumThumbLength(); + return toRenderScrollbar(scrollbar)->minimumThumbLength(); } IntRect RenderScrollbarTheme::backButtonRect(Scrollbar* scrollbar, ScrollbarPart partType, bool) { - return static_cast<RenderScrollbar*>(scrollbar)->buttonRect(partType); + return toRenderScrollbar(scrollbar)->buttonRect(partType); } IntRect RenderScrollbarTheme::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart partType, bool) { - return static_cast<RenderScrollbar*>(scrollbar)->buttonRect(partType); + return toRenderScrollbar(scrollbar)->buttonRect(partType); } IntRect RenderScrollbarTheme::trackRect(Scrollbar* scrollbar, bool) @@ -88,13 +88,13 @@ IntRect RenderScrollbarTheme::trackRect(Scrollbar* scrollbar, bool) int endLength; buttonSizesAlongTrackAxis(scrollbar, startLength, endLength); - return static_cast<RenderScrollbar*>(scrollbar)->trackRect(startLength, endLength); + return toRenderScrollbar(scrollbar)->trackRect(startLength, endLength); } IntRect RenderScrollbarTheme::constrainTrackRectToTrackPieces(Scrollbar* scrollbar, const IntRect& rect) { - IntRect backRect = static_cast<RenderScrollbar*>(scrollbar)->trackPieceRectWithMargins(BackTrackPart, rect); - IntRect forwardRect = static_cast<RenderScrollbar*>(scrollbar)->trackPieceRectWithMargins(ForwardTrackPart, rect); + IntRect backRect = toRenderScrollbar(scrollbar)->trackPieceRectWithMargins(BackTrackPart, rect); + IntRect forwardRect = toRenderScrollbar(scrollbar)->trackPieceRectWithMargins(ForwardTrackPart, rect); IntRect result = rect; if (scrollbar->orientation() == HorizontalScrollbar) { result.setX(backRect.x()); @@ -114,27 +114,27 @@ void RenderScrollbarTheme::paintScrollCorner(ScrollView*, GraphicsContext* conte void RenderScrollbarTheme::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar) { - static_cast<RenderScrollbar*>(scrollbar)->paintPart(context, ScrollbarBGPart, scrollbar->frameRect()); + toRenderScrollbar(scrollbar)->paintPart(context, ScrollbarBGPart, scrollbar->frameRect()); } void RenderScrollbarTheme::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) { - static_cast<RenderScrollbar*>(scrollbar)->paintPart(context, TrackBGPart, rect); + toRenderScrollbar(scrollbar)->paintPart(context, TrackBGPart, rect); } void RenderScrollbarTheme::paintTrackPiece(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part) { - static_cast<RenderScrollbar*>(scrollbar)->paintPart(context, part, rect); + toRenderScrollbar(scrollbar)->paintPart(context, part, rect); } void RenderScrollbarTheme::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part) { - static_cast<RenderScrollbar*>(scrollbar)->paintPart(context, part, rect); + toRenderScrollbar(scrollbar)->paintPart(context, part, rect); } void RenderScrollbarTheme::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) { - static_cast<RenderScrollbar*>(scrollbar)->paintPart(context, ThumbPart, rect); + toRenderScrollbar(scrollbar)->paintPart(context, ThumbPart, rect); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSlider.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSlider.cpp index 7df774363..442af3940 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSlider.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSlider.cpp @@ -50,7 +50,7 @@ static const int defaultTrackLength = 129; struct SliderRange { bool isIntegral; double minimum; - double maximum; + double maximum; // maximum must be >= minimum. explicit SliderRange(HTMLInputElement*); double clampValue(double value); @@ -80,12 +80,8 @@ SliderRange::SliderRange(HTMLInputElement* element) isIntegral = !equalIgnoringCase(element->getAttribute(precisionAttr), "float"); - // FIXME: This treats maximum strings that can't be parsed as 0, but perhaps 100 would be more appropriate. - const AtomicString& maxString = element->getAttribute(maxAttr); - maximum = maxString.isNull() ? 100.0 : maxString.toDouble(); - - // If the maximum is smaller, use it as the minimum. - minimum = min(element->getAttribute(minAttr).toDouble(), maximum); + maximum = element->rangeMaximum(); + minimum = element->rangeMinimum(); } double SliderRange::clampValue(double value) @@ -96,12 +92,14 @@ double SliderRange::clampValue(double value) double SliderRange::valueFromElement(HTMLInputElement* element, bool* wasClamped) { - String valueString = element->value(); - double oldValue = valueString.isNull() ? (minimum + maximum) / 2 : valueString.toDouble(); + double oldValue; + bool parseSuccess = HTMLInputElement::formStringToDouble(element->value(), &oldValue); + if (!parseSuccess) + oldValue = (minimum + maximum) / 2; double newValue = clampValue(oldValue); if (wasClamped) - *wasClamped = valueString.isNull() || newValue != oldValue; + *wasClamped = !parseSuccess || newValue != oldValue; return newValue; } @@ -152,7 +150,7 @@ void SliderThumbElement::defaultEventHandler(Event* event) if (eventType == eventNames().mousedownEvent && isLeftButton) { if (document()->frame() && renderer()) { - RenderSlider* slider = static_cast<RenderSlider*>(renderer()->parent()); + RenderSlider* slider = toRenderSlider(renderer()->parent()); if (slider) { if (slider->mouseEventIsInThumb(mouseEvent)) { // We selected the thumb, we want the cursor to always stay at @@ -181,7 +179,7 @@ void SliderThumbElement::defaultEventHandler(Event* event) } } else if (eventType == eventNames().mousemoveEvent) { if (m_inDragMode && renderer() && renderer()->parent()) { - RenderSlider* slider = static_cast<RenderSlider*>(renderer()->parent()); + RenderSlider* slider = toRenderSlider(renderer()->parent()); if (slider) { FloatPoint curPoint = slider->absoluteToLocal(mouseEvent->absoluteLocation(), false, true); IntPoint eventOffset(curPoint.x() + m_offsetToThumb.x(), curPoint.y() + m_offsetToThumb.y()); @@ -281,10 +279,36 @@ PassRefPtr<RenderStyle> RenderSlider::createThumbStyle(const RenderStyle* parent style->setAppearance(SliderThumbHorizontalPart); else if (parentStyle->appearance() == MediaSliderPart) style->setAppearance(MediaSliderThumbPart); + else if (parentStyle->appearance() == MediaVolumeSliderPart) + style->setAppearance(MediaVolumeSliderThumbPart); return style.release(); } +IntRect RenderSlider::thumbRect() +{ + if (!m_thumb) + return IntRect(); + + IntRect thumbRect; + RenderBox* thumb = toRenderBox(m_thumb->renderer()); + + thumbRect.setWidth(thumb->style()->width().calcMinValue(contentWidth())); + thumbRect.setHeight(thumb->style()->height().calcMinValue(contentHeight())); + + double fraction = sliderPosition(static_cast<HTMLInputElement*>(node())); + IntRect contentRect = contentBoxRect(); + if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart) { + thumbRect.setX(contentRect.x() + (contentRect.width() - thumbRect.width()) / 2); + thumbRect.setY(contentRect.y() + static_cast<int>(nextafter((contentRect.height() - thumbRect.height()) + 1, 0) * (1 - fraction))); + } else { + thumbRect.setX(contentRect.x() + static_cast<int>(nextafter((contentRect.width() - thumbRect.width()) + 1, 0) * fraction)); + thumbRect.setY(contentRect.y() + (contentRect.height() - thumbRect.height()) / 2); + } + + return thumbRect; +} + void RenderSlider::layout() { ASSERT(needsLayout()); @@ -312,8 +336,6 @@ void RenderSlider::layout() calcWidth(); calcHeight(); - IntRect overflowRect(IntPoint(), size()); - if (thumb) { if (oldSize != size()) thumb->setChildNeedsLayout(true, false); @@ -324,39 +346,15 @@ void RenderSlider::layout() thumb->layoutIfNeeded(); - IntRect thumbRect; - - thumbRect.setWidth(thumb->style()->width().calcMinValue(contentWidth())); - thumbRect.setHeight(thumb->style()->height().calcMinValue(contentHeight())); - - double fraction = sliderPosition(static_cast<HTMLInputElement*>(node())); - IntRect contentRect = contentBoxRect(); - if (style()->appearance() == SliderVerticalPart) { - thumbRect.setX(contentRect.x() + (contentRect.width() - thumbRect.width()) / 2); - thumbRect.setY(contentRect.y() + static_cast<int>(nextafter((contentRect.height() - thumbRect.height()) + 1, 0) * (1 - fraction))); - } else { - thumbRect.setX(contentRect.x() + static_cast<int>(nextafter((contentRect.width() - thumbRect.width()) + 1, 0) * fraction)); - thumbRect.setY(contentRect.y() + (contentRect.height() - thumbRect.height()) / 2); - } - - thumb->setFrameRect(thumbRect); - + IntRect rect = thumbRect(); + thumb->setFrameRect(rect); if (thumb->checkForRepaintDuringLayout()) thumb->repaintDuringLayoutIfMoved(oldThumbRect); statePusher.pop(); - - IntRect thumbOverflowRect = thumb->overflowRect(); - thumbOverflowRect.move(thumb->x(), thumb->y()); - overflowRect.unite(thumbOverflowRect); } - // FIXME: m_overflowWidth and m_overflowHeight should be renamed - // m_overflowRight and m_overflowBottom. - m_overflowLeft = overflowRect.x(); - m_overflowTop = overflowRect.y(); - m_overflowWidth = overflowRect.right(); - m_overflowHeight = overflowRect.bottom(); + addOverflowFromChild(thumb); repainter.repaintAfterLayout(); @@ -393,7 +391,7 @@ bool RenderSlider::mouseEventIsInThumb(MouseEvent* evt) return false; #if ENABLE(VIDEO) - if (style()->appearance() == MediaSliderPart) { + if (style()->appearance() == MediaSliderPart || style()->appearance() == MediaVolumeSliderPart) { MediaControlInputElement *sliderThumb = static_cast<MediaControlInputElement*>(m_thumb->renderer()->node()); return sliderThumb->hitTest(evt->absoluteLocation()); } @@ -425,7 +423,7 @@ void RenderSlider::setValueForPosition(int position) // Calculate the new value based on the position, and send it to the element. SliderRange range(element); double fraction = static_cast<double>(position) / trackSize(); - if (style()->appearance() == SliderVerticalPart) + if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart) fraction = 1 - fraction; double value = range.clampValue(range.valueFromProportion(fraction)); element->setValueFromRenderer(String::number(value)); @@ -446,7 +444,7 @@ int RenderSlider::positionForOffset(const IntPoint& p) return 0; int position; - if (style()->appearance() == SliderVerticalPart) + if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart) position = p.y() - m_thumb->renderBox()->height() / 2; else position = p.x() - m_thumb->renderBox()->width() / 2; @@ -459,7 +457,7 @@ int RenderSlider::currentPosition() ASSERT(m_thumb); ASSERT(m_thumb->renderer()); - if (style()->appearance() == SliderVerticalPart) + if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart) return toRenderBox(m_thumb->renderer())->y() - contentBoxRect().y(); return toRenderBox(m_thumb->renderer())->x() - contentBoxRect().x(); } @@ -469,7 +467,7 @@ int RenderSlider::trackSize() ASSERT(m_thumb); ASSERT(m_thumb->renderer()); - if (style()->appearance() == SliderVerticalPart) + if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart) return contentHeight() - m_thumb->renderBox()->height(); return contentWidth() - m_thumb->renderBox()->width(); } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSlider.h b/src/3rdparty/webkit/WebCore/rendering/RenderSlider.h index 779d82ff2..92ad73b24 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSlider.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSlider.h @@ -36,6 +36,7 @@ namespace WebCore { void forwardEvent(Event*); bool inDragMode() const; + IntRect thumbRect(); private: virtual const char* renderName() const { return "RenderSlider"; } @@ -66,6 +67,15 @@ namespace WebCore { friend class SliderThumbElement; }; + inline RenderSlider* toRenderSlider(RenderObject* object) + { + ASSERT(!object || object->isSlider()); + return static_cast<RenderSlider*>(object); + } + + // This will catch anyone doing an unnecessary cast. + void toRenderSlider(const RenderSlider*); + } // namespace WebCore #endif // RenderSlider_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp index 009a37529..73f365410 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp @@ -50,7 +50,6 @@ RenderTable::RenderTable(Node* node) , m_head(0) , m_foot(0) , m_firstBody(0) - , m_tableLayout(0) , m_currentBorder(0) , m_hasColElements(false) , m_needsSectionRecalc(0) @@ -63,11 +62,6 @@ RenderTable::RenderTable(Node* node) m_columns.fill(ColumnStruct(), 1); } -RenderTable::~RenderTable() -{ - delete m_tableLayout; -} - void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderBlock::styleDidChange(diff, oldStyle); @@ -80,14 +74,12 @@ void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldSty m_columnPos[0] = m_hSpacing; if (!m_tableLayout || style()->tableLayout() != oldTableLayout) { - delete m_tableLayout; - // According to the CSS2 spec, you only use fixed table layout if an // explicit width is specified on the table. Auto width implies auto table layout. if (style()->tableLayout() == TFIXED && !style()->width().isAuto()) - m_tableLayout = new FixedTableLayout(this); + m_tableLayout.set(new FixedTableLayout(this)); else - m_tableLayout = new AutoTableLayout(this); + m_tableLayout.set(new AutoTableLayout(this)); } } @@ -130,18 +122,18 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild) case TABLE_HEADER_GROUP: resetSectionPointerIfNotBefore(m_head, beforeChild); if (!m_head) { - m_head = static_cast<RenderTableSection*>(child); + m_head = toRenderTableSection(child); } else { resetSectionPointerIfNotBefore(m_firstBody, beforeChild); if (!m_firstBody) - m_firstBody = static_cast<RenderTableSection*>(child); + m_firstBody = toRenderTableSection(child); } wrapInAnonymousSection = false; break; case TABLE_FOOTER_GROUP: resetSectionPointerIfNotBefore(m_foot, beforeChild); if (!m_foot) { - m_foot = static_cast<RenderTableSection*>(child); + m_foot = toRenderTableSection(child); wrapInAnonymousSection = false; break; } @@ -149,7 +141,7 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild) case TABLE_ROW_GROUP: resetSectionPointerIfNotBefore(m_firstBody, beforeChild); if (!m_firstBody) - m_firstBody = static_cast<RenderTableSection*>(child); + m_firstBody = toRenderTableSection(child); wrapInAnonymousSection = false; break; default: @@ -252,8 +244,8 @@ void RenderTable::layout() LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y())); setHeight(0); - m_overflowHeight = 0; - m_overflowTop = 0; + m_overflow.clear(); + initMaxMarginValues(); int oldWidth = width(); @@ -280,7 +272,7 @@ void RenderTable::layout() for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) { child->layoutIfNeeded(); - RenderTableSection* section = static_cast<RenderTableSection*>(child); + RenderTableSection* section = toRenderTableSection(child); calculatedHeight += section->calcRowHeight(); if (collapsing) section->recalcOuterBorder(); @@ -295,9 +287,6 @@ void RenderTable::layout() if (m_caption) m_caption->layoutIfNeeded(); - m_overflowWidth = width() + (collapsing ? outerBorderRight() - borderRight() : 0); - m_overflowLeft = collapsing ? borderLeft() - outerBorderLeft() : 0; - // If any table section moved vertically, we will just repaint everything from that // section down (it is quite unlikely that any of the following sections // did not shift). @@ -313,10 +302,6 @@ void RenderTable::layout() m_caption->repaintDuringLayoutIfMoved(captionRect); setHeight(height() + m_caption->height() + m_caption->marginTop() + m_caption->marginBottom()); - m_overflowLeft = min(m_overflowLeft, m_caption->x() + m_caption->overflowLeft(false)); - m_overflowWidth = max(m_overflowWidth, m_caption->x() + m_caption->overflowWidth(false)); - m_overflowTop = min(m_overflowTop, m_caption->y() + m_caption->overflowTop(false)); - m_overflowHeight = max(m_overflowHeight, m_caption->y() + m_caption->overflowHeight(false)); if (height() != oldTableTop) { sectionMoved = true; @@ -344,7 +329,7 @@ void RenderTable::layout() for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one. - static_cast<RenderTableSection*>(child)->layoutRows(child == m_firstBody ? max(0, th - calculatedHeight) : 0); + toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, th - calculatedHeight) : 0); } if (!m_firstBody && th > calculatedHeight && !style()->htmlHacks()) { @@ -362,15 +347,11 @@ void RenderTable::layout() while (section) { if (!sectionMoved && section->y() != height()) { sectionMoved = true; - movedSectionTop = min(height(), section->y()) + section->overflowTop(false); + movedSectionTop = min(height(), section->y()) + section->topVisibleOverflow(); } section->setLocation(bl, height()); setHeight(height() + section->height()); - m_overflowLeft = min(m_overflowLeft, section->x() + section->overflowLeft(false)); - m_overflowWidth = max(m_overflowWidth, section->x() + section->overflowWidth(false)); - m_overflowTop = min(m_overflowTop, section->y() + section->overflowTop(false)); - m_overflowHeight = max(m_overflowHeight, section->y() + section->overflowHeight(false)); section = sectionBelow(section); } @@ -384,33 +365,34 @@ void RenderTable::layout() m_caption->repaintDuringLayoutIfMoved(captionRect); setHeight(height() + m_caption->height() + m_caption->marginTop() + m_caption->marginBottom()); - m_overflowLeft = min(m_overflowLeft, m_caption->x() + m_caption->overflowLeft(false)); - m_overflowWidth = max(m_overflowWidth, m_caption->x() + m_caption->overflowWidth(false)); } if (isPositioned()) calcHeight(); - m_overflowHeight = max(m_overflowHeight, height()); - // table can be containing block of positioned elements. // FIXME: Only pass true if width or height changed. layoutPositionedObjects(true); - if (!hasOverflowClip()) { - for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - m_overflowLeft = min(m_overflowLeft, boxShadow->x - boxShadow->blur); - m_overflowWidth = max(m_overflowWidth, width() + boxShadow->x + boxShadow->blur); - m_overflowTop = min(m_overflowTop, boxShadow->y - boxShadow->blur); - m_overflowHeight = max(m_overflowHeight, height() + boxShadow->y + boxShadow->blur); - } - - if (hasReflection()) { - IntRect reflection(reflectionBox()); - m_overflowTop = min(m_overflowTop, reflection.y()); - m_overflowHeight = max(m_overflowHeight, reflection.bottom()); - m_overflowLeft = min(m_overflowLeft, reflection.x()); - m_overflowHeight = max(m_overflowWidth, reflection.right()); + // Add overflow from borders. + int rightBorderOverflow = width() + (collapsing ? outerBorderRight() - borderRight() : 0); + int leftBorderOverflow = collapsing ? borderLeft() - outerBorderLeft() : 0; + int bottomBorderOverflow = height() + (collapsing ? outerBorderBottom() - borderBottom() : 0); + int topBorderOverflow = collapsing ? borderTop() - outerBorderTop() : 0; + addLayoutOverflow(IntRect(leftBorderOverflow, topBorderOverflow, rightBorderOverflow - leftBorderOverflow, bottomBorderOverflow - topBorderOverflow)); + + // Add visual overflow from box-shadow and reflections. + addShadowOverflow(); + + // Add overflow from our caption. + if (m_caption) + addOverflowFromChild(m_caption); + + // Add overflow from our sections. + for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { + if (child->isTableSection()) { + RenderTableSection* section = toRenderTableSection(child); + addOverflowFromChild(section); } } @@ -419,7 +401,7 @@ void RenderTable::layout() bool didFullRepaint = repainter.repaintAfterLayout(); // Repaint with our new bounds if they are different from our old bounds. if (!didFullRepaint && sectionMoved) - repaintRectangle(IntRect(m_overflowLeft, movedSectionTop, m_overflowWidth - m_overflowLeft, m_overflowHeight - movedSectionTop)); + repaintRectangle(IntRect(leftVisibleOverflow(), movedSectionTop, rightVisibleOverflow() - leftVisibleOverflow(), bottomVisibleOverflow() - movedSectionTop)); setNeedsLayout(false); } @@ -428,7 +410,7 @@ void RenderTable::setCellWidths() { for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) - static_cast<RenderTableSection*>(child)->setCellWidths(); + toRenderTableSection(child)->setCellWidths(); } } @@ -440,9 +422,9 @@ void RenderTable::paint(PaintInfo& paintInfo, int tx, int ty) PaintPhase paintPhase = paintInfo.phase; int os = 2 * maximalOutlineSize(paintPhase); - if (ty + overflowTop(false) >= paintInfo.rect.bottom() + os || ty + overflowHeight(false) <= paintInfo.rect.y() - os) + if (ty + topVisibleOverflow() >= paintInfo.rect.bottom() + os || ty + bottomVisibleOverflow() <= paintInfo.rect.y() - os) return; - if (tx + overflowLeft(false) >= paintInfo.rect.right() + os || tx + overflowWidth(false) <= paintInfo.rect.x() - os) + if (tx + leftVisibleOverflow() >= paintInfo.rect.right() + os || tx + rightVisibleOverflow() <= paintInfo.rect.x() - os) return; bool pushedClip = pushContentsClip(paintInfo, tx, ty); @@ -488,7 +470,7 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty) RenderObject* stop = nextInPreOrderAfterChildren(); for (RenderObject* o = firstChild(); o && o != stop; o = o->nextInPreOrder()) if (o->isTableCell()) - static_cast<RenderTableCell*>(o)->collectBorderStyles(borderStyles); + toRenderTableCell(o)->collectBorderStyles(borderStyles); RenderTableCell::sortBorderStyles(borderStyles); size_t count = borderStyles.size(); for (size_t i = 0; i < count; ++i) { @@ -571,7 +553,7 @@ void RenderTable::splitColumn(int pos, int firstSpan) // change width of all rows. for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) - static_cast<RenderTableSection*>(child)->splitColumn(pos, oldSize + 1); + toRenderTableSection(child)->splitColumn(pos, oldSize + 1); } m_columnPos.grow(numEffCols() + 1); @@ -589,7 +571,7 @@ void RenderTable::appendColumn(int span) // change width of all rows. for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) - static_cast<RenderTableSection*>(child)->appendColumn(pos); + toRenderTableSection(child)->appendColumn(pos); } m_columnPos.grow(numEffCols() + 1); @@ -605,7 +587,7 @@ RenderTableCol* RenderTable::colElement(int col, bool* startEdge, bool* endEdge) while (child) { if (child->isTableCol()) { - RenderTableCol* colElem = static_cast<RenderTableCol*>(child); + RenderTableCol* colElem = toRenderTableCol(child); int span = colElem->span(); if (!colElem->firstChild()) { int startCol = cCol; @@ -658,7 +640,7 @@ void RenderTable::recalcSections() const break; case TABLE_HEADER_GROUP: if (child->isTableSection()) { - RenderTableSection* section = static_cast<RenderTableSection*>(child); + RenderTableSection* section = toRenderTableSection(child); if (!m_head) m_head = section; else if (!m_firstBody) @@ -668,7 +650,7 @@ void RenderTable::recalcSections() const break; case TABLE_FOOTER_GROUP: if (child->isTableSection()) { - RenderTableSection* section = static_cast<RenderTableSection*>(child); + RenderTableSection* section = toRenderTableSection(child); if (!m_foot) m_foot = section; else if (!m_firstBody) @@ -678,7 +660,7 @@ void RenderTable::recalcSections() const break; case TABLE_ROW_GROUP: if (child->isTableSection()) { - RenderTableSection* section = static_cast<RenderTableSection*>(child); + RenderTableSection* section = toRenderTableSection(child); if (!m_firstBody) m_firstBody = section; section->recalcCellsIfNeeded(); @@ -693,7 +675,7 @@ void RenderTable::recalcSections() const int maxCols = 0; for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) { - RenderTableSection* section = static_cast<RenderTableSection*>(child); + RenderTableSection* section = toRenderTableSection(child); int sectionCols = section->numColumns(); if (sectionCols > maxCols) maxCols = sectionCols; @@ -884,7 +866,7 @@ int RenderTable::outerBorderBottom() const else { RenderObject* child; for (child = lastChild(); child && !child->isTableSection(); child = child->previousSibling()) { } - bottomSection = child ? static_cast<RenderTableSection*>(child) : 0; + bottomSection = child ? toRenderTableSection(child) : 0; } if (bottomSection) { borderWidth = bottomSection->outerBorderBottom(); @@ -916,7 +898,7 @@ int RenderTable::outerBorderLeft() const for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (!child->isTableSection()) continue; - int sw = static_cast<RenderTableSection*>(child)->outerBorderLeft(); + int sw = toRenderTableSection(child)->outerBorderLeft(); if (sw == -1) continue; else @@ -946,7 +928,7 @@ int RenderTable::outerBorderRight() const for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (!child->isTableSection()) continue; - int sw = static_cast<RenderTableSection*>(child)->outerBorderRight(); + int sw = toRenderTableSection(child)->outerBorderRight(); if (sw == -1) continue; else @@ -968,13 +950,13 @@ RenderTableSection* RenderTable::sectionAbove(const RenderTableSection* section, RenderObject* prevSection = section == m_foot ? lastChild() : section->previousSibling(); while (prevSection) { - if (prevSection->isTableSection() && prevSection != m_head && prevSection != m_foot && (!skipEmptySections || static_cast<RenderTableSection*>(prevSection)->numRows())) + if (prevSection->isTableSection() && prevSection != m_head && prevSection != m_foot && (!skipEmptySections || toRenderTableSection(prevSection)->numRows())) break; prevSection = prevSection->previousSibling(); } if (!prevSection && m_head && (!skipEmptySections || m_head->numRows())) prevSection = m_head; - return static_cast<RenderTableSection*>(prevSection); + return toRenderTableSection(prevSection); } RenderTableSection* RenderTable::sectionBelow(const RenderTableSection* section, bool skipEmptySections) const @@ -986,13 +968,13 @@ RenderTableSection* RenderTable::sectionBelow(const RenderTableSection* section, RenderObject* nextSection = section == m_head ? firstChild() : section->nextSibling(); while (nextSection) { - if (nextSection->isTableSection() && nextSection != m_head && nextSection != m_foot && (!skipEmptySections || static_cast<RenderTableSection*>(nextSection)->numRows())) + if (nextSection->isTableSection() && nextSection != m_head && nextSection != m_foot && (!skipEmptySections || toRenderTableSection(nextSection)->numRows())) break; nextSection = nextSection->nextSibling(); } if (!nextSection && m_foot && (!skipEmptySections || m_foot->numRows())) nextSection = m_foot; - return static_cast<RenderTableSection*>(nextSection); + return toRenderTableSection(nextSection); } RenderTableCell* RenderTable::cellAbove(const RenderTableCell* cell) const diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTable.h b/src/3rdparty/webkit/WebCore/rendering/RenderTable.h index 07e02b05e..e75d644d3 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTable.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTable.h @@ -1,12 +1,10 @@ /* - * This file is part of the DOM implementation for KDE. - * * Copyright (C) 1997 Martin Jones (mjones@kde.org) * (C) 1997 Torben Weis (weis@kde.org) * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -40,13 +38,6 @@ class TableLayout; class RenderTable : public RenderBlock { public: RenderTable(Node*); - ~RenderTable(); - - virtual const char* renderName() const { return "RenderTable"; } - - virtual bool isTable() const { return true; } - - virtual bool avoidsFloats() const { return true; } int getColumnPos(int col) const { return m_columnPos[col]; } @@ -70,26 +61,7 @@ public: int calcBorderRight() const; void recalcHorizontalBorders(); - // overrides virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0); - virtual void removeChild(RenderObject* oldChild); - - virtual void paint(PaintInfo&, int tx, int ty); - virtual void paintObject(PaintInfo&, int tx, int ty); - virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); - virtual void paintMask(PaintInfo& paintInfo, int tx, int ty); - virtual void layout(); - virtual void calcPrefWidths(); - virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int xPos, int yPos, int tx, int ty, HitTestAction); - - virtual int firstLineBoxBaseline() const; - - virtual RenderBlock* firstLineBlock() const; - virtual void updateFirstLetter(); - - virtual void setCellWidths(); - - virtual void calcWidth(); struct ColumnStruct { enum { @@ -163,8 +135,6 @@ public: bool hasSections() const { return m_head || m_foot || m_firstBody; } - virtual IntRect overflowClipRect(int tx, int ty); - void recalcSectionsIfNeeded() const { if (m_needsSectionRecalc) @@ -175,6 +145,33 @@ protected: virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); private: + virtual const char* renderName() const { return "RenderTable"; } + + virtual bool isTable() const { return true; } + + virtual bool avoidsFloats() const { return true; } + + virtual void removeChild(RenderObject* oldChild); + + virtual void paint(PaintInfo&, int tx, int ty); + virtual void paintObject(PaintInfo&, int tx, int ty); + virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); + virtual void paintMask(PaintInfo&, int tx, int ty); + virtual void layout(); + virtual void calcPrefWidths(); + virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int xPos, int yPos, int tx, int ty, HitTestAction); + + virtual int firstLineBoxBaseline() const; + + virtual RenderBlock* firstLineBlock() const; + virtual void updateFirstLetter(); + + virtual void setCellWidths(); + + virtual void calcWidth(); + + virtual IntRect overflowClipRect(int tx, int ty); + void recalcSections() const; mutable Vector<int> m_columnPos; @@ -185,7 +182,7 @@ private: mutable RenderTableSection* m_foot; mutable RenderTableSection* m_firstBody; - TableLayout* m_tableLayout; + OwnPtr<TableLayout> m_tableLayout; const CollapsedBorderValue* m_currentBorder; @@ -198,6 +195,21 @@ private: int m_borderRight; }; +inline RenderTable* toRenderTable(RenderObject* object) +{ + ASSERT(!object || object->isTable()); + return static_cast<RenderTable*>(object); +} + +inline const RenderTable* toRenderTable(const RenderObject* object) +{ + ASSERT(!object || object->isTable()); + return static_cast<const RenderTable*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderTable(const RenderTable*); + } // namespace WebCore #endif // RenderTable_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp index acdd5d52c..8dc9145b4 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp @@ -193,9 +193,9 @@ IntRect RenderTableCell::clippedOverflowRectForRepaint(RenderBoxModelObject* rep right = max(right, below->borderHalfRight(true)); } } - left = max(left, -overflowLeft(false)); - top = max(top, -overflowTop(false)); - IntRect r(-left, - top, left + max(width() + right, overflowWidth(false)), top + max(height() + bottom, overflowHeight(false))); + left = max(left, -leftVisibleOverflow()); + top = max(top, -topVisibleOverflow()); + IntRect r(-left, - top, left + max(width() + right, rightVisibleOverflow()), top + max(height() + bottom, bottomVisibleOverflow())); if (RenderView* v = view()) { // FIXME: layoutDelta needs to be applied in parts before/after transforms and @@ -550,7 +550,7 @@ CollapsedBorderValue RenderTableCell::collapsedBottomBorder() const // Now check row groups. RenderTableSection* currSection = section(); - if (row() + rowSpan() >= static_cast<RenderTableSection*>(currSection)->numRows()) { + if (row() + rowSpan() >= currSection->numRows()) { // (5) Our row group's bottom border. result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderBottom(), BROWGROUP)); if (!result.exists()) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.h b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.h index a57b24bb6..8855dff9c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.h @@ -4,7 +4,7 @@ * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -33,12 +33,6 @@ class RenderTableCell : public RenderBlock { public: RenderTableCell(Node*); - virtual const char* renderName() const { return isAnonymous() ? "RenderTableCell (anonymous)" : "RenderTableCell"; } - - virtual bool isTableCell() const { return true; } - - virtual void destroy(); - // FIXME: need to implement cellIndex int cellIndex() const { return 0; } void setCellIndex(int) { } @@ -54,15 +48,13 @@ public: int row() const { return m_row; } void setRow(int row) { m_row = row; } - RenderTableSection* section() const { return static_cast<RenderTableSection*>(parent()->parent()); } - RenderTable* table() const { return static_cast<RenderTable*>(parent()->parent()->parent()); } + RenderTableSection* section() const { return toRenderTableSection(parent()->parent()); } + RenderTable* table() const { return toRenderTable(parent()->parent()->parent()); } Length styleOrColWidth() const; - virtual bool requiresLayer() const { return isPositioned() || isTransparent() || hasOverflowClip() || hasTransform() || hasMask() || hasReflection(); } - virtual void calcPrefWidths(); - virtual void calcWidth(); + void updateWidth(int); int borderLeft() const; @@ -89,13 +81,8 @@ public: virtual void layout(); virtual void paint(PaintInfo&, int tx, int ty); - virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); - virtual void paintMask(PaintInfo& paintInfo, int tx, int ty); - void paintCollapsedBorder(GraphicsContext*, int x, int y, int w, int h); - void paintBackgroundsBehindCell(PaintInfo&, int tx, int ty, RenderObject* backgroundObject); - virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer); - virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false); + void paintBackgroundsBehindCell(PaintInfo&, int tx, int ty, RenderObject* backgroundObject); virtual int baselinePosition(bool firstLine = false, bool isRootLineBox = false) const; @@ -120,6 +107,24 @@ protected: virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const; private: + virtual const char* renderName() const { return isAnonymous() ? "RenderTableCell (anonymous)" : "RenderTableCell"; } + + virtual bool isTableCell() const { return true; } + + virtual void destroy(); + + virtual bool requiresLayer() const { return isPositioned() || isTransparent() || hasOverflowClip() || hasTransform() || hasMask() || hasReflection(); } + + virtual void calcWidth(); + + virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); + virtual void paintMask(PaintInfo&, int tx, int ty); + + virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer); + virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false); + + void paintCollapsedBorder(GraphicsContext*, int x, int y, int w, int h); + int m_row; int m_column; int m_rowSpan; @@ -129,6 +134,21 @@ private: int m_percentageHeight; }; +inline RenderTableCell* toRenderTableCell(RenderObject* object) +{ + ASSERT(!object || object->isTableCell()); + return static_cast<RenderTableCell*>(object); +} + +inline const RenderTableCell* toRenderTableCell(const RenderObject* object) +{ + ASSERT(!object || object->isTableCell()); + return static_cast<const RenderTableCell*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderTableCell(const RenderTableCell*); + } // namespace WebCore #endif // RenderTableCell_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.cpp index d9a4172c7..80e74e117 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.cpp @@ -1,12 +1,10 @@ -/** - * This file is part of the DOM implementation for KDE. - * +/* * Copyright (C) 1997 Martin Jones (mjones@kde.org) * (C) 1997 Torben Weis (weis@kde.org) * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * This library is free software; you can redistribute it and/or @@ -31,13 +29,15 @@ #include "CachedImage.h" #include "HTMLNames.h" #include "HTMLTableColElement.h" +#include "RenderTable.h" namespace WebCore { using namespace HTMLNames; RenderTableCol::RenderTableCol(Node* node) - : RenderBox(node), m_span(1) + : RenderBox(node) + , m_span(1) { // init RenderObject attributes setInline(true); // our object is not Inline @@ -75,10 +75,11 @@ IntRect RenderTableCol::clippedOverflowRectForRepaint(RenderBoxModelObject* repa // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we // might have propagated a background color or borders into. // FIXME: check for repaintContainer each time here? - if (RenderObject* parentTable = table()) - return parentTable->clippedOverflowRectForRepaint(repaintContainer); - return IntRect(); + RenderTable* parentTable = table(); + if (!parentTable) + return IntRect(); + return parentTable->clippedOverflowRectForRepaint(repaintContainer); } void RenderTableCol::imageChanged(WrappedImagePtr, const IntRect*) @@ -100,7 +101,7 @@ RenderTable* RenderTableCol::table() const RenderObject* table = parent(); if (table && !table->isTable()) table = table->parent(); - return table && table->isTable() ? static_cast<RenderTable*>(table) : 0; + return table && table->isTable() ? toRenderTable(table) : 0; } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.h b/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.h index 12b6d9db2..87209a14e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.h @@ -1,12 +1,10 @@ /* - * This file is part of the DOM implementation for KDE. - * * Copyright (C) 1997 Martin Jones (mjones@kde.org) * (C) 1997 Torben Weis (weis@kde.org) * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * This library is free software; you can redistribute it and/or @@ -29,19 +27,27 @@ #define RenderTableCol_h #include "RenderBox.h" -#include "RenderTable.h" namespace WebCore { +class RenderTable; + class RenderTableCol : public RenderBox { public: RenderTableCol(Node*); - virtual RenderObjectChildList* virtualChildren() { return children(); } - virtual const RenderObjectChildList* virtualChildren() const { return children(); } const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } + virtual void calcPrefWidths(); + + int span() const { return m_span; } + void setSpan(int span) { m_span = span; } + +private: + virtual RenderObjectChildList* virtualChildren() { return children(); } + virtual const RenderObjectChildList* virtualChildren() const { return children(); } + virtual const char* renderName() const { return "RenderTableCol"; } virtual bool isTableCol() const { return true; } virtual int lineHeight(bool) const { return 0; } @@ -54,18 +60,27 @@ public: virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer); virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); - virtual void calcPrefWidths(); - - int span() const { return m_span; } - void setSpan(int s) { m_span = s; } - -private: RenderTable* table() const; RenderObjectChildList m_children; int m_span; }; +inline RenderTableCol* toRenderTableCol(RenderObject* object) +{ + ASSERT(!object || object->isTableCol()); + return static_cast<RenderTableCol*>(object); +} + +inline const RenderTableCol* toRenderTableCol(const RenderObject* object) +{ + ASSERT(!object || object->isTableCol()); + return static_cast<const RenderTableCol*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderTableCol(const RenderTableCol*); + } #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.cpp index 33b2c3957..bafadfc46 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.cpp @@ -99,7 +99,7 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild) while (beforeChild && beforeChild->parent() != this) beforeChild = beforeChild->parent(); - RenderTableCell* cell = static_cast<RenderTableCell*>(child); + RenderTableCell* cell = toRenderTableCell(child); // Generated content can result in us having a null section so make sure to null check our parent. if (parent()) @@ -121,7 +121,7 @@ void RenderTableRow::layout() for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableCell()) { - RenderTableCell* cell = static_cast<RenderTableCell*>(child); + RenderTableCell* cell = toRenderTableCell(child); if (child->needsLayout()) { cell->calcVerticalMargins(); cell->layout(); @@ -147,6 +147,11 @@ void RenderTableRow::layout() IntRect RenderTableRow::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) { + ASSERT(parent()); + + if (repaintContainer == this) + return RenderBox::clippedOverflowRectForRepaint(repaintContainer); + // For now, just repaint the whole table. // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we // might have propagated a background color into. @@ -185,7 +190,7 @@ void RenderTableRow::paint(PaintInfo& paintInfo, int tx, int ty) if (child->isTableCell()) { // Paint the row background behind the cell. if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseChildBlockBackground) { - RenderTableCell* cell = static_cast<RenderTableCell*>(child); + RenderTableCell* cell = toRenderTableCell(child); cell->paintBackgroundsBehindCell(paintInfo, tx, ty, this); } if (!toRenderBox(child)->hasSelfPaintingLayer()) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.h b/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.h index 9622480b5..588252bc8 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.h @@ -1,12 +1,10 @@ /* - * This file is part of the DOM implementation for KDE. - * * Copyright (C) 1997 Martin Jones (mjones@kde.org) * (C) 1997 Torben Weis (weis@kde.org) * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -35,15 +33,16 @@ class RenderTableRow : public RenderBox { public: RenderTableRow(Node*); - virtual RenderObjectChildList* virtualChildren() { return children(); } - virtual const RenderObjectChildList* virtualChildren() const { return children(); } const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } - RenderTableSection* section() const { return static_cast<RenderTableSection*>(parent()); } - RenderTable* table() const { return static_cast<RenderTable*>(parent()->parent()); } + RenderTableSection* section() const { return toRenderTableSection(parent()); } + RenderTable* table() const { return toRenderTable(parent()->parent()); } private: + virtual RenderObjectChildList* virtualChildren() { return children(); } + virtual const RenderObjectChildList* virtualChildren() const { return children(); } + virtual const char* renderName() const { return isAnonymous() ? "RenderTableRow (anonymous)" : "RenderTableRow"; } virtual bool isTableRow() const { return true; } @@ -65,10 +64,24 @@ private: virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); -private: RenderObjectChildList m_children; }; +inline RenderTableRow* toRenderTableRow(RenderObject* object) +{ + ASSERT(!object || object->isTableRow()); + return static_cast<RenderTableRow*>(object); +} + +inline const RenderTableRow* toRenderTableRow(const RenderObject* object) +{ + ASSERT(!object || object->isTableRow()); + return static_cast<const RenderTableRow*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderTableRow(const RenderTableRow*); + } // namespace WebCore #endif // RenderTableRow_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.cpp index 27c230bb2..b8ac497b7 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.cpp @@ -51,10 +51,6 @@ RenderTableSection::RenderTableSection(Node* node) , m_outerBorderRight(0) , m_outerBorderTop(0) , m_outerBorderBottom(0) - , m_overflowLeft(0) - , m_overflowWidth(0) - , m_overflowTop(0) - , m_overflowHeight(0) , m_needsCellRecalc(false) , m_hasOverflowingCell(false) { @@ -124,7 +120,7 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild if (!ensureRows(m_cRow + 1)) return; - m_grid[m_cRow].rowRenderer = static_cast<RenderTableRow*>(child); + m_grid[m_cRow].rowRenderer = toRenderTableRow(child); if (!beforeChild) { m_grid[m_cRow].height = child->style()->height(); @@ -419,10 +415,7 @@ int RenderTableSection::layoutRows(int toAdd) // Set the width of our section now. The rows will also be this width. setWidth(table()->contentWidth()); - m_overflowLeft = 0; - m_overflowWidth = width(); - m_overflowTop = 0; - m_overflowHeight = 0; + m_overflow.clear(); m_hasOverflowingCell = false; if (toAdd && totalRows && (m_rowPos[totalRows] || !nextSibling())) { @@ -530,7 +523,7 @@ int RenderTableSection::layoutRows(int toAdd) for (RenderObject* o = cell->firstChild(); o; o = o->nextSibling()) { if (!o->isText() && o->style()->height().isPercent() && (flexAllChildren || o->isReplaced() || (o->isBox() && toRenderBox(o)->scrollsOverflow()))) { // Tables with no sections do not flex. - if (!o->isTable() || static_cast<RenderTable*>(o)->hasSections()) { + if (!o->isTable() || toRenderTable(o)->hasSections()) { o->setNeedsLayout(true, false); cellChildrenFlex = true; } @@ -623,12 +616,6 @@ int RenderTableSection::layoutRows(int toAdd) } else cell->setLocation(table()->columnPositions()[c] + hspacing, m_rowPos[rindx]); - m_overflowLeft = min(m_overflowLeft, cell->x() + cell->overflowLeft(false)); - m_overflowWidth = max(m_overflowWidth, cell->x() + cell->overflowWidth(false)); - m_overflowTop = min(m_overflowTop, cell->y() + cell->overflowTop(false)); - m_overflowHeight = max(m_overflowHeight, cell->y() + cell->overflowHeight(false)); - m_hasOverflowingCell |= cell->overflowLeft(false) || cell->overflowWidth(false) > cell->width() || cell->overflowTop(false) || cell->overflowHeight(false) > cell->height(); - // If the cell moved, we have to repaint it as well as any floating/positioned // descendants. An exception is if we need a layout. In this case, we know we're going to // repaint ourselves (and the cell) anyway. @@ -643,10 +630,23 @@ int RenderTableSection::layoutRows(int toAdd) ASSERT(!needsLayout()); + setHeight(m_rowPos[totalRows]); + + // Now that our height has been determined, add in overflow from cells. + for (int r = 0; r < totalRows; r++) { + for (int c = 0; c < nEffCols; c++) { + RenderTableCell* cell = cellAt(r, c).cell; + if (!cell) + continue; + if (r < totalRows - 1 && cell == cellAt(r + 1, c).cell) + continue; + addOverflowFromChild(cell); + } + } + m_hasOverflowingCell = m_overflow; + statePusher.pop(); - setHeight(m_rowPos[totalRows]); - m_overflowHeight = max(m_overflowHeight, height()); return height(); } @@ -659,7 +659,7 @@ int RenderTableSection::lowestPosition(bool includeOverflowInterior, bool includ for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) { if (curr->isTableCell()) { - RenderTableCell* cell = static_cast<RenderTableCell*>(curr); + RenderTableCell* cell = toRenderTableCell(curr); bottom = max(bottom, cell->y() + cell->lowestPosition(false)); } } @@ -677,7 +677,7 @@ int RenderTableSection::rightmostPosition(bool includeOverflowInterior, bool inc for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) { if (curr->isTableCell()) { - RenderTableCell* cell = static_cast<RenderTableCell*>(curr); + RenderTableCell* cell = toRenderTableCell(curr); right = max(right, cell->x() + cell->rightmostPosition(false)); } } @@ -695,7 +695,7 @@ int RenderTableSection::leftmostPosition(bool includeOverflowInterior, bool incl for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) { if (curr->isTableCell()) { - RenderTableCell* cell = static_cast<RenderTableCell*>(curr); + RenderTableCell* cell = toRenderTableCell(curr); left = min(left, cell->x() + cell->leftmostPosition(false)); } } @@ -1027,7 +1027,7 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty) if (!cell || (r > startrow && (cellAt(r - 1, c).cell == cell))) continue; - RenderTableRow* row = static_cast<RenderTableRow*>(cell->parent()); + RenderTableRow* row = toRenderTableRow(cell->parent()); if (paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) { // We need to handle painting a stack of backgrounds. This stack (from bottom to top) consists of @@ -1081,12 +1081,12 @@ void RenderTableSection::recalcCells() if (!ensureRows(m_cRow + 1)) break; - RenderTableRow* tableRow = static_cast<RenderTableRow*>(row); + RenderTableRow* tableRow = toRenderTableRow(row); m_grid[m_cRow].rowRenderer = tableRow; for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) { if (cell->isTableCell()) - addCell(static_cast<RenderTableCell*>(cell), tableRow); + addCell(toRenderTableCell(cell), tableRow); } } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.h b/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.h index 30614f090..9f6d5ea84 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.h @@ -1,12 +1,10 @@ /* - * This file is part of the DOM implementation for KDE. - * * Copyright (C) 1997 Martin Jones (mjones@kde.org) * (C) 1997 Torben Weis (weis@kde.org) * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -38,23 +36,12 @@ class RenderTableRow; class RenderTableSection : public RenderBox { public: RenderTableSection(Node*); - ~RenderTableSection(); + virtual ~RenderTableSection(); - virtual RenderObjectChildList* virtualChildren() { return children(); } - virtual const RenderObjectChildList* virtualChildren() const { return children(); } const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } - virtual const char* renderName() const { return isAnonymous() ? "RenderTableSection (anonymous)" : "RenderTableSection"; } - - virtual bool isTableSection() const { return true; } - - virtual void destroy(); - - virtual void layout(); - virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0); - virtual void removeChild(RenderObject* oldChild); virtual int firstLineBoxBaseline() const; @@ -64,7 +51,7 @@ public: int calcRowHeight(); int layoutRows(int height); - RenderTable* table() const { return static_cast<RenderTable*>(parent()); } + RenderTable* table() const { return toRenderTable(parent()); } struct CellStruct { RenderTableCell* cell; @@ -86,15 +73,6 @@ public: void appendColumn(int pos); void splitColumn(int pos, int newSize); - virtual int overflowWidth(bool includeInterior = true) const { return (!includeInterior && hasOverflowClip()) ? width() : m_overflowWidth; } - virtual int overflowLeft(bool includeInterior = true) const { return (!includeInterior && hasOverflowClip()) ? 0 : m_overflowLeft; } - virtual int overflowHeight(bool includeInterior = true) const { return (!includeInterior && hasOverflowClip()) ? height() : m_overflowHeight; } - virtual int overflowTop(bool includeInterior = true) const { return (!includeInterior && hasOverflowClip()) ? 0 : m_overflowTop; } - - virtual int lowestPosition(bool includeOverflowInterior, bool includeSelf) const; - virtual int rightmostPosition(bool includeOverflowInterior, bool includeSelf) const; - virtual int leftmostPosition(bool includeOverflowInterior, bool includeSelf) const; - int calcOuterBorderTop() const; int calcOuterBorderBottom() const; int calcOuterBorderLeft(bool rtl) const; @@ -106,11 +84,6 @@ public: int outerBorderLeft() const { return m_outerBorderLeft; } int outerBorderRight() const { return m_outerBorderRight; } - virtual void paint(PaintInfo&, int tx, int ty); - virtual void paintObject(PaintInfo&, int tx, int ty); - - virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); - int numRows() const { return m_gridRows; } int numColumns() const; void recalcCells(); @@ -129,9 +102,31 @@ public: int getBaseline(int row) { return m_grid[row].baseline; } +private: + virtual RenderObjectChildList* virtualChildren() { return children(); } + virtual const RenderObjectChildList* virtualChildren() const { return children(); } + + virtual const char* renderName() const { return isAnonymous() ? "RenderTableSection (anonymous)" : "RenderTableSection"; } + + virtual bool isTableSection() const { return true; } + + virtual void destroy(); + + virtual void layout(); + + virtual void removeChild(RenderObject* oldChild); + + virtual int lowestPosition(bool includeOverflowInterior, bool includeSelf) const; + virtual int rightmostPosition(bool includeOverflowInterior, bool includeSelf) const; + virtual int leftmostPosition(bool includeOverflowInterior, bool includeSelf) const; + + virtual void paint(PaintInfo&, int tx, int ty); + virtual void paintObject(PaintInfo&, int tx, int ty); + + virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); + virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); -private: virtual int lineHeight(bool, bool) const { return 0; } bool ensureRows(int); @@ -152,15 +147,26 @@ private: int m_outerBorderRight; int m_outerBorderTop; int m_outerBorderBottom; - int m_overflowLeft; - int m_overflowWidth; - int m_overflowTop; - int m_overflowHeight; bool m_needsCellRecalc; bool m_hasOverflowingCell; }; +inline RenderTableSection* toRenderTableSection(RenderObject* object) +{ + ASSERT(!object || object->isTableSection()); + return static_cast<RenderTableSection*>(object); +} + +inline const RenderTableSection* toRenderTableSection(const RenderObject* object) +{ + ASSERT(!object || object->isTableSection()); + return static_cast<const RenderTableSection*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderTableSection(const RenderTableSection*); + } // namespace WebCore #endif // RenderTableSection_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp index ada3961d7..40c3d75a5 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp @@ -207,7 +207,7 @@ void RenderText::deleteTextBoxes() PassRefPtr<StringImpl> RenderText::originalText() const { Node* e = node(); - return e ? static_cast<Text*>(e)->string() : 0; + return e ? static_cast<Text*>(e)->dataImpl() : 0; } void RenderText::absoluteRects(Vector<IntRect>& rects, int tx, int ty) @@ -328,13 +328,13 @@ VisiblePosition RenderText::positionForPoint(const IntPoint& point) int offset; // FIXME: We should be able to roll these special cases into the general cases in the loop below. - if (firstTextBox() && point.y() < firstTextBox()->root()->bottomOverflow() && point.x() < firstTextBox()->m_x) { + if (firstTextBox() && point.y() < firstTextBox()->root()->lineBottom() && point.x() < firstTextBox()->m_x) { // at the y coordinate of the first line or above // and the x coordinate is to the left of the first text box left edge offset = firstTextBox()->offsetForPosition(point.x()); return createVisiblePosition(offset + firstTextBox()->start(), DOWNSTREAM); } - if (lastTextBox() && point.y() >= lastTextBox()->root()->topOverflow() && point.x() >= lastTextBox()->m_x + lastTextBox()->m_width) { + if (lastTextBox() && point.y() >= lastTextBox()->root()->lineTop() && point.x() >= lastTextBox()->m_x + lastTextBox()->m_width) { // at the y coordinate of the last line or below // and the x coordinate is to the right of the last text box right edge offset = lastTextBox()->offsetForPosition(point.x()); @@ -343,8 +343,8 @@ VisiblePosition RenderText::positionForPoint(const IntPoint& point) InlineTextBox* lastBoxAbove = 0; for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { - if (point.y() >= box->root()->topOverflow()) { - int bottom = box->root()->nextRootBox() ? box->root()->nextRootBox()->topOverflow() : box->root()->bottomOverflow(); + if (point.y() >= box->root()->lineTop()) { + int bottom = box->root()->nextRootBox() ? box->root()->nextRootBox()->lineTop() : box->root()->lineBottom(); if (point.y() < bottom) { offset = box->offsetForPosition(point.x()); @@ -387,8 +387,8 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e InlineTextBox* box = static_cast<InlineTextBox*>(inlineBox); - int height = box->root()->bottomOverflow() - box->root()->topOverflow(); - int top = box->root()->topOverflow(); + int height = box->root()->lineBottom() - box->root()->lineTop(); + int top = box->root()->lineTop(); int left = box->positionForOffset(caretOffset); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderText.h b/src/3rdparty/webkit/WebCore/rendering/RenderText.h index 2e04a9e92..915ff40ac 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderText.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderText.h @@ -173,16 +173,16 @@ private: mutable bool m_knownNotToUseFallbackFonts : 1; }; -inline RenderText* toRenderText(RenderObject* o) +inline RenderText* toRenderText(RenderObject* object) { - ASSERT(!o || o->isText()); - return static_cast<RenderText*>(o); + ASSERT(!object || object->isText()); + return static_cast<RenderText*>(object); } -inline const RenderText* toRenderText(const RenderObject* o) +inline const RenderText* toRenderText(const RenderObject* object) { - ASSERT(!o || o->isText()); - return static_cast<const RenderText*>(o); + ASSERT(!object || object->isText()); + return static_cast<const RenderText*>(object); } // This will catch anyone doing an unnecessary cast. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp index 95e71ddee..f43039956 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp @@ -67,8 +67,9 @@ static Color disabledTextColor(const Color& textColor, const Color& backgroundCo return disabledColor; } -RenderTextControl::RenderTextControl(Node* node) +RenderTextControl::RenderTextControl(Node* node, bool placeholderVisible) : RenderBlock(node) + , m_placeholderVisible(placeholderVisible) , m_edited(false) , m_userEdited(false) { @@ -92,14 +93,22 @@ void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* // Reset them now to avoid getting a spurious layout hint. textBlockRenderer->style()->setHeight(Length()); textBlockRenderer->style()->setWidth(Length()); - textBlockRenderer->setStyle(textBlockStyle); + setInnerTextStyle(textBlockStyle); + } + + setReplaced(isInline()); +} + +void RenderTextControl::setInnerTextStyle(PassRefPtr<RenderStyle> style) +{ + if (m_innerText) { + RefPtr<RenderStyle> textStyle = style; + m_innerText->renderer()->setStyle(textStyle); for (Node* n = m_innerText->firstChild(); n; n = n->traverseNextNode(m_innerText.get())) { if (n->renderer()) - n->renderer()->setStyle(textBlockStyle); + n->renderer()->setStyle(textStyle); } } - - setReplaced(isInline()); } static inline bool updateUserModifyProperty(Node* node, RenderStyle* style) @@ -173,7 +182,7 @@ void RenderTextControl::setInnerTextValue(const String& innerTextValue) frame->editor()->clearUndoRedoOperations(); if (AXObjectCache::accessibilityEnabled()) - document()->axObjectCache()->postNotification(this, "AXValueChanged", false); + document()->axObjectCache()->postNotification(this, AXObjectCache::AXValueChanged, false); } } @@ -492,7 +501,7 @@ void RenderTextControl::selectionChanged(bool userTriggered) if (Frame* frame = document()->frame()) { if (frame->selection()->isRange() && userTriggered) - node()->dispatchEvent(eventNames().selectEvent, true, false); + node()->dispatchEvent(Event::create(eventNames().selectEvent, true, false)); } } @@ -506,4 +515,18 @@ HTMLElement* RenderTextControl::innerTextElement() const return m_innerText.get(); } +void RenderTextControl::updatePlaceholderVisibility(bool placeholderShouldBeVisible, bool placeholderValueChanged) +{ + bool oldPlaceholderVisible = m_placeholderVisible; + m_placeholderVisible = placeholderShouldBeVisible; + if (oldPlaceholderVisible != m_placeholderVisible || placeholderValueChanged) { + // Sets the inner text style to the normal style or :placeholder style. + setInnerTextStyle(createInnerTextStyle(textBaseStyle())); + + // updateFromElement() of the subclasses updates the text content + // to the element's value(), placeholder(), or the empty string. + updateFromElement(); + } +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.h b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.h index bce961988..cdd8716d6 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.h @@ -34,17 +34,6 @@ class RenderTextControl : public RenderBlock { public: virtual ~RenderTextControl(); - virtual const char* renderName() const { return "RenderTextControl"; } - virtual bool isTextControl() const { return true; } - virtual bool hasControlClip() const { return false; } - virtual IntRect controlClipRect(int tx, int ty) const; - virtual void calcHeight(); - virtual void calcPrefWidths(); - virtual void removeLeftoverAnonymousBlock(RenderBlock*) { } - virtual void updateFromElement(); - virtual bool canHaveChildren() const { return false; } - virtual bool avoidsFloats() const { return true; } - bool isEdited() const { return m_edited; } void setEdited(bool isEdited) { m_edited = isEdited; } @@ -64,15 +53,13 @@ public: String textWithHardLineBreaks(); void selectionChanged(bool userTriggered); - virtual void addFocusRingRects(GraphicsContext*, int tx, int ty); - - virtual bool canBeProgramaticallyScrolled(bool) const { return true; } - VisiblePosition visiblePositionForIndex(int index); int indexForVisiblePosition(const VisiblePosition&); + void updatePlaceholderVisibility(bool, bool); + protected: - RenderTextControl(Node*); + RenderTextControl(Node*, bool); int scrollbarThickness() const; void adjustInnerTextStyle(const RenderStyle* startStyle, RenderStyle* textBlockStyle) const; @@ -91,11 +78,31 @@ protected: virtual void adjustControlHeightBasedOnLineHeight(int lineHeight) = 0; virtual void cacheSelection(int start, int end) = 0; virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const = 0; + virtual RenderStyle* textBaseStyle() const = 0; + + virtual void updateFromElement(); + virtual void calcHeight(); friend class TextIterator; HTMLElement* innerTextElement() const; + bool m_placeholderVisible; + private: + virtual const char* renderName() const { return "RenderTextControl"; } + virtual bool isTextControl() const { return true; } + virtual bool hasControlClip() const { return false; } + virtual IntRect controlClipRect(int tx, int ty) const; + virtual void calcPrefWidths(); + virtual void removeLeftoverAnonymousBlock(RenderBlock*) { } + virtual bool canHaveChildren() const { return false; } + virtual bool avoidsFloats() const { return true; } + void setInnerTextStyle(PassRefPtr<RenderStyle>); + + virtual void addFocusRingRects(GraphicsContext*, int tx, int ty); + + virtual bool canBeProgramaticallyScrolled(bool) const { return true; } + String finishText(Vector<UChar>&) const; bool m_edited; @@ -103,16 +110,16 @@ private: RefPtr<TextControlInnerTextElement> m_innerText; }; -inline RenderTextControl* toRenderTextControl(RenderObject* o) +inline RenderTextControl* toRenderTextControl(RenderObject* object) { - ASSERT(!o || o->isTextControl()); - return static_cast<RenderTextControl*>(o); + ASSERT(!object || object->isTextControl()); + return static_cast<RenderTextControl*>(object); } -inline const RenderTextControl* toRenderTextControl(const RenderObject* o) +inline const RenderTextControl* toRenderTextControl(const RenderObject* object) { - ASSERT(!o || o->isTextControl()); - return static_cast<const RenderTextControl*>(o); + ASSERT(!object || object->isTextControl()); + return static_cast<const RenderTextControl*>(object); } // This will catch anyone doing an unnecessary cast. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp index 566a81c86..a49e092b1 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp @@ -22,15 +22,17 @@ #include "config.h" #include "RenderTextControlMultiLine.h" +#include "Event.h" #include "EventNames.h" #include "Frame.h" -#include "HitTestResult.h" +#include "HTMLNames.h" #include "HTMLTextAreaElement.h" +#include "HitTestResult.h" namespace WebCore { -RenderTextControlMultiLine::RenderTextControlMultiLine(Node* node) - : RenderTextControl(node) +RenderTextControlMultiLine::RenderTextControlMultiLine(Node* node, bool placeholderVisible) + : RenderTextControl(node, placeholderVisible) { } @@ -43,16 +45,17 @@ RenderTextControlMultiLine::~RenderTextControlMultiLine() void RenderTextControlMultiLine::subtreeHasChanged() { RenderTextControl::subtreeHasChanged(); - static_cast<Element*>(node())->setFormControlValueMatchesRenderer(false); + HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node()); + textArea->setFormControlValueMatchesRenderer(false); + textArea->updateValidity(); if (!node()->focused()) return; - // Fire the "input" DOM event - node()->dispatchEvent(eventNames().inputEvent, true, false); + node()->dispatchEvent(Event::create(eventNames().inputEvent, true, false)); if (Frame* frame = document()->frame()) - frame->textDidChangeInTextArea(static_cast<Element*>(node())); + frame->textDidChangeInTextArea(textArea); } bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) @@ -60,7 +63,10 @@ bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitT if (!RenderTextControl::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction)) return false; - if (result.innerNode() == node() || result.innerNode() == innerTextElement()) + bool resultIsTextValueOrPlaceholder + = !m_placeholderVisible && result.innerNode() == innerTextElement() + || m_placeholderVisible && result.innerNode()->isDescendantOf(innerTextElement()); + if (result.innerNode() == node() || resultIsTextValueOrPlaceholder) hitInnerTextElement(result, x, y, tx, ty); return true; @@ -92,7 +98,11 @@ void RenderTextControlMultiLine::updateFromElement() createSubtreeIfNeeded(0); RenderTextControl::updateFromElement(); - setInnerTextValue(static_cast<HTMLTextAreaElement*>(node())->value()); + HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node()); + if (m_placeholderVisible) + setInnerTextValue(textArea->getAttribute(HTMLNames::placeholderAttr)); + else + setInnerTextValue(textArea->value()); } void RenderTextControlMultiLine::cacheSelection(int start, int end) @@ -102,8 +112,15 @@ void RenderTextControlMultiLine::cacheSelection(int start, int end) PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const RenderStyle* startStyle) const { - RefPtr<RenderStyle> textBlockStyle = RenderStyle::create(); - textBlockStyle->inheritFrom(startStyle); + RefPtr<RenderStyle> textBlockStyle; + if (m_placeholderVisible) { + if (RenderStyle* pseudoStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER)) + textBlockStyle = RenderStyle::clone(pseudoStyle); + } + if (!textBlockStyle) { + textBlockStyle = RenderStyle::create(); + textBlockStyle->inheritFrom(startStyle); + } adjustInnerTextStyle(startStyle, textBlockStyle.get()); textBlockStyle->setDisplay(BLOCK); @@ -111,4 +128,9 @@ PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const R return textBlockStyle.release(); } +RenderStyle* RenderTextControlMultiLine::textBaseStyle() const +{ + return style(); +} + } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.h b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.h index 579047dd9..3371a8f1a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (C) 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -27,17 +28,18 @@ namespace WebCore { class RenderTextControlMultiLine : public RenderTextControl { public: - RenderTextControlMultiLine(Node*); + RenderTextControlMultiLine(Node*, bool); virtual ~RenderTextControlMultiLine(); + void forwardEvent(Event*); + +private: virtual bool isTextArea() const { return true; } virtual void subtreeHasChanged(); virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); - void forwardEvent(Event*); -private: virtual int preferredContentWidth(float charWidth) const; virtual void adjustControlHeightBasedOnLineHeight(int lineHeight); virtual int baselinePosition(bool firstLine, bool isRootLineBox) const; @@ -45,9 +47,19 @@ private: virtual void updateFromElement(); virtual void cacheSelection(int start, int end); + virtual RenderStyle* textBaseStyle() const; virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const; }; +inline RenderTextControlMultiLine* toRenderTextControlMultiLine(RenderObject* object) +{ + ASSERT(!object || object->isTextArea()); + return static_cast<RenderTextControlMultiLine*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderTextControlMultiLine(const RenderTextControlMultiLine*); + } #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp index 9c022d6de..be800a731 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp @@ -48,9 +48,8 @@ namespace WebCore { using namespace HTMLNames; -RenderTextControlSingleLine::RenderTextControlSingleLine(Node* node) - : RenderTextControl(node) - , m_placeholderVisible(false) +RenderTextControlSingleLine::RenderTextControlSingleLine(Node* node, bool placeholderVisible) + : RenderTextControl(node, placeholderVisible) , m_searchPopupIsVisible(false) , m_shouldDrawCapsLockIndicator(false) , m_searchEventTimer(this, &RenderTextControlSingleLine::searchEventTimerFired) @@ -69,25 +68,9 @@ RenderTextControlSingleLine::~RenderTextControlSingleLine() m_innerBlock->detach(); } -bool RenderTextControlSingleLine::placeholderShouldBeVisible() const +RenderStyle* RenderTextControlSingleLine::textBaseStyle() const { - return inputElement()->placeholderShouldBeVisible(); -} - -void RenderTextControlSingleLine::updatePlaceholderVisibility() -{ - RenderStyle* parentStyle = m_innerBlock ? m_innerBlock->renderer()->style() : style(); - - RefPtr<RenderStyle> textBlockStyle = createInnerTextStyle(parentStyle); - HTMLElement* innerText = innerTextElement(); - innerText->renderer()->setStyle(textBlockStyle); - - for (Node* n = innerText->firstChild(); n; n = n->traverseNextNode(innerText)) { - if (RenderObject* renderer = n->renderer()) - renderer->setStyle(textBlockStyle); - } - - updateFromElement(); + return m_innerBlock ? m_innerBlock->renderer()->style() : style(); } void RenderTextControlSingleLine::addSearchResult() @@ -163,8 +146,6 @@ void RenderTextControlSingleLine::hidePopup() ASSERT(node()->isHTMLElement()); if (m_searchPopup) m_searchPopup->hide(); - - m_searchPopupIsVisible = false; } void RenderTextControlSingleLine::subtreeHasChanged() @@ -173,7 +154,11 @@ void RenderTextControlSingleLine::subtreeHasChanged() RenderTextControl::subtreeHasChanged(); InputElement* input = inputElement(); - input->setValueFromRenderer(input->constrainValue(text())); + // We don't need to call sanitizeUserInputValue() function here because + // InputElement::handleBeforeTextInsertedEvent() has already called + // sanitizeUserInputValue(). + // sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent. + input->setValueFromRenderer(input->sanitizeValue(text())); if (m_cancelButton) updateCancelButtonVisibility(); @@ -469,17 +454,14 @@ void RenderTextControlSingleLine::updateFromElement() createSubtreeIfNeeded(); RenderTextControl::updateFromElement(); - bool placeholderVisibilityShouldChange = m_placeholderVisible != placeholderShouldBeVisible(); - m_placeholderVisible = placeholderShouldBeVisible(); - if (m_cancelButton) updateCancelButtonVisibility(); if (m_placeholderVisible) { ExceptionCode ec = 0; - innerTextElement()->setInnerText(inputElement()->placeholder(), ec); + innerTextElement()->setInnerText(static_cast<Element*>(node())->getAttribute(placeholderAttr), ec); ASSERT(!ec); - } else if (!static_cast<Element*>(node())->formControlValueMatchesRenderer() || placeholderVisibilityShouldChange) + } else setInnerTextValue(inputElement()->value()); if (m_searchPopupIsVisible) @@ -494,7 +476,7 @@ void RenderTextControlSingleLine::cacheSelection(int start, int end) PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const RenderStyle* startStyle) const { RefPtr<RenderStyle> textBlockStyle; - if (placeholderShouldBeVisible()) { + if (m_placeholderVisible) { if (RenderStyle* pseudoStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER)) textBlockStyle = RenderStyle::clone(pseudoStyle); } @@ -524,7 +506,7 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const // After this, updateFromElement will immediately update the text displayed. // When the placeholder is no longer visible, updatePlaceholderVisiblity will reset the style, // and the text security mode will be set back to the computed value correctly. - if (placeholderShouldBeVisible()) + if (m_placeholderVisible) textBlockStyle->setTextSecurity(TSNONE); return textBlockStyle.release(); @@ -742,6 +724,11 @@ int RenderTextControlSingleLine::selectedIndex() const return -1; } +void RenderTextControlSingleLine::popupDidHide() +{ + m_searchPopupIsVisible = false; +} + bool RenderTextControlSingleLine::itemIsSeparator(unsigned listIndex) const { // The separator will be the second to last item in our list. @@ -821,12 +808,12 @@ void RenderTextControlSingleLine::setScrollTop(int newTop) innerTextElement()->setScrollTop(newTop); } -bool RenderTextControlSingleLine::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier) +bool RenderTextControlSingleLine::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier, Node** stopNode) { RenderLayer* layer = innerTextElement()->renderBox()->layer(); if (layer && layer->scroll(direction, granularity, multiplier)) return true; - return RenderBlock::scroll(direction, granularity, multiplier); + return RenderBlock::scroll(direction, granularity, multiplier, stopNode); } PassRefPtr<Scrollbar> RenderTextControlSingleLine::createScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize controlSize) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.h b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.h index 23352b45b..e30ff0d3d 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved. * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * This library is free software; you can redistribute it and/or @@ -35,31 +36,32 @@ class TextControlInnerElement; class RenderTextControlSingleLine : public RenderTextControl, private PopupMenuClient { public: - RenderTextControlSingleLine(Node*); + RenderTextControlSingleLine(Node*, bool); virtual ~RenderTextControlSingleLine(); - virtual bool hasControlClip() const { return m_cancelButton; } - virtual bool isTextField() const { return true; } - bool placeholderIsVisible() const { return m_placeholderVisible; } bool placeholderShouldBeVisible() const; - void updatePlaceholderVisibility(); void addSearchResult(); void stopSearchEventTimer(); bool popupIsVisible() const { return m_searchPopupIsVisible; } void showPopup(); - virtual void hidePopup(); // PopupMenuClient method + void hidePopup(); + + void forwardEvent(Event*); + + void capsLockStateMayHaveChanged(); + +private: + virtual bool hasControlClip() const { return m_cancelButton; } + virtual bool isTextField() const { return true; } virtual void subtreeHasChanged(); virtual void paint(PaintInfo&, int tx, int ty); virtual void layout(); virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); - void forwardEvent(Event*); - - void capsLockStateMayHaveChanged(); virtual void autoscroll(); @@ -70,9 +72,8 @@ public: virtual int scrollHeight() const; virtual void setScrollLeft(int); virtual void setScrollTop(int); - virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f); + virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0); -private: int textBlockWidth() const; virtual int preferredContentWidth(float charWidth) const; virtual void adjustControlHeightBasedOnLineHeight(int lineHeight); @@ -82,6 +83,7 @@ private: virtual void cacheSelection(int start, int end); virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + virtual RenderStyle* textBaseStyle() const; virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const; PassRefPtr<RenderStyle> createInnerBlockStyle(const RenderStyle* startStyle) const; PassRefPtr<RenderStyle> createResultsButtonStyle(const RenderStyle* startStyle) const; @@ -94,10 +96,10 @@ private: void startSearchEventTimer(); void searchEventTimerFired(Timer<RenderTextControlSingleLine>*); -private: // PopupMenuClient methods virtual void valueChanged(unsigned listIndex, bool fireEvents = true); virtual String itemText(unsigned listIndex) const; + virtual String itemToolTip(unsigned) const { return String(); } virtual bool itemIsEnabled(unsigned listIndex) const; virtual PopupMenuStyle itemStyle(unsigned listIndex) const; virtual PopupMenuStyle menuStyle() const; @@ -107,6 +109,7 @@ private: virtual int clientPaddingRight() const; virtual int listSize() const; virtual int selectedIndex() const; + virtual void popupDidHide(); virtual bool itemIsSeparator(unsigned listIndex) const; virtual bool itemIsLabel(unsigned listIndex) const; virtual bool itemIsSelected(unsigned listIndex) const; @@ -119,8 +122,6 @@ private: InputElement* inputElement() const; -private: - bool m_placeholderVisible; bool m_searchPopupIsVisible; bool m_shouldDrawCapsLockIndicator; @@ -133,6 +134,15 @@ private: Vector<String> m_recentSearches; }; +inline RenderTextControlSingleLine* toRenderTextControlSingleLine(RenderObject* object) +{ + ASSERT(!object || object->isTextField()); + return static_cast<RenderTextControlSingleLine*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderTextControlSingleLine(const RenderTextControlSingleLine*); + } #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextFragment.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextFragment.cpp index 7da9e5a98..9ff110649 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextFragment.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextFragment.cpp @@ -47,7 +47,7 @@ RenderTextFragment::RenderTextFragment(Node* node, StringImpl* str) PassRefPtr<StringImpl> RenderTextFragment::originalText() const { Node* e = node(); - RefPtr<StringImpl> result = (e ? static_cast<Text*>(e)->string() : contentString()); + RefPtr<StringImpl> result = (e ? static_cast<Text*>(e)->dataImpl() : contentString()); if (result && (start() > 0 || start() < result->length())) result = result->substring(start(), end()); return result.release(); @@ -76,7 +76,7 @@ UChar RenderTextFragment::previousCharacter() { if (start()) { Node* e = node(); - StringImpl* original = (e ? static_cast<Text*>(e)->string() : contentString()); + StringImpl* original = (e ? static_cast<Text*>(e)->dataImpl() : contentString()); if (original) return (*original)[start() - 1]; } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp index d48652fbf..5ee01e445 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp @@ -30,6 +30,7 @@ #include "GraphicsContext.h" #include "HTMLInputElement.h" #include "HTMLNames.h" +#include "MediaControlElements.h" #include "Page.h" #include "RenderStyle.h" #include "RenderView.h" @@ -84,6 +85,7 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El #if USE(NEW_THEME) switch (part) { + case ListButtonPart: case CheckboxPart: case RadioPart: case PushButtonPart: @@ -170,6 +172,7 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El return adjustRadioStyle(selector, style, e); case PushButtonPart: case SquareButtonPart: + case ListButtonPart: case DefaultButtonPart: case ButtonPart: return adjustButtonStyle(selector, style, e); @@ -183,6 +186,7 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El case MenulistButtonPart: return adjustMenuListButtonStyle(selector, style, e); case MediaSliderPart: + case MediaVolumeSliderPart: case SliderHorizontalPart: case SliderVerticalPart: return adjustSliderTrackStyle(selector, style, e); @@ -225,6 +229,7 @@ bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInf case RadioPart: case PushButtonPart: case SquareButtonPart: + case ListButtonPart: case DefaultButtonPart: case ButtonPart: m_theme->paint(part, controlStatesForRenderer(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->style()->effectiveZoom(), o->view()->frameView()); @@ -243,6 +248,7 @@ bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInf return paintRadio(o, paintInfo, r); case PushButtonPart: case SquareButtonPart: + case ListButtonPart: case DefaultButtonPart: case ButtonPart: return paintButton(o, paintInfo, r); @@ -278,6 +284,14 @@ bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInf if (o->parent()->isSlider()) return paintMediaSliderThumb(o, paintInfo, r); break; + case MediaVolumeSliderContainerPart: + return paintMediaVolumeSliderContainer(o, paintInfo, r); + case MediaVolumeSliderPart: + return paintMediaVolumeSliderTrack(o, paintInfo, r); + case MediaVolumeSliderThumbPart: + if (o->parent()->isSlider()) + return paintMediaVolumeSliderThumb(o, paintInfo, r); + break; case MediaTimeRemainingPart: return paintMediaTimeRemaining(o, paintInfo, r); case MediaCurrentTimePart: @@ -325,6 +339,7 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const RenderObject::PaintInfo case RadioPart: case PushButtonPart: case SquareButtonPart: + case ListButtonPart: case DefaultButtonPart: case ButtonPart: case MenulistPart: @@ -359,6 +374,7 @@ bool RenderTheme::paintDecorations(RenderObject* o, const RenderObject::PaintInf case RadioPart: case PushButtonPart: case SquareButtonPart: + case ListButtonPart: case DefaultButtonPart: case ButtonPart: case MenulistPart: @@ -387,6 +403,23 @@ bool RenderTheme::hitTestMediaControlPart(RenderObject* o, const IntPoint& absPo FloatPoint localPoint = o->absoluteToLocal(absPoint, false, true); // respect transforms return toRenderBox(o)->borderBoxRect().contains(roundedIntPoint(localPoint)); } + +bool RenderTheme::shouldRenderMediaControlPart(ControlPart part, Element* e) +{ + HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(e); + switch (part) { + case MediaMuteButtonPart: + return mediaElement->hasAudio(); + case MediaRewindButtonPart: + return mediaElement->movieLoadType() != MediaPlayer::LiveStream; + case MediaReturnToRealtimeButtonPart: + return mediaElement->movieLoadType() == MediaPlayer::LiveStream; + case MediaFullscreenButtonPart: + return mediaElement->supportsFullscreen(); + default: + return true; + } +} #endif Color RenderTheme::activeSelectionBackgroundColor() const diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h index 795daa206..1b6a7e44e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h @@ -172,6 +172,7 @@ public: #if ENABLE(VIDEO) // Media controls virtual bool hitTestMediaControlPart(RenderObject*, const IntPoint& absPoint); + virtual bool shouldRenderMediaControlPart(ControlPart, Element*); #endif protected: @@ -244,6 +245,9 @@ protected: virtual bool paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; } virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; } virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; } + virtual bool paintMediaVolumeSliderContainer(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; } + virtual bool paintMediaVolumeSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; } + virtual bool paintMediaVolumeSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; } virtual bool paintMediaRewindButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; } virtual bool paintMediaReturnToRealtimeButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; } virtual bool paintMediaControlsBackground(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp index c4020d36c..9048ce38e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp @@ -45,6 +45,7 @@ PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) RenderThemeChromiumLinux::RenderThemeChromiumLinux() { + m_caretBlinkInterval = RenderTheme::caretBlinkInterval(); } RenderThemeChromiumLinux::~RenderThemeChromiumLinux() @@ -91,9 +92,34 @@ Color RenderThemeChromiumLinux::inactiveListBoxSelectionForegroundColor() const return Color(0x32, 0x32, 0x32); } +void RenderThemeChromiumLinux::adjustSliderThumbSize(RenderObject* o) const +{ + // These sizes match the sizes in Chromium Win. + const int sliderThumbAlongAxis = 11; + const int sliderThumbAcrossAxis = 21; + if (o->style()->appearance() == SliderThumbHorizontalPart) { + o->style()->setWidth(Length(sliderThumbAlongAxis, Fixed)); + o->style()->setHeight(Length(sliderThumbAcrossAxis, Fixed)); + } else if (o->style()->appearance() == SliderThumbVerticalPart) { + o->style()->setWidth(Length(sliderThumbAcrossAxis, Fixed)); + o->style()->setHeight(Length(sliderThumbAlongAxis, Fixed)); + } else + RenderThemeChromiumSkia::adjustSliderThumbSize(o); +} + bool RenderThemeChromiumLinux::supportsControlTints() const { return true; } +void RenderThemeChromiumLinux::setCaretBlinkInterval(double interval) +{ + m_caretBlinkInterval = interval; +} + +double RenderThemeChromiumLinux::caretBlinkIntervalInternal() const +{ + return m_caretBlinkInterval; +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h index e75ddd51f..e137ad598 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h @@ -49,12 +49,19 @@ namespace WebCore { virtual Color inactiveListBoxSelectionBackgroundColor() const; virtual Color inactiveListBoxSelectionForegroundColor() const; + virtual void adjustSliderThumbSize(RenderObject*) const; + + void setCaretBlinkInterval(double interval); + virtual double caretBlinkIntervalInternal() const; + private: RenderThemeChromiumLinux(); virtual ~RenderThemeChromiumLinux(); // A general method asking if any control tinting is supported at all. virtual bool supportsControlTints() const; + + double m_caretBlinkInterval; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h index f8204cf60..61b5e8f39 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h @@ -3,7 +3,6 @@ * * Copyright (C) 2005 Apple Computer, Inc. * Copyright (C) 2008, 2009 Google, Inc. - * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -26,7 +25,6 @@ #define RenderThemeChromiumMac_h #import "RenderTheme.h" -#import <AppKit/AppKit.h> #import <wtf/HashMap.h> #import <wtf/RetainPtr.h> @@ -36,185 +34,166 @@ class WebCoreRenderThemeNotificationObserver; #endif +// This file (and its associated .mm file) is a clone of RenderThemeMac.h. See +// the .mm file for details. + namespace WebCore { - class RenderStyle; +class RenderStyle; + +class RenderThemeChromiumMac : public RenderTheme { +public: + static PassRefPtr<RenderTheme> create(); + + // A method asking if the control changes its tint when the window has focus or not. + virtual bool controlSupportsTints(const RenderObject*) const; + + // A general method asking if any control tinting is supported at all. + virtual bool supportsControlTints() const { return true; } + + virtual void adjustRepaintRect(const RenderObject*, IntRect&); + + virtual bool isControlStyled(const RenderStyle*, const BorderData&, + const FillLayer&, const Color& backgroundColor) const; + + virtual Color platformActiveSelectionBackgroundColor() const; + virtual Color platformInactiveSelectionBackgroundColor() const; + virtual Color platformActiveListBoxSelectionBackgroundColor() const; + virtual Color platformActiveListBoxSelectionForegroundColor() const; + virtual Color platformInactiveListBoxSelectionBackgroundColor() const; + virtual Color platformInactiveListBoxSelectionForegroundColor() const; + virtual Color platformFocusRingColor() const; - class RenderThemeChromiumMac : public RenderTheme { - public: - static PassRefPtr<RenderTheme> create(); + virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return SmallScrollbar; } + + virtual void platformColorsDidChange(); + + // System fonts. + virtual void systemFont(int cssValueId, FontDescription&) const; + + virtual int minimumMenuListSize(RenderStyle*) const; + + virtual void adjustSliderThumbSize(RenderObject*) const; + + virtual int popupInternalPaddingLeft(RenderStyle*) const; + virtual int popupInternalPaddingRight(RenderStyle*) const; + virtual int popupInternalPaddingTop(RenderStyle*) const; + virtual int popupInternalPaddingBottom(RenderStyle*) const; + + virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - // A method to obtain the baseline position for a "leaf" control. This will only be used if a baseline - // position cannot be determined by examining child content. Checkboxes and radio buttons are examples of - // controls that need to do this. - virtual int baselinePosition(const RenderObject*) const; + virtual Color systemColor(int cssValueId) const; - // A method asking if the control changes its tint when the window has focus or not. - virtual bool controlSupportsTints(const RenderObject*) const; +protected: + virtual bool supportsSelectionForegroundColors() const { return false; } - // A general method asking if any control tinting is supported at all. - virtual bool supportsControlTints() const { return true; } + virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual void adjustRepaintRect(const RenderObject*, IntRect&); + virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool isControlStyled(const RenderStyle*, const BorderData&, - const FillLayer&, const Color& backgroundColor) const; + virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual Color platformActiveSelectionBackgroundColor() const; - virtual Color platformInactiveSelectionBackgroundColor() const; - virtual Color activeListBoxSelectionBackgroundColor() const; + virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual Color platformFocusRingColor() const; - - virtual void platformColorsDidChange(); + virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - // System fonts. - virtual void systemFont(int cssValueId, FontDescription&) const; + virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual int minimumMenuListSize(RenderStyle*) const; + virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual void adjustSliderThumbSize(RenderObject*) const; - - virtual int popupInternalPaddingLeft(RenderStyle*) const; - virtual int popupInternalPaddingRight(RenderStyle*) const; - virtual int popupInternalPaddingTop(RenderStyle*) const; - virtual int popupInternalPaddingBottom(RenderStyle*) const; - - virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return SmallScrollbar; } + virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + +#if ENABLE(VIDEO) + virtual bool shouldRenderMediaControlPart(ControlPart, Element*); + virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaControlsBackground(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + // Media controls + virtual String extraMediaControlsStyleSheet(); +#endif + +private: + RenderThemeChromiumMac(); + virtual ~RenderThemeChromiumMac(); + + IntRect inflateRect(const IntRect&, const IntSize&, const int* margins, float zoomLevel = 1.0f) const; + + FloatRect convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const; - virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + // Get the control size based off the font. Used by some of the controls (like buttons). + NSControlSize controlSizeForFont(RenderStyle*) const; + NSControlSize controlSizeForSystemFont(RenderStyle*) const; + void setControlSize(NSCell*, const IntSize* sizes, const IntSize& minSize, float zoomLevel = 1.0f); + void setSizeFromFont(RenderStyle*, const IntSize* sizes) const; + IntSize sizeForFont(RenderStyle*, const IntSize* sizes) const; + IntSize sizeForSystemFont(RenderStyle*, const IntSize* sizes) const; + void setFontFromControlSize(CSSStyleSelector*, RenderStyle*, NSControlSize) const; + + void updateActiveState(NSCell*, const RenderObject*); + void updateCheckedState(NSCell*, const RenderObject*); + void updateEnabledState(NSCell*, const RenderObject*); + void updateFocusedState(NSCell*, const RenderObject*); + void updatePressedState(NSCell*, const RenderObject*); + + // Helpers for adjusting appearance and for painting + + void setPopupButtonCellState(const RenderObject*, const IntRect&); + const IntSize* popupButtonSizes() const; + const int* popupButtonMargins() const; + const int* popupButtonPadding(NSControlSize) const; + void paintMenuListButtonGradients(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + const IntSize* menuListSizes() const; + + const IntSize* searchFieldSizes() const; + const IntSize* cancelButtonSizes() const; + const IntSize* resultsButtonSizes() const; + void setSearchCellState(RenderObject*, const IntRect&); + void setSearchFieldSize(RenderStyle*) const; + + NSPopUpButtonCell* popupButton() const; + NSSearchFieldCell* search() const; + NSMenu* searchMenuTemplate() const; + NSSliderCell* sliderThumbHorizontal() const; + NSSliderCell* sliderThumbVertical() const; + +private: + mutable RetainPtr<NSPopUpButtonCell> m_popupButton; + mutable RetainPtr<NSSearchFieldCell> m_search; + mutable RetainPtr<NSMenu> m_searchMenuTemplate; + mutable RetainPtr<NSSliderCell> m_sliderThumbHorizontal; + mutable RetainPtr<NSSliderCell> m_sliderThumbVertical; - virtual Color systemColor(int cssValueId) const; + bool m_isSliderThumbHorizontalPressed; + bool m_isSliderThumbVerticalPressed; - protected: - virtual bool supportsSelectionForegroundColors() const { return false; } + mutable HashMap<int, RGBA32> m_systemColorCache; - // Methods for each appearance value. - virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void setCheckboxSize(RenderStyle*) const; - - virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void setRadioSize(RenderStyle*) const; - - virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, WebCore::Element*) const; - virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void setButtonSize(RenderStyle*) const; - - virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual bool paintMediaFullscreenButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSeekBackButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - private: - RenderThemeChromiumMac(); - virtual ~RenderThemeChromiumMac(); - - IntRect inflateRect(const IntRect&, const IntSize&, const int* margins, float zoomLevel = 1.0f) const; - - // Get the control size based off the font. Used by some of the controls (like buttons). - NSControlSize controlSizeForFont(RenderStyle*) const; - NSControlSize controlSizeForSystemFont(RenderStyle*) const; - void setControlSize(NSCell*, const IntSize* sizes, const IntSize& minSize, float zoomLevel = 1.0f); - void setSizeFromFont(RenderStyle*, const IntSize* sizes) const; - IntSize sizeForFont(RenderStyle*, const IntSize* sizes) const; - IntSize sizeForSystemFont(RenderStyle*, const IntSize* sizes) const; - void setFontFromControlSize(CSSStyleSelector*, RenderStyle*, NSControlSize) const; - - void updateCheckedState(NSCell*, const RenderObject*); - void updateEnabledState(NSCell*, const RenderObject*); - void updateFocusedState(NSCell*, const RenderObject*); - void updatePressedState(NSCell*, const RenderObject*); - - // Helpers for adjusting appearance and for painting - const IntSize* checkboxSizes() const; - const int* checkboxMargins() const; - void setCheckboxCellState(const RenderObject*, const IntRect&); - - const IntSize* radioSizes() const; - const int* radioMargins() const; - void setRadioCellState(const RenderObject*, const IntRect&); - - void setButtonPaddingFromControlSize(RenderStyle*, NSControlSize) const; - const IntSize* buttonSizes() const; - const int* buttonMargins() const; - void setButtonCellState(const RenderObject*, const IntRect&); - - void setPopupButtonCellState(const RenderObject*, const IntRect&); - const IntSize* popupButtonSizes() const; - const int* popupButtonMargins() const; - const int* popupButtonPadding(NSControlSize) const; - void paintMenuListButtonGradients(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - const IntSize* menuListSizes() const; - - const IntSize* searchFieldSizes() const; - const IntSize* cancelButtonSizes() const; - const IntSize* resultsButtonSizes() const; - void setSearchCellState(RenderObject*, const IntRect&); - void setSearchFieldSize(RenderStyle*) const; - - NSButtonCell* checkbox() const; - NSButtonCell* radio() const; - NSButtonCell* button() const; - NSPopUpButtonCell* popupButton() const; - NSSearchFieldCell* search() const; - NSMenu* searchMenuTemplate() const; - NSSliderCell* sliderThumbHorizontal() const; - NSSliderCell* sliderThumbVertical() const; - - private: - mutable RetainPtr<NSButtonCell> m_checkbox; - mutable RetainPtr<NSButtonCell> m_radio; - mutable RetainPtr<NSButtonCell> m_button; - mutable RetainPtr<NSPopUpButtonCell> m_popupButton; - mutable RetainPtr<NSSearchFieldCell> m_search; - mutable RetainPtr<NSMenu> m_searchMenuTemplate; - mutable RetainPtr<NSSliderCell> m_sliderThumbHorizontal; - mutable RetainPtr<NSSliderCell> m_sliderThumbVertical; - - bool m_isSliderThumbHorizontalPressed; - bool m_isSliderThumbVerticalPressed; - - mutable HashMap<int, RGBA32> m_systemColorCache; - - RetainPtr<WebCoreRenderThemeNotificationObserver> m_notificationObserver; - }; + RetainPtr<WebCoreRenderThemeNotificationObserver> m_notificationObserver; + bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*); +}; } // namespace WebCore -#endif +#endif // RenderThemeChromiumMac_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm index efd28d95e..bcfcd577c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm @@ -1,7 +1,6 @@ /* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2008, 2009 Google, Inc. - * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,25 +18,16 @@ * Boston, MA 02110-1301, USA. */ -// FIXME: we still need to figure out if passing a null view to the cell -// drawing routines will work. I expect not, and if that's the case we'll have -// to figure out something else. For now, at least leave the lines commented -// in, but the procurement of the view if 0'd. - #import "config.h" #import "RenderThemeChromiumMac.h" -#import <Carbon/Carbon.h> -#import <Cocoa/Cocoa.h> -#import <math.h> - #import "BitmapImage.h" #import "ChromiumBridge.h" #import "ColorMac.h" #import "CSSStyleSelector.h" #import "CSSValueKeywords.h" +#import "Document.h" #import "Element.h" -#import "FoundationExtras.h" #import "FrameView.h" #import "GraphicsContext.h" #import "HTMLInputElement.h" @@ -47,11 +37,18 @@ #import "LocalCurrentGraphicsContext.h" #import "MediaControlElements.h" #import "RenderMedia.h" +#import "RenderMediaControlsChromium.h" #import "RenderSlider.h" #import "RenderView.h" #import "SharedBuffer.h" +#import "UserAgentStyleSheets.h" #import "WebCoreSystemInterface.h" +#import "UserAgentStyleSheets.h" +#import <Carbon/Carbon.h> +#import <Cocoa/Cocoa.h> #import <wtf/RetainPtr.h> +#import <wtf/StdLibExtras.h> +#import <math.h> #ifdef BUILDING_ON_TIGER typedef int NSInteger; @@ -60,6 +57,25 @@ typedef unsigned NSUInteger; using std::min; +// This file (and its associated .h file) is a clone of RenderThemeMac.mm. +// Because the original file is designed to run in-process inside a Cocoa view, +// we must maintain a fork. Please maintain this file by performing parallel +// changes to it. +// +// The only changes from RenderThemeMac should be: +// - The classname change from RenderThemeMac to RenderThemeChromiumMac. +// - The introduction of RTCMFlippedView and FlippedView() and its use as the +// parent view for cell rendering. +// - In platformFocusRingColor(), the use of ChromiumBridge to determine if +// we're in layout test mode. +// - updateActiveState() and its use to update the cells' visual appearance. +// - All the paintMedia*() functions and extraMediaControlsStyleSheet() +// are forked from RenderThemeChromiumSkia instead of RenderThemeMac. +// +// For all other differences, if it was introduced in this file, then the +// maintainer forgot to include it in the list; otherwise it is an update that +// should have been applied to this file but was not. + // The methods in this file are specific to the Mac OS X platform. // FIXME: The platform-independent code in this class should be factored out and merged with RenderThemeSafari. @@ -84,48 +100,66 @@ using std::min; return self; } -- (void)systemColorsDidChange:(NSNotification *)notification +- (void)systemColorsDidChange:(NSNotification *)unusedNotification { - ASSERT([[notification name] isEqualToString:NSSystemColorsDidChangeNotification]); + ASSERT_UNUSED(unusedNotification, [[unusedNotification name] isEqualToString:NSSystemColorsDidChangeNotification]); _theme->platformColorsDidChange(); } @end +@interface RTCMFlippedView : NSView +{} + +- (BOOL)isFlipped; +- (NSText *)currentEditor; + +@end + +@implementation RTCMFlippedView + +- (BOOL)isFlipped { + return [[NSGraphicsContext currentContext] isFlipped]; +} + +- (NSText *)currentEditor { + return nil; +} + +@end + namespace WebCore { using namespace HTMLNames; enum { - TopMargin, - RightMargin, - BottomMargin, - LeftMargin + topMargin, + rightMargin, + bottomMargin, + leftMargin }; enum { - TopPadding, - RightPadding, - BottomPadding, - LeftPadding + topPadding, + rightPadding, + bottomPadding, + leftPadding }; -// In our Mac port, we don't define PLATFORM(MAC) and thus don't pick up the -// |operator NSRect()| on WebCore::IntRect and FloatRect. This substitues for -// that missing conversion operator. -NSRect IntRectToNSRect(const IntRect & rect) +// In Snow Leopard, many cells only check to see if the view they're passed is +// flipped, and if a nil view is passed, neglect to check if the current +// graphics context is flipped. Thus we pass a sham view to them, one whose +// flipped state just reflects the state of the context. +NSView* FlippedView() { - return NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); + static NSView* view = [[RTCMFlippedView alloc] init]; + return view; } -NSRect FloatRectToNSRect(const FloatRect & rect) +PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page*) { - return NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); -} - -IntRect NSRectToIntRect(const NSRect & rect) -{ - return IntRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + static RenderTheme* rt = RenderThemeChromiumMac::create().releaseRef(); + return rt; } PassRefPtr<RenderTheme> RenderThemeChromiumMac::create() @@ -133,12 +167,6 @@ PassRefPtr<RenderTheme> RenderThemeChromiumMac::create() return adoptRef(new RenderThemeChromiumMac); } -PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) -{ - static RenderTheme* rt = RenderThemeChromiumMac::create().releaseRef(); - return rt; -} - RenderThemeChromiumMac::RenderThemeChromiumMac() : m_isSliderThumbHorizontalPressed(false) , m_isSliderThumbVerticalPressed(false) @@ -167,12 +195,22 @@ Color RenderThemeChromiumMac::platformInactiveSelectionBackgroundColor() const return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent])); } -Color RenderThemeChromiumMac::activeListBoxSelectionBackgroundColor() const +Color RenderThemeChromiumMac::platformActiveListBoxSelectionBackgroundColor() const { NSColor* color = [[NSColor alternateSelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace]; return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent])); } +Color RenderThemeChromiumMac::platformActiveListBoxSelectionForegroundColor() const +{ + return Color::white; +} + +Color RenderThemeChromiumMac::platformInactiveListBoxSelectionForegroundColor() const +{ + return Color::black; +} + Color RenderThemeChromiumMac::platformFocusRingColor() const { if (ChromiumBridge::layoutTestMode()) @@ -181,6 +219,11 @@ Color RenderThemeChromiumMac::platformFocusRingColor() const return systemColor(CSSValueWebkitFocusRingColor); } +Color RenderThemeChromiumMac::platformInactiveListBoxSelectionBackgroundColor() const +{ + return platformInactiveSelectionBackgroundColor(); +} + static FontWeight toFontWeight(NSInteger appKitFontWeight) { ASSERT(appKitFontWeight > 0 && appKitFontWeight < 15); @@ -210,51 +253,51 @@ static FontWeight toFontWeight(NSInteger appKitFontWeight) void RenderThemeChromiumMac::systemFont(int cssValueId, FontDescription& fontDescription) const { - static FontDescription systemFont; - static FontDescription smallSystemFont; - static FontDescription menuFont; - static FontDescription labelFont; - static FontDescription miniControlFont; - static FontDescription smallControlFont; - static FontDescription controlFont; + DEFINE_STATIC_LOCAL(FontDescription, systemFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, smallSystemFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, menuFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, labelFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, miniControlFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, smallControlFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, controlFont, ()); FontDescription* cachedDesc; NSFont* font = nil; switch (cssValueId) { - case CSSValueSmallCaption: - cachedDesc = &smallSystemFont; - if (!smallSystemFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; - break; - case CSSValueMenu: - cachedDesc = &menuFont; - if (!menuFont.isAbsoluteSize()) - font = [NSFont menuFontOfSize:[NSFont systemFontSize]]; - break; - case CSSValueStatusBar: - cachedDesc = &labelFont; - if (!labelFont.isAbsoluteSize()) - font = [NSFont labelFontOfSize:[NSFont labelFontSize]]; - break; - case CSSValueWebkitMiniControl: - cachedDesc = &miniControlFont; - if (!miniControlFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]]; - break; - case CSSValueWebkitSmallControl: - cachedDesc = &smallControlFont; - if (!smallControlFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]; - break; - case CSSValueWebkitControl: - cachedDesc = &controlFont; - if (!controlFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]; - break; - default: - cachedDesc = &systemFont; - if (!systemFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont systemFontSize]]; + case CSSValueSmallCaption: + cachedDesc = &smallSystemFont; + if (!smallSystemFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; + break; + case CSSValueMenu: + cachedDesc = &menuFont; + if (!menuFont.isAbsoluteSize()) + font = [NSFont menuFontOfSize:[NSFont systemFontSize]]; + break; + case CSSValueStatusBar: + cachedDesc = &labelFont; + if (!labelFont.isAbsoluteSize()) + font = [NSFont labelFontOfSize:[NSFont labelFontSize]]; + break; + case CSSValueWebkitMiniControl: + cachedDesc = &miniControlFont; + if (!miniControlFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]]; + break; + case CSSValueWebkitSmallControl: + cachedDesc = &smallControlFont; + if (!smallControlFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]; + break; + case CSSValueWebkitControl: + cachedDesc = &controlFont; + if (!controlFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]; + break; + default: + cachedDesc = &systemFont; + if (!systemFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont systemFontSize]]; } if (font) { @@ -271,7 +314,7 @@ void RenderThemeChromiumMac::systemFont(int cssValueId, FontDescription& fontDes static RGBA32 convertNSColorToColor(NSColor *color) { - NSColor *colorInColorSpace = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + NSColor *colorInColorSpace = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace]; if (colorInColorSpace) { static const double scaleFactor = nextafter(256.0, 0.0); return makeRGB(static_cast<int>(scaleFactor * [colorInColorSpace redComponent]), @@ -291,7 +334,7 @@ static RGBA32 convertNSColorToColor(NSColor *color) samplesPerPixel:4 hasAlpha:YES isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace + colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:4 bitsPerPixel:32]; @@ -318,7 +361,7 @@ static RGBA32 menuBackgroundColor() samplesPerPixel:4 hasAlpha:YES isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace + colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:4 bitsPerPixel:32]; @@ -350,101 +393,101 @@ Color RenderThemeChromiumMac::systemColor(int cssValueId) const Color color; switch (cssValueId) { - case CSSValueActiveborder: - color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]); - break; - case CSSValueActivecaption: - color = convertNSColorToColor([NSColor windowFrameTextColor]); - break; - case CSSValueAppworkspace: - color = convertNSColorToColor([NSColor headerColor]); - break; - case CSSValueBackground: - // Use theme independent default - break; - case CSSValueButtonface: - // We use this value instead of NSColor's controlColor to avoid website incompatibilities. - // We may want to change this to use the NSColor in future. - color = 0xFFC0C0C0; - break; - case CSSValueButtonhighlight: - color = convertNSColorToColor([NSColor controlHighlightColor]); - break; - case CSSValueButtonshadow: - color = convertNSColorToColor([NSColor controlShadowColor]); - break; - case CSSValueButtontext: - color = convertNSColorToColor([NSColor controlTextColor]); - break; - case CSSValueCaptiontext: - color = convertNSColorToColor([NSColor textColor]); - break; - case CSSValueGraytext: - color = convertNSColorToColor([NSColor disabledControlTextColor]); - break; - case CSSValueHighlight: - color = convertNSColorToColor([NSColor selectedTextBackgroundColor]); - break; - case CSSValueHighlighttext: - color = convertNSColorToColor([NSColor selectedTextColor]); - break; - case CSSValueInactiveborder: - color = convertNSColorToColor([NSColor controlBackgroundColor]); - break; - case CSSValueInactivecaption: - color = convertNSColorToColor([NSColor controlBackgroundColor]); - break; - case CSSValueInactivecaptiontext: - color = convertNSColorToColor([NSColor textColor]); - break; - case CSSValueInfobackground: - // There is no corresponding NSColor for this so we use a hard coded value. - color = 0xFFFBFCC5; - break; - case CSSValueInfotext: - color = convertNSColorToColor([NSColor textColor]); - break; - case CSSValueMenu: - color = menuBackgroundColor(); - break; - case CSSValueMenutext: - color = convertNSColorToColor([NSColor selectedMenuItemTextColor]); - break; - case CSSValueScrollbar: - color = convertNSColorToColor([NSColor scrollBarColor]); - break; - case CSSValueText: - color = convertNSColorToColor([NSColor textColor]); - break; - case CSSValueThreeddarkshadow: - color = convertNSColorToColor([NSColor controlDarkShadowColor]); - break; - case CSSValueThreedshadow: - color = convertNSColorToColor([NSColor shadowColor]); - break; - case CSSValueThreedface: - // We use this value instead of NSColor's controlColor to avoid website incompatibilities. - // We may want to change this to use the NSColor in future. - color = 0xFFC0C0C0; - break; - case CSSValueThreedhighlight: - color = convertNSColorToColor([NSColor highlightColor]); - break; - case CSSValueThreedlightshadow: - color = convertNSColorToColor([NSColor controlLightHighlightColor]); - break; - case CSSValueWebkitFocusRingColor: - color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]); - break; - case CSSValueWindow: - color = convertNSColorToColor([NSColor windowBackgroundColor]); - break; - case CSSValueWindowframe: - color = convertNSColorToColor([NSColor windowFrameColor]); - break; - case CSSValueWindowtext: - color = convertNSColorToColor([NSColor windowFrameTextColor]); - break; + case CSSValueActiveborder: + color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]); + break; + case CSSValueActivecaption: + color = convertNSColorToColor([NSColor windowFrameTextColor]); + break; + case CSSValueAppworkspace: + color = convertNSColorToColor([NSColor headerColor]); + break; + case CSSValueBackground: + // Use theme independent default + break; + case CSSValueButtonface: + // We use this value instead of NSColor's controlColor to avoid website incompatibilities. + // We may want to change this to use the NSColor in future. + color = 0xFFC0C0C0; + break; + case CSSValueButtonhighlight: + color = convertNSColorToColor([NSColor controlHighlightColor]); + break; + case CSSValueButtonshadow: + color = convertNSColorToColor([NSColor controlShadowColor]); + break; + case CSSValueButtontext: + color = convertNSColorToColor([NSColor controlTextColor]); + break; + case CSSValueCaptiontext: + color = convertNSColorToColor([NSColor textColor]); + break; + case CSSValueGraytext: + color = convertNSColorToColor([NSColor disabledControlTextColor]); + break; + case CSSValueHighlight: + color = convertNSColorToColor([NSColor selectedTextBackgroundColor]); + break; + case CSSValueHighlighttext: + color = convertNSColorToColor([NSColor selectedTextColor]); + break; + case CSSValueInactiveborder: + color = convertNSColorToColor([NSColor controlBackgroundColor]); + break; + case CSSValueInactivecaption: + color = convertNSColorToColor([NSColor controlBackgroundColor]); + break; + case CSSValueInactivecaptiontext: + color = convertNSColorToColor([NSColor textColor]); + break; + case CSSValueInfobackground: + // There is no corresponding NSColor for this so we use a hard coded value. + color = 0xFFFBFCC5; + break; + case CSSValueInfotext: + color = convertNSColorToColor([NSColor textColor]); + break; + case CSSValueMenu: + color = menuBackgroundColor(); + break; + case CSSValueMenutext: + color = convertNSColorToColor([NSColor selectedMenuItemTextColor]); + break; + case CSSValueScrollbar: + color = convertNSColorToColor([NSColor scrollBarColor]); + break; + case CSSValueText: + color = convertNSColorToColor([NSColor textColor]); + break; + case CSSValueThreeddarkshadow: + color = convertNSColorToColor([NSColor controlDarkShadowColor]); + break; + case CSSValueThreedshadow: + color = convertNSColorToColor([NSColor shadowColor]); + break; + case CSSValueThreedface: + // We use this value instead of NSColor's controlColor to avoid website incompatibilities. + // We may want to change this to use the NSColor in future. + color = 0xFFC0C0C0; + break; + case CSSValueThreedhighlight: + color = convertNSColorToColor([NSColor highlightColor]); + break; + case CSSValueThreedlightshadow: + color = convertNSColorToColor([NSColor controlLightHighlightColor]); + break; + case CSSValueWebkitFocusRingColor: + color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]); + break; + case CSSValueWindow: + color = convertNSColorToColor([NSColor windowBackgroundColor]); + break; + case CSSValueWindowframe: + color = convertNSColorToColor([NSColor windowFrameColor]); + break; + case CSSValueWindowtext: + color = convertNSColorToColor([NSColor windowFrameTextColor]); + break; } if (!color.isValid()) @@ -457,7 +500,7 @@ Color RenderThemeChromiumMac::systemColor(int cssValueId) const } bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const BorderData& border, - const FillLayer& background, const Color& backgroundColor) const + const FillLayer& background, const Color& backgroundColor) const { if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart || style->appearance() == ListboxPart) return style->border() != border; @@ -472,62 +515,32 @@ bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const Bor return RenderTheme::isControlStyled(style, border, background, backgroundColor); } -// FIXME: Use the code from the old upstream version, before it was converted to the new theme API in r37731. void RenderThemeChromiumMac::adjustRepaintRect(const RenderObject* o, IntRect& r) { - float zoomLevel = o->style()->effectiveZoom(); - - switch (o->style()->appearance()) { - case CheckboxPart: { - // Since we query the prototype cell, we need to update its state to match. - setCheckboxCellState(o, r); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - IntSize size = checkboxSizes()[[checkbox() controlSize]]; - size.setHeight(size.height() * zoomLevel); - size.setWidth(size.width() * zoomLevel); - r = inflateRect(r, size, checkboxMargins(), zoomLevel); - break; + ControlPart part = o->style()->appearance(); + +#if USE(NEW_THEME) + switch (part) { + case CheckboxPart: + case RadioPart: + case PushButtonPart: + case SquareButtonPart: + case DefaultButtonPart: + case ButtonPart: + return RenderTheme::adjustRepaintRect(o, r); + default: + break; } - case RadioPart: { - // Since we query the prototype cell, we need to update its state to match. - setRadioCellState(o, r); +#endif - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - IntSize size = radioSizes()[[radio() controlSize]]; - size.setHeight(size.height() * zoomLevel); - size.setWidth(size.width() * zoomLevel); - r = inflateRect(r, size, radioMargins(), zoomLevel); - break; - } - case PushButtonPart: - case DefaultButtonPart: - case ButtonPart: { - // Since we query the prototype cell, we need to update its state to match. - setButtonCellState(o, r); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - if ([button() bezelStyle] == NSRoundedBezelStyle) { - IntSize size = buttonSizes()[[button() controlSize]]; - size.setHeight(size.height() * zoomLevel); - size.setWidth(r.width()); - r = inflateRect(r, size, buttonMargins(), zoomLevel); - } - break; - } - case MenulistPart: { + float zoomLevel = o->style()->effectiveZoom(); + + if (part == MenulistPart) { setPopupButtonCellState(o, r); IntSize size = popupButtonSizes()[[popupButton() controlSize]]; size.setHeight(size.height() * zoomLevel); size.setWidth(r.width()); r = inflateRect(r, size, popupButtonMargins(), zoomLevel); - break; - } - default: - break; } } @@ -535,20 +548,61 @@ IntRect RenderThemeChromiumMac::inflateRect(const IntRect& r, const IntSize& siz { // Only do the inflation if the available width/height are too small. Otherwise try to // fit the glow/check space into the available box's width/height. - int widthDelta = r.width() - (size.width() + margins[LeftMargin] * zoomLevel + margins[RightMargin] * zoomLevel); - int heightDelta = r.height() - (size.height() + margins[TopMargin] * zoomLevel + margins[BottomMargin] * zoomLevel); + int widthDelta = r.width() - (size.width() + margins[leftMargin] * zoomLevel + margins[rightMargin] * zoomLevel); + int heightDelta = r.height() - (size.height() + margins[topMargin] * zoomLevel + margins[bottomMargin] * zoomLevel); IntRect result(r); if (widthDelta < 0) { - result.setX(result.x() - margins[LeftMargin] * zoomLevel); + result.setX(result.x() - margins[leftMargin] * zoomLevel); result.setWidth(result.width() - widthDelta); } if (heightDelta < 0) { - result.setY(result.y() - margins[TopMargin] * zoomLevel); + result.setY(result.y() - margins[topMargin] * zoomLevel); result.setHeight(result.height() - heightDelta); } return result; } +FloatRect RenderThemeChromiumMac::convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const +{ + FloatRect partRect(inputRect); + + // Compute an offset between the part renderer and the input renderer + FloatSize offsetFromInputRenderer; + const RenderObject* renderer = partRenderer; + while (renderer && renderer != inputRenderer) { + RenderObject* containingRenderer = renderer->container(); + offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer); + renderer = containingRenderer; + } + // If the input renderer was not a container, something went wrong + ASSERT(renderer == inputRenderer); + // Move the rect into partRenderer's coords + partRect.move(offsetFromInputRenderer); + // Account for the local drawing offset (tx, ty) + partRect.move(r.x(), r.y()); + + return partRect; +} + +// Updates the control tint (a.k.a. active state) of |cell| (from |o|). +// In the Chromium port, the renderer runs as a background process and controls' +// NSCell(s) lack a parent NSView. Therefore controls don't have their tint +// color updated correctly when the application is activated/deactivated. +// FocusController's setActive() is called when the application is +// activated/deactivated, which causes a repaint at which time this code is +// called. +// This function should be called before drawing any NSCell-derived controls, +// unless you're sure it isn't needed. +void RenderThemeChromiumMac::updateActiveState(NSCell* cell, const RenderObject* o) +{ + NSControlTint oldTint = [cell controlTint]; + NSControlTint tint = isActive(o) ? [NSColor currentControlTint] : + NSClearControlTint; + + if (tint != oldTint) + [cell setControlTint:tint]; +} + void RenderThemeChromiumMac::updateCheckedState(NSCell* cell, const RenderObject* o) { bool oldIndeterminate = [cell state] == NSMixedState; @@ -589,19 +643,6 @@ void RenderThemeChromiumMac::updatePressedState(NSCell* cell, const RenderObject [cell setHighlighted:pressed]; } -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -int RenderThemeChromiumMac::baselinePosition(const RenderObject* o) const -{ - if (!o->isBox()) - return 0; - - if (o->style()->appearance() == CheckboxPart || o->style()->appearance() == RadioPart) { - const RenderBox* box = toRenderBox(o); - return box->marginTop() + box->height() - 2 * o->style()->effectiveZoom(); // The baseline is 2px up from the bottom of the checkbox/radio in AppKit. - } - return RenderTheme::baselinePosition(o); -} - bool RenderThemeChromiumMac::controlSupportsTints(const RenderObject* o) const { // An alternate way to implement this would be to get the appropriate cell object @@ -673,7 +714,7 @@ void RenderThemeChromiumMac::setSizeFromFont(RenderStyle* style, const IntSize* style->setHeight(Length(size.height(), Fixed)); } -void RenderThemeChromiumMac::setFontFromControlSize(CSSStyleSelector* selector, RenderStyle* style, NSControlSize controlSize) const +void RenderThemeChromiumMac::setFontFromControlSize(CSSStyleSelector*, RenderStyle* style, NSControlSize controlSize) const { FontDescription fontDescription; fontDescription.setIsAbsoluteSize(true); @@ -701,349 +742,10 @@ NSControlSize RenderThemeChromiumMac::controlSizeForSystemFont(RenderStyle* styl return NSMiniControlSize; } -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -bool RenderThemeChromiumMac::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) -{ - LocalCurrentGraphicsContext localContext(paintInfo.context); - - // Determine the width and height needed for the control and prepare the cell for painting. - setCheckboxCellState(o, r); - - paintInfo.context->save(); - - float zoomLevel = o->style()->effectiveZoom(); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - NSButtonCell* checkbox = this->checkbox(); - IntSize size = checkboxSizes()[[checkbox controlSize]]; - size.setWidth(size.width() * zoomLevel); - size.setHeight(size.height() * zoomLevel); - IntRect inflatedRect = inflateRect(r, size, checkboxMargins(), zoomLevel); - - if (zoomLevel != 1.0f) { - inflatedRect.setWidth(inflatedRect.width() / zoomLevel); - inflatedRect.setHeight(inflatedRect.height() / zoomLevel); - paintInfo.context->translate(inflatedRect.x(), inflatedRect.y()); - paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel)); - paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y()); - } - - [checkbox drawWithFrame:NSRect(IntRectToNSRect(inflatedRect)) inView:nil]; - [checkbox setControlView:nil]; - - paintInfo.context->restore(); - - return false; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const IntSize* RenderThemeChromiumMac::checkboxSizes() const -{ - static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) }; - return sizes; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const int* RenderThemeChromiumMac::checkboxMargins() const -{ - static const int margins[3][4] = - { - { 3, 4, 4, 2 }, - { 4, 3, 3, 3 }, - { 4, 3, 3, 3 }, - }; - return margins[[checkbox() controlSize]]; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setCheckboxCellState(const RenderObject* o, const IntRect& r) -{ - NSButtonCell* checkbox = this->checkbox(); - - // Set the control size based off the rectangle we're painting into. - setControlSize(checkbox, checkboxSizes(), r.size(), o->style()->effectiveZoom()); - - // Update the various states we respond to. - updateCheckedState(checkbox, o); - updateEnabledState(checkbox, o); - updatePressedState(checkbox, o); - updateFocusedState(checkbox, o); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setCheckboxSize(RenderStyle* style) const -{ - // If the width and height are both specified, then we have nothing to do. - if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) - return; - - // Use the font size to determine the intrinsic width of the control. - setSizeFromFont(style, checkboxSizes()); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -bool RenderThemeChromiumMac::paintRadio(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) -{ - LocalCurrentGraphicsContext localContext(paintInfo.context); - - // Determine the width and height needed for the control and prepare the cell for painting. - setRadioCellState(o, r); - - paintInfo.context->save(); - - float zoomLevel = o->style()->effectiveZoom(); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - NSButtonCell* radio = this->radio(); - IntSize size = radioSizes()[[radio controlSize]]; - size.setWidth(size.width() * zoomLevel); - size.setHeight(size.height() * zoomLevel); - IntRect inflatedRect = inflateRect(r, size, radioMargins(), zoomLevel); - - if (zoomLevel != 1.0f) { - inflatedRect.setWidth(inflatedRect.width() / zoomLevel); - inflatedRect.setHeight(inflatedRect.height() / zoomLevel); - paintInfo.context->translate(inflatedRect.x(), inflatedRect.y()); - paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel)); - paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y()); - } - - [radio drawWithFrame:NSRect(IntRectToNSRect(inflatedRect)) inView:nil]; - [radio setControlView:nil]; - - paintInfo.context->restore(); - - return false; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const IntSize* RenderThemeChromiumMac::radioSizes() const -{ - static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) }; - return sizes; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const int* RenderThemeChromiumMac::radioMargins() const -{ - static const int margins[3][4] = - { - { 2, 2, 4, 2 }, - { 3, 2, 3, 2 }, - { 1, 0, 2, 0 }, - }; - return margins[[radio() controlSize]]; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setRadioCellState(const RenderObject* o, const IntRect& r) -{ - NSButtonCell* radio = this->radio(); - - // Set the control size based off the rectangle we're painting into. - setControlSize(radio, radioSizes(), r.size(), o->style()->effectiveZoom()); - - // Update the various states we respond to. - updateCheckedState(radio, o); - updateEnabledState(radio, o); - updatePressedState(radio, o); - updateFocusedState(radio, o); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setRadioSize(RenderStyle* style) const -{ - // If the width and height are both specified, then we have nothing to do. - if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) - return; - - // Use the font size to determine the intrinsic width of the control. - setSizeFromFont(style, radioSizes()); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setButtonPaddingFromControlSize(RenderStyle* style, NSControlSize size) const -{ - // Just use 8px. AppKit wants to use 11px for mini buttons, but that padding is just too large - // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is - // by definition constrained, since we select mini only for small cramped environments. - // This also guarantees the HTML4 <button> will match our rendering by default, since we're using a consistent - // padding. - const int padding = 8 * style->effectiveZoom(); - style->setPaddingLeft(Length(padding, Fixed)); - style->setPaddingRight(Length(padding, Fixed)); - style->setPaddingTop(Length(0, Fixed)); - style->setPaddingBottom(Length(0, Fixed)); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const -{ - // There are three appearance constants for buttons. - // (1) Push-button is the constant for the default Aqua system button. Push buttons will not scale vertically and will not allow - // custom fonts or colors. <input>s use this constant. This button will allow custom colors and font weights/variants but won't - // scale vertically. - // (2) square-button is the constant for the square button. This button will allow custom fonts and colors and will scale vertically. - // (3) Button is the constant that means "pick the best button as appropriate." <button>s use this constant. This button will - // also scale vertically and allow custom fonts and colors. It will attempt to use Aqua if possible and will make this determination - // solely on the rectangle of the control. - - // Determine our control size based off our font. - NSControlSize controlSize = controlSizeForFont(style); - - if (style->appearance() == PushButtonPart) { - // Ditch the border. - style->resetBorder(); - - // Height is locked to auto. - style->setHeight(Length(Auto)); - - // White-space is locked to pre - style->setWhiteSpace(PRE); - - // Set the button's vertical size. - setButtonSize(style); - - // Add in the padding that we'd like to use. - setButtonPaddingFromControlSize(style, controlSize); - - // Our font is locked to the appropriate system font size for the control. To clarify, we first use the CSS-specified font to figure out - // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate - // system font for the control size instead. - setFontFromControlSize(selector, style, controlSize); - } else { - // Set a min-height so that we can't get smaller than the mini button. - style->setMinHeight(Length(static_cast<int>(15 * style->effectiveZoom()), Fixed)); - - // Reset the top and bottom borders. - style->resetBorderTop(); - style->resetBorderBottom(); - } - - style->setBoxShadow(0); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const IntSize* RenderThemeChromiumMac::buttonSizes() const -{ - static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) }; - return sizes; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const int* RenderThemeChromiumMac::buttonMargins() const -{ - static const int margins[3][4] = - { - { 4, 6, 7, 6 }, - { 4, 5, 6, 5 }, - { 0, 1, 1, 1 }, - }; - return margins[[button() controlSize]]; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setButtonSize(RenderStyle* style) const -{ - // If the width and height are both specified, then we have nothing to do. - if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) - return; - - // Use the font size to determine the intrinsic width of the control. - setSizeFromFont(style, buttonSizes()); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setButtonCellState(const RenderObject* o, const IntRect& r) -{ - NSButtonCell* button = this->button(); - - // Set the control size based off the rectangle we're painting into. - if (o->style()->appearance() == SquareButtonPart || - r.height() > buttonSizes()[NSRegularControlSize].height() * o->style()->effectiveZoom()) { - // Use the square button - if ([button bezelStyle] != NSShadowlessSquareBezelStyle) - [button setBezelStyle:NSShadowlessSquareBezelStyle]; - } else if ([button bezelStyle] != NSRoundedBezelStyle) - [button setBezelStyle:NSRoundedBezelStyle]; - - setControlSize(button, buttonSizes(), r.size(), o->style()->effectiveZoom()); - - NSWindow *window = [nil window]; - BOOL isDefaultButton = (isDefault(o) && [window isKeyWindow]); - [button setKeyEquivalent:(isDefaultButton ? @"\r" : @"")]; - - // Update the various states we respond to. - updateCheckedState(button, o); - updateEnabledState(button, o); - updatePressedState(button, o); - updateFocusedState(button, o); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -bool RenderThemeChromiumMac::paintButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) -{ - NSButtonCell* button = this->button(); - LocalCurrentGraphicsContext localContext(paintInfo.context); - - // Determine the width and height needed for the control and prepare the cell for painting. - setButtonCellState(o, r); - - paintInfo.context->save(); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the button - // shadow. We don't consider this part of the bounds of the control in WebKit. - float zoomLevel = o->style()->effectiveZoom(); - IntSize size = buttonSizes()[[button controlSize]]; - size.setWidth(r.width()); - size.setHeight(size.height() * zoomLevel); - IntRect inflatedRect = r; - if ([button bezelStyle] == NSRoundedBezelStyle) { - // Center the button within the available space. - if (inflatedRect.height() > size.height()) { - inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - size.height()) / 2); - inflatedRect.setHeight(size.height()); - } - - // Now inflate it to account for the shadow. - inflatedRect = inflateRect(inflatedRect, size, buttonMargins(), zoomLevel); - - if (zoomLevel != 1.0f) { - inflatedRect.setWidth(inflatedRect.width() / zoomLevel); - inflatedRect.setHeight(inflatedRect.height() / zoomLevel); - paintInfo.context->translate(inflatedRect.x(), inflatedRect.y()); - paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel)); - paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y()); - } - } - - NSView *view = nil; - NSWindow *window = [view window]; - NSButtonCell *previousDefaultButtonCell = [window defaultButtonCell]; - - if (isDefault(o) && [window isKeyWindow]) { - [window setDefaultButtonCell:button]; - wkAdvanceDefaultButtonPulseAnimation(button); - } else if ([previousDefaultButtonCell isEqual:button]) - [window setDefaultButtonCell:nil]; - - [button drawWithFrame:NSRect(IntRectToNSRect(inflatedRect)) inView:view]; - [button setControlView:nil]; - - if (![previousDefaultButtonCell isEqual:button]) - [window setDefaultButtonCell:previousDefaultButtonCell]; - - paintInfo.context->restore(); - - return false; -} - bool RenderThemeChromiumMac::paintTextField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawBezeledTextFieldCell(IntRectToNSRect(r), isEnabled(o) && !isReadOnlyControl(o)); + wkDrawBezeledTextFieldCell(r, isEnabled(o) && !isReadOnlyControl(o)); return false; } @@ -1051,7 +753,7 @@ void RenderThemeChromiumMac::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle { } -bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { if (paintInfo.context->paintingDisabled()) return true; @@ -1065,7 +767,7 @@ bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject* o, const Rende bool RenderThemeChromiumMac::paintTextArea(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawBezeledTextArea(IntRectToNSRect(r), isEnabled(o) && !isReadOnlyControl(o)); + wkDrawBezeledTextArea(r, isEnabled(o) && !isReadOnlyControl(o)); return false; } @@ -1103,8 +805,6 @@ const int* RenderThemeChromiumMac::popupButtonPadding(NSControlSize size) const bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - LocalCurrentGraphicsContext localContext(paintInfo.context); - setPopupButtonCellState(o, r); NSPopUpButtonCell* popupButton = this->popupButton(); @@ -1134,7 +834,7 @@ bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const RenderObject:: paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y()); } - [popupButton drawWithFrame:IntRectToNSRect(inflatedRect) inView:nil]; + [popupButton drawWithFrame:inflatedRect inView:FlippedView()]; [popupButton setControlView:nil]; paintInfo.context->restore(); @@ -1142,19 +842,19 @@ bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const RenderObject:: return false; } -static const float baseFontSize = 11.0f; -static const float baseArrowHeight = 4.0f; -static const float baseArrowWidth = 5.0f; -static const float baseSpaceBetweenArrows = 2.0f; -static const int arrowPaddingLeft = 6; -static const int arrowPaddingRight = 6; -static const int paddingBeforeSeparator = 4; -static const int baseBorderRadius = 5; -static const int styledPopupPaddingLeft = 8; -static const int styledPopupPaddingTop = 1; -static const int styledPopupPaddingBottom = 2; +const float baseFontSize = 11.0f; +const float baseArrowHeight = 4.0f; +const float baseArrowWidth = 5.0f; +const float baseSpaceBetweenArrows = 2.0f; +const int arrowPaddingLeft = 6; +const int arrowPaddingRight = 6; +const int paddingBeforeSeparator = 4; +const int baseBorderRadius = 5; +const int styledPopupPaddingLeft = 8; +const int styledPopupPaddingTop = 1; +const int styledPopupPaddingBottom = 2; -static void TopGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) +static void TopGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData) { static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.4f }; static float light[4] = { 1.0f, 1.0f, 1.0f, 0.15f }; @@ -1164,7 +864,7 @@ static void TopGradientInterpolate(void* info, const CGFloat* inData, CGFloat* o outData[i] = (1.0f - a) * dark[i] + a * light[i]; } -static void BottomGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) +static void BottomGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData) { static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.0f }; static float light[4] = { 1.0f, 1.0f, 1.0f, 0.3f }; @@ -1174,7 +874,7 @@ static void BottomGradientInterpolate(void* info, const CGFloat* inData, CGFloat outData[i] = (1.0f - a) * dark[i] + a * light[i]; } -static void MainGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) +static void MainGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData) { static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.15f }; static float light[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -1184,7 +884,7 @@ static void MainGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData[i] = (1.0f - a) * dark[i] + a * light[i]; } -static void TrackGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) +static void TrackGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData) { static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.678f }; static float light[4] = { 0.0f, 0.0f, 0.0f, 0.13f }; @@ -1196,11 +896,21 @@ static void TrackGradientInterpolate(void* info, const CGFloat* inData, CGFloat* void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { + if (r.isEmpty()) + return; + CGContextRef context = paintInfo.context->platformContext(); paintInfo.context->save(); - int radius = o->style()->borderTopLeftRadius().width(); + IntSize topLeftRadius; + IntSize topRightRadius; + IntSize bottomLeftRadius; + IntSize bottomRightRadius; + + o->style()->getBorderRadiiForRect(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); + + int radius = topLeftRadius.width(); RetainPtr<CGColorSpaceRef> cspace(AdoptCF, CGColorSpaceCreateDeviceRGB()); @@ -1223,33 +933,27 @@ void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.right(), r.y()), CGPointMake(r.right() - radius, r.y()), mainFunction.get(), false, false)); paintInfo.context->save(); CGContextClipToRect(context, r); - paintInfo.context->addRoundedRectClip(r, - o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), - o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); + paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); CGContextDrawShading(context, mainShading.get()); paintInfo.context->restore(); paintInfo.context->save(); CGContextClipToRect(context, topGradient); - paintInfo.context->addRoundedRectClip(enclosingIntRect(topGradient), - o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), - IntSize(), IntSize()); + paintInfo.context->addRoundedRectClip(enclosingIntRect(topGradient), topLeftRadius, topRightRadius, IntSize(), IntSize()); CGContextDrawShading(context, topShading.get()); paintInfo.context->restore(); - paintInfo.context->save(); - CGContextClipToRect(context, bottomGradient); - paintInfo.context->addRoundedRectClip(enclosingIntRect(bottomGradient), - IntSize(), IntSize(), - o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); - CGContextDrawShading(context, bottomShading.get()); - paintInfo.context->restore(); + if (!bottomGradient.isEmpty()) { + paintInfo.context->save(); + CGContextClipToRect(context, bottomGradient); + paintInfo.context->addRoundedRectClip(enclosingIntRect(bottomGradient), IntSize(), IntSize(), bottomLeftRadius, bottomRightRadius); + CGContextDrawShading(context, bottomShading.get()); + paintInfo.context->restore(); + } paintInfo.context->save(); CGContextClipToRect(context, r); - paintInfo.context->addRoundedRectClip(r, - o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), - o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); + paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); CGContextDrawShading(context, leftShading.get()); CGContextDrawShading(context, rightShading.get()); paintInfo.context->restore(); @@ -1259,8 +963,6 @@ void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - paintInfo.context->save(); - IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(), r.y() + o->style()->borderTopWidth(), r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(), @@ -1279,6 +981,8 @@ bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const RenderOb if (bounds.width() < arrowWidth + arrowPaddingLeft * o->style()->effectiveZoom()) return false; + paintInfo.context->save(); + paintInfo.context->setFillColor(o->style()->color()); paintInfo.context->setStrokeStyle(NoStroke); @@ -1357,7 +1061,7 @@ void RenderThemeChromiumMac::adjustMenuListStyle(CSSStyleSelector* selector, Ren int RenderThemeChromiumMac::popupInternalPaddingLeft(RenderStyle* style) const { if (style->appearance() == MenulistPart) - return popupButtonPadding(controlSizeForFont(style))[LeftPadding] * style->effectiveZoom(); + return popupButtonPadding(controlSizeForFont(style))[leftPadding] * style->effectiveZoom(); if (style->appearance() == MenulistButtonPart) return styledPopupPaddingLeft * style->effectiveZoom(); return 0; @@ -1366,7 +1070,7 @@ int RenderThemeChromiumMac::popupInternalPaddingLeft(RenderStyle* style) const int RenderThemeChromiumMac::popupInternalPaddingRight(RenderStyle* style) const { if (style->appearance() == MenulistPart) - return popupButtonPadding(controlSizeForFont(style))[RightPadding] * style->effectiveZoom(); + return popupButtonPadding(controlSizeForFont(style))[rightPadding] * style->effectiveZoom(); if (style->appearance() == MenulistButtonPart) { float fontScale = style->fontSize() / baseFontSize; float arrowWidth = baseArrowWidth * fontScale; @@ -1378,7 +1082,7 @@ int RenderThemeChromiumMac::popupInternalPaddingRight(RenderStyle* style) const int RenderThemeChromiumMac::popupInternalPaddingTop(RenderStyle* style) const { if (style->appearance() == MenulistPart) - return popupButtonPadding(controlSizeForFont(style))[TopPadding] * style->effectiveZoom(); + return popupButtonPadding(controlSizeForFont(style))[topPadding] * style->effectiveZoom(); if (style->appearance() == MenulistButtonPart) return styledPopupPaddingTop * style->effectiveZoom(); return 0; @@ -1387,13 +1091,13 @@ int RenderThemeChromiumMac::popupInternalPaddingTop(RenderStyle* style) const int RenderThemeChromiumMac::popupInternalPaddingBottom(RenderStyle* style) const { if (style->appearance() == MenulistPart) - return popupButtonPadding(controlSizeForFont(style))[BottomPadding] * style->effectiveZoom(); + return popupButtonPadding(controlSizeForFont(style))[bottomPadding] * style->effectiveZoom(); if (style->appearance() == MenulistButtonPart) return styledPopupPaddingBottom * style->effectiveZoom(); return 0; } -void RenderThemeChromiumMac::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { float fontScale = style->fontSize() / baseFontSize; @@ -1414,6 +1118,7 @@ void RenderThemeChromiumMac::setPopupButtonCellState(const RenderObject* o, cons setControlSize(popupButton, popupButtonSizes(), r.size(), o->style()->effectiveZoom()); // Update the various states we respond to. + updateActiveState(popupButton, o); updateCheckedState(popupButton, o); updateEnabledState(popupButton, o); updatePressedState(popupButton, o); @@ -1431,16 +1136,16 @@ int RenderThemeChromiumMac::minimumMenuListSize(RenderStyle* style) const return sizeForSystemFont(style, menuListSizes()).width(); } -static const int trackWidth = 5; -static const int trackRadius = 2; - -void RenderThemeChromiumMac::adjustSliderTrackStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { style->setBoxShadow(0); } bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { + static const int trackWidth = 5; + static const int trackRadius = 2; + IntRect bounds = r; float zoomLevel = o->style()->effectiveZoom(); float zoomedTrackWidth = trackWidth * zoomLevel; @@ -1478,12 +1183,12 @@ bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const RenderObjec return false; } -void RenderThemeChromiumMac::adjustSliderThumbStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { style->setBoxShadow(0); } -static const float verticalSliderHeightPadding = 0.1f; +const float verticalSliderHeightPadding = 0.1f; bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { @@ -1496,6 +1201,7 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObjec LocalCurrentGraphicsContext localContext(paintInfo.context); // Update the various states we respond to. + updateActiveState(sliderThumbCell, o); updateEnabledState(sliderThumbCell, o->parent()); updateFocusedState(sliderThumbCell, o->parent()); @@ -1506,7 +1212,7 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObjec else oldPressed = m_isSliderThumbHorizontalPressed; - bool pressed = static_cast<RenderSlider*>(o->parent())->inDragMode(); + bool pressed = toRenderSlider(o->parent())->inDragMode(); if (o->style()->appearance() == SliderThumbVerticalPart) m_isSliderThumbVerticalPressed = pressed; @@ -1537,7 +1243,7 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObjec paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y()); } - [sliderThumbCell drawWithFrame:FloatRectToNSRect(unzoomedRect) inView:nil]; + [sliderThumbCell drawWithFrame:unzoomedRect inView:FlippedView()]; [sliderThumbCell setControlView:nil]; paintInfo.context->restore(); @@ -1545,21 +1251,20 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObjec return false; } -const int sliderThumbWidth = 15; -const int sliderThumbHeight = 15; -const int mediaSliderThumbWidth = 13; -const int mediaSliderThumbHeight = 14; - void RenderThemeChromiumMac::adjustSliderThumbSize(RenderObject* o) const { + static const int sliderThumbWidth = 15; + static const int sliderThumbHeight = 15; + float zoomLevel = o->style()->effectiveZoom(); if (o->style()->appearance() == SliderThumbHorizontalPart || o->style()->appearance() == SliderThumbVerticalPart) { o->style()->setWidth(Length(static_cast<int>(sliderThumbWidth * zoomLevel), Fixed)); o->style()->setHeight(Length(static_cast<int>(sliderThumbHeight * zoomLevel), Fixed)); - } else if (o->style()->appearance() == MediaSliderThumbPart) { - o->style()->setWidth(Length(mediaSliderThumbWidth, Fixed)); - o->style()->setHeight(Length(mediaSliderThumbHeight, Fixed)); } + +#if ENABLE(VIDEO) + RenderMediaControlsChromium::adjustMediaSliderThumbSize(o); +#endif } bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) @@ -1586,7 +1291,7 @@ bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const RenderObjec // Set the search button to nil before drawing. Then reset it so we can draw it later. [search setSearchButtonCell:nil]; - [search drawWithFrame:NSRect(IntRectToNSRect(unzoomedRect)) inView:nil]; + [search drawWithFrame:NSRect(unzoomedRect) inView:FlippedView()]; #ifdef BUILDING_ON_TIGER if ([search showsFirstResponder]) wkDrawTextFieldCellFocusRing(search, NSRect(unzoomedRect)); @@ -1600,13 +1305,14 @@ bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const RenderObjec return false; } -void RenderThemeChromiumMac::setSearchCellState(RenderObject* o, const IntRect& r) +void RenderThemeChromiumMac::setSearchCellState(RenderObject* o, const IntRect&) { NSSearchFieldCell* search = this->search(); [search setControlSize:controlSizeForFont(o->style())]; // Update the various states we respond to. + updateActiveState(search, o); updateEnabledState(search, o); updateFocusedState(search, o); } @@ -1627,7 +1333,7 @@ void RenderThemeChromiumMac::setSearchFieldSize(RenderStyle* style) const setSizeFromFont(style, searchFieldSizes()); } -void RenderThemeChromiumMac::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element*) const { // Override border. style->resetBorder(); @@ -1660,22 +1366,25 @@ void RenderThemeChromiumMac::adjustSearchFieldStyle(CSSStyleSelector* selector, bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - LocalCurrentGraphicsContext localContext(paintInfo.context); - Node* input = o->node()->shadowAncestorNode(); + if (!input->renderer()->isBox()) + return false; + setSearchCellState(input->renderer(), r); NSSearchFieldCell* search = this->search(); + updateActiveState([search cancelButtonCell], o); updatePressedState([search cancelButtonCell], o); paintInfo.context->save(); float zoomLevel = o->style()->effectiveZoom(); - NSRect bounds = [search cancelButtonRectForBounds:NSRect(IntRectToNSRect(input->renderer()->absoluteBoundingBoxRect()))]; - - IntRect unzoomedRect(NSRectToIntRect(bounds)); + FloatRect localBounds = [search cancelButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())]; + localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r); + + FloatRect unzoomedRect(localBounds); if (zoomLevel != 1.0f) { unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel); unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel); @@ -1684,7 +1393,7 @@ bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y()); } - [[search cancelButtonCell] drawWithFrame:IntRectToNSRect(unzoomedRect) inView:nil]; + [[search cancelButtonCell] drawWithFrame:unzoomedRect inView:FlippedView()]; [[search cancelButtonCell] setControlView:nil]; paintInfo.context->restore(); @@ -1697,7 +1406,7 @@ const IntSize* RenderThemeChromiumMac::cancelButtonSizes() const return sizes; } -void RenderThemeChromiumMac::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { IntSize size = sizeForSystemFont(style, cancelButtonSizes()); style->setWidth(Length(size.width(), Fixed)); @@ -1711,8 +1420,8 @@ const IntSize* RenderThemeChromiumMac::resultsButtonSizes() const return sizes; } -static const int emptyResultsOffset = 9; -void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +const int emptyResultsOffset = 9; +void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { IntSize size = sizeForSystemFont(style, resultsButtonSizes()); style->setWidth(Length(size.width() - emptyResultsOffset, Fixed)); @@ -1720,12 +1429,12 @@ void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(CSSStyleSelector* style->setBoxShadow(0); } -bool RenderThemeChromiumMac::paintSearchFieldDecoration(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return false; } -void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { IntSize size = sizeForSystemFont(style, resultsButtonSizes()); style->setWidth(Length(size.width(), Fixed)); @@ -1735,24 +1444,29 @@ void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(CSSStyleSel bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - LocalCurrentGraphicsContext localContext(paintInfo.context); - Node* input = o->node()->shadowAncestorNode(); + if (!input->renderer()->isBox()) + return false; + setSearchCellState(input->renderer(), r); NSSearchFieldCell* search = this->search(); + updateActiveState([search searchButtonCell], o); + if ([search searchMenuTemplate] != nil) [search setSearchMenuTemplate:nil]; - NSRect bounds = [search searchButtonRectForBounds:NSRect(IntRectToNSRect(input->renderer()->absoluteBoundingBoxRect()))]; - [[search searchButtonCell] drawWithFrame:bounds inView:nil]; + FloatRect localBounds = [search searchButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())]; + localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r); + + [[search searchButtonCell] drawWithFrame:localBounds inView:FlippedView()]; [[search searchButtonCell] setControlView:nil]; return false; } -static const int resultsArrowWidth = 5; -void RenderThemeChromiumMac::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +const int resultsArrowWidth = 5; +void RenderThemeChromiumMac::adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { IntSize size = sizeForSystemFont(style, resultsButtonSizes()); style->setWidth(Length(size.width() + resultsArrowWidth, Fixed)); @@ -1762,13 +1476,16 @@ void RenderThemeChromiumMac::adjustSearchFieldResultsButtonStyle(CSSStyleSelecto bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - LocalCurrentGraphicsContext localContext(paintInfo.context); - Node* input = o->node()->shadowAncestorNode(); + if (!input->renderer()->isBox()) + return false; + setSearchCellState(input->renderer(), r); NSSearchFieldCell* search = this->search(); + updateActiveState([search searchButtonCell], o); + if (![search searchMenuTemplate]) [search setSearchMenuTemplate:searchMenuTemplate()]; @@ -1776,9 +1493,10 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, cons float zoomLevel = o->style()->effectiveZoom(); - NSRect bounds = [search searchButtonRectForBounds:NSRect(IntRectToNSRect(input->renderer()->absoluteBoundingBoxRect()))]; + FloatRect localBounds = [search searchButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())]; + localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r); - IntRect unzoomedRect(NSRectToIntRect(bounds)); + IntRect unzoomedRect(localBounds); if (zoomLevel != 1.0f) { unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel); unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel); @@ -1787,7 +1505,7 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, cons paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y()); } - [[search searchButtonCell] drawWithFrame:IntRectToNSRect(unzoomedRect) inView:nil]; + [[search searchButtonCell] drawWithFrame:unzoomedRect inView:FlippedView()]; [[search searchButtonCell] setControlView:nil]; paintInfo.context->restore(); @@ -1796,179 +1514,53 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, cons } #if ENABLE(VIDEO) -// FIXME: This enum is lifted from RenderThemeMac.mm We need to decide which theme to use for the default controls, or decide to avoid wkDrawMediaUIPart and render our own. -typedef enum { - MediaControllerThemeClassic = 1, - MediaControllerThemeQT = 2 -} MediaControllerThemeStyle; - -enum WKMediaControllerThemeState { - MediaUIPartDisabledFlag = 1 << 0, - MediaUIPartPressedFlag = 1 << 1, - MediaUIPartDrawEndCapsFlag = 1 << 3, -}; -#endif - -bool RenderThemeChromiumMac::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::shouldRenderMediaControlPart(ControlPart part, Element* e) { -#if ENABLE(VIDEO) - Node* node = o->node(); - if (!node) - return false; - - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(MediaFullscreenButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + return RenderMediaControlsChromium::shouldRenderMediaControlPart(part, e); } -bool RenderThemeChromiumMac::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaPlayButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - Node* mediaNode = node ? node->shadowAncestorNode() : 0; - if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag))) - return false; - - HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode); - if (!mediaElement) - return false; - - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(mediaElement->muted() ? MediaUnMuteButton : MediaMuteButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + return RenderMediaControlsChromium::paintMediaControlsPart(MediaPlayButton, object, paintInfo, rect); } -bool RenderThemeChromiumMac::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaMuteButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - Node* mediaNode = node ? node->shadowAncestorNode() : 0; - if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag))) - return false; - - HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode); - if (!mediaElement) - return false; - - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(mediaElement->canPlay() ? MediaPlayButton : MediaPauseButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + return RenderMediaControlsChromium::paintMediaControlsPart(MediaMuteButton, object, paintInfo, rect); } -bool RenderThemeChromiumMac::paintMediaSeekBackButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaSliderTrack(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - if (!node) - return false; - - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(MediaSeekBackButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + return RenderMediaControlsChromium::paintMediaControlsPart(MediaSlider, object, paintInfo, rect); } -bool RenderThemeChromiumMac::paintMediaSeekForwardButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaVolumeSliderTrack(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - if (!node) - return false; - - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(MediaSeekForwardButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSlider, object, paintInfo, rect); } -bool RenderThemeChromiumMac::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - Node* mediaNode = node ? node->shadowAncestorNode() : 0; - if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag))) - return false; - - HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode); - if (!mediaElement) - return false; - - float timeLoaded = 0; - float currentTime = 0; - float duration = 0; - if (MediaPlayer* player = mediaElement->player()) { - duration = player->duration(); - timeLoaded = player->maxTimeBuffered(); - currentTime = player->currentTime(); - } - - bool shouldDrawEndCaps = !static_cast<RenderMedia*>(mediaElement->renderer())->shouldShowTimeDisplayControls(); - wkDrawMediaSliderTrack(MediaControllerThemeClassic, paintInfo.context->platformContext(), r, timeLoaded, currentTime, duration, shouldDrawEndCaps ? MediaUIPartDrawEndCapsFlag : 0); -#endif - return false; + return RenderMediaControlsChromium::paintMediaControlsPart(MediaSliderThumb, object, paintInfo, rect); } -bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaVolumeSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - if (!node) - return false; - - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(MediaSliderThumb, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSliderThumb, object, paintInfo, rect); } -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -NSButtonCell* RenderThemeChromiumMac::checkbox() const +bool RenderThemeChromiumMac::paintMediaControlsBackground(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { - if (!m_checkbox) { - m_checkbox.adoptNS([[NSButtonCell alloc] init]); - [m_checkbox.get() setButtonType:NSSwitchButton]; - [m_checkbox.get() setTitle:nil]; - [m_checkbox.get() setAllowsMixedState:YES]; - [m_checkbox.get() setFocusRingType:NSFocusRingTypeExterior]; - } - - return m_checkbox.get(); + return RenderMediaControlsChromium::paintMediaControlsPart(MediaTimelineContainer, object, paintInfo, rect); } - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -NSButtonCell* RenderThemeChromiumMac::radio() const -{ - if (!m_radio) { - m_radio.adoptNS([[NSButtonCell alloc] init]); - [m_radio.get() setButtonType:NSRadioButton]; - [m_radio.get() setTitle:nil]; - [m_radio.get() setFocusRingType:NSFocusRingTypeExterior]; - } - return m_radio.get(); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -NSButtonCell* RenderThemeChromiumMac::button() const +String RenderThemeChromiumMac::extraMediaControlsStyleSheet() { - if (!m_button) { - m_button.adoptNS([[NSButtonCell alloc] init]); - [m_button.get() setTitle:nil]; - [m_button.get() setButtonType:NSMomentaryPushInButton]; - } - - return m_button.get(); + return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet)); } +#endif + NSPopUpButtonCell* RenderThemeChromiumMac::popupButton() const { if (!m_popupButton) { diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp index 95ffd0293..fb42bb7af 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp @@ -33,8 +33,11 @@ #include "MediaControlElements.h" #include "PlatformContextSkia.h" #include "RenderBox.h" +#include "RenderMediaControlsChromium.h" #include "RenderObject.h" +#include "RenderSlider.h" #include "ScrollbarTheme.h" +#include "TimeRanges.h" #include "TransformationMatrix.h" #include "UserAgentStyleSheets.h" @@ -52,10 +55,6 @@ enum PaddingType { static const int styledMenuListInternalPadding[4] = { 1, 4, 1, 4 }; -// The background for the media player controls should be a 60% opaque black rectangle. This -// matches the UI mockups for the default UI theme. -static const float defaultMediaControlOpacity = 0.6f; - // These values all match Safari/Win. static const float defaultControlFontPixelSize = 13; static const float defaultCancelButtonSize = 9; @@ -74,19 +73,29 @@ static void setSizeIfAuto(RenderStyle* style, const IntSize& size) style->setHeight(Length(size.height(), Fixed)); } -#if ENABLE(VIDEO) -// Attempt to retrieve a HTMLMediaElement from a Node. Returns NULL if one cannot be found. -static HTMLMediaElement* mediaElementParent(Node* node) +static void drawVertLine(SkCanvas* canvas, int x, int y1, int y2, const SkPaint& paint) { - if (!node) - return 0; - Node* mediaNode = node->shadowAncestorNode(); - if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag))) - return 0; + SkIRect skrect; + skrect.set(x, y1, x + 1, y2 + 1); + canvas->drawIRect(skrect, paint); +} - return static_cast<HTMLMediaElement*>(mediaNode); +static void drawHorizLine(SkCanvas* canvas, int x1, int x2, int y, const SkPaint& paint) +{ + SkIRect skrect; + skrect.set(x1, y, x2 + 1, y + 1); + canvas->drawIRect(skrect, paint); +} + +static void drawBox(SkCanvas* canvas, const IntRect& rect, const SkPaint& paint) +{ + const int right = rect.x() + rect.width() - 1; + const int bottom = rect.y() + rect.height() - 1; + drawHorizLine(canvas, rect.x(), right, rect.y(), paint); + drawVertLine(canvas, right, rect.y(), bottom, paint); + drawHorizLine(canvas, rect.x(), right, bottom, paint); + drawVertLine(canvas, rect.x(), rect.y(), bottom, paint); } -#endif // We aim to match IE here. // -IE uses a font based on the encoding as the default font for form controls. @@ -306,7 +315,7 @@ static void paintButtonLike(RenderTheme* theme, RenderObject* o, const RenderObj canvas->drawLine(rect.x() + 1, bottom - 1, right - 1, bottom - 1, paint); canvas->drawLine(rect.x(), rect.y() + 1, rect.x(), bottom - 1, paint); - paint.setARGB(0xff, 0, 0, 0); + paint.setColor(SK_ColorBLACK); SkPoint p[2]; const int lightEnd = theme->isPressed(o) ? 1 : 0; const int darkEnd = !lightEnd; @@ -464,60 +473,95 @@ bool RenderThemeChromiumSkia::paintSearchFieldResultsButton(RenderObject* o, con return false; } -bool RenderThemeChromiumSkia::paintMediaButtonInternal(GraphicsContext* context, const IntRect& rect, Image* image) +bool RenderThemeChromiumSkia::paintMediaControlsBackground(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { - context->beginTransparencyLayer(defaultMediaControlOpacity); - - // Draw background. - Color oldFill = context->fillColor(); - Color oldStroke = context->strokeColor(); - - context->setFillColor(Color::black); - context->setStrokeColor(Color::black); - context->drawRect(rect); - - context->setFillColor(oldFill); - context->setStrokeColor(oldStroke); - - // Create a destination rectangle for the image that is centered in the drawing rectangle, rounded left, and down. - IntRect imageRect = image->rect(); - imageRect.setY(rect.y() + (rect.height() - image->height() + 1) / 2); - imageRect.setX(rect.x() + (rect.width() - image->width() + 1) / 2); - - context->drawImage(image, imageRect, CompositeSourceAtop); - context->endTransparencyLayer(); +#if ENABLE(VIDEO) + return RenderMediaControlsChromium::paintMediaControlsPart(MediaTimelineContainer, object, paintInfo, rect); +#else + UNUSED_PARAM(object); + UNUSED_PARAM(paintInfo); + UNUSED_PARAM(rect); + return false; +#endif +} +bool RenderThemeChromiumSkia::paintMediaSliderTrack(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ +#if ENABLE(VIDEO) + return RenderMediaControlsChromium::paintMediaControlsPart(MediaSlider, object, paintInfo, rect); +#else + UNUSED_PARAM(object); + UNUSED_PARAM(paintInfo); + UNUSED_PARAM(rect); return false; +#endif } -bool RenderThemeChromiumSkia::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeChromiumSkia::paintMediaVolumeSliderTrack(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { #if ENABLE(VIDEO) - HTMLMediaElement* mediaElement = mediaElementParent(o->node()); - if (!mediaElement) - return false; + return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSlider, object, paintInfo, rect); +#else + UNUSED_PARAM(object); + UNUSED_PARAM(paintInfo); + UNUSED_PARAM(rect); + return false; +#endif +} - static Image* mediaPlay = Image::loadPlatformResource("mediaPlay").releaseRef(); - static Image* mediaPause = Image::loadPlatformResource("mediaPause").releaseRef(); +void RenderThemeChromiumSkia::adjustSliderThumbSize(RenderObject* object) const +{ +#if ENABLE(VIDEO) + RenderMediaControlsChromium::adjustMediaSliderThumbSize(object); +#else + UNUSED_PARAM(object); +#endif +} - return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->paused() ? mediaPlay : mediaPause); +bool RenderThemeChromiumSkia::paintMediaSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ +#if ENABLE(VIDEO) + return RenderMediaControlsChromium::paintMediaControlsPart(MediaSliderThumb, object, paintInfo, rect); #else + UNUSED_PARAM(object); + UNUSED_PARAM(paintInfo); + UNUSED_PARAM(rect); return false; #endif } -bool RenderThemeChromiumSkia::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeChromiumSkia::paintMediaVolumeSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { #if ENABLE(VIDEO) - HTMLMediaElement* mediaElement = mediaElementParent(o->node()); - if (!mediaElement) - return false; + return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSliderThumb, object, paintInfo, rect); +#else + UNUSED_PARAM(object); + UNUSED_PARAM(paintInfo); + UNUSED_PARAM(rect); + return false; +#endif +} - static Image* soundFull = Image::loadPlatformResource("mediaSoundFull").releaseRef(); - static Image* soundNone = Image::loadPlatformResource("mediaSoundNone").releaseRef(); +bool RenderThemeChromiumSkia::paintMediaPlayButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ +#if ENABLE(VIDEO) + return RenderMediaControlsChromium::paintMediaControlsPart(MediaPlayButton, object, paintInfo, rect); +#else + UNUSED_PARAM(object); + UNUSED_PARAM(paintInfo); + UNUSED_PARAM(rect); + return false; +#endif +} - return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->muted() ? soundNone: soundFull); +bool RenderThemeChromiumSkia::paintMediaMuteButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ +#if ENABLE(VIDEO) + return RenderMediaControlsChromium::paintMediaControlsPart(MediaMuteButton, object, paintInfo, rect); #else + UNUSED_PARAM(object); + UNUSED_PARAM(paintInfo); + UNUSED_PARAM(rect); return false; #endif } @@ -537,12 +581,13 @@ bool RenderThemeChromiumSkia::paintMenuList(RenderObject* o, const RenderObject: paintButtonLike(this, o, i, rect); SkPaint paint; - paint.setARGB(0xff, 0, 0, 0); + paint.setColor(SK_ColorBLACK); paint.setAntiAlias(true); paint.setStyle(SkPaint::kFill_Style); + int arrowXPosition = (o->style()->direction() == RTL) ? rect.x() + 7 : right - 13; SkPath path; - path.moveTo(right - 13, middle - 3); + path.moveTo(arrowXPosition, middle - 3); path.rLineTo(6, 0); path.rLineTo(-3, 6); path.close(); @@ -562,6 +607,69 @@ bool RenderThemeChromiumSkia::paintMenuListButton(RenderObject* o, const RenderO return paintMenuList(o, i, rect); } +bool RenderThemeChromiumSkia::paintSliderTrack(RenderObject*, const RenderObject::PaintInfo& i, const IntRect& rect) +{ + // Just paint a grey box for now (matches the color of a scrollbar background. + SkCanvas* const canvas = i.context->platformContext()->canvas(); + int verticalCenter = rect.y() + rect.height() / 2; + int top = std::max(rect.y(), verticalCenter - 2); + int bottom = std::min(rect.y() + rect.height(), verticalCenter + 2); + + SkPaint paint; + const SkColor grey = SkColorSetARGB(0xff, 0xe3, 0xdd, 0xd8); + paint.setColor(grey); + + SkRect skrect; + skrect.set(rect.x(), top, rect.x() + rect.width(), bottom); + canvas->drawRect(skrect, paint); + + return false; +} + +bool RenderThemeChromiumSkia::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +{ + // Make a thumb similar to the scrollbar thumb. + const bool hovered = isHovered(o) || toRenderSlider(o->parent())->inDragMode(); + const int midx = rect.x() + rect.width() / 2; + const int midy = rect.y() + rect.height() / 2; + const bool vertical = (o->style()->appearance() == SliderThumbVerticalPart); + SkCanvas* const canvas = i.context->platformContext()->canvas(); + + const SkColor thumbLightGrey = SkColorSetARGB(0xff, 0xf4, 0xf2, 0xef); + const SkColor thumbDarkGrey = SkColorSetARGB(0xff, 0xea, 0xe5, 0xe0); + SkPaint paint; + paint.setColor(hovered ? SK_ColorWHITE : thumbLightGrey); + + SkIRect skrect; + if (vertical) + skrect.set(rect.x(), rect.y(), midx + 1, rect.bottom()); + else + skrect.set(rect.x(), rect.y(), rect.right(), midy + 1); + + canvas->drawIRect(skrect, paint); + + paint.setColor(hovered ? thumbLightGrey : thumbDarkGrey); + + if (vertical) + skrect.set(midx + 1, rect.y(), rect.right(), rect.bottom()); + else + skrect.set(rect.x(), midy + 1, rect.right(), rect.bottom()); + + canvas->drawIRect(skrect, paint); + + const SkColor borderDarkGrey = SkColorSetARGB(0xff, 0x9d, 0x96, 0x8e); + paint.setColor(borderDarkGrey); + drawBox(canvas, rect, paint); + + if (rect.height() > 10 && rect.width() > 10) { + drawHorizLine(canvas, midx - 2, midx + 2, midy, paint); + drawHorizLine(canvas, midx - 2, midx + 2, midy - 3, paint); + drawHorizLine(canvas, midx - 2, midx + 2, midy + 3, paint); + } + + return false; +} + int RenderThemeChromiumSkia::popupInternalPaddingLeft(RenderStyle* style) const { return menuListInternalPadding(style, LeftPadding); @@ -602,6 +710,13 @@ int RenderThemeChromiumSkia::buttonInternalPaddingBottom() const return 1; } +#if ENABLE(VIDEO) +bool RenderThemeChromiumSkia::shouldRenderMediaControlPart(ControlPart part, Element* e) +{ + return RenderMediaControlsChromium::shouldRenderMediaControlPart(part, e); +} +#endif + // static void RenderThemeChromiumSkia::setDefaultFontSize(int fontSize) { diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h index 8be64e57f..98e3a3557 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h @@ -89,6 +89,12 @@ namespace WebCore { virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaControlsBackground(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustSliderThumbSize(RenderObject*) const; + virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); @@ -106,6 +112,9 @@ namespace WebCore { virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + // These methods define the padding for the MenuList's inner block. virtual int popupInternalPaddingLeft(RenderStyle*) const; virtual int popupInternalPaddingRight(RenderStyle*) const; @@ -117,6 +126,11 @@ namespace WebCore { virtual int buttonInternalPaddingTop() const; virtual int buttonInternalPaddingBottom() const; +#if ENABLE(VIDEO) + // Media controls + virtual bool shouldRenderMediaControlPart(ControlPart, Element*); +#endif + // Provide a way to pass the default font size from the Settings object // to the render theme. FIXME: http://b/1129186 A cleaner way would be // to remove the default font size from this object and have callers diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp index 8459144e9..4b38d53e7 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp @@ -311,18 +311,65 @@ void RenderThemeChromiumWin::systemFont(int propId, FontDescription& fontDescrip fontDescription = *cachedDesc; } +// Map a CSSValue* system color to an index understood by GetSysColor(). +static int cssValueIdToSysColorIndex(int cssValueId) +{ + switch (cssValueId) { + case CSSValueActiveborder: return COLOR_ACTIVEBORDER; + case CSSValueActivecaption: return COLOR_ACTIVECAPTION; + case CSSValueAppworkspace: return COLOR_APPWORKSPACE; + case CSSValueBackground: return COLOR_BACKGROUND; + case CSSValueButtonface: return COLOR_BTNFACE; + case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT; + case CSSValueButtonshadow: return COLOR_BTNSHADOW; + case CSSValueButtontext: return COLOR_BTNTEXT; + case CSSValueCaptiontext: return COLOR_CAPTIONTEXT; + case CSSValueGraytext: return COLOR_GRAYTEXT; + case CSSValueHighlight: return COLOR_HIGHLIGHT; + case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT; + case CSSValueInactiveborder: return COLOR_INACTIVEBORDER; + case CSSValueInactivecaption: return COLOR_INACTIVECAPTION; + case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT; + case CSSValueInfobackground: return COLOR_INFOBK; + case CSSValueInfotext: return COLOR_INFOTEXT; + case CSSValueMenu: return COLOR_MENU; + case CSSValueMenutext: return COLOR_MENUTEXT; + case CSSValueScrollbar: return COLOR_SCROLLBAR; + case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW; + case CSSValueThreedface: return COLOR_3DFACE; + case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT; + case CSSValueThreedlightshadow: return COLOR_3DLIGHT; + case CSSValueThreedshadow: return COLOR_3DSHADOW; + case CSSValueWindow: return COLOR_WINDOW; + case CSSValueWindowframe: return COLOR_WINDOWFRAME; + case CSSValueWindowtext: return COLOR_WINDOWTEXT; + default: return -1; // Unsupported CSSValue + } +} + +Color RenderThemeChromiumWin::systemColor(int cssValueId) const +{ + int sysColorIndex = cssValueIdToSysColorIndex(cssValueId); + if (ChromiumBridge::layoutTestMode() || (sysColorIndex == -1)) + return RenderTheme::systemColor(cssValueId); + + COLORREF color = GetSysColor(sysColorIndex); + return Color(GetRValue(color), GetGValue(color), GetBValue(color)); +} + void RenderThemeChromiumWin::adjustSliderThumbSize(RenderObject* o) const { // These sizes match what WinXP draws for various menus. const int sliderThumbAlongAxis = 11; const int sliderThumbAcrossAxis = 21; - if (o->style()->appearance() == SliderThumbHorizontalPart || o->style()->appearance() == MediaSliderThumbPart) { + if (o->style()->appearance() == SliderThumbHorizontalPart) { o->style()->setWidth(Length(sliderThumbAlongAxis, Fixed)); o->style()->setHeight(Length(sliderThumbAcrossAxis, Fixed)); } else if (o->style()->appearance() == SliderThumbVerticalPart) { o->style()->setWidth(Length(sliderThumbAcrossAxis, Fixed)); o->style()->setHeight(Length(sliderThumbAlongAxis, Fixed)); - } + } else + RenderThemeChromiumSkia::adjustSliderThumbSize(o); } bool RenderThemeChromiumWin::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) @@ -464,7 +511,7 @@ unsigned RenderThemeChromiumWin::determineSliderThumbState(RenderObject* o) result = TUS_DISABLED; else if (supportsFocus(o->style()->appearance()) && isFocused(o->parent())) result = TUS_FOCUSED; - else if (static_cast<RenderSlider*>(o->parent())->inDragMode()) + else if (toRenderSlider(o->parent())->inDragMode()) result = TUS_PRESSED; else if (isHovered(o)) result = TUS_HOT; @@ -474,14 +521,36 @@ unsigned RenderThemeChromiumWin::determineSliderThumbState(RenderObject* o) unsigned RenderThemeChromiumWin::determineClassicState(RenderObject* o) { unsigned result = 0; - if (!isEnabled(o)) - result = DFCS_INACTIVE; - else if (isPressed(o)) // Active supersedes hover - result = DFCS_PUSHED; - else if (isHovered(o)) - result = DFCS_HOT; - if (isChecked(o)) - result |= DFCS_CHECKED; + + ControlPart part = o->style()->appearance(); + + // Sliders are always in the normal state. + if (part == SliderHorizontalPart || part == SliderVerticalPart) + return result; + + // So are readonly text fields. + if (isReadOnlyControl(o) && (part == TextFieldPart || part == TextAreaPart || part == SearchFieldPart)) + return result; + + if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) { + if (!isEnabled(o->parent())) + result = DFCS_INACTIVE; + else if (toRenderSlider(o->parent())->inDragMode()) // Active supersedes hover + result = DFCS_PUSHED; + else if (isHovered(o)) + result = DFCS_HOT; + } else { + if (!isEnabled(o)) + result = DFCS_INACTIVE; + else if (isPressed(o)) // Active supersedes hover + result = DFCS_PUSHED; + else if (supportsFocus(part) && isFocused(o)) // So does focused + result = 0; + else if (isHovered(o)) + result = DFCS_HOT; + if (isChecked(o)) + result |= DFCS_CHECKED; + } return result; } @@ -523,6 +592,7 @@ ThemeData RenderThemeChromiumWin::getThemeData(RenderObject* o) break; case ListboxPart: case MenulistPart: + case MenulistButtonPart: case SearchFieldPart: case TextFieldPart: case TextAreaPart: @@ -541,21 +611,11 @@ bool RenderThemeChromiumWin::paintTextFieldInternal(RenderObject* o, const IntRect& r, bool drawEdges) { - // Nasty hack to make us not paint the border on text fields with a - // border-radius. Webkit paints elements with border-radius for us. - // FIXME: Get rid of this if-check once we can properly clip rounded - // borders: http://b/1112604 and http://b/1108635 - // FIXME: make sure we do the right thing if css background-clip is set. - if (o->style()->hasBorderRadius()) - return false; - - const ThemeData& themeData = getThemeData(o); - // Fallback to white if the specified color object is invalid. + // (Note ChromiumBridge::paintTextField duplicates this check). Color backgroundColor(Color::white); - if (o->style()->backgroundColor().isValid()) { + if (o->style()->backgroundColor().isValid()) backgroundColor = o->style()->backgroundColor(); - } // If we have background-image, don't fill the content area to expose the // parent's background. Also, we shouldn't fill the content area if the @@ -564,17 +624,32 @@ bool RenderThemeChromiumWin::paintTextFieldInternal(RenderObject* o, // Note that we should paint the content area white if we have neither the // background color nor background image explicitly specified to keep the // appearance of select element consistent with other browsers. - bool fillContentArea = !o->style()->hasBackgroundImage() && backgroundColor.alpha() != 0; - - WebCore::ThemePainter painter(i.context, r); - ChromiumBridge::paintTextField(painter.context(), - themeData.m_part, - themeData.m_state, - themeData.m_classicState, - painter.drawRect(), - backgroundColor, - fillContentArea, - drawEdges); + bool fillContentArea = !o->style()->hasBackgroundImage() && backgroundColor.alpha(); + + if (o->style()->hasBorderRadius()) { + // If the style has rounded borders, setup the context to clip the + // background (themed or filled) appropriately. + // FIXME: make sure we do the right thing if css background-clip is set. + i.context->save(); + IntSize topLeft, topRight, bottomLeft, bottomRight; + o->style()->getBorderRadiiForRect(r, topLeft, topRight, bottomLeft, bottomRight); + i.context->addRoundedRectClip(r, topLeft, topRight, bottomLeft, bottomRight); + } + { + const ThemeData& themeData = getThemeData(o); + WebCore::ThemePainter painter(i.context, r); + ChromiumBridge::paintTextField(painter.context(), + themeData.m_part, + themeData.m_state, + themeData.m_classicState, + painter.drawRect(), + backgroundColor, + fillContentArea, + drawEdges); + // End of block commits the painter before restoring context. + } + if (o->style()->hasBorderRadius()) + i.context->restore(); return false; } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h index 5e98c9bd9..bbc54a720 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h @@ -59,6 +59,7 @@ namespace WebCore { // System fonts. virtual void systemFont(int propId, FontDescription&) const; + virtual Color systemColor(int cssValueId) const; virtual void adjustSliderThumbSize(RenderObject*) const; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h index 85f141f60..1d68c630c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h @@ -132,6 +132,8 @@ protected: // Media controls virtual String extraMediaControlsStyleSheet(); + + virtual bool shouldRenderMediaControlPart(ControlPart, Element*); #endif private: diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp index 05facef97..2ea3b8bea 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. + * Copyright (C) 2007, 2008, 2009 Apple Inc. * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or @@ -86,7 +86,7 @@ PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) return safariTheme; // keep the reference of one. } -#if !defined(NDEBUG) && defined(USE_DEBUG_SAFARI_THEME) +#ifdef DEBUG_ALL SOFT_LINK_DEBUG_LIBRARY(SafariTheme) #else SOFT_LINK_LIBRARY(SafariTheme) @@ -744,11 +744,21 @@ static void TrackGradientInterpolate(void* info, const CGFloat* inData, CGFloat* void RenderThemeSafari::paintMenuListButtonGradients(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { + if (r.isEmpty()) + return; + CGContextRef context = paintInfo.context->platformContext(); paintInfo.context->save(); - int radius = o->style()->borderTopLeftRadius().width(); + IntSize topLeftRadius; + IntSize topRightRadius; + IntSize bottomLeftRadius; + IntSize bottomRightRadius; + + o->style()->getBorderRadiiForRect(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); + + int radius = topLeftRadius.width(); RetainPtr<CGColorSpaceRef> cspace(AdoptCF, CGColorSpaceCreateDeviceRGB()); @@ -771,33 +781,27 @@ void RenderThemeSafari::paintMenuListButtonGradients(RenderObject* o, const Rend RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.right(), r.y()), CGPointMake(r.right() - radius, r.y()), mainFunction.get(), false, false)); paintInfo.context->save(); CGContextClipToRect(context, r); - paintInfo.context->addRoundedRectClip(r, - o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), - o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); + paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); CGContextDrawShading(context, mainShading.get()); paintInfo.context->restore(); paintInfo.context->save(); CGContextClipToRect(context, topGradient); - paintInfo.context->addRoundedRectClip(enclosingIntRect(topGradient), - o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), - IntSize(), IntSize()); + paintInfo.context->addRoundedRectClip(enclosingIntRect(topGradient), topLeftRadius, topRightRadius, IntSize(), IntSize()); CGContextDrawShading(context, topShading.get()); paintInfo.context->restore(); - paintInfo.context->save(); - CGContextClipToRect(context, bottomGradient); - paintInfo.context->addRoundedRectClip(enclosingIntRect(bottomGradient), - IntSize(), IntSize(), - o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); - CGContextDrawShading(context, bottomShading.get()); - paintInfo.context->restore(); + if (!bottomGradient.isEmpty()) { + paintInfo.context->save(); + CGContextClipToRect(context, bottomGradient); + paintInfo.context->addRoundedRectClip(enclosingIntRect(bottomGradient), IntSize(), IntSize(), bottomLeftRadius, bottomRightRadius); + CGContextDrawShading(context, bottomShading.get()); + paintInfo.context->restore(); + } paintInfo.context->save(); CGContextClipToRect(context, r); - paintInfo.context->addRoundedRectClip(r, - o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), - o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); + paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); CGContextDrawShading(context, leftShading.get()); CGContextDrawShading(context, rightShading.get()); paintInfo.context->restore(); @@ -807,8 +811,6 @@ void RenderThemeSafari::paintMenuListButtonGradients(RenderObject* o, const Rend bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - paintInfo.context->save(); - IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(), r.y() + o->style()->borderTopWidth(), r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(), @@ -826,6 +828,8 @@ bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const RenderObject: if (bounds.width() < arrowWidth + arrowPaddingLeft) return false; + paintInfo.context->save(); + paintInfo.context->setFillColor(o->style()->color()); paintInfo.context->setStrokeColor(NoStroke); @@ -1000,7 +1004,7 @@ bool RenderThemeSafari::paintSliderThumb(RenderObject* o, const RenderObject::Pa ASSERT(o->parent()->isSlider()); - bool pressed = static_cast<RenderSlider*>(o->parent())->inDragMode(); + bool pressed = toRenderSlider(o->parent())->inDragMode(); ThemeControlState state = determineState(o->parent()); state &= ~SafariTheme::PressedState; if (pressed) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp index 9491aaeb5..92bfd0358 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp @@ -428,7 +428,7 @@ unsigned RenderThemeWin::determineSliderThumbState(RenderObject* o) result = TUS_DISABLED; else if (supportsFocus(o->style()->appearance()) && isFocused(o->parent())) result = TUS_FOCUSED; - else if (static_cast<RenderSlider*>(o->parent())->inDragMode()) + else if (toRenderSlider(o->parent())->inDragMode()) result = TUS_PRESSED; else if (isHovered(o)) result = TUS_HOT; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.cpp index 79d172406..b7ab191d7 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.cpp @@ -28,6 +28,7 @@ #include "CSSMutableStyleDeclaration.h" #include "CharacterNames.h" +#include "CString.h" #include "Document.h" #include "Frame.h" #include "FrameView.h" @@ -204,14 +205,14 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o) // FIXME: Deliberately dump the "inner" box of table cells, since that is what current results reflect. We'd like // to clean up the results to dump both the outer box and the intrinsic padding so that both bits of information are // captured by the results. - const RenderTableCell& cell = static_cast<const RenderTableCell&>(o); + const RenderTableCell& cell = *toRenderTableCell(&o); r = IntRect(cell.x(), cell.y() + cell.intrinsicPaddingTop(), cell.width(), cell.height() - cell.intrinsicPaddingTop() - cell.intrinsicPaddingBottom()); } else if (o.isBox()) r = toRenderBox(&o)->frameRect(); // FIXME: Temporary in order to ensure compatibility with existing layout test results. if (adjustForTableCells) - r.move(0, -static_cast<RenderTableCell*>(o.containingBlock())->intrinsicPaddingTop()); + r.move(0, -toRenderTableCell(o.containingBlock())->intrinsicPaddingTop()); ts << " " << r; @@ -307,12 +308,12 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o) } if (o.isTableCell()) { - const RenderTableCell& c = static_cast<const RenderTableCell&>(o); + const RenderTableCell& c = *toRenderTableCell(&o); ts << " [r=" << c.row() << " c=" << c.col() << " rs=" << c.rowSpan() << " cs=" << c.colSpan() << "]"; } if (o.isListMarker()) { - String text = static_cast<const RenderListMarker&>(o).text(); + String text = toRenderListMarker(&o)->text(); if (!text.isEmpty()) { if (text.length() != 1) text = quoteAndEscapeNonPrintables(text); @@ -343,7 +344,7 @@ static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBo // FIXME: Table cell adjustment is temporary until results can be updated. int y = run.m_y; if (o.containingBlock()->isTableCell()) - y -= static_cast<RenderTableCell*>(o.containingBlock())->intrinsicPaddingTop(); + y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingTop(); ts << "text run at (" << run.m_x << "," << y << ") width " << run.m_width; if (run.direction() == RTL || run.m_dirOverride) { ts << (run.direction() == RTL ? " RTL" : " LTR"); @@ -359,26 +360,26 @@ void write(TextStream& ts, const RenderObject& o, int indent) { #if ENABLE(SVG) if (o.isRenderPath()) { - write(ts, static_cast<const RenderPath&>(o), indent); + write(ts, *toRenderPath(&o), indent); return; } if (o.isSVGContainer()) { - write(ts, static_cast<const RenderSVGContainer&>(o), indent); + writeSVGContainer(ts, o, indent); return; } if (o.isSVGRoot()) { - write(ts, static_cast<const RenderSVGRoot&>(o), indent); + write(ts, *toRenderSVGRoot(&o), indent); return; } if (o.isSVGText()) { if (!o.isText()) - write(ts, static_cast<const RenderSVGText&>(o), indent); + writeSVGText(ts, *toRenderBlock(&o), indent); else - write(ts, static_cast<const RenderSVGInlineText&>(o), indent); + writeSVGInlineText(ts, *toRenderText(&o), indent); return; } if (o.isSVGImage()) { - write(ts, static_cast<const RenderSVGImage&>(o), indent); + writeSVGImage(ts, *toRenderImage(&o), indent); return; } #endif @@ -402,7 +403,7 @@ void write(TextStream& ts, const RenderObject& o, int indent) } if (o.isWidget()) { - Widget* widget = static_cast<const RenderWidget&>(o).widget(); + Widget* widget = toRenderWidget(&o)->widget(); if (widget && widget->isFrameView()) { FrameView* view = static_cast<FrameView*>(widget); RenderView* root = view->frame()->contentRenderer(); @@ -553,4 +554,31 @@ String externalRepresentation(RenderObject* o) return ts.release(); } +static void writeCounterValuesFromChildren(TextStream& stream, RenderObject* parent) +{ + for (RenderObject* child = parent->firstChild(); child; child = child->nextSibling()) { + if (child->isCounter()) { + String str(toRenderText(child)->text()); + stream << str; + } + } +} + +String counterValueForElement(Element* element) +{ + // Make sure the element is not freed during the layout. + RefPtr<Element> elementRef(element); + element->document()->updateLayout(); + TextStream stream; + // The counter renderers should be children of anonymous children + // (i.e., :before or :after pseudo-elements). + if (RenderObject* renderer = element->renderer()) { + for (RenderObject* child = renderer->firstChild(); child; child = child->nextSibling()) { + if (child->isAnonymous()) + writeCounterValuesFromChildren(stream, child); + } + } + return stream.release(); +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.h b/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.h index daca25379..325f10947 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.h @@ -28,15 +28,18 @@ namespace WebCore { - class RenderObject; - class String; - class TextStream; +class Element; +class RenderObject; +class String; +class TextStream; - String externalRepresentation(RenderObject*); - void write(TextStream&, const RenderObject&, int indent = 0); +String externalRepresentation(RenderObject*); +void write(TextStream&, const RenderObject&, int indent = 0); - // Helper function shared with SVGRenderTreeAsText - String quoteAndEscapeNonPrintables(const String&); +// Helper function shared with SVGRenderTreeAsText +String quoteAndEscapeNonPrintables(const String&); + +String counterValueForElement(Element*); } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h index 1c7b25964..79e5b4e3c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -42,12 +42,26 @@ public: RenderVideo(HTMLMediaElement*); virtual ~RenderVideo(); + void videoSizeChanged(); + IntRect videoBox() const; + +#if USE(ACCELERATED_COMPOSITING) + bool supportsAcceleratedRendering() const; + void acceleratedRenderingStateChanged(); + GraphicsLayer* videoGraphicsLayer() const; +#endif + +private: + virtual void updateFromElement(); + + virtual void intrinsicSizeChanged() { videoSizeChanged(); } + virtual const char* renderName() const { return "RenderVideo"; } virtual bool requiresLayer() const { return true; } virtual bool isVideo() const { return true; } - virtual void paintReplaced(PaintInfo& paintInfo, int tx, int ty); + virtual void paintReplaced(PaintInfo&, int tx, int ty); virtual void layout(); @@ -56,21 +70,6 @@ public: virtual void calcPrefWidths(); - void videoSizeChanged(); - IntRect videoBox() const; - - void updateFromElement(); - -#if USE(ACCELERATED_COMPOSITING) - bool supportsAcceleratedRendering() const; - virtual void acceleratedRenderingStateChanged(); - GraphicsLayer* videoGraphicsLayer() const; -#endif - -protected: - virtual void intrinsicSizeChanged() { videoSizeChanged(); } - -private: int calcAspectRatioWidth() const; int calcAspectRatioHeight() const; @@ -80,6 +79,15 @@ private: void updatePlayer(); }; +inline RenderVideo* toRenderVideo(RenderObject* object) +{ + ASSERT(!object || object->isVideo()); + return static_cast<RenderVideo*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderVideo(const RenderVideo*); + } // namespace WebCore #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderView.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderView.cpp index 3b8a4fb59..e2b4b045f 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderView.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderView.cpp @@ -121,12 +121,10 @@ void RenderView::layout() if (needsLayout()) RenderBlock::layout(); - // Reset overflowWidth and overflowHeight, since they act as a lower bound for docWidth() and docHeight(). - setOverflowWidth(width()); - setOverflowHeight(height()); - - setOverflowWidth(docWidth()); - setOverflowHeight(docHeight()); + // Reset overflow and then replace it with docWidth and docHeight. + m_overflow.clear(); + addLayoutOverflow(IntRect(0, 0, docWidth(), docHeight())); + ASSERT(layoutDelta() == IntSize()); ASSERT(m_layoutStateDisableCount == 0); @@ -460,6 +458,8 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e return; } + m_frameView->beginDeferredRepaints(); + // Have any of the old selected objects changed compared to the new selection? for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) { RenderObject* obj = i->first; @@ -511,6 +511,8 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e newInfo->repaint(); delete newInfo; } + + m_frameView->endDeferredRepaints(); } void RenderView::clearSelection() diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderView.h b/src/3rdparty/webkit/WebCore/rendering/RenderView.h index 854a4214d..bc5db9e64 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderView.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderView.h @@ -205,16 +205,16 @@ private: #endif }; -inline RenderView* toRenderView(RenderObject* o) +inline RenderView* toRenderView(RenderObject* object) { - ASSERT(!o || o->isRenderView()); - return static_cast<RenderView*>(o); + ASSERT(!object || object->isRenderView()); + return static_cast<RenderView*>(object); } -inline const RenderView* toRenderView(const RenderObject* o) +inline const RenderView* toRenderView(const RenderObject* object) { - ASSERT(!o || o->isRenderView()); - return static_cast<const RenderView*>(o); + ASSERT(!object || object->isRenderView()); + return static_cast<const RenderView*>(object); } // This will catch anyone doing an unnecessary cast. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp index 16526ca49..9af7137fa 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp @@ -28,6 +28,7 @@ #include "GraphicsContext.h" #include "HitTestResult.h" #include "RenderView.h" +#include "RenderWidgetProtector.h" using namespace std; @@ -60,6 +61,15 @@ void RenderWidget::destroy() // So the code below includes copied and pasted contents of // both RenderBox::destroy() and RenderObject::destroy(). // Fix originally made for <rdar://problem/4228818>. + + // <rdar://problem/6937089> suggests that node() can be null by the time we call renderArena() + // in the end of this function. One way this might happen is if this function was invoked twice + // in a row, so bail out and turn a crash into an assertion failure in debug builds and a leak + // in release builds. + ASSERT(node()); + if (!node()) + return; + animation()->cancelAnimations(this); if (RenderView* v = view()) @@ -90,6 +100,14 @@ void RenderWidget::destroy() destroyLayer(); } + // <rdar://problem/6937089> suggests that node() can be null here. One way this might happen is + // if this function was re-entered (and therefore the null check at the beginning did not fail), + // so bail out and turn a crash into an assertion failure in debug builds and a leak in release + // builds. + ASSERT(node()); + if (!node()) + return; + // Grab the arena from node()->document()->renderArena() before clearing the node pointer. // Clear the node before deref-ing, as this may be deleted when deref is called. RenderArena* arena = renderArena(); @@ -106,10 +124,9 @@ RenderWidget::~RenderWidget() void RenderWidget::setWidgetGeometry(const IntRect& frame) { if (node() && m_widget->frameRect() != frame) { - RenderArena* arena = ref(); - RefPtr<Node> protectedElement(node()); + RenderWidgetProtector protector(this); + RefPtr<Node> protectedNode(node()); m_widget->setFrameRect(frame); - deref(arena); } } @@ -158,6 +175,12 @@ void RenderWidget::styleDidChange(StyleDifference diff, const RenderStyle* oldSt } } +void RenderWidget::showSubstituteImage(PassRefPtr<Image> prpImage) +{ + m_substituteImage = prpImage; + repaint(); +} + void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty) { if (!shouldPaint(paintInfo, tx, ty)) @@ -183,11 +206,15 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty) #endif if (style()->hasBorderRadius()) { + IntRect borderRect = IntRect(tx, ty, width(), height()); + + if (borderRect.isEmpty()) + return; + // Push a clip if we have a border radius, since we want to round the foreground content that gets painted. paintInfo.context->save(); IntSize topLeft, topRight, bottomLeft, bottomRight; - IntRect borderRect = IntRect(tx, ty, width(), height()); style()->getBorderRadiiForRect(borderRect, topLeft, topRight, bottomLeft, bottomRight); paintInfo.context->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight); @@ -201,7 +228,10 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty) // Tell the widget to paint now. This is the only time the widget is allowed // to paint itself. That way it will composite properly with z-indexed layers. - m_widget->paint(paintInfo.context, paintInfo.rect); + if (m_substituteImage) + paintInfo.context->drawImage(m_substituteImage.get(), m_widget->frameRect()); + else + m_widget->paint(paintInfo.context, paintInfo.rect); if (m_widget->isFrameView() && paintInfo.overlapTestRequests && !static_cast<FrameView*>(m_widget.get())->useSlowRepaints()) { ASSERT(!paintInfo.overlapTestRequests->contains(this)); @@ -248,11 +278,9 @@ void RenderWidget::updateWidgetPosition() IntRect oldBounds(m_widget->frameRect()); bool boundsChanged = newBounds != oldBounds; if (boundsChanged) { - RenderArena* arena = ref(); - node()->ref(); + RenderWidgetProtector protector(this); + RefPtr<Node> protectedNode(node()); m_widget->setFrameRect(newBounds); - node()->deref(); - deref(arena); } // if the frame bounds got changed, or if view needs layout (possibly indicating diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.h b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.h index 97d0b722e..78537fdfa 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.h @@ -40,6 +40,8 @@ public: void updateWidgetPosition(); + void showSubstituteImage(PassRefPtr<Image>); + protected: RenderWidget(Node*); @@ -61,14 +63,31 @@ private: void setWidgetGeometry(const IntRect&); + friend class RenderWidgetProtector; RenderArena* ref() { ++m_refCount; return renderArena(); } void deref(RenderArena*); RefPtr<Widget> m_widget; + RefPtr<Image> m_substituteImage; FrameView* m_frameView; int m_refCount; }; +inline RenderWidget* toRenderWidget(RenderObject* object) +{ + ASSERT(!object || object->isWidget()); + return static_cast<RenderWidget*>(object); +} + +inline const RenderWidget* toRenderWidget(const RenderObject* object) +{ + ASSERT(!object || object->isWidget()); + return static_cast<const RenderWidget*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderWidget(const RenderWidget*); + } // namespace WebCore #endif // RenderWidget_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderWidgetProtector.h b/src/3rdparty/webkit/WebCore/rendering/RenderWidgetProtector.h new file mode 100644 index 000000000..788304cf3 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/rendering/RenderWidgetProtector.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RenderWidgetProtector_h +#define RenderWidgetProtector_h + +#include "RenderWidget.h" + +namespace WebCore { + +class RenderWidgetProtector : private Noncopyable { +public: + RenderWidgetProtector(RenderWidget* object) + : m_object(object) + , m_arena(object->ref()) + { + } + + ~RenderWidgetProtector() + { + m_object->deref(m_arena); + } + +private: + RenderWidget* m_object; + RenderArena* m_arena; +}; + +} + +#endif // RenderWidgetProtector_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.cpp index e8f04da7b..c8e072ea7 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.cpp @@ -38,28 +38,8 @@ namespace WebCore { typedef WTF::HashMap<const RootInlineBox*, EllipsisBox*> EllipsisBoxMap; static EllipsisBoxMap* gEllipsisBoxMap = 0; -void* RootInlineBox::Overflow::operator new(size_t sz, RenderArena* renderArena) throw() -{ - return renderArena->allocate(sz); -} - -void RootInlineBox::Overflow::operator delete(void* ptr, size_t sz) -{ - // Stash size where destroy can find it. - *(size_t *)ptr = sz; -} - -void RootInlineBox::Overflow::destroy(RenderArena* renderArena) -{ - delete this; - // Recover the size left there for us by operator delete and free the memory. - renderArena->free(*(size_t *)this, this); -} - void RootInlineBox::destroy(RenderArena* arena) { - if (m_overflow) - m_overflow->destroy(arena); detachEllipsisBox(arena); InlineFlowBox::destroy(arena); } @@ -155,8 +135,8 @@ void RootInlineBox::addHighlightOverflow() // Highlight acts as a selection inflation. FloatRect rootRect(0, selectionTop(), width(), selectionHeight()); IntRect inflatedRect = enclosingIntRect(page->chrome()->client()->customHighlightRect(renderer()->node(), renderer()->style()->highlight(), rootRect)); - setHorizontalOverflowPositions(min(leftOverflow(), inflatedRect.x()), max(rightOverflow(), inflatedRect.right())); - setVerticalOverflowPositions(min(topOverflow(), inflatedRect.y()), max(bottomOverflow(), inflatedRect.bottom())); + setHorizontalOverflowPositions(leftLayoutOverflow(), rightLayoutOverflow(), min(leftVisualOverflow(), inflatedRect.x()), max(rightVisualOverflow(), inflatedRect.right())); + setVerticalOverflowPositions(topLayoutOverflow(), bottomLayoutOverflow(), min(topVisualOverflow(), inflatedRect.y()), max(bottomVisualOverflow(), inflatedRect.bottom()), height()); } void RootInlineBox::paintCustomHighlight(RenderObject::PaintInfo& paintInfo, int tx, int ty, const AtomicString& highlightType) @@ -205,12 +185,8 @@ bool RootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re void RootInlineBox::adjustPosition(int dx, int dy) { InlineFlowBox::adjustPosition(dx, dy); - if (m_overflow) { - m_overflow->m_topOverflow += dy; - m_overflow->m_bottomOverflow += dy; - m_overflow->m_selectionTop += dy; - m_overflow->m_selectionBottom += dy; - } + m_lineTop += dy; + m_lineBottom += dy; m_blockHeight += dy; } @@ -225,6 +201,37 @@ void RootInlineBox::childRemoved(InlineBox* box) } } +int RootInlineBox::verticallyAlignBoxes(int heightOfBlock) +{ + int maxPositionTop = 0; + int maxPositionBottom = 0; + int maxAscent = 0; + int maxDescent = 0; + + // Figure out if we're in strict mode. Note that we can't simply use !style()->htmlHacks(), + // because that would match almost strict mode as well. + RenderObject* curr = renderer(); + while (curr && !curr->node()) + curr = curr->container(); + bool strictMode = (curr && curr->document()->inStrictMode()); + + computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode); + + if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom)) + adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom); + + int maxHeight = maxAscent + maxDescent; + int lineTop = heightOfBlock; + int lineBottom = heightOfBlock; + placeBoxesVertically(heightOfBlock, maxHeight, maxAscent, strictMode, lineTop, lineBottom); + computeVerticalOverflow(lineTop, lineBottom, strictMode); + setLineTopBottomPositions(lineTop, lineBottom); + + heightOfBlock += maxHeight; + + return heightOfBlock; +} + GapRects RootInlineBox::fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, const RenderObject::PaintInfo* paintInfo) { @@ -321,9 +328,9 @@ InlineBox* RootInlineBox::lastSelectedBox() return 0; } -int RootInlineBox::selectionTop() +int RootInlineBox::selectionTop() const { - int selectionTop = m_overflow ? m_overflow->m_selectionTop : m_y; + int selectionTop = m_lineTop; if (!prevRootBox()) return selectionTop; @@ -407,18 +414,6 @@ EllipsisBox* RootInlineBox::ellipsisBox() const return gEllipsisBoxMap->get(this); } -void RootInlineBox::setVerticalOverflowPositions(int top, int bottom) -{ - if (!m_overflow) { - const Font& font = renderer()->style(m_firstLine)->font(); - if (top == m_y && bottom == m_y + font.height()) - return; - m_overflow = new (renderer()->renderArena()) Overflow(this); - } - m_overflow->m_topOverflow = top; - m_overflow->m_bottomOverflow = bottom; -} - void RootInlineBox::removeLineBoxFromRenderObject() { block()->lineBoxes()->removeLineBox(this); diff --git a/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.h b/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.h index 171be9d1d..b0b0e15da 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.h +++ b/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.h @@ -38,31 +38,33 @@ class RootInlineBox : public InlineFlowBox { public: RootInlineBox(RenderObject* obj) : InlineFlowBox(obj) - , m_overflow(0) , m_lineBreakObj(0) , m_lineBreakPos(0) + , m_lineTop(0) + , m_lineBottom(0) { } + virtual void destroy(RenderArena*); + virtual bool isRootInlineBox() const { return true; } - virtual void destroy(RenderArena*); void detachEllipsisBox(RenderArena*); - RootInlineBox* nextRootBox() { return static_cast<RootInlineBox*>(m_nextLine); } - RootInlineBox* prevRootBox() { return static_cast<RootInlineBox*>(m_prevLine); } + RootInlineBox* nextRootBox() const { return static_cast<RootInlineBox*>(m_nextLine); } + RootInlineBox* prevRootBox() const { return static_cast<RootInlineBox*>(m_prevLine); } virtual void adjustPosition(int dx, int dy); - virtual int topOverflow() const { return m_overflow ? m_overflow->m_topOverflow : m_y; } - virtual int bottomOverflow() const { return m_overflow ? m_overflow->m_bottomOverflow : m_y + m_renderer->style(m_firstLine)->font().height(); } - virtual int leftOverflow() const { return m_overflow ? m_overflow->m_leftOverflow : m_x; } - virtual int rightOverflow() const { return m_overflow ? m_overflow->m_rightOverflow : m_x + m_width; } + int lineTop() const { return m_lineTop; } + int lineBottom() const { return m_lineBottom; } - virtual void setVerticalOverflowPositions(int top, int bottom); - void setHorizontalOverflowPositions(int left, int right); + int selectionTop() const; + int selectionBottom() const { return lineBottom(); } + int selectionHeight() const { return max(0, selectionBottom() - selectionTop()); } - virtual void setVerticalSelectionPositions(int top, int bottom); + virtual int verticallyAlignBoxes(int heightOfBlock); + void setLineTopBottomPositions(int top, int bottom); virtual RenderLineBoxList* rendererLineBoxes() const; @@ -116,68 +118,36 @@ public: RenderBlock* block() const; - int selectionTop(); - int selectionBottom() { return m_overflow ? m_overflow->m_selectionBottom : m_y + height(); } - int selectionHeight() { return max(0, selectionBottom() - selectionTop()); } - InlineBox* closestLeafChildForXPos(int x, bool onlyEditableLeaves = false); Vector<RenderBox*>& floats() { ASSERT(!isDirty()); - if (!m_overflow) - m_overflow = new (m_renderer->renderArena()) Overflow(this); - return m_overflow->floats; + if (!m_floats) + m_floats.set(new Vector<RenderBox*>()); + return *m_floats; } - Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_overflow ? &m_overflow->floats : 0; } + Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_floats.get(); } virtual void extractLineBoxFromRenderObject(); virtual void attachLineBoxToRenderObject(); virtual void removeLineBoxFromRenderObject(); protected: - // Normally we are only as tall as the style on our block dictates, but we might have content - // that spills out above the height of our font (e.g, a tall image), or something that extends further - // below our line (e.g., a child whose font has a huge descent). - - // Allocated only when some of these fields have non-default values - struct Overflow { - Overflow(RootInlineBox* box) - : m_topOverflow(box->m_y) - , m_bottomOverflow(box->m_y + box->height()) - , m_leftOverflow(box->m_x) - , m_rightOverflow(box->m_x + box->m_width) - , m_selectionTop(box->m_y) - , m_selectionBottom(box->m_y + box->height()) - { - } - - void destroy(RenderArena*); - void* operator new(size_t, RenderArena*) throw(); - void operator delete(void*, size_t); - - int m_topOverflow; - int m_bottomOverflow; - int m_leftOverflow; - int m_rightOverflow; - int m_selectionTop; - int m_selectionBottom; - // Floats hanging off the line are pushed into this vector during layout. It is only - // good for as long as the line has not been marked dirty. - Vector<RenderBox*> floats; - private: - void* operator new(size_t) throw(); - }; - - Overflow* m_overflow; - // Where this line ended. The exact object and the position within that object are stored so that // we can create an InlineIterator beginning just after the end of this line. RenderObject* m_lineBreakObj; unsigned m_lineBreakPos; RefPtr<BidiContext> m_lineBreakContext; + int m_lineTop; + int m_lineBottom; + + // Floats hanging off the line are pushed into this vector during layout. It is only + // good for as long as the line has not been marked dirty. + OwnPtr<Vector<RenderBox*> > m_floats; + // The height of the block at the end of this line. This is where the next line starts. int m_blockHeight; @@ -186,27 +156,10 @@ protected: WTF::Unicode::Direction m_lineBreakBidiStatusLast : 5; }; -inline void RootInlineBox::setHorizontalOverflowPositions(int left, int right) -{ - if (!m_overflow) { - if (left == m_x && right == m_x + m_width) - return; - m_overflow = new (m_renderer->renderArena()) Overflow(this); - } - m_overflow->m_leftOverflow = left; - m_overflow->m_rightOverflow = right; -} - -inline void RootInlineBox::setVerticalSelectionPositions(int top, int bottom) +inline void RootInlineBox::setLineTopBottomPositions(int top, int bottom) { - if (!m_overflow) { - const Font& font = m_renderer->style(m_firstLine)->font(); - if (top == m_y && bottom == m_y + font.height()) - return; - m_overflow = new (m_renderer->renderArena()) Overflow(this); - } - m_overflow->m_selectionTop = top; - m_overflow->m_selectionBottom = bottom; + m_lineTop = top; + m_lineBottom = bottom; } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.cpp index b53e3d951..900e0baed 100644 --- a/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.cpp @@ -274,7 +274,7 @@ void SVGCharacterLayoutInfo::addLayoutInformation(InlineFlowBox* flowBox, float angleStack.isEmpty() && baselineShiftStack.isEmpty() && curx == 0.0f && cury == 0.0f; - RenderSVGTextPath* textPath = static_cast<RenderSVGTextPath*>(flowBox->renderer()); + RenderSVGTextPath* textPath = toRenderSVGTextPath(flowBox->renderer()); Path path = textPath->layoutPath(); float baselineShift = calculateBaselineShift(textPath); diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp index f3f2b8cba..ea087f903 100644 --- a/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp @@ -94,6 +94,9 @@ void SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject paintInfo.context->beginTransparencyLayer(opacity); } + if (ShadowData* shadow = svgStyle->shadow()) + paintInfo.context->setShadow(IntSize(shadow->x, shadow->y), shadow->blur, shadow->color); + #if ENABLE(FILTERS) AtomicString filterId(svgStyle->filter()); #endif @@ -169,9 +172,11 @@ void renderSubtreeToImage(ImageBuffer* image, RenderObject* item) ASSERT(image->context()); RenderObject::PaintInfo info(image->context(), IntRect(), PaintPhaseForeground, 0, 0, 0); + // FIXME: isSVGContainer returns true for RenderSVGViewportContainer, so if this is ever + // called with one of those, we will read from the wrong offset in an object due to a bad cast. RenderSVGContainer* svgContainer = 0; if (item && item->isSVGContainer()) - svgContainer = static_cast<RenderSVGContainer*>(item); + svgContainer = toRenderSVGContainer(item); bool drawsContents = svgContainer ? svgContainer->drawsContents() : false; if (svgContainer && !drawsContents) @@ -218,7 +223,7 @@ FloatRect SVGRenderBase::filterBoundingBoxForRenderer(const RenderObject* object #if ENABLE(FILTERS) SVGResourceFilter* filter = getFilterById(object->document(), object->style()->svgStyle()->filter()); if (filter) - return filter->filterBBoxForItemBBox(object->objectBoundingBox()); + return filter->filterBoundingBox(); #else UNUSED_PARAM(object); #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.cpp index cc5e4b855..28e506ad9 100644 --- a/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2007, 2009 Apple Inc. All rights reserved. * (C) 2005 Rob Buis <buis@kde.org> * (C) 2006 Alexander Kellett <lypanov@kde.org> * @@ -31,15 +31,15 @@ #include "SVGRenderTreeAsText.h" #include "GraphicsTypes.h" -#include "InlineTextBox.h" #include "HTMLNames.h" +#include "InlineTextBox.h" #include "NodeRenderStyle.h" +#include "RenderImage.h" #include "RenderPath.h" #include "RenderSVGContainer.h" -#include "RenderSVGImage.h" #include "RenderSVGInlineText.h" -#include "RenderSVGText.h" #include "RenderSVGRoot.h" +#include "RenderSVGText.h" #include "RenderTreeAsText.h" #include "SVGCharacterLayoutInfo.h" #include "SVGInlineTextBox.h" @@ -322,35 +322,23 @@ static TextStream& operator<<(TextStream& ts, const RenderPath& path) return ts; } -static TextStream& operator<<(TextStream& ts, const RenderSVGContainer& container) -{ - return writePositionAndStyle(ts, container); -} - static TextStream& operator<<(TextStream& ts, const RenderSVGRoot& root) { return writePositionAndStyle(ts, root); } -static TextStream& operator<<(TextStream& ts, const RenderSVGImage& root) -{ - return writePositionAndStyle(ts, root); -} - -static TextStream& operator<<(TextStream& ts, const RenderSVGText& text) +static void writeRenderSVGTextBox(TextStream& ts, const RenderBlock& text) { SVGRootInlineBox* box = static_cast<SVGRootInlineBox*>(text.firstRootBox()); if (!box) - return ts; + return; Vector<SVGTextChunk>& chunks = const_cast<Vector<SVGTextChunk>& >(box->svgTextChunks()); ts << " at (" << text.x() << "," << text.y() << ") size " << box->width() << "x" << box->height() << " contains " << chunks.size() << " chunk(s)"; if (text.parent() && (text.parent()->style()->color() != text.style()->color())) writeNameValuePair(ts, "color", text.style()->color().name()); - - return ts; } static inline bool containsInlineTextBox(SVGTextChunk& chunk, SVGInlineTextBox* box) @@ -455,7 +443,7 @@ static inline void writeSVGInlineTextBox(TextStream& ts, SVGInlineTextBox* textB } } -static inline void writeSVGInlineText(TextStream& ts, const RenderSVGInlineText& text, int indent) +static inline void writeSVGInlineTextBoxes(TextStream& ts, const RenderText& text, int indent) { for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) writeSVGInlineTextBox(ts, static_cast<SVGInlineTextBox*>(box), indent); @@ -476,10 +464,11 @@ static void writeChildren(TextStream& ts, const RenderObject& object, int indent write(ts, *child, indent + 1); } -void write(TextStream& ts, const RenderSVGContainer& container, int indent) +void writeSVGContainer(TextStream& ts, const RenderObject& container, int indent) { writeStandardPrefix(ts, container, indent); - ts << container << "\n"; + writePositionAndStyle(ts, container); + ts << "\n"; writeChildren(ts, container, indent); } @@ -490,20 +479,21 @@ void write(TextStream& ts, const RenderSVGRoot& root, int indent) writeChildren(ts, root, indent); } -void write(TextStream& ts, const RenderSVGText& text, int indent) +void writeSVGText(TextStream& ts, const RenderBlock& text, int indent) { writeStandardPrefix(ts, text, indent); - ts << text << "\n"; + writeRenderSVGTextBox(ts, text); + ts << "\n"; writeChildren(ts, text, indent); } -void write(TextStream& ts, const RenderSVGInlineText& text, int indent) +void writeSVGInlineText(TextStream& ts, const RenderText& text, int indent) { writeStandardPrefix(ts, text, indent); // Why not just linesBoundingBox()? ts << " " << FloatRect(text.firstRunOrigin(), text.linesBoundingBox().size()) << "\n"; - writeSVGInlineText(ts, text, indent); + writeSVGInlineTextBoxes(ts, text, indent); } void write(TextStream& ts, const RenderPath& path, int indent) @@ -512,10 +502,11 @@ void write(TextStream& ts, const RenderPath& path, int indent) ts << path << "\n"; } -void write(TextStream& ts, const RenderSVGImage& image, int indent) +void writeSVGImage(TextStream& ts, const RenderImage& image, int indent) { writeStandardPrefix(ts, image, indent); - ts << image << "\n"; + writePositionAndStyle(ts, image); + ts << "\n"; } void writeRenderResources(TextStream& ts, Node* parent) diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.h b/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.h index 35c3d5ccc..bee4f36fb 100644 --- a/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.h +++ b/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,7 +32,6 @@ namespace WebCore { - class TransformationMatrix; class Color; class FloatPoint; class FloatRect; @@ -40,20 +39,21 @@ namespace WebCore { class IntPoint; class IntRect; class Node; + class RenderBlock; + class RenderImage; + class RenderObject; class RenderPath; - class RenderSVGContainer; - class RenderSVGInlineText; class RenderSVGRoot; - class RenderSVGText; - class RenderSVGImage; + class RenderText; + class TransformationMatrix; // functions used by the main RenderTreeAsText code -void write(TextStream&, const RenderPath&, int indent = 0); -void write(TextStream&, const RenderSVGContainer&, int indent = 0); -void write(TextStream&, const RenderSVGInlineText&, int indent = 0); -void write(TextStream&, const RenderSVGRoot&, int indent = 0); -void write(TextStream&, const RenderSVGText&, int indent = 0); -void write(TextStream&, const RenderSVGImage&, int indent = 0); +void write(TextStream&, const RenderPath&, int indent); +void write(TextStream&, const RenderSVGRoot&, int indent); +void writeSVGContainer(TextStream&, const RenderObject&, int indent); +void writeSVGImage(TextStream&, const RenderImage&, int indent); +void writeSVGInlineText(TextStream&, const RenderText&, int indent); +void writeSVGText(TextStream&, const RenderBlock&, int indent); void writeRenderResources(TextStream&, Node* parent); diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.cpp index d92f54cf8..58297428d 100644 --- a/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.cpp @@ -285,14 +285,11 @@ static inline void closeTextChunk(SVGTextChunkLayoutInfo& info) RenderSVGRoot* findSVGRootObject(RenderObject* start) { - // Find associated root inline box + // Find associated root inline box. while (start && !start->isSVGRoot()) start = start->parent(); - ASSERT(start); - ASSERT(start->isSVGRoot()); - - return static_cast<RenderSVGRoot*>(start); + return toRenderSVGRoot(start); } static inline FloatPoint topLeftPositionOfCharacterRange(Vector<SVGChar>& chars) @@ -1090,8 +1087,8 @@ void SVGRootInlineBox::layoutInlineBoxes(InlineFlowBox* start, Vector<SVGChar>:: start->setWidth(highX - lowX); static_cast<SVGRootInlineBox*>(start)->setHeight(highY - lowY); - start->setVerticalOverflowPositions(top, bottom); - start->setVerticalSelectionPositions(top, bottom); + start->computeVerticalOverflow(top, bottom, true); + static_cast<SVGRootInlineBox*>(start)->setLineTopBottomPositions(top, bottom); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/TextControlInnerElements.cpp b/src/3rdparty/webkit/WebCore/rendering/TextControlInnerElements.cpp index e205882f8..fc7f7f0e0 100644 --- a/src/3rdparty/webkit/WebCore/rendering/TextControlInnerElements.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/TextControlInnerElements.cpp @@ -56,7 +56,7 @@ bool RenderTextControlInnerBlock::nodeAtPoint(const HitTestRequest& request, Hit bool placeholderIsVisible = false; if (renderer->isTextField()) - placeholderIsVisible = static_cast<RenderTextControlSingleLine*>(renderer)->placeholderIsVisible(); + placeholderIsVisible = toRenderTextControlSingleLine(renderer)->placeholderIsVisible(); return RenderBlock::nodeAtPoint(request, result, x, y, tx, ty, placeholderIsVisible ? HitTestBlockBackground : hitTestAction); } @@ -69,7 +69,7 @@ VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& po // Multiline text controls have the scroll on shadowAncestorNode, so we need to take that // into account here. if (m_multiLine) { - RenderTextControl* renderer = static_cast<RenderTextControl*>(node()->shadowAncestorNode()->renderer()); + RenderTextControl* renderer = toRenderTextControl(node()->shadowAncestorNode()->renderer()); if (renderer->hasOverflowClip()) renderer->layer()->addScrolledContentOffset(contentsX, contentsY); } @@ -155,7 +155,7 @@ void SearchFieldResultsButtonElement::defaultEventHandler(Event* evt) if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) { input->focus(); input->select(); - RenderTextControlSingleLine* renderer = static_cast<RenderTextControlSingleLine*>(input->renderer()); + RenderTextControlSingleLine* renderer = toRenderTextControlSingleLine(input->renderer()); if (renderer->popupIsVisible()) renderer->hidePopup(); else if (input->maxResults() > 0) diff --git a/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.cpp b/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.cpp index 9c491aa69..ec910c9cf 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.cpp @@ -31,18 +31,20 @@ FillLayer::FillLayer(EFillLayerType type) , m_attachment(FillLayer::initialFillAttachment(type)) , m_clip(FillLayer::initialFillClip(type)) , m_origin(FillLayer::initialFillOrigin(type)) - , m_repeat(FillLayer::initialFillRepeat(type)) + , m_repeatX(FillLayer::initialFillRepeatX(type)) + , m_repeatY(FillLayer::initialFillRepeatY(type)) , m_composite(FillLayer::initialFillComposite(type)) - , m_size(FillLayer::initialFillSize(type)) + , m_sizeType(SizeNone) + , m_sizeLength(FillLayer::initialFillSizeLength(type)) , m_imageSet(false) , m_attachmentSet(false) , m_clipSet(false) , m_originSet(false) - , m_repeatSet(false) + , m_repeatXSet(false) + , m_repeatYSet(false) , m_xPosSet(false) , m_yPosSet(false) , m_compositeSet(type == MaskFillLayer) - , m_sizeSet(false) , m_type(type) , m_next(0) { @@ -55,18 +57,20 @@ FillLayer::FillLayer(const FillLayer& o) , m_attachment(o.m_attachment) , m_clip(o.m_clip) , m_origin(o.m_origin) - , m_repeat(o.m_repeat) + , m_repeatX(o.m_repeatX) + , m_repeatY(o.m_repeatY) , m_composite(o.m_composite) - , m_size(o.m_size) + , m_sizeType(o.m_sizeType) + , m_sizeLength(o.m_sizeLength) , m_imageSet(o.m_imageSet) , m_attachmentSet(o.m_attachmentSet) , m_clipSet(o.m_clipSet) , m_originSet(o.m_originSet) - , m_repeatSet(o.m_repeatSet) + , m_repeatXSet(o.m_repeatXSet) + , m_repeatYSet(o.m_repeatYSet) , m_xPosSet(o.m_xPosSet) , m_yPosSet(o.m_yPosSet) , m_compositeSet(o.m_compositeSet) - , m_sizeSet(o.m_sizeSet) , m_type(o.m_type) , m_next(o.m_next ? new FillLayer(*o.m_next) : 0) { @@ -91,18 +95,20 @@ FillLayer& FillLayer::operator=(const FillLayer& o) m_clip = o.m_clip; m_composite = o.m_composite; m_origin = o.m_origin; - m_repeat = o.m_repeat; - m_size = o.m_size; + m_repeatX = o.m_repeatX; + m_repeatY = o.m_repeatY; + m_sizeType = o.m_sizeType; + m_sizeLength = o.m_sizeLength; m_imageSet = o.m_imageSet; m_attachmentSet = o.m_attachmentSet; m_clipSet = o.m_clipSet; m_compositeSet = o.m_compositeSet; m_originSet = o.m_originSet; - m_repeatSet = o.m_repeatSet; + m_repeatXSet = o.m_repeatXSet; + m_repeatYSet = o.m_repeatYSet; m_xPosSet = o.m_xPosSet; m_yPosSet = o.m_yPosSet; - m_sizeSet = o.m_sizeSet; m_type = o.m_type; @@ -115,9 +121,9 @@ bool FillLayer::operator==(const FillLayer& o) const // to propagate patterns into layers. All layer comparisons happen after values have all been filled in anyway. return StyleImage::imagesEquivalent(m_image.get(), o.m_image.get()) && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition && m_attachment == o.m_attachment && m_clip == o.m_clip && - m_composite == o.m_composite && m_origin == o.m_origin && m_repeat == o.m_repeat && - m_size == o.m_size && m_type == o.m_type && - ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next); + m_composite == o.m_composite && m_origin == o.m_origin && m_repeatX == o.m_repeatX && + m_repeatY == o.m_repeatY && m_sizeType == o.m_sizeType && m_sizeLength == o.m_sizeLength && + m_type == o.m_type && ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next); } void FillLayer::fillUnsetProperties() @@ -200,11 +206,22 @@ void FillLayer::fillUnsetProperties() } } - for (curr = this; curr && curr->isRepeatSet(); curr = curr->next()) { } + for (curr = this; curr && curr->isRepeatXSet(); curr = curr->next()) { } if (curr && curr != this) { // We need to fill in the remaining values with the pattern specified. for (FillLayer* pattern = this; curr; curr = curr->next()) { - curr->m_repeat = pattern->m_repeat; + curr->m_repeatX = pattern->m_repeatX; + pattern = pattern->next(); + if (pattern == curr || !pattern) + pattern = this; + } + } + + for (curr = this; curr && curr->isRepeatYSet(); curr = curr->next()) { } + if (curr && curr != this) { + // We need to fill in the remaining values with the pattern specified. + for (FillLayer* pattern = this; curr; curr = curr->next()) { + curr->m_repeatY = pattern->m_repeatY; pattern = pattern->next(); if (pattern == curr || !pattern) pattern = this; @@ -215,7 +232,8 @@ void FillLayer::fillUnsetProperties() if (curr && curr != this) { // We need to fill in the remaining values with the pattern specified. for (FillLayer* pattern = this; curr; curr = curr->next()) { - curr->m_size = pattern->m_size; + curr->m_sizeType = pattern->m_sizeType; + curr->m_sizeLength = pattern->m_sizeLength; pattern = pattern->next(); if (pattern == curr || !pattern) pattern = this; @@ -232,7 +250,8 @@ void FillLayer::cullEmptyLayers() !next->isXPositionSet() && !next->isYPositionSet() && !next->isAttachmentSet() && !next->isClipSet() && !next->isCompositeSet() && !next->isOriginSet() && - !next->isRepeatSet() && !next->isSizeSet()) { + !next->isRepeatXSet() && !next->isRepeatYSet() + && !next->isSizeSet()) { delete next; p->m_next = 0; break; diff --git a/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.h b/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.h index c3944adc9..fb928b659 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.h +++ b/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.h @@ -34,6 +34,31 @@ namespace WebCore { +struct FillSize { + FillSize() + : type(SizeLength) + { + } + + FillSize(EFillSizeType t, LengthSize l) + : type(t) + , size(l) + { + } + + bool operator==(const FillSize& o) const + { + return type == o.type && size == o.size; + } + bool operator!=(const FillSize& o) const + { + return !(*this == o); + } + + EFillSizeType type; + LengthSize size; +}; + struct FillLayer { public: FillLayer(EFillLayerType); @@ -45,9 +70,11 @@ public: EFillAttachment attachment() const { return static_cast<EFillAttachment>(m_attachment); } EFillBox clip() const { return static_cast<EFillBox>(m_clip); } EFillBox origin() const { return static_cast<EFillBox>(m_origin); } - EFillRepeat repeat() const { return static_cast<EFillRepeat>(m_repeat); } + EFillRepeat repeatX() const { return static_cast<EFillRepeat>(m_repeatX); } + EFillRepeat repeatY() const { return static_cast<EFillRepeat>(m_repeatY); } CompositeOperator composite() const { return static_cast<CompositeOperator>(m_composite); } - LengthSize size() const { return m_size; } + LengthSize sizeLength() const { return m_sizeLength; } + FillSize size() const { return FillSize(static_cast<EFillSizeType>(m_sizeType), m_sizeLength); } const FillLayer* next() const { return m_next; } FillLayer* next() { return m_next; } @@ -58,19 +85,23 @@ public: bool isAttachmentSet() const { return m_attachmentSet; } bool isClipSet() const { return m_clipSet; } bool isOriginSet() const { return m_originSet; } - bool isRepeatSet() const { return m_repeatSet; } + bool isRepeatXSet() const { return m_repeatXSet; } + bool isRepeatYSet() const { return m_repeatYSet; } bool isCompositeSet() const { return m_compositeSet; } - bool isSizeSet() const { return m_sizeSet; } + bool isSizeSet() const { return m_sizeType != SizeNone; } void setImage(StyleImage* i) { m_image = i; m_imageSet = true; } - void setXPosition(const Length& l) { m_xPosition = l; m_xPosSet = true; } - void setYPosition(const Length& l) { m_yPosition = l; m_yPosSet = true; } + void setXPosition(Length l) { m_xPosition = l; m_xPosSet = true; } + void setYPosition(Length l) { m_yPosition = l; m_yPosSet = true; } void setAttachment(EFillAttachment attachment) { m_attachment = attachment; m_attachmentSet = true; } void setClip(EFillBox b) { m_clip = b; m_clipSet = true; } void setOrigin(EFillBox b) { m_origin = b; m_originSet = true; } - void setRepeat(EFillRepeat r) { m_repeat = r; m_repeatSet = true; } + void setRepeatX(EFillRepeat r) { m_repeatX = r; m_repeatXSet = true; } + void setRepeatY(EFillRepeat r) { m_repeatY = r; m_repeatYSet = true; } void setComposite(CompositeOperator c) { m_composite = c; m_compositeSet = true; } - void setSize(const LengthSize& b) { m_size = b; m_sizeSet = true; } + void setSizeType(EFillSizeType b) { m_sizeType = b; } + void setSizeLength(LengthSize l) { m_sizeLength = l; } + void setSize(FillSize f) { m_sizeType = f.type; m_sizeLength = f.size; } void clearImage() { m_imageSet = false; } void clearXPosition() { m_xPosSet = false; } @@ -78,9 +109,10 @@ public: void clearAttachment() { m_attachmentSet = false; } void clearClip() { m_clipSet = false; } void clearOrigin() { m_originSet = false; } - void clearRepeat() { m_repeatSet = false; } + void clearRepeatX() { m_repeatXSet = false; } + void clearRepeatY() { m_repeatYSet = false; } void clearComposite() { m_compositeSet = false; } - void clearSize() { m_sizeSet = false; } + void clearSize() { m_sizeType = SizeNone; } void setNext(FillLayer* n) { if (m_next != n) { delete m_next; m_next = n; } } @@ -117,9 +149,12 @@ public: static EFillAttachment initialFillAttachment(EFillLayerType) { return ScrollBackgroundAttachment; } static EFillBox initialFillClip(EFillLayerType) { return BorderFillBox; } static EFillBox initialFillOrigin(EFillLayerType type) { return type == BackgroundFillLayer ? PaddingFillBox : BorderFillBox; } - static EFillRepeat initialFillRepeat(EFillLayerType) { return RepeatFill; } + static EFillRepeat initialFillRepeatX(EFillLayerType) { return RepeatFill; } + static EFillRepeat initialFillRepeatY(EFillLayerType) { return RepeatFill; } static CompositeOperator initialFillComposite(EFillLayerType) { return CompositeSourceOver; } - static LengthSize initialFillSize(EFillLayerType) { return LengthSize(); } + static EFillSizeType initialFillSizeType(EFillLayerType) { return SizeLength; } + static LengthSize initialFillSizeLength(EFillLayerType) { return LengthSize(); } + static FillSize initialFillSize(EFillLayerType) { return FillSize(); } static Length initialFillXPosition(EFillLayerType) { return Length(0.0, Percent); } static Length initialFillYPosition(EFillLayerType) { return Length(0.0, Percent); } static StyleImage* initialFillImage(EFillLayerType) { return 0; } @@ -136,20 +171,22 @@ public: unsigned m_attachment : 2; // EFillAttachment unsigned m_clip : 2; // EFillBox unsigned m_origin : 2; // EFillBox - unsigned m_repeat : 2; // EFillRepeat + unsigned m_repeatX : 3; // EFillRepeat + unsigned m_repeatY : 3; // EFillRepeat unsigned m_composite : 4; // CompositeOperator - - LengthSize m_size; + unsigned m_sizeType : 2; // EFillSizeType + + LengthSize m_sizeLength; bool m_imageSet : 1; bool m_attachmentSet : 1; bool m_clipSet : 1; bool m_originSet : 1; - bool m_repeatSet : 1; + bool m_repeatXSet : 1; + bool m_repeatYSet : 1; bool m_xPosSet : 1; bool m_yPosSet : 1; bool m_compositeSet : 1; - bool m_sizeSet : 1; unsigned m_type : 1; // EFillLayerType diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp index efec1bdd5..a861fea31 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp @@ -324,6 +324,7 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon *rareNonInheritedData->flexibleBox.get() != *other->rareNonInheritedData->flexibleBox.get()) return StyleDifferenceLayout; + // FIXME: We should add an optimized form of layout that just recomputes visual overflow. if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get())) return StyleDifferenceLayout; @@ -453,6 +454,12 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon if (inherited->m_effectiveZoom != other->inherited->m_effectiveZoom) return StyleDifferenceLayout; + if (rareNonInheritedData->opacity == 1 && other->rareNonInheritedData->opacity < 1 || + rareNonInheritedData->opacity < 1 && other->rareNonInheritedData->opacity == 1) { + // FIXME: We should add an optimized form of layout that just recomputes visual overflow. + return StyleDifferenceLayout; + } + // Make sure these left/top/right/bottom checks stay below all layout checks and above // all visible checks. if (position() != StaticPosition) { @@ -695,7 +702,7 @@ void RenderStyle::addBindingURI(StringImpl* uri) void RenderStyle::setTextShadow(ShadowData* val, bool add) { - ASSERT(!val || !val->spread); + ASSERT(!val || !val->spread && val->style == Normal); StyleRareInheritedData* rareData = rareInheritedData.access(); if (!add) { @@ -906,4 +913,53 @@ void RenderStyle::setBlendedFontSize(int size) font().update(font().fontSelector()); } +void RenderStyle::getBoxShadowExtent(int &top, int &right, int &bottom, int &left) const +{ + top = 0; + right = 0; + bottom = 0; + left = 0; + + for (ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next) { + if (boxShadow->style == Inset) + continue; + int blurAndSpread = boxShadow->blur + boxShadow->spread; + + top = min(top, boxShadow->y - blurAndSpread); + right = max(right, boxShadow->x + blurAndSpread); + bottom = max(bottom, boxShadow->y + blurAndSpread); + left = min(left, boxShadow->x - blurAndSpread); + } +} + +void RenderStyle::getBoxShadowHorizontalExtent(int &left, int &right) const +{ + left = 0; + right = 0; + + for (ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next) { + if (boxShadow->style == Inset) + continue; + int blurAndSpread = boxShadow->blur + boxShadow->spread; + + left = min(left, boxShadow->x - blurAndSpread); + right = max(right, boxShadow->x + blurAndSpread); + } +} + +void RenderStyle::getBoxShadowVerticalExtent(int &top, int &bottom) const +{ + top = 0; + bottom = 0; + + for (ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next) { + if (boxShadow->style == Inset) + continue; + int blurAndSpread = boxShadow->blur + boxShadow->spread; + + top = min(top, boxShadow->y - blurAndSpread); + bottom = max(bottom, boxShadow->y + blurAndSpread); + } +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h index 4582dbb2b..2e8fb0acd 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h +++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h @@ -87,7 +87,11 @@ #include "BindingURI.h" #endif +#ifdef __WINS__ +#define compareEqual(t, u) ((t) == (u)) +#else template<typename T, typename U> inline bool compareEqual(const T& t, const U& u) { return t == static_cast<T>(u); } +#endif #define SET_VAR(group, variable, value) \ if (!compareEqual(group->variable, value)) \ @@ -458,7 +462,7 @@ public: return font().lineSpacing(); if (lh.isPercent()) - return lh.calcMinValue(fontSize()); + return lh.calcMinValue(fontSize(), true); return lh.value(); } @@ -521,26 +525,29 @@ public: const Color& backgroundColor() const { return background->m_color; } StyleImage* backgroundImage() const { return background->m_background.m_image.get(); } - EFillRepeat backgroundRepeat() const { return static_cast<EFillRepeat>(background->m_background.m_repeat); } + EFillRepeat backgroundRepeatX() const { return static_cast<EFillRepeat>(background->m_background.m_repeatX); } + EFillRepeat backgroundRepeatY() const { return static_cast<EFillRepeat>(background->m_background.m_repeatY); } CompositeOperator backgroundComposite() const { return static_cast<CompositeOperator>(background->m_background.m_composite); } EFillAttachment backgroundAttachment() const { return static_cast<EFillAttachment>(background->m_background.m_attachment); } EFillBox backgroundClip() const { return static_cast<EFillBox>(background->m_background.m_clip); } EFillBox backgroundOrigin() const { return static_cast<EFillBox>(background->m_background.m_origin); } Length backgroundXPosition() const { return background->m_background.m_xPosition; } Length backgroundYPosition() const { return background->m_background.m_yPosition; } - LengthSize backgroundSize() const { return background->m_background.m_size; } + EFillSizeType backgroundSizeType() const { return static_cast<EFillSizeType>(background->m_background.m_sizeType); } + LengthSize backgroundSizeLength() const { return background->m_background.m_sizeLength; } FillLayer* accessBackgroundLayers() { return &(background.access()->m_background); } const FillLayer* backgroundLayers() const { return &(background->m_background); } StyleImage* maskImage() const { return rareNonInheritedData->m_mask.m_image.get(); } - EFillRepeat maskRepeat() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.m_repeat); } + EFillRepeat maskRepeatX() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.m_repeatX); } + EFillRepeat maskRepeatY() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.m_repeatY); } CompositeOperator maskComposite() const { return static_cast<CompositeOperator>(rareNonInheritedData->m_mask.m_composite); } EFillAttachment maskAttachment() const { return static_cast<EFillAttachment>(rareNonInheritedData->m_mask.m_attachment); } EFillBox maskClip() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.m_clip); } EFillBox maskOrigin() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.m_origin); } Length maskXPosition() const { return rareNonInheritedData->m_mask.m_xPosition; } Length maskYPosition() const { return rareNonInheritedData->m_mask.m_yPosition; } - LengthSize maskSize() const { return rareNonInheritedData->m_mask.m_size; } + LengthSize maskSize() const { return rareNonInheritedData->m_mask.m_sizeLength; } FillLayer* accessMaskLayers() { return &(rareNonInheritedData.access()->m_mask); } const FillLayer* maskLayers() const { return &(rareNonInheritedData->m_mask); } const NinePieceImage& maskBoxImage() const { return rareNonInheritedData->m_maskBoxImage; } @@ -606,7 +613,12 @@ public: unsigned int boxOrdinalGroup() const { return rareNonInheritedData->flexibleBox->ordinal_group; } EBoxOrient boxOrient() const { return static_cast<EBoxOrient>(rareNonInheritedData->flexibleBox->orient); } EBoxAlignment boxPack() const { return static_cast<EBoxAlignment>(rareNonInheritedData->flexibleBox->pack); } + ShadowData* boxShadow() const { return rareNonInheritedData->m_boxShadow.get(); } + void getBoxShadowExtent(int &top, int &right, int &bottom, int &left) const; + void getBoxShadowHorizontalExtent(int &left, int &right) const; + void getBoxShadowVerticalExtent(int &top, int &bottom) const; + StyleReflection* boxReflect() const { return rareNonInheritedData->m_boxReflect.get(); } EBoxSizing boxSizing() const { return static_cast<EBoxSizing>(box->boxSizing); } Length marqueeIncrement() const { return rareNonInheritedData->marquee->increment; } @@ -746,7 +758,8 @@ public: void setBackgroundXPosition(Length l) { SET_VAR(background, m_background.m_xPosition, l) } void setBackgroundYPosition(Length l) { SET_VAR(background, m_background.m_yPosition, l) } - void setBackgroundSize(LengthSize l) { SET_VAR(background, m_background.m_size, l) } + void setBackgroundSize(EFillSizeType b) { SET_VAR(background, m_background.m_sizeType, b) } + void setBackgroundSizeLength(LengthSize l) { SET_VAR(background, m_background.m_sizeLength, l) } void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.image, b) } @@ -859,7 +872,7 @@ public: void setMaskBoxImage(const NinePieceImage& b) { SET_VAR(rareNonInheritedData, m_maskBoxImage, b) } void setMaskXPosition(Length l) { SET_VAR(rareNonInheritedData, m_mask.m_xPosition, l) } void setMaskYPosition(Length l) { SET_VAR(rareNonInheritedData, m_mask.m_yPosition, l) } - void setMaskSize(LengthSize l) { SET_VAR(rareNonInheritedData, m_mask.m_size, l) } + void setMaskSize(LengthSize l) { SET_VAR(rareNonInheritedData, m_mask.m_sizeLength, l) } void setBorderCollapse(bool collapse) { inherited_flags._border_collapse = collapse; } void setHorizontalBorderSpacing(short v) { SET_VAR(inherited, horizontal_border_spacing, v) } @@ -1169,6 +1182,7 @@ public: static float initialPerspective() { return 0; } static Length initialPerspectiveOriginX() { return Length(50.0, Percent); } static Length initialPerspectiveOriginY() { return Length(50.0, Percent); } + static Color initialBackgroundColor() { return Color::transparent; } // Keep these at the end. static int initialLineClamp() { return -1; } diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h index 1b3e1f405..3010947ad 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h +++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h @@ -4,6 +4,7 @@ * (C) 2000 Dirk Mueller (mueller@kde.org) * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) + * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -68,10 +69,10 @@ enum PseudoId { NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR, FILE_UPLOAD_BUTTON, INPUT_PLACEHOLDER, SLIDER_THUMB, SEARCH_CANCEL_BUTTON, SEARCH_DECORATION, SEARCH_RESULTS_DECORATION, SEARCH_RESULTS_BUTTON, MEDIA_CONTROLS_PANEL, MEDIA_CONTROLS_PLAY_BUTTON, MEDIA_CONTROLS_MUTE_BUTTON, MEDIA_CONTROLS_TIMELINE, MEDIA_CONTROLS_TIMELINE_CONTAINER, - MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, MEDIA_CONTROLS_SEEK_BACK_BUTTON, - MEDIA_CONTROLS_SEEK_FORWARD_BUTTON, MEDIA_CONTROLS_FULLSCREEN_BUTTON, MEDIA_CONTROLS_REWIND_BUTTON, - MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, MEDIA_CONTROLS_STATUS_DISPLAY, - SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER, + MEDIA_CONTROLS_VOLUME_SLIDER, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER, MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, MEDIA_CONTROLS_SEEK_BACK_BUTTON, + MEDIA_CONTROLS_SEEK_FORWARD_BUTTON, MEDIA_CONTROLS_FULLSCREEN_BUTTON, MEDIA_CONTROLS_REWIND_BUTTON, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, + MEDIA_CONTROLS_STATUS_DISPLAY, SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER, + INPUT_LIST_BUTTON, FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON }; @@ -131,13 +132,16 @@ enum EFillBox { }; enum EFillRepeat { - RepeatFill, RepeatXFill, RepeatYFill, NoRepeatFill + RepeatFill, NoRepeatFill, RoundFill, SpaceFill }; enum EFillLayerType { BackgroundFillLayer, MaskFillLayer }; +// CSS3 Background Values +enum EFillSizeType { Contain, Cover, SizeLength, SizeNone }; + // CSS3 Marquee Properties enum EMarqueeBehavior { MNONE, MSCROLL, MSLIDE, MALTERNATE }; @@ -212,6 +216,11 @@ enum StyleContentType { enum EBorderFit { BorderFitBorder, BorderFitLines }; +enum EAnimPlayState { + AnimPlayStatePlaying = 0x0, + AnimPlayStatePaused = 0x1 +}; + enum ETimingFunctionType { LinearTimingFunction, CubicBezierTimingFunction }; enum EWhiteSpace { @@ -293,7 +302,11 @@ enum EDisplay { TABLE, INLINE_TABLE, TABLE_ROW_GROUP, TABLE_HEADER_GROUP, TABLE_FOOTER_GROUP, TABLE_ROW, TABLE_COLUMN_GROUP, TABLE_COLUMN, TABLE_CELL, - TABLE_CAPTION, BOX, INLINE_BOX, NONE + TABLE_CAPTION, BOX, INLINE_BOX, +#if ENABLE(WCSS) + WAP_MARQUEE, +#endif + NONE }; enum EPointerEvents { diff --git a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.cpp b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.cpp index 1289b06b7..e8827c473 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.cpp @@ -51,6 +51,7 @@ SVGRenderStyle::SVGRenderStyle() mask = defaultStyle->mask; misc = defaultStyle->misc; markers = defaultStyle->markers; + shadowSVG = defaultStyle->shadowSVG; setBitDefaults(); } @@ -67,6 +68,7 @@ SVGRenderStyle::SVGRenderStyle(CreateDefaultType) mask.init(); misc.init(); markers.init(); + shadowSVG.init(); } SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other) @@ -80,6 +82,7 @@ SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other) mask = other.mask; misc = other.misc; markers = other.markers; + shadowSVG = other.shadowSVG; svg_inherited_flags = other.svg_inherited_flags; svg_noninherited_flags = other.svg_noninherited_flags; @@ -93,7 +96,7 @@ bool SVGRenderStyle::operator==(const SVGRenderStyle& o) const { return (fill == o.fill && stroke == o.stroke && text == o.text && stops == o.stops && clip == o.clip && mask == o.mask && - misc == o.misc && markers == o.markers && + misc == o.misc && markers == o.markers && shadowSVG == o.shadowSVG && svg_inherited_flags == o.svg_inherited_flags && svg_noninherited_flags == o.svg_noninherited_flags); } diff --git a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.h b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.h index 0e9dae463..12477d771 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.h +++ b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.h @@ -30,6 +30,7 @@ #include "GraphicsTypes.h" #include "SVGPaint.h" #include "SVGRenderStyleDefs.h" +#include "ShadowData.h" #include <wtf/Platform.h> @@ -65,7 +66,6 @@ namespace WebCore { SVG_RS_DEFINE_ATTRIBUTE_INHERITED(LineJoin, JoinStyle, joinStyle, MiterJoin) SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EShapeRendering, ShapeRendering, shapeRendering, SR_AUTO) SVG_RS_DEFINE_ATTRIBUTE_INHERITED(ETextAnchor, TextAnchor, textAnchor, TA_START) - SVG_RS_DEFINE_ATTRIBUTE_INHERITED(ETextRendering, TextRendering, textRendering, TR_AUTO) SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EWritingMode, WritingMode, writingMode, WM_LRTB) SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EGlyphOrientation, GlyphOrientationHorizontal, glyphOrientationHorizontal, GO_0DEG) SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EGlyphOrientation, GlyphOrientationVertical, glyphOrientationVertical, GO_AUTO) @@ -99,6 +99,8 @@ namespace WebCore { SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, misc, lightingColor, LightingColor, lightingColor, Color(255, 255, 255)) SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, misc, baselineShiftValue, BaselineShiftValue, baselineShiftValue, 0) + SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_OWNPTR(ShadowData, shadowSVG, shadow, Shadow, shadow, 0) + // convenience bool hasStroke() const { return (strokePaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE); } bool hasFill() const { return (fillPaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE); } @@ -113,7 +115,6 @@ namespace WebCore { return (_colorRendering == other._colorRendering) && (_imageRendering == other._imageRendering) && (_shapeRendering == other._shapeRendering) && - (_textRendering == other._textRendering) && (_clipRule == other._clipRule) && (_fillRule == other._fillRule) && (_capStyle == other._capStyle) && @@ -134,7 +135,6 @@ namespace WebCore { unsigned _colorRendering : 2; // EColorRendering unsigned _imageRendering : 2; // EImageRendering unsigned _shapeRendering : 2; // EShapeRendering - unsigned _textRendering : 2; // ETextRendering unsigned _clipRule : 1; // WindRule unsigned _fillRule : 1; // WindRule unsigned _capStyle : 2; // LineCap @@ -175,6 +175,7 @@ namespace WebCore { DataRef<StyleClipData> clip; DataRef<StyleMaskData> mask; DataRef<StyleMiscData> misc; + DataRef<StyleShadowSVGData> shadowSVG; private: enum CreateDefaultType { CreateDefault }; @@ -190,7 +191,6 @@ namespace WebCore { svg_inherited_flags._fillRule = initialFillRule(); svg_inherited_flags._imageRendering = initialImageRendering(); svg_inherited_flags._shapeRendering = initialShapeRendering(); - svg_inherited_flags._textRendering = initialTextRendering(); svg_inherited_flags._textAnchor = initialTextAnchor(); svg_inherited_flags._capStyle = initialCapStyle(); svg_inherited_flags._joinStyle = initialJoinStyle(); diff --git a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.cpp b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.cpp index f5faad3e8..2ed1d8fcc 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.cpp @@ -213,6 +213,25 @@ bool StyleMiscData::operator==(const StyleMiscData &other) const && baselineShiftValue == other.baselineShiftValue; } +StyleShadowSVGData::StyleShadowSVGData() +{ +} + +StyleShadowSVGData::StyleShadowSVGData(const StyleShadowSVGData& other) + : RefCounted<StyleShadowSVGData>() + , shadow(other.shadow ? new ShadowData(*other.shadow) : 0) +{ +} + +bool StyleShadowSVGData::operator==(const StyleShadowSVGData& other) const +{ + if ((!shadow && other.shadow) || (shadow && !other.shadow)) + return false; + if (shadow && other.shadow && (*shadow != *other.shadow)) + return false; + return true; +} + #endif // ENABLE(SVG) // vim:ts=4:noet diff --git a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.h b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.h index b7bf0261d..f4cf9327a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.h +++ b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.h @@ -33,6 +33,9 @@ #include "Color.h" #include "Path.h" #include "PlatformString.h" +#include "ShadowData.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> @@ -65,6 +68,13 @@ } \ static Data* initial##Type() { return Initial; } +#define SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_OWNPTR(Data, Group, Variable, Type, Name, Initial) \ + Data* Name() const { return Group->Variable.get(); } \ + void set##Type(Data* obj) { \ + Group.access()->Variable.set(obj); \ + } \ + static Data* initial##Type() { return Initial; } + #define SVG_RS_SET_VARIABLE(Group, Variable, Value) \ if (!(Group->Variable == Value)) \ Group.access()->Variable = Value; @@ -95,10 +105,6 @@ namespace WebCore { SR_AUTO, SR_OPTIMIZESPEED, SR_CRISPEDGES, SR_GEOMETRICPRECISION }; - enum ETextRendering { - TR_AUTO, TR_OPTIMIZESPEED, TR_OPTIMIZELEGIBILITY, TR_GEOMETRICPRECISION - }; - enum EWritingMode { WM_LRTB, WM_LR, WM_RLTB, WM_RL, WM_TBRL, WM_TB }; @@ -283,6 +289,24 @@ namespace WebCore { StyleMiscData(); StyleMiscData(const StyleMiscData&); }; + + class StyleShadowSVGData : public RefCounted<StyleShadowSVGData> { + public: + static PassRefPtr<StyleShadowSVGData> create() { return adoptRef(new StyleShadowSVGData); } + PassRefPtr<StyleShadowSVGData> copy() const { return adoptRef(new StyleShadowSVGData(*this)); } + + bool operator==(const StyleShadowSVGData& other) const; + bool operator!=(const StyleShadowSVGData& other) const + { + return !(*this == other); + } + + OwnPtr<ShadowData> shadow; + + private: + StyleShadowSVGData(); + StyleShadowSVGData(const StyleShadowSVGData& other); + }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/style/StyleBackgroundData.cpp b/src/3rdparty/webkit/WebCore/rendering/style/StyleBackgroundData.cpp index 68a9dddbc..08f5527ad 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/StyleBackgroundData.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/style/StyleBackgroundData.cpp @@ -22,12 +22,14 @@ #include "config.h" #include "StyleBackgroundData.h" +#include "RenderStyle.h" #include "RenderStyleConstants.h" namespace WebCore { StyleBackgroundData::StyleBackgroundData() : m_background(BackgroundFillLayer) + , m_color(RenderStyle::initialBackgroundColor()) { } |