summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering')
-rw-r--r--Source/WebCore/rendering/AutoTableLayout.cpp6
-rw-r--r--Source/WebCore/rendering/ColumnInfo.h5
-rw-r--r--Source/WebCore/rendering/CounterNode.cpp19
-rw-r--r--Source/WebCore/rendering/FilterEffectRenderer.cpp7
-rw-r--r--Source/WebCore/rendering/FixedTableLayout.cpp9
-rw-r--r--Source/WebCore/rendering/HitTestResult.cpp37
-rw-r--r--Source/WebCore/rendering/HitTestResult.h2
-rw-r--r--Source/WebCore/rendering/InlineBox.cpp2
-rw-r--r--Source/WebCore/rendering/InlineFlowBox.cpp3
-rw-r--r--Source/WebCore/rendering/InlineTextBox.cpp9
-rwxr-xr-xSource/WebCore/rendering/RenderBlock.cpp191
-rwxr-xr-xSource/WebCore/rendering/RenderBlockLineLayout.cpp39
-rw-r--r--Source/WebCore/rendering/RenderBox.cpp41
-rw-r--r--Source/WebCore/rendering/RenderBox.h8
-rw-r--r--Source/WebCore/rendering/RenderBoxModelObject.cpp416
-rw-r--r--Source/WebCore/rendering/RenderBoxModelObject.h6
-rw-r--r--Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp18
-rw-r--r--Source/WebCore/rendering/RenderFieldset.cpp22
-rw-r--r--Source/WebCore/rendering/RenderFileUploadControl.cpp4
-rw-r--r--Source/WebCore/rendering/RenderFlexibleBox.cpp137
-rw-r--r--Source/WebCore/rendering/RenderFlexibleBox.h13
-rw-r--r--Source/WebCore/rendering/RenderFlowThread.cpp7
-rw-r--r--Source/WebCore/rendering/RenderImage.cpp10
-rw-r--r--Source/WebCore/rendering/RenderInline.cpp24
-rw-r--r--Source/WebCore/rendering/RenderInline.h2
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp206
-rw-r--r--Source/WebCore/rendering/RenderLayer.h69
-rw-r--r--Source/WebCore/rendering/RenderLayerBacking.cpp58
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp157
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.h7
-rw-r--r--Source/WebCore/rendering/RenderListBox.cpp3
-rw-r--r--Source/WebCore/rendering/RenderMarquee.cpp2
-rw-r--r--Source/WebCore/rendering/RenderMediaControlsChromium.cpp271
-rw-r--r--Source/WebCore/rendering/RenderMediaControlsChromium.h3
-rw-r--r--Source/WebCore/rendering/RenderMenuList.cpp3
-rwxr-xr-xSource/WebCore/rendering/RenderObject.cpp139
-rw-r--r--Source/WebCore/rendering/RenderObject.h27
-rw-r--r--Source/WebCore/rendering/RenderObjectChildList.cpp4
-rw-r--r--Source/WebCore/rendering/RenderReplaced.cpp5
-rw-r--r--Source/WebCore/rendering/RenderRubyText.cpp6
-rw-r--r--Source/WebCore/rendering/RenderSearchField.cpp385
-rw-r--r--Source/WebCore/rendering/RenderSearchField.h104
-rw-r--r--Source/WebCore/rendering/RenderTable.cpp203
-rw-r--r--Source/WebCore/rendering/RenderTable.h6
-rw-r--r--Source/WebCore/rendering/RenderTableCell.cpp21
-rw-r--r--Source/WebCore/rendering/RenderTableCell.h28
-rw-r--r--Source/WebCore/rendering/RenderTableRow.h16
-rw-r--r--Source/WebCore/rendering/RenderTableSection.cpp242
-rw-r--r--Source/WebCore/rendering/RenderTableSection.h40
-rw-r--r--Source/WebCore/rendering/RenderText.cpp7
-rw-r--r--Source/WebCore/rendering/RenderTextControlSingleLine.cpp315
-rw-r--r--Source/WebCore/rendering/RenderTextControlSingleLine.h72
-rw-r--r--Source/WebCore/rendering/RenderTheme.cpp18
-rw-r--r--Source/WebCore/rendering/RenderTheme.h4
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp8
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumAndroid.h11
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumLinux.cpp4
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumLinux.h2
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumMac.h6
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumMac.mm25
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumSkia.cpp65
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumSkia.h10
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumWin.cpp4
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumWin.h2
-rw-r--r--Source/WebCore/rendering/RenderThemeMac.h2
-rw-r--r--Source/WebCore/rendering/RenderThemeMac.mm6
-rw-r--r--Source/WebCore/rendering/RenderThemeSafari.cpp2
-rw-r--r--Source/WebCore/rendering/RenderThemeSafari.h2
-rw-r--r--Source/WebCore/rendering/RenderThemeWin.cpp2
-rw-r--r--Source/WebCore/rendering/RenderThemeWin.h2
-rw-r--r--Source/WebCore/rendering/RenderThemeWinCE.cpp2
-rw-r--r--Source/WebCore/rendering/RenderThemeWinCE.h2
-rw-r--r--Source/WebCore/rendering/RenderTreeAsText.cpp17
-rw-r--r--Source/WebCore/rendering/RenderView.cpp34
-rw-r--r--Source/WebCore/rendering/RenderView.h13
-rw-r--r--Source/WebCore/rendering/RenderingAllInOne.cpp1
-rw-r--r--Source/WebCore/rendering/TableLayout.h2
-rw-r--r--Source/WebCore/rendering/break_lines.cpp39
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp17
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLBlock.h8
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp36
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLFenced.h4
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp35
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLFraction.h3
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp12
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLOperator.h2
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h2
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp38
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLSubSup.h3
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp16
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h3
-rw-r--r--Source/WebCore/rendering/style/KeyframeList.h4
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.cpp21
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.h72
-rw-r--r--Source/WebCore/rendering/style/RenderStyleConstants.h16
-rw-r--r--Source/WebCore/rendering/style/StyleBoxData.cpp17
-rw-r--r--Source/WebCore/rendering/style/StyleBoxData.h6
-rw-r--r--Source/WebCore/rendering/style/StyleCachedImage.cpp2
-rw-r--r--Source/WebCore/rendering/style/StyleCachedImageSet.cpp2
-rw-r--r--Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp21
-rw-r--r--Source/WebCore/rendering/style/StyleFlexibleBoxData.h8
-rw-r--r--Source/WebCore/rendering/style/StyleMultiColData.cpp5
-rw-r--r--Source/WebCore/rendering/style/StyleMultiColData.h1
-rw-r--r--Source/WebCore/rendering/style/StyleRareInheritedData.cpp54
-rw-r--r--Source/WebCore/rendering/style/StyleRareInheritedData.h18
-rw-r--r--Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp9
-rw-r--r--Source/WebCore/rendering/style/StyleRareNonInheritedData.h5
-rw-r--r--Source/WebCore/rendering/style/StyleVariableData.h66
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGContainer.cpp5
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.cpp4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGModelObject.cpp12
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp22
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceContainer.h1
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp7
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp6
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.cpp5
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTextPath.cpp1
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTextPath.h2
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.cpp2
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderSupport.cpp15
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderingContext.cpp9
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderingContext.h1
122 files changed, 2541 insertions, 1778 deletions
diff --git a/Source/WebCore/rendering/AutoTableLayout.cpp b/Source/WebCore/rendering/AutoTableLayout.cpp
index 2c3636e04..0af1f78bf 100644
--- a/Source/WebCore/rendering/AutoTableLayout.cpp
+++ b/Source/WebCore/rendering/AutoTableLayout.cpp
@@ -244,8 +244,8 @@ void AutoTableLayout::computePreferredLogicalWidths(LayoutUnit& minWidth, Layout
if (scaleColumns) {
maxNonPercent = maxNonPercent * 100 / max(remainingPercent, epsilon);
- maxWidth = max<int>(maxWidth, static_cast<int>(min(maxNonPercent, MAX_LAYOUT_UNIT / 2.0f)));
- maxWidth = max<int>(maxWidth, static_cast<int>(min(maxPercent, MAX_LAYOUT_UNIT / 2.0f)));
+ maxWidth = max<int>(maxWidth, static_cast<int>(min(maxNonPercent, static_cast<float>(tableMaxWidth))));
+ maxWidth = max<int>(maxWidth, static_cast<int>(min(maxPercent, static_cast<float>(tableMaxWidth))));
}
maxWidth = max<int>(maxWidth, spanMaxLogicalWidth);
@@ -260,7 +260,7 @@ void AutoTableLayout::computePreferredLogicalWidths(LayoutUnit& minWidth, Layout
maxWidth = minWidth;
} else if (!remainingPercent && maxNonPercent) {
// if there was no remaining percent, maxWidth is invalid
- maxWidth = MAX_LAYOUT_UNIT;
+ maxWidth = tableMaxWidth;
}
Length tableLogicalMinWidth = m_table->style()->logicalMinWidth();
diff --git a/Source/WebCore/rendering/ColumnInfo.h b/Source/WebCore/rendering/ColumnInfo.h
index e462a84a5..553564c53 100644
--- a/Source/WebCore/rendering/ColumnInfo.h
+++ b/Source/WebCore/rendering/ColumnInfo.h
@@ -38,6 +38,7 @@ public:
: m_desiredColumnWidth(0)
, m_desiredColumnCount(1)
, m_progressionAxis(InlineAxis)
+ , m_progressionIsReversed(false)
, m_columnCount(1)
, m_columnHeight(0)
, m_minimumColumnHeight(0)
@@ -59,6 +60,9 @@ public:
Axis progressionAxis() const { return m_progressionAxis; }
void setProgressionAxis(Axis progressionAxis) { m_progressionAxis = progressionAxis; }
+ bool progressionIsReversed() const { return m_progressionIsReversed; }
+ void setProgressionIsReversed(bool reversed) { m_progressionIsReversed = reversed; }
+
unsigned columnCount() const { return m_columnCount; }
LayoutUnit columnHeight() const { return m_columnHeight; }
@@ -102,6 +106,7 @@ private:
LayoutUnit m_desiredColumnWidth;
unsigned m_desiredColumnCount;
Axis m_progressionAxis;
+ bool m_progressionIsReversed;
unsigned m_columnCount;
LayoutUnit m_columnHeight;
diff --git a/Source/WebCore/rendering/CounterNode.cpp b/Source/WebCore/rendering/CounterNode.cpp
index f3cc4da03..09f0175e5 100644
--- a/Source/WebCore/rendering/CounterNode.cpp
+++ b/Source/WebCore/rendering/CounterNode.cpp
@@ -261,25 +261,22 @@ void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, cons
newChild->m_parent = this;
newChild->m_previousSibling = refChild;
- if (!newChild->m_firstChild || newChild->m_hasResetType) {
+ if (next) {
+ ASSERT(next->m_previousSibling == refChild);
+ next->m_previousSibling = newChild;
newChild->m_nextSibling = next;
- if (next) {
- ASSERT(next->m_previousSibling == refChild);
- next->m_previousSibling = newChild;
- } else {
- ASSERT(m_lastChild == refChild);
- m_lastChild = newChild;
- }
+ } else {
+ ASSERT(m_lastChild == refChild);
+ m_lastChild = newChild;
+ }
+ if (!newChild->m_firstChild || newChild->m_hasResetType) {
newChild->m_countInParent = newChild->computeCountInParent();
newChild->resetThisAndDescendantsRenderers();
if (next)
next->recount();
return;
}
- // If the new child is the last in the sibling list we must set the parent's lastChild.
- if (!newChild->m_nextSibling)
- m_lastChild = newChild;
// The code below handles the case when a formerly root increment counter is loosing its root position
// and therefore its children become next siblings.
diff --git a/Source/WebCore/rendering/FilterEffectRenderer.cpp b/Source/WebCore/rendering/FilterEffectRenderer.cpp
index 54e8c1cf5..ebf6b7ee6 100644
--- a/Source/WebCore/rendering/FilterEffectRenderer.cpp
+++ b/Source/WebCore/rendering/FilterEffectRenderer.cpp
@@ -42,10 +42,11 @@
#include <wtf/MathExtras.h>
#if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
+#include "CustomFilterGlobalContext.h"
#include "CustomFilterProgram.h"
#include "CustomFilterOperation.h"
#include "FECustomFilter.h"
-#include "FrameView.h"
+#include "RenderView.h"
#include "Settings.h"
#endif
@@ -271,7 +272,9 @@ bool FilterEffectRenderer::build(Document* document, const FilterOperations& ope
CustomFilterOperation* customFilterOperation = static_cast<CustomFilterOperation*>(filterOperation);
RefPtr<CustomFilterProgram> program = customFilterOperation->program();
if (program->isLoaded()) {
- effect = FECustomFilter::create(this, document->view()->root()->hostWindow(), program, customFilterOperation->parameters(),
+ CustomFilterGlobalContext* globalContext = document->renderView()->customFilterGlobalContext();
+ globalContext->prepareContextIfNeeded(document->view()->hostWindow());
+ effect = FECustomFilter::create(this, globalContext, program, customFilterOperation->parameters(),
customFilterOperation->meshRows(), customFilterOperation->meshColumns(),
customFilterOperation->meshBoxType(), customFilterOperation->meshType());
m_hasCustomShaderFilter = true;
diff --git a/Source/WebCore/rendering/FixedTableLayout.cpp b/Source/WebCore/rendering/FixedTableLayout.cpp
index 54272b117..41dd906e1 100644
--- a/Source/WebCore/rendering/FixedTableLayout.cpp
+++ b/Source/WebCore/rendering/FixedTableLayout.cpp
@@ -166,11 +166,6 @@ 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::computePreferredLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth)
{
// FIXME: This entire calculation is incorrect for both minwidth and maxwidth.
@@ -204,8 +199,8 @@ void FixedTableLayout::computePreferredLogicalWidths(LayoutUnit& minWidth, Layou
// 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->document()->inQuirksMode() && m_table->style()->logicalWidth().isPercent() && maxWidth < TABLE_MAX_WIDTH)
- maxWidth = TABLE_MAX_WIDTH;
+ if (m_table->document()->inQuirksMode() && m_table->style()->logicalWidth().isPercent() && maxWidth < tableMaxWidth)
+ maxWidth = tableMaxWidth;
}
void FixedTableLayout::layout()
diff --git a/Source/WebCore/rendering/HitTestResult.cpp b/Source/WebCore/rendering/HitTestResult.cpp
index 66e1da96b..5ffb65969 100644
--- a/Source/WebCore/rendering/HitTestResult.cpp
+++ b/Source/WebCore/rendering/HitTestResult.cpp
@@ -622,21 +622,23 @@ bool HitTestResult::addNodeToRectBasedTestResult(Node* node, const LayoutPoint&
mutableRectBasedTestResult().add(node);
- if (node->renderer()->isInline()) {
+ bool regionFilled = rect.contains(rectForPoint(pointInContainer));
+ // FIXME: This code (incorrectly) attempts to correct for culled inline nodes. See https://bugs.webkit.org/show_bug.cgi?id=85849.
+ if (node->renderer()->isInline() && !regionFilled) {
for (RenderObject* curr = node->renderer()->parent(); curr; curr = curr->parent()) {
if (!curr->isRenderInline())
break;
-
+
// We need to make sure the nodes for culled inlines get included.
RenderInline* currInline = toRenderInline(curr);
if (currInline->alwaysCreateLineBoxes())
break;
-
+
if (currInline->visibleToHitTesting() && currInline->node())
mutableRectBasedTestResult().add(currInline->node()->shadowAncestorNode());
}
}
- return !rect.contains(rectForPoint(pointInContainer));
+ return !regionFilled;
}
bool HitTestResult::addNodeToRectBasedTestResult(Node* node, const LayoutPoint& pointInContainer, const FloatRect& rect)
@@ -655,21 +657,23 @@ bool HitTestResult::addNodeToRectBasedTestResult(Node* node, const LayoutPoint&
mutableRectBasedTestResult().add(node);
- if (node->renderer()->isInline()) {
+ bool regionFilled = rect.contains(rectForPoint(pointInContainer));
+ // FIXME: This code (incorrectly) attempts to correct for culled inline nodes. See https://bugs.webkit.org/show_bug.cgi?id=85849.
+ if (node->renderer()->isInline() && !regionFilled) {
for (RenderObject* curr = node->renderer()->parent(); curr; curr = curr->parent()) {
if (!curr->isRenderInline())
break;
-
+
// We need to make sure the nodes for culled inlines get included.
RenderInline* currInline = toRenderInline(curr);
if (currInline->alwaysCreateLineBoxes())
break;
-
+
if (currInline->visibleToHitTesting() && currInline->node())
mutableRectBasedTestResult().add(currInline->node()->shadowAncestorNode());
}
}
- return !rect.contains(rectForPoint(pointInContainer));
+ return !regionFilled;
}
void HitTestResult::append(const HitTestResult& other)
@@ -706,4 +710,21 @@ HitTestResult::NodeSet& HitTestResult::mutableRectBasedTestResult()
return *m_rectBasedTestResult;
}
+Vector<String> HitTestResult::dictationAlternatives() const
+{
+ // Return the dictation context handle if the text at this point has DictationAlternative marker, which means this text is
+ if (!m_innerNonSharedNode)
+ return Vector<String>();
+
+ DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(hitTestPoint().point(), DocumentMarker::DictationAlternatives);
+ if (!marker)
+ return Vector<String>();
+
+ Frame* frame = innerNonSharedNode()->document()->frame();
+ if (!frame)
+ return Vector<String>();
+
+ return frame->editor()->dictationAlternativesForMarker(marker);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/HitTestResult.h b/Source/WebCore/rendering/HitTestResult.h
index a18fdb5a2..19ddbd1ac 100644
--- a/Source/WebCore/rendering/HitTestResult.h
+++ b/Source/WebCore/rendering/HitTestResult.h
@@ -157,6 +157,8 @@ public:
// the same thing as mutableRectBasedTestResult(), but here the return value is const.
const NodeSet& rectBasedTestResult() const;
+ Vector<String> dictationAlternatives() const;
+
private:
NodeSet& mutableRectBasedTestResult(); // See above.
diff --git a/Source/WebCore/rendering/InlineBox.cpp b/Source/WebCore/rendering/InlineBox.cpp
index 957e0f0cb..6f328c1af 100644
--- a/Source/WebCore/rendering/InlineBox.cpp
+++ b/Source/WebCore/rendering/InlineBox.cpp
@@ -37,7 +37,7 @@ using namespace std;
namespace WebCore {
-class SameSizeAsInlineBox {
+struct SameSizeAsInlineBox {
virtual ~SameSizeAsInlineBox() { }
void* a[4];
FloatPoint b;
diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp
index 58c97dd69..c10941875 100644
--- a/Source/WebCore/rendering/InlineFlowBox.cpp
+++ b/Source/WebCore/rendering/InlineFlowBox.cpp
@@ -27,7 +27,6 @@
#include "GraphicsContext.h"
#include "InlineTextBox.h"
#include "HitTestResult.h"
-#include "RootInlineBox.h"
#include "RenderBlock.h"
#include "RenderInline.h"
#include "RenderLayer.h"
@@ -45,7 +44,7 @@ using namespace std;
namespace WebCore {
-class SameSizeAsInlineFlowBox : public InlineBox {
+struct SameSizeAsInlineFlowBox : public InlineBox {
void* pointers[5];
uint32_t bitfields : 24;
};
diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp
index be7e76673..9e731d638 100644
--- a/Source/WebCore/rendering/InlineTextBox.cpp
+++ b/Source/WebCore/rendering/InlineTextBox.cpp
@@ -851,8 +851,8 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b
LayoutUnit selectionBottom = root()->selectionBottom();
LayoutUnit selectionTop = root()->selectionTopAdjustedForPrecedingBlock();
- LayoutUnit deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - selectionTop;
- LayoutUnit selHeight = max<LayoutUnit>(ZERO_LAYOUT_UNIT, selectionBottom - selectionTop);
+ int deltaY = roundToInt(renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - selectionTop);
+ int selHeight = max(0, roundToInt(selectionBottom - selectionTop));
FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, selHeight));
@@ -1030,7 +1030,8 @@ void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b
if (m_truncation != cNoTruncation)
markerSpansWholeBox = false;
- if (!markerSpansWholeBox || grammar) {
+ bool isDictationMarker = marker->type() == DocumentMarker::DictationAlternatives;
+ if (!markerSpansWholeBox || grammar || isDictationMarker) {
int startPosition = max<int>(marker->startOffset() - m_start, 0);
int endPosition = min<int>(marker->endOffset() - m_start, m_len);
@@ -1050,7 +1051,7 @@ void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b
// Store rendered rects for bad grammar markers, so we can hit-test against it elsewhere in order to
// display a toolTip. We don't do this for misspelling markers.
- if (grammar) {
+ if (grammar || isDictationMarker) {
markerRect.move(-boxOrigin.x(), -boxOrigin.y());
markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
toRenderedDocumentMarker(marker)->setRenderedRect(markerRect);
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index 157d84bcc..1fc2d80f9 100755
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -590,7 +590,13 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
RenderBoxModelObject* currChild = this;
RenderObject* currChildNextSibling = currChild->nextSibling();
-
+ bool documentUsesBeforeAfterRules = document()->usesBeforeAfterRules();
+
+ // Note: |this| can be destroyed inside this loop if it is an empty anonymous
+ // block and we try to call updateBeforeAfterContent inside which removes the
+ // generated content and additionally cleans up |this| empty anonymous block.
+ // See RenderBlock::removeChild(). DO NOT reference any local variables to |this|
+ // after this point.
while (curr && curr != fromBlock) {
ASSERT(curr->isRenderBlock());
@@ -617,7 +623,7 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
// has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after
// content gets properly destroyed.
bool isLastChild = (currChildNextSibling == blockCurr->lastChild());
- if (document()->usesBeforeAfterRules())
+ if (documentUsesBeforeAfterRules)
blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
if (isLastChild && currChildNextSibling != blockCurr->lastChild())
currChildNextSibling = 0; // We destroyed the last child, so now we need to update
@@ -627,8 +633,7 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
// Since we are doing layout anyway, it is easier to blow away the entire list, than
// traversing down the subtree looking for positioned children and then remove them
// from our positioned objects list.
- if (currChildNextSibling)
- blockCurr->removePositionedObjects(0);
+ blockCurr->removePositionedObjects(0);
// Now we need to take all of the children starting from the first child
// *after* currChild and append them all to the clone.
@@ -1228,6 +1233,32 @@ void RenderBlock::removeChild(RenderObject* oldChild)
// If this was our last child be sure to clear out our line boxes.
if (childrenInline())
deleteLineBoxTree();
+
+ // If we are an empty anonymous block in the continuation chain,
+ // we need to remove ourself and fix the continuation chain.
+ if (!beingDestroyed() && isAnonymousBlockContinuation()) {
+ RenderObject* containingBlockIgnoringAnonymous = containingBlock();
+ while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
+ containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
+ for (RenderObject* curr = this; curr; curr = curr->previousInPreOrder(containingBlockIgnoringAnonymous)) {
+ if (curr->virtualContinuation() != this)
+ continue;
+
+ // Found our previous continuation. We just need to point it to
+ // |this|'s next continuation.
+ RenderBoxModelObject* nextContinuation = continuation();
+ if (curr->isRenderInline())
+ toRenderInline(curr)->setContinuation(nextContinuation);
+ else if (curr->isRenderBlock())
+ toRenderBlock(curr)->setContinuation(nextContinuation);
+ else
+ ASSERT_NOT_REACHED();
+
+ break;
+ }
+ setContinuation(0);
+ destroy();
+ }
}
}
@@ -2643,17 +2674,18 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain
bool antialias = shouldAntialiasLines(paintInfo.context);
if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
- LayoutUnit currLogicalLeftOffset = style()->isLeftToRightDirection() ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
+ bool leftToRight = style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed();
+ LayoutUnit currLogicalLeftOffset = leftToRight ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
LayoutUnit ruleAdd = logicalLeftOffsetForContent();
- LayoutUnit ruleLogicalLeft = style()->isLeftToRightDirection() ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
+ LayoutUnit ruleLogicalLeft = leftToRight ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
BoxSide boxSide = isHorizontalWritingMode()
- ? style()->isLeftToRightDirection() ? BSLeft : BSRight
- : style()->isLeftToRightDirection() ? BSTop : BSBottom;
+ ? leftToRight ? BSLeft : BSRight
+ : leftToRight ? BSTop : BSBottom;
for (unsigned i = 0; i < colCount; i++) {
// Move to the next position.
- if (style()->isLeftToRightDirection()) {
+ if (leftToRight) {
ruleLogicalLeft += inlineDirectionSize + colGap / 2;
currLogicalLeftOffset += inlineDirectionSize + colGap;
} else {
@@ -2674,20 +2706,31 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain
ruleLogicalLeft = currLogicalLeftOffset;
}
} else {
- LayoutUnit ruleLeft = isHorizontalWritingMode() ? borderLeft() + paddingLeft() : colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore();
+ bool topToBottom = !style()->isFlippedBlocksWritingMode() ^ colInfo->progressionIsReversed();
+ LayoutUnit ruleLeft = isHorizontalWritingMode()
+ ? borderLeft() + paddingLeft()
+ : colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter());
LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : ruleThickness;
- LayoutUnit ruleTop = isHorizontalWritingMode() ? colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore() : borderStart() + paddingStart();
+ LayoutUnit ruleTop = isHorizontalWritingMode()
+ ? colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter())
+ : borderStart() + paddingStart();
LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : contentHeight();
LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
- flipForWritingMode(ruleRect);
+ if (!topToBottom) {
+ if (isHorizontalWritingMode())
+ ruleRect.setY(height() - ruleRect.maxY());
+ else
+ ruleRect.setX(width() - ruleRect.maxX());
+ }
+
ruleRect.moveBy(paintOffset);
BoxSide boxSide = isHorizontalWritingMode()
- ? !style()->isFlippedBlocksWritingMode() ? BSTop : BSBottom
- : !style()->isFlippedBlocksWritingMode() ? BSLeft : BSRight;
+ ? topToBottom ? BSTop : BSBottom
+ : topToBottom ? BSLeft : BSRight;
- LayoutSize step(0, !style()->isFlippedBlocksWritingMode() ? colInfo->columnHeight() + colGap : -(colInfo->columnHeight() + colGap));
+ LayoutSize step(0, topToBottom ? colInfo->columnHeight() + colGap : -(colInfo->columnHeight() + colGap));
if (!isHorizontalWritingMode())
step = step.transposedSize();
@@ -2739,7 +2782,7 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& p
// like overflow:hidden.
// FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
// are clipped according to the 'overflow' property.
- context->clip(clipRect);
+ context->clip(pixelSnappedIntRect(clipRect));
// Adjust our x and y when painting.
LayoutPoint adjustedPaintOffset = paintOffset + offset;
@@ -3166,12 +3209,12 @@ static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoi
}
}
-static int blockDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
+static LayoutUnit blockDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
{
return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
}
-static int inlineDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
+static LayoutUnit inlineDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
{
return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
}
@@ -3377,31 +3420,23 @@ LayoutRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const LayoutPo
LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
+ paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selectionBackgroundColor(), style()->colorSpace());
return gapRect;
}
-static inline void alignSelectionRectToDevicePixels(LayoutRect& rect)
-{
- LayoutUnit maxX = floorToInt(rect.maxX());
- rect.setX(floorToInt(rect.x()));
- rect.setWidth((maxX - rect.x()).round());
-}
-
LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
{
LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
LayoutUnit rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
- LayoutUnit rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
+ LayoutUnit rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalLeft), min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
if (rootBlockLogicalWidth <= ZERO_LAYOUT_UNIT)
return LayoutRect();
LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
- alignSelectionRectToDevicePixels(gapRect);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
+ paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -3409,16 +3444,15 @@ LayoutRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const L
RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
{
LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
- LayoutUnit rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
+ LayoutUnit rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalRight), max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
LayoutUnit rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
if (rootBlockLogicalWidth <= ZERO_LAYOUT_UNIT)
return LayoutRect();
LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
- alignSelectionRectToDevicePixels(gapRect);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
+ paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -3513,18 +3547,12 @@ void RenderBlock::insertPositionedObject(RenderBox* o)
m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
m_positionedObjects->add(o);
-
- if (o->style()->position() == FixedPosition && view())
- view()->insertFixedPositionedObject(o);
}
void RenderBlock::removePositionedObject(RenderBox* o)
{
if (m_positionedObjects)
m_positionedObjects->remove(o);
-
- if (view())
- view()->removeFixedPositionedObject(o);
}
void RenderBlock::removePositionedObjects(RenderBlock* o)
@@ -4963,6 +4991,7 @@ void RenderBlock::setDesiredColumnCountAndWidth(int count, LayoutUnit width)
info->setDesiredColumnCount(count);
info->setDesiredColumnWidth(width);
info->setProgressionAxis(style()->hasInlineColumnAxis() ? ColumnInfo::InlineAxis : ColumnInfo::BlockAxis);
+ info->setProgressionIsReversed(style()->columnProgression() == ReverseColumnProgression);
}
}
@@ -5005,12 +5034,16 @@ LayoutRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
LayoutUnit colLogicalLeft = logicalLeftOffsetForContent();
int colGap = columnGap();
if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
- if (style()->isLeftToRightDirection())
+ if (style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed())
colLogicalLeft += index * (colLogicalWidth + colGap);
else
colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
- } else
- colLogicalTop += index * (colLogicalHeight + colGap);
+ } else {
+ if (!colInfo->progressionIsReversed())
+ colLogicalTop += index * (colLogicalHeight + colGap);
+ else
+ colLogicalTop += contentLogicalHeight() - colLogicalHeight - index * (colLogicalHeight + colGap);
+ }
if (isHorizontalWritingMode())
return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
@@ -5697,9 +5730,6 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
}
-// Use a very large value (in effect infinite).
-#define BLOCK_MAX_WIDTH 15000
-
void RenderBlock::computeBlockPreferredLogicalWidths()
{
RenderStyle* styleToUse = style();
@@ -6493,80 +6523,17 @@ LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, La
if (firstChild())
return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
- // This is a special case:
- // The element is not an inline element, and it's empty. So we have to
- // calculate a fake position to indicate where objects are to be inserted.
-
- // FIXME: This does not take into account either :first-line or :first-letter
- // However, as soon as some content is entered, the line boxes will be
- // constructed and this kludge is not called any more. So only the caret size
- // of an empty :first-line'd block is wrong. I think we can live with that.
- RenderStyle* currentStyle = firstLineStyle();
- LayoutUnit height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
-
- enum CaretAlignment { alignLeft, alignRight, alignCenter };
-
- CaretAlignment alignment = alignLeft;
-
- switch (currentStyle->textAlign()) {
- case TAAUTO:
- case JUSTIFY:
- if (!currentStyle->isLeftToRightDirection())
- alignment = alignRight;
- break;
- case LEFT:
- case WEBKIT_LEFT:
- break;
- case CENTER:
- case WEBKIT_CENTER:
- alignment = alignCenter;
- break;
- case RIGHT:
- case WEBKIT_RIGHT:
- alignment = alignRight;
- break;
- case TASTART:
- if (!currentStyle->isLeftToRightDirection())
- alignment = alignRight;
- break;
- case TAEND:
- if (currentStyle->isLeftToRightDirection())
- alignment = alignRight;
- break;
- }
-
- LayoutUnit x = borderLeft() + paddingLeft();
- LayoutUnit w = width();
-
- switch (alignment) {
- case alignLeft:
- if (currentStyle->isLeftToRightDirection())
- x += textIndentOffset();
- break;
- case alignCenter:
- x = (x + w - (borderRight() + paddingRight())) / 2;
- if (currentStyle->isLeftToRightDirection())
- x += textIndentOffset() / 2;
- else
- x -= textIndentOffset() / 2;
- break;
- case alignRight:
- x = w - (borderRight() + paddingRight()) - caretWidth;
- if (!currentStyle->isLeftToRightDirection())
- x -= textIndentOffset();
- break;
- }
- x = min(x, w - borderRight() - paddingRight() - caretWidth);
+ LayoutRect caretRect = localCaretRectForEmptyElement(width(), textIndentOffset());
if (extraWidthToEndOfLine) {
if (isRenderBlock()) {
- *extraWidthToEndOfLine = w - (x + caretWidth);
+ *extraWidthToEndOfLine = width() - caretRect.maxX();
} else {
// FIXME: This code looks wrong.
// myRight and containerRight are set up, but then clobbered.
// So *extraWidthToEndOfLine will always be 0 here.
- LayoutUnit myRight = x + caretWidth;
+ LayoutUnit myRight = caretRect.maxX();
// FIXME: why call localToAbsoluteForContent() twice here, too?
FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
@@ -6577,9 +6544,7 @@ LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, La
}
}
- LayoutUnit y = paddingTop() + borderTop();
-
- return LayoutRect(x, y, caretWidth, height);
+ return caretRect;
}
void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset)
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index eb7e87efb..046ffef39 100755
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -98,7 +98,7 @@ public:
private:
void computeAvailableWidthFromLeftAndRight()
{
- m_availableWidth = max(0, m_right - m_left) + m_overhangWidth;
+ m_availableWidth = max(0.0f, m_right - m_left) + m_overhangWidth;
}
private:
@@ -106,8 +106,8 @@ private:
float m_uncommittedWidth;
float m_committedWidth;
float m_overhangWidth; // The amount by which |m_availableWidth| has been inflated to account for possible contraction due to ruby overhang.
- int m_left;
- int m_right;
+ float m_left;
+ float m_right;
float m_availableWidth;
bool m_isFirstLine;
};
@@ -115,8 +115,8 @@ private:
inline void LineWidth::updateAvailableWidth()
{
LayoutUnit height = m_block->logicalHeight();
- m_left = m_block->pixelSnappedLogicalLeftOffsetForLine(height, m_isFirstLine);
- m_right = m_block->pixelSnappedLogicalRightOffsetForLine(height, m_isFirstLine);
+ m_left = m_block->logicalLeftOffsetForLine(height, m_isFirstLine);
+ m_right = m_block->logicalRightOffsetForLine(height, m_isFirstLine);
computeAvailableWidthFromLeftAndRight();
}
@@ -554,7 +554,7 @@ ETextAlign RenderBlock::textAlignmentForLine(bool endsWithSoftBreak) const
{
ETextAlign alignment = style()->textAlign();
if (!endsWithSoftBreak && alignment == JUSTIFY)
- alignment = TAAUTO;
+ alignment = TASTART;
return alignment;
}
@@ -714,6 +714,14 @@ void RenderBlock::updateLogicalWidthForAlignment(const ETextAlign& textAlign, Bi
case WEBKIT_LEFT:
updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
break;
+ case RIGHT:
+ case WEBKIT_RIGHT:
+ updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
+ break;
+ case CENTER:
+ case WEBKIT_CENTER:
+ updateLogicalWidthForCenterAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
+ break;
case JUSTIFY:
adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, availableLogicalWidth);
if (expansionOpportunityCount) {
@@ -723,22 +731,7 @@ void RenderBlock::updateLogicalWidthForAlignment(const ETextAlign& textAlign, Bi
}
break;
}
- // fall through
- case TAAUTO:
- // for right to left fall through to right aligned
- if (style()->isLeftToRightDirection()) {
- if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
- trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
- break;
- }
- case RIGHT:
- case WEBKIT_RIGHT:
- updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
- break;
- case CENTER:
- case WEBKIT_CENTER:
- updateLogicalWidthForCenterAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
- break;
+ // Fall through
case TASTART:
if (style()->isLeftToRightDirection())
updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
@@ -2774,7 +2767,7 @@ LayoutUnit RenderBlock::startAlignedOffsetForLine(RenderBox* child, LayoutUnit p
{
ETextAlign textAlign = style()->textAlign();
- if (textAlign == TAAUTO)
+ if (textAlign == TASTART) // FIXME: Handle TAEND here
return startOffsetForLine(position, firstLine);
// updateLogicalWidthForAlignment() handles the direction of the block so no need to consider it here
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index d6f460eb3..ddca07dd2 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -142,7 +142,7 @@ void RenderBox::willBeDestroyed()
if (RenderView* view = this->view()) {
if (FrameView* frameView = view->frameView()) {
if (styleToUse->position() == FixedPosition)
- frameView->removeFixedObject();
+ frameView->removeFixedObject(this);
}
}
}
@@ -221,9 +221,9 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl
bool oldStyleIsFixed = oldStyle && oldStyle->position() == FixedPosition;
if (newStyleIsFixed != oldStyleIsFixed) {
if (newStyleIsFixed)
- frameView->addFixedObject();
+ frameView->addFixedObject(this);
else
- frameView->removeFixedObject();
+ frameView->removeFixedObject(this);
}
}
@@ -677,14 +677,14 @@ bool RenderBox::hasOverrideWidth() const
return gOverrideWidthMap && gOverrideWidthMap->contains(this);
}
-void RenderBox::setOverrideHeight(LayoutUnit height)
+void RenderBox::setOverrideLogicalContentHeight(LayoutUnit height)
{
if (!gOverrideHeightMap)
gOverrideHeightMap = new OverrideSizeMap();
gOverrideHeightMap->set(this, height);
}
-void RenderBox::setOverrideWidth(LayoutUnit width)
+void RenderBox::setOverrideLogicalContentWidth(LayoutUnit width)
{
if (!gOverrideWidthMap)
gOverrideWidthMap = new OverrideSizeMap();
@@ -699,14 +699,14 @@ void RenderBox::clearOverrideSize()
gOverrideWidthMap->remove(this);
}
-LayoutUnit RenderBox::overrideWidth() const
+LayoutUnit RenderBox::overrideLogicalContentWidth() const
{
- return hasOverrideWidth() ? gOverrideWidthMap->get(this) : width();
+ return hasOverrideWidth() ? gOverrideWidthMap->get(this) : contentWidth();
}
-LayoutUnit RenderBox::overrideHeight() const
+LayoutUnit RenderBox::overrideLogicalContentHeight() const
{
- return hasOverrideHeight() ? gOverrideHeightMap->get(this) : height();
+ return hasOverrideHeight() ? gOverrideHeightMap->get(this) : contentHeight();
}
LayoutUnit RenderBox::computeBorderBoxLogicalWidth(LayoutUnit width) const
@@ -1241,6 +1241,9 @@ LayoutUnit RenderBox::containingBlockAvailableLineWidthInRegion(RenderRegion* re
LayoutUnit RenderBox::perpendicularContainingBlockLogicalHeight() const
{
RenderBlock* cb = containingBlock();
+ if (cb->hasOverrideHeight())
+ return cb->overrideLogicalContentHeight();
+
RenderStyle* containingBlockStyle = cb->style();
Length logicalHeightLength = containingBlockStyle->logicalHeight();
@@ -1649,7 +1652,7 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
// FIXME: Account for block-flow in flexible boxes.
// https://bugs.webkit.org/show_bug.cgi?id=46418
if (hasOverrideWidth() && parent()->isFlexibleBoxIncludingDeprecated()) {
- setLogicalWidth(overrideWidth());
+ setLogicalWidth(overrideLogicalContentWidth() + borderAndPaddingLogicalWidth());
return;
}
@@ -1689,25 +1692,19 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
// Calculate MaxLogicalWidth
if (!styleToUse->logicalMaxWidth().isUndefined()) {
LayoutUnit maxLogicalWidth = computeLogicalWidthInRegionUsing(MaxLogicalWidth, containerWidthInInlineDirection, cb, region, offsetFromLogicalTopOfFirstPage);
- if (logicalWidth() > maxLogicalWidth) {
+ if (logicalWidth() > maxLogicalWidth)
setLogicalWidth(maxLogicalWidth);
- logicalWidthLength = styleToUse->logicalMaxWidth();
- }
}
// Calculate MinLogicalWidth
LayoutUnit minLogicalWidth = computeLogicalWidthInRegionUsing(MinLogicalWidth, containerWidthInInlineDirection, cb, region, offsetFromLogicalTopOfFirstPage);
- if (logicalWidth() < minLogicalWidth) {
+ if (logicalWidth() < minLogicalWidth)
setLogicalWidth(minLogicalWidth);
- logicalWidthLength = styleToUse->logicalMinWidth();
- }
}
// Fieldsets are currently the only objects that stretch to their minimum width.
- if (stretchesToMinIntrinsicLogicalWidth()) {
+ if (stretchesToMinIntrinsicLogicalWidth())
setLogicalWidth(max(logicalWidth(), minPreferredLogicalWidth()));
- logicalWidthLength = Length(logicalWidth(), Fixed);
- }
// Margin calculations.
if (hasPerpendicularContainingBlock || isFloating() || isInline()) {
@@ -1983,7 +1980,7 @@ void RenderBox::computeLogicalHeight()
// https://bugs.webkit.org/show_bug.cgi?id=46418
RenderStyle* styleToUse = style();
if (hasOverrideHeight() && parent()->isFlexibleBoxIncludingDeprecated())
- h = Length(overrideHeight() - borderAndPaddingLogicalHeight(), Fixed);
+ h = Length(overrideLogicalContentHeight(), Fixed);
else if (treatAsReplaced)
h = Length(computeReplacedLogicalHeight(), Fixed);
else {
@@ -2122,7 +2119,7 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height)
return 0;
return -1;
}
- result = cb->overrideHeight();
+ result = cb->overrideLogicalContentHeight();
includeBorderPadding = true;
}
}
@@ -2286,7 +2283,7 @@ LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h) const
// artificially. We're going to rely on this cell getting expanded to some new
// height, and then when we lay out again we'll use the calculation below.
if (isTableCell() && (h.isAuto() || h.isPercent()))
- return overrideHeight() - borderAndPaddingLogicalWidth();
+ return overrideLogicalContentHeight();
if (h.isPercent()) {
LayoutUnit availableHeight;
diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h
index c3696ab8d..4bebf7eab 100644
--- a/Source/WebCore/rendering/RenderBox.h
+++ b/Source/WebCore/rendering/RenderBox.h
@@ -268,12 +268,12 @@ public:
virtual LayoutUnit minPreferredLogicalWidth() const;
virtual LayoutUnit maxPreferredLogicalWidth() const;
- LayoutUnit overrideWidth() const;
- LayoutUnit overrideHeight() const;
+ LayoutUnit overrideLogicalContentWidth() const;
+ LayoutUnit overrideLogicalContentHeight() const;
bool hasOverrideHeight() const;
bool hasOverrideWidth() const;
- void setOverrideHeight(LayoutUnit);
- void setOverrideWidth(LayoutUnit);
+ void setOverrideLogicalContentHeight(LayoutUnit);
+ void setOverrideLogicalContentWidth(LayoutUnit);
void clearOverrideSize();
virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp
index 0cbf9913f..d40fba151 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp
@@ -811,7 +811,11 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
scrolledPaintRect.width() - bLeft - bRight - (includePadding ? pLeft + pRight : ZERO_LAYOUT_UNIT),
scrolledPaintRect.height() - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : ZERO_LAYOUT_UNIT));
backgroundClipStateSaver.save();
- context->clip(clipRect);
+ if (clipToBorderRadius && includePadding) {
+ RoundedRect rounded = getBackgroundRoundedRect(clipRect, box, boxSize.width(), boxSize.height(), includeLeftEdge, includeRightEdge);
+ context->addRoundedRectClip(rounded);
+ } else
+ context->clip(clipRect);
} else if (bgLayer->clip() == TextFillBox) {
// We have to draw our text into a mask that can then be used to clip background drawing.
// First figure out how big the mask has to be. It should be no bigger than what we need
@@ -977,7 +981,7 @@ static inline IntSize resolveAgainstIntrinsicRatio(const IntSize& size, const Fl
return IntSize(size.width(), solutionHeight);
}
-IntSize RenderBoxModelObject::calculateImageIntrinsicDimensions(StyleImage* image, const IntSize& positioningAreaSize) const
+IntSize RenderBoxModelObject::calculateImageIntrinsicDimensions(StyleImage* image, const IntSize& positioningAreaSize, ScaleByEffectiveZoomOrNot shouldScaleOrNot) const
{
// A generated image without a fixed size, will always return the container size as intrinsic size.
if (image->isGeneratedImage() && image->usesImageContainerSize())
@@ -1001,7 +1005,8 @@ IntSize RenderBoxModelObject::calculateImageIntrinsicDimensions(StyleImage* imag
IntSize resolvedSize(intrinsicWidth.isFixed() ? intrinsicWidth.value() : 0, intrinsicHeight.isFixed() ? intrinsicHeight.value() : 0);
IntSize minimumSize(resolvedSize.width() > 0 ? 1 : 0, resolvedSize.height() > 0 ? 1 : 0);
- resolvedSize.scale(style()->effectiveZoom());
+ if (shouldScaleOrNot == ScaleByEffectiveZoom)
+ resolvedSize.scale(style()->effectiveZoom());
resolvedSize.clampToMinimumSize(minimumSize);
if (!resolvedSize.isEmpty())
@@ -1030,7 +1035,7 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
StyleImage* image = fillLayer->image();
EFillSizeType type = fillLayer->size().type;
- IntSize imageIntrinsicSize = calculateImageIntrinsicDimensions(image, positioningAreaSize);
+ IntSize imageIntrinsicSize = calculateImageIntrinsicDimensions(image, positioningAreaSize, ScaleByEffectiveZoom);
imageIntrinsicSize.scale(1 / image->imageScaleFactor(), 1 / image->imageScaleFactor());
RenderView* renderView = view();
switch (type) {
@@ -1241,13 +1246,13 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
LayoutUnit rightWithOutset = rect.maxX() + rightOutset;
IntRect borderImageRect = pixelSnappedIntRect(leftWithOutset, topWithOutset, rightWithOutset - leftWithOutset, bottomWithOutset - topWithOutset);
- IntSize imageSize = calculateImageIntrinsicDimensions(styleImage, borderImageRect.size());
+ IntSize imageSize = calculateImageIntrinsicDimensions(styleImage, borderImageRect.size(), DoNotScaleByEffectiveZoom);
// If both values are ‘auto’ then the intrinsic width and/or height of the image should be used, if any.
styleImage->setContainerSizeForRenderer(this, imageSize, style->effectiveZoom());
- int imageWidth = imageSize.width() / style->effectiveZoom();
- int imageHeight = imageSize.height() / style->effectiveZoom();
+ int imageWidth = imageSize.width();
+ int imageHeight = imageSize.height();
RenderView* renderView = view();
float imageScaleFactor = styleImage->imageScaleFactor();
@@ -1493,7 +1498,6 @@ static bool allCornersClippedOut(const RoundedRect& border, const LayoutRect& cl
return true;
}
-#if HAVE(PATH_BASED_BORDER_RADIUS_DRAWING)
static bool borderWillArcInnerEdge(const LayoutSize& firstRadius, const FloatSize& secondRadius)
{
return !firstRadius.isZero() || !secondRadius.isZero();
@@ -2100,337 +2104,17 @@ void RenderBoxModelObject::drawBoxSideFromPath(GraphicsContext* graphicsContext,
graphicsContext->setFillColor(color, style->colorSpace());
graphicsContext->drawRect(pixelSnappedIntRect(borderRect));
}
-#else
-void RenderBoxModelObject::paintBorder(const PaintInfo& info, const IntRect& rect, const RenderStyle* style,
- BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
-{
- GraphicsContext* graphicsContext = info.context;
- // FIXME: This old version of paintBorder should be removed when all ports implement
- // GraphicsContext::clipConvexPolygon()!! This should happen soon.
- if (paintNinePieceImage(graphicsContext, rect, style, style->borderImage()))
- return;
-
- const Color& topColor = style->visitedDependentColor(CSSPropertyBorderTopColor);
- const Color& bottomColor = style->visitedDependentColor(CSSPropertyBorderBottomColor);
- const Color& leftColor = style->visitedDependentColor(CSSPropertyBorderLeftColor);
- const Color& rightColor = style->visitedDependentColor(CSSPropertyBorderRightColor);
-
- bool topTransparent = style->borderTopIsTransparent();
- bool bottomTransparent = style->borderBottomIsTransparent();
- bool rightTransparent = style->borderRightIsTransparent();
- bool leftTransparent = style->borderLeftIsTransparent();
-
- EBorderStyle topStyle = style->borderTopStyle();
- EBorderStyle bottomStyle = style->borderBottomStyle();
- EBorderStyle leftStyle = style->borderLeftStyle();
- EBorderStyle rightStyle = style->borderRightStyle();
-
- bool horizontal = style->isHorizontalWritingMode();
- bool renderTop = topStyle > BHIDDEN && !topTransparent && (horizontal || includeLogicalLeftEdge);
- bool renderLeft = leftStyle > BHIDDEN && !leftTransparent && (!horizontal || includeLogicalLeftEdge);
- bool renderRight = rightStyle > BHIDDEN && !rightTransparent && (!horizontal || includeLogicalRightEdge);
- bool renderBottom = bottomStyle > BHIDDEN && !bottomTransparent && (horizontal || includeLogicalRightEdge);
-
-
- RoundedRect border(rect);
-
- GraphicsContextStateSaver stateSaver(*graphicsContext, false);
- if (style->hasBorderRadius()) {
- border.includeLogicalEdges(style->getRoundedBorderFor(border.rect(), view()).radii(),
- horizontal, includeLogicalLeftEdge, includeLogicalRightEdge);
- if (border.isRounded()) {
- stateSaver.save();
- graphicsContext->addRoundedRectClip(border);
- }
- }
-
- int firstAngleStart, secondAngleStart, firstAngleSpan, secondAngleSpan;
- float thickness;
- bool renderRadii = border.isRounded();
- bool upperLeftBorderStylesMatch = renderLeft && (topStyle == leftStyle) && (topColor == leftColor);
- bool upperRightBorderStylesMatch = renderRight && (topStyle == rightStyle) && (topColor == rightColor) && (topStyle != OUTSET) && (topStyle != RIDGE) && (topStyle != INSET) && (topStyle != GROOVE);
- bool lowerLeftBorderStylesMatch = renderLeft && (bottomStyle == leftStyle) && (bottomColor == leftColor) && (bottomStyle != OUTSET) && (bottomStyle != RIDGE) && (bottomStyle != INSET) && (bottomStyle != GROOVE);
- bool lowerRightBorderStylesMatch = renderRight && (bottomStyle == rightStyle) && (bottomColor == rightColor);
-
- if (renderTop) {
- bool ignoreLeft = (renderRadii && border.radii().topLeft().width() > 0)
- || (topColor == leftColor && topTransparent == leftTransparent && topStyle >= OUTSET
- && (leftStyle == DOTTED || leftStyle == DASHED || leftStyle == SOLID || leftStyle == OUTSET));
-
- bool ignoreRight = (renderRadii && border.radii().topRight().width() > 0)
- || (topColor == rightColor && topTransparent == rightTransparent && topStyle >= OUTSET
- && (rightStyle == DOTTED || rightStyle == DASHED || rightStyle == SOLID || rightStyle == INSET));
-
- int x = rect.x();
- int x2 = rect.maxX();
- if (renderRadii) {
- x += border.radii().topLeft().width();
- x2 -= border.radii().topRight().width();
- }
-
- drawLineForBoxSide(graphicsContext, x, rect.y(), x2, rect.y() + style->borderTopWidth(), BSTop, topColor, topStyle,
- ignoreLeft ? 0 : style->borderLeftWidth(), ignoreRight ? 0 : style->borderRightWidth());
-
- if (renderRadii) {
- int leftY = rect.y();
-
- // We make the arc double thick and let the clip rect take care of clipping the extra off.
- // We're doing this because it doesn't seem possible to match the curve of the clip exactly
- // with the arc-drawing function.
- thickness = style->borderTopWidth() * 2;
-
- if (border.radii().topLeft().width()) {
- int leftX = rect.x();
- // The inner clip clips inside the arc. This is especially important for 1px borders.
- bool applyLeftInnerClip = (style->borderLeftWidth() < border.radii().topLeft().width())
- && (style->borderTopWidth() < border.radii().topLeft().height())
- && (topStyle != DOUBLE || style->borderTopWidth() > 6);
-
- GraphicsContextStateSaver stateSaver(*graphicsContext, applyLeftInnerClip);
- if (applyLeftInnerClip)
- graphicsContext->addInnerRoundedRectClip(IntRect(leftX, leftY, border.radii().topLeft().width() * 2, border.radii().topLeft().height() * 2),
- style->borderTopWidth());
-
- firstAngleStart = 90;
- firstAngleSpan = upperLeftBorderStylesMatch ? 90 : 45;
-
- // Draw upper left arc
- drawArcForBoxSide(graphicsContext, leftX, leftY, thickness, border.radii().topLeft(), firstAngleStart, firstAngleSpan,
- BSTop, topColor, topStyle, true);
- }
-
- if (border.radii().topRight().width()) {
- int rightX = rect.maxX() - border.radii().topRight().width() * 2;
- bool applyRightInnerClip = (style->borderRightWidth() < border.radii().topRight().width())
- && (style->borderTopWidth() < border.radii().topRight().height())
- && (topStyle != DOUBLE || style->borderTopWidth() > 6);
-
- GraphicsContextStateSaver stateSaver(*graphicsContext, applyRightInnerClip);
- if (applyRightInnerClip)
- graphicsContext->addInnerRoundedRectClip(IntRect(rightX, leftY, border.radii().topRight().width() * 2, border.radii().topRight().height() * 2),
- style->borderTopWidth());
-
- if (upperRightBorderStylesMatch) {
- secondAngleStart = 0;
- secondAngleSpan = 90;
- } else {
- secondAngleStart = 45;
- secondAngleSpan = 45;
- }
-
- // Draw upper right arc
- drawArcForBoxSide(graphicsContext, rightX, leftY, thickness, border.radii().topRight(), secondAngleStart, secondAngleSpan,
- BSTop, topColor, topStyle, false);
- }
- }
- }
-
- if (renderBottom) {
- bool ignoreLeft = (renderRadii && border.radii().bottomLeft().width() > 0)
- || (bottomColor == leftColor && bottomTransparent == leftTransparent && bottomStyle >= OUTSET
- && (leftStyle == DOTTED || leftStyle == DASHED || leftStyle == SOLID || leftStyle == OUTSET));
-
- bool ignoreRight = (renderRadii && border.radii().bottomRight().width() > 0)
- || (bottomColor == rightColor && bottomTransparent == rightTransparent && bottomStyle >= OUTSET
- && (rightStyle == DOTTED || rightStyle == DASHED || rightStyle == SOLID || rightStyle == INSET));
-
- int x = rect.x();
- int x2 = rect.maxX();
- if (renderRadii) {
- x += border.radii().bottomLeft().width();
- x2 -= border.radii().bottomRight().width();
- }
-
- drawLineForBoxSide(graphicsContext, x, rect.maxY() - style->borderBottomWidth(), x2, rect.maxY(), BSBottom, bottomColor, bottomStyle,
- ignoreLeft ? 0 : style->borderLeftWidth(), ignoreRight ? 0 : style->borderRightWidth());
-
- if (renderRadii) {
- thickness = style->borderBottomWidth() * 2;
-
- if (border.radii().bottomLeft().width()) {
- int leftX = rect.x();
- int leftY = rect.maxY() - border.radii().bottomLeft().height() * 2;
- bool applyLeftInnerClip = (style->borderLeftWidth() < border.radii().bottomLeft().width())
- && (style->borderBottomWidth() < border.radii().bottomLeft().height())
- && (bottomStyle != DOUBLE || style->borderBottomWidth() > 6);
-
- GraphicsContextStateSaver stateSaver(*graphicsContext, applyLeftInnerClip);
- if (applyLeftInnerClip)
- graphicsContext->addInnerRoundedRectClip(IntRect(leftX, leftY, border.radii().bottomLeft().width() * 2, border.radii().bottomLeft().height() * 2),
- style->borderBottomWidth());
-
- if (lowerLeftBorderStylesMatch) {
- firstAngleStart = 180;
- firstAngleSpan = 90;
- } else {
- firstAngleStart = 225;
- firstAngleSpan = 45;
- }
-
- // Draw lower left arc
- drawArcForBoxSide(graphicsContext, leftX, leftY, thickness, border.radii().bottomLeft(), firstAngleStart, firstAngleSpan,
- BSBottom, bottomColor, bottomStyle, true);
- }
-
- if (border.radii().bottomRight().width()) {
- int rightY = rect.maxY() - border.radii().bottomRight().height() * 2;
- int rightX = rect.maxX() - border.radii().bottomRight().width() * 2;
- bool applyRightInnerClip = (style->borderRightWidth() < border.radii().bottomRight().width())
- && (style->borderBottomWidth() < border.radii().bottomRight().height())
- && (bottomStyle != DOUBLE || style->borderBottomWidth() > 6);
-
- GraphicsContextStateSaver stateSaver(*graphicsContext, applyRightInnerClip);
- if (applyRightInnerClip)
- graphicsContext->addInnerRoundedRectClip(IntRect(rightX, rightY, border.radii().bottomRight().width() * 2, border.radii().bottomRight().height() * 2),
- style->borderBottomWidth());
-
- secondAngleStart = 270;
- secondAngleSpan = lowerRightBorderStylesMatch ? 90 : 45;
-
- // Draw lower right arc
- drawArcForBoxSide(graphicsContext, rightX, rightY, thickness, border.radii().bottomRight(), secondAngleStart, secondAngleSpan,
- BSBottom, bottomColor, bottomStyle, false);
- }
- }
- }
-
- if (renderLeft) {
- bool ignoreTop = (renderRadii && border.radii().topLeft().height() > 0)
- || (topColor == leftColor && topTransparent == leftTransparent && leftStyle >= OUTSET
- && (topStyle == DOTTED || topStyle == DASHED || topStyle == SOLID || topStyle == OUTSET));
-
- bool ignoreBottom = (renderRadii && border.radii().bottomLeft().height() > 0)
- || (bottomColor == leftColor && bottomTransparent == leftTransparent && leftStyle >= OUTSET
- && (bottomStyle == DOTTED || bottomStyle == DASHED || bottomStyle == SOLID || bottomStyle == INSET));
-
- int y = rect.y();
- int y2 = rect.maxY();
- if (renderRadii) {
- y += border.radii().topLeft().height();
- y2 -= border.radii().bottomLeft().height();
- }
-
- drawLineForBoxSide(graphicsContext, rect.x(), y, rect.x() + style->borderLeftWidth(), y2, BSLeft, leftColor, leftStyle,
- ignoreTop ? 0 : style->borderTopWidth(), ignoreBottom ? 0 : style->borderBottomWidth());
-
- if (renderRadii && (!upperLeftBorderStylesMatch || !lowerLeftBorderStylesMatch)) {
- int topX = rect.x();
- thickness = style->borderLeftWidth() * 2;
-
- if (!upperLeftBorderStylesMatch && border.radii().topLeft().width()) {
- int topY = rect.y();
- bool applyTopInnerClip = (style->borderLeftWidth() < border.radii().topLeft().width())
- && (style->borderTopWidth() < border.radii().topLeft().height())
- && (leftStyle != DOUBLE || style->borderLeftWidth() > 6);
-
- GraphicsContextStateSaver stateSaver(*graphicsContext, applyTopInnerClip);
- if (applyTopInnerClip)
- graphicsContext->addInnerRoundedRectClip(IntRect(topX, topY, border.radii().topLeft().width() * 2, border.radii().topLeft().height() * 2),
- style->borderLeftWidth());
-
- firstAngleStart = 135;
- firstAngleSpan = 45;
-
- // Draw top left arc
- drawArcForBoxSide(graphicsContext, topX, topY, thickness, border.radii().topLeft(), firstAngleStart, firstAngleSpan,
- BSLeft, leftColor, leftStyle, true);
- }
-
- if (!lowerLeftBorderStylesMatch && border.radii().bottomLeft().width()) {
- int bottomY = rect.maxY() - border.radii().bottomLeft().height() * 2;
- bool applyBottomInnerClip = (style->borderLeftWidth() < border.radii().bottomLeft().width())
- && (style->borderBottomWidth() < border.radii().bottomLeft().height())
- && (leftStyle != DOUBLE || style->borderLeftWidth() > 6);
-
- GraphicsContextStateSaver stateSaver(*graphicsContext, applyBottomInnerClip);
- if (applyBottomInnerClip)
- graphicsContext->addInnerRoundedRectClip(IntRect(topX, bottomY, border.radii().bottomLeft().width() * 2, border.radii().bottomLeft().height() * 2),
- style->borderLeftWidth());
-
- secondAngleStart = 180;
- secondAngleSpan = 45;
-
- // Draw bottom left arc
- drawArcForBoxSide(graphicsContext, topX, bottomY, thickness, border.radii().bottomLeft(), secondAngleStart, secondAngleSpan,
- BSLeft, leftColor, leftStyle, false);
- }
- }
- }
-
- if (renderRight) {
- bool ignoreTop = (renderRadii && border.radii().topRight().height() > 0)
- || ((topColor == rightColor) && (topTransparent == rightTransparent)
- && (rightStyle >= DOTTED || rightStyle == INSET)
- && (topStyle == DOTTED || topStyle == DASHED || topStyle == SOLID || topStyle == OUTSET));
-
- bool ignoreBottom = (renderRadii && border.radii().bottomRight().height() > 0)
- || ((bottomColor == rightColor) && (bottomTransparent == rightTransparent)
- && (rightStyle >= DOTTED || rightStyle == INSET)
- && (bottomStyle == DOTTED || bottomStyle == DASHED || bottomStyle == SOLID || bottomStyle == INSET));
-
- int y = rect.y();
- int y2 = rect.maxY();
- if (renderRadii) {
- y += border.radii().topRight().height();
- y2 -= border.radii().bottomRight().height();
- }
-
- drawLineForBoxSide(graphicsContext, rect.maxX() - style->borderRightWidth(), y, rect.maxX(), y2, BSRight, rightColor, rightStyle,
- ignoreTop ? 0 : style->borderTopWidth(), ignoreBottom ? 0 : style->borderBottomWidth());
-
- if (renderRadii && (!upperRightBorderStylesMatch || !lowerRightBorderStylesMatch)) {
- thickness = style->borderRightWidth() * 2;
-
- if (!upperRightBorderStylesMatch && border.radii().topRight().width()) {
- int topX = rect.maxX() - border.radii().topRight().width() * 2;
- int topY = rect.y();
- bool applyTopInnerClip = (style->borderRightWidth() < border.radii().topRight().width())
- && (style->borderTopWidth() < border.radii().topRight().height())
- && (rightStyle != DOUBLE || style->borderRightWidth() > 6);
-
- GraphicsContextStateSaver stateSaver(*graphicsContext, applyTopInnerClip);
- if (applyTopInnerClip)
- graphicsContext->addInnerRoundedRectClip(IntRect(topX, topY, border.radii().topRight().width() * 2, border.radii().topRight().height() * 2),
- style->borderRightWidth());
-
- firstAngleStart = 0;
- firstAngleSpan = 45;
-
- // Draw top right arc
- drawArcForBoxSide(graphicsContext, topX, topY, thickness, border.radii().topRight(), firstAngleStart, firstAngleSpan,
- BSRight, rightColor, rightStyle, true);
- }
-
- if (!lowerRightBorderStylesMatch && border.radii().bottomRight().width()) {
- int bottomX = rect.maxX() - border.radii().bottomRight().width() * 2;
- int bottomY = rect.maxY() - border.radii().bottomRight().height() * 2;
- bool applyBottomInnerClip = (style->borderRightWidth() < border.radii().bottomRight().width())
- && (style->borderBottomWidth() < border.radii().bottomRight().height())
- && (rightStyle != DOUBLE || style->borderRightWidth() > 6);
-
- GraphicsContextStateSaver stateSaver(*graphicsContext, applyBottomInnerClip);
- if (applyBottomInnerClip)
- graphicsContext->addInnerRoundedRectClip(IntRect(bottomX, bottomY, border.radii().bottomRight().width() * 2, border.radii().bottomRight().height() * 2),
- style->borderRightWidth());
-
- secondAngleStart = 315;
- secondAngleSpan = 45;
-
- // Draw bottom right arc
- drawArcForBoxSide(graphicsContext, bottomX, bottomY, thickness, border.radii().bottomRight(), secondAngleStart, secondAngleSpan,
- BSRight, rightColor, rightStyle, false);
- }
- }
- }
-}
-#endif
static void findInnerVertex(const FloatPoint& outerCorner, const FloatPoint& innerCorner, const FloatPoint& centerPoint, FloatPoint& result)
{
// If the line between outer and inner corner is towards the horizontal, intersect with a vertical line through the center,
// otherwise with a horizontal line through the center. The points that form this line are arbitrary (we use 0, 100).
// Note that if findIntersection fails, it will leave result untouched.
- if (fabs(outerCorner.x() - innerCorner.x()) > fabs(outerCorner.y() - innerCorner.y()))
+ float diffInnerOuterX = fabs(innerCorner.x() - outerCorner.x());
+ float diffInnerOuterY = fabs(innerCorner.y() - outerCorner.y());
+ float diffCenterOuterX = fabs(centerPoint.x() - outerCorner.x());
+ float diffCenterOuterY = fabs(centerPoint.y() - outerCorner.y());
+ if (diffInnerOuterY * diffCenterOuterX < diffCenterOuterY * diffInnerOuterX)
findIntersection(outerCorner, innerCorner, FloatPoint(centerPoint.x(), 0), FloatPoint(centerPoint.x(), 100), result);
else
findIntersection(outerCorner, innerCorner, FloatPoint(0, centerPoint.y()), FloatPoint(100, centerPoint.y()), result);
@@ -2970,6 +2654,72 @@ void RenderBoxModelObject::setFirstLetterRemainingText(RenderObject* remainingTe
firstLetterRemainingTextMap->remove(this);
}
+LayoutRect RenderBoxModelObject::localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset)
+{
+ ASSERT(!firstChild());
+
+ // FIXME: This does not take into account either :first-line or :first-letter
+ // However, as soon as some content is entered, the line boxes will be
+ // constructed and this kludge is not called any more. So only the caret size
+ // of an empty :first-line'd block is wrong. I think we can live with that.
+ RenderStyle* currentStyle = firstLineStyle();
+ LayoutUnit height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
+
+ enum CaretAlignment { alignLeft, alignRight, alignCenter };
+
+ CaretAlignment alignment = alignLeft;
+
+ switch (currentStyle->textAlign()) {
+ case LEFT:
+ case WEBKIT_LEFT:
+ break;
+ case CENTER:
+ case WEBKIT_CENTER:
+ alignment = alignCenter;
+ break;
+ case RIGHT:
+ case WEBKIT_RIGHT:
+ alignment = alignRight;
+ break;
+ case JUSTIFY:
+ case TASTART:
+ if (!currentStyle->isLeftToRightDirection())
+ alignment = alignRight;
+ break;
+ case TAEND:
+ if (currentStyle->isLeftToRightDirection())
+ alignment = alignRight;
+ break;
+ }
+
+ LayoutUnit x = borderLeft() + paddingLeft();
+ LayoutUnit maxX = width - borderRight() - paddingRight();
+
+ switch (alignment) {
+ case alignLeft:
+ if (currentStyle->isLeftToRightDirection())
+ x += textIndentOffset;
+ break;
+ case alignCenter:
+ x = (x + maxX) / 2;
+ if (currentStyle->isLeftToRightDirection())
+ x += textIndentOffset / 2;
+ else
+ x -= textIndentOffset / 2;
+ break;
+ case alignRight:
+ x = maxX - caretWidth;
+ if (!currentStyle->isLeftToRightDirection())
+ x -= textIndentOffset;
+ break;
+ }
+ x = min(x, max(maxX - caretWidth, ZERO_LAYOUT_UNIT));
+
+ LayoutUnit y = paddingTop() + borderTop();
+
+ return LayoutRect(x, y, caretWidth, height);
+}
+
bool RenderBoxModelObject::shouldAntialiasLines(GraphicsContext* context)
{
// FIXME: We may want to not antialias when scaled by an integral value,
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.h b/Source/WebCore/rendering/RenderBoxModelObject.h
index 28a50ebdf..6c0bcca64 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.h
+++ b/Source/WebCore/rendering/RenderBoxModelObject.h
@@ -237,6 +237,8 @@ protected:
RenderBoxModelObject* continuation() const;
void setContinuation(RenderBoxModelObject*);
+ LayoutRect localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset);
+
static bool shouldAntialiasLines(GraphicsContext*);
public:
@@ -272,7 +274,9 @@ private:
virtual bool isBoxModelObject() const { return true; }
IntSize calculateFillTileSize(const FillLayer*, const IntSize& scaledPositioningAreaSize) const;
- IntSize calculateImageIntrinsicDimensions(StyleImage*, const IntSize& scaledPositioningAreaSize) const;
+
+ enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom };
+ IntSize calculateImageIntrinsicDimensions(StyleImage*, const IntSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) const;
RoundedRect getBackgroundRoundedRect(const LayoutRect&, InlineFlowBox*, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
bool includeLogicalLeftEdge, bool includeLogicalRightEdge);
diff --git a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
index d6165e092..a4c4b8910 100644
--- a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
+++ b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
@@ -543,7 +543,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
if (allowedChildFlex(child, expanding, i)) {
LayoutUnit spaceAdd = LayoutUnit(spaceAvailableThisPass * (child->style()->boxFlex() / totalFlex));
if (spaceAdd) {
- child->setOverrideWidth(child->overrideWidth() + spaceAdd);
+ child->setOverrideLogicalContentWidth(child->overrideLogicalContentWidth() + spaceAdd);
m_flexingChildren = true;
relayoutChildren = true;
}
@@ -560,7 +560,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
LayoutUnit spaceAdd = groupRemainingSpace > 0 ? 1 : -1;
for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) {
if (allowedChildFlex(child, expanding, i)) {
- child->setOverrideWidth(child->overrideWidth() + spaceAdd);
+ child->setOverrideLogicalContentWidth(child->overrideLogicalContentWidth() + spaceAdd);
m_flexingChildren = true;
relayoutChildren = true;
remainingSpace -= spaceAdd;
@@ -794,7 +794,7 @@ void RenderDeprecatedFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (allowedChildFlex(child, expanding, i)) {
LayoutUnit spaceAdd = static_cast<LayoutUnit>(spaceAvailableThisPass * (child->style()->boxFlex() / totalFlex));
if (spaceAdd) {
- child->setOverrideHeight(child->overrideHeight() + spaceAdd);
+ child->setOverrideLogicalContentHeight(child->overrideLogicalContentHeight() + spaceAdd);
m_flexingChildren = true;
relayoutChildren = true;
}
@@ -811,7 +811,7 @@ void RenderDeprecatedFlexibleBox::layoutVerticalBox(bool relayoutChildren)
LayoutUnit spaceAdd = groupRemainingSpace > 0 ? 1 : -1;
for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) {
if (allowedChildFlex(child, expanding, i)) {
- child->setOverrideHeight(child->overrideHeight() + spaceAdd);
+ child->setOverrideLogicalContentHeight(child->overrideLogicalContentHeight() + spaceAdd);
m_flexingChildren = true;
relayoutChildren = true;
remainingSpace -= spaceAdd;
@@ -925,7 +925,7 @@ void RenderDeprecatedFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool
continue;
child->setChildNeedsLayout(true, MarkOnlyThis);
- child->setOverrideHeight(newHeight);
+ child->setOverrideLogicalContentHeight(newHeight - child->borderAndPaddingHeight());
m_flexingChildren = true;
child->layoutIfNeeded();
m_flexingChildren = false;
@@ -1026,7 +1026,7 @@ LayoutUnit RenderDeprecatedFlexibleBox::allowedChildFlex(RenderBox* child, bool
if (isHorizontal()) {
// FIXME: For now just handle fixed values.
LayoutUnit maxWidth = MAX_LAYOUT_UNIT;
- LayoutUnit width = child->overrideWidth() - child->borderAndPaddingWidth();
+ LayoutUnit width = child->overrideLogicalContentWidth();
if (!child->style()->maxWidth().isUndefined() && child->style()->maxWidth().isFixed())
maxWidth = child->style()->maxWidth().value();
else if (child->style()->maxWidth().type() == Intrinsic)
@@ -1039,7 +1039,7 @@ LayoutUnit RenderDeprecatedFlexibleBox::allowedChildFlex(RenderBox* child, bool
} else {
// FIXME: For now just handle fixed values.
LayoutUnit maxHeight = MAX_LAYOUT_UNIT;
- LayoutUnit height = child->overrideHeight() - child->borderAndPaddingHeight();
+ LayoutUnit height = child->overrideLogicalContentHeight();
if (!child->style()->maxHeight().isUndefined() && child->style()->maxHeight().isFixed())
maxHeight = child->style()->maxHeight().value();
if (maxHeight == MAX_LAYOUT_UNIT)
@@ -1051,7 +1051,7 @@ LayoutUnit RenderDeprecatedFlexibleBox::allowedChildFlex(RenderBox* child, bool
// FIXME: For now just handle fixed values.
if (isHorizontal()) {
LayoutUnit minWidth = child->minPreferredLogicalWidth();
- LayoutUnit width = child->overrideWidth() - child->borderAndPaddingWidth();
+ LayoutUnit width = child->overrideLogicalContentWidth();
if (child->style()->minWidth().isFixed())
minWidth = child->style()->minWidth().value();
else if (child->style()->minWidth().type() == Intrinsic)
@@ -1064,7 +1064,7 @@ LayoutUnit RenderDeprecatedFlexibleBox::allowedChildFlex(RenderBox* child, bool
} else {
if (child->style()->minHeight().isFixed()) {
LayoutUnit minHeight = child->style()->minHeight().value();
- LayoutUnit height = child->overrideHeight() - child->borderAndPaddingHeight();
+ LayoutUnit height = child->overrideLogicalContentHeight();
LayoutUnit allowedShrinkage = min<LayoutUnit>(0, minHeight - height);
return allowedShrinkage;
}
diff --git a/Source/WebCore/rendering/RenderFieldset.cpp b/Source/WebCore/rendering/RenderFieldset.cpp
index 8870a872f..3138f22fc 100644
--- a/Source/WebCore/rendering/RenderFieldset.cpp
+++ b/Source/WebCore/rendering/RenderFieldset.cpp
@@ -101,10 +101,24 @@ RenderObject* RenderFieldset::layoutSpecialExcludedChild(bool relayoutChildren)
setLogicalLeftForChild(legend, logicalLeft);
- LayoutUnit b = borderBefore();
- LayoutUnit h = logicalHeightForChild(legend);
- setLogicalTopForChild(legend, max<LayoutUnit>((b - h) / 2, 0));
- setLogicalHeight(max(b, h) + paddingBefore());
+ LayoutUnit fieldsetBorderBefore = borderBefore();
+ LayoutUnit legendLogicalHeight = logicalHeightForChild(legend);
+
+ LayoutUnit legendLogicalTop;
+ LayoutUnit collapsedLegendExtent;
+ // FIXME: We need to account for the legend's margin before too.
+ if (fieldsetBorderBefore > legendLogicalHeight) {
+ // The <legend> is smaller than the associated fieldset before border
+ // so the latter determines positioning of the <legend>. The sizing depends
+ // on the legend's margins as we want to still follow the author's cues.
+ // Firefox completely ignores the margins in this case which seems wrong.
+ legendLogicalTop = (fieldsetBorderBefore - legendLogicalHeight) / 2;
+ collapsedLegendExtent = max<LayoutUnit>(fieldsetBorderBefore, legendLogicalTop + legendLogicalHeight + marginAfterForChild(legend));
+ } else
+ collapsedLegendExtent = legendLogicalHeight + marginAfterForChild(legend);
+
+ setLogicalTopForChild(legend, legendLogicalTop);
+ setLogicalHeight(paddingBefore() + collapsedLegendExtent);
}
return legend;
}
diff --git a/Source/WebCore/rendering/RenderFileUploadControl.cpp b/Source/WebCore/rendering/RenderFileUploadControl.cpp
index db4e6c5cd..3b880ccf1 100644
--- a/Source/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/Source/WebCore/rendering/RenderFileUploadControl.cpp
@@ -109,8 +109,8 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, const LayoutPoin
// Push a clip.
GraphicsContextStateSaver stateSaver(*paintInfo.context, false);
if (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseChildBlockBackgrounds) {
- IntRect clipRect = pixelSnappedIntRect(paintOffset.x() + borderLeft(), paintOffset.y() + borderTop(),
- width() - borderLeft() - borderRight(), height() - borderBottom() - borderTop() + buttonShadowHeight);
+ IntRect clipRect = enclosingIntRect(LayoutRect(paintOffset.x() + borderLeft(), paintOffset.y() + borderTop(),
+ width() - borderLeft() - borderRight(), height() - borderBottom() - borderTop() + buttonShadowHeight));
if (clipRect.isEmpty())
return;
stateSaver.save();
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp
index e62554062..8aba6d9a0 100644
--- a/Source/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp
@@ -39,16 +39,6 @@
namespace WebCore {
-// Normally, -1 and 0 are not valid in a HashSet, but these are relatively likely flex-order values. Instead,
-// we make the two smallest int values invalid flex-order values (in the css parser code we clamp them to
-// int min + 2).
-struct RenderFlexibleBox::OrderHashTraits : WTF::GenericHashTraits<int> {
- static const bool emptyValueIsZero = false;
- static int emptyValue() { return std::numeric_limits<int>::min(); }
- static void constructDeletedValue(int& slot) { slot = std::numeric_limits<int>::min() + 1; }
- static bool isDeletedValue(int value) { return value == std::numeric_limits<int>::min() + 1; }
-};
-
class RenderFlexibleBox::OrderIterator {
public:
OrderIterator(RenderFlexibleBox* flexibleBox, const OrderHashSet& orderValues)
@@ -99,8 +89,8 @@ public:
private:
RenderFlexibleBox* m_flexibleBox;
RenderBox* m_currentChild;
- Vector<int> m_orderValues;
- Vector<int>::const_iterator m_orderValuesIterator;
+ Vector<float> m_orderValues;
+ Vector<float>::const_iterator m_orderValuesIterator;
};
struct RenderFlexibleBox::LineContext {
@@ -299,7 +289,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit)
void RenderFlexibleBox::repositionLogicalHeightDependentFlexItems(OrderIterator& iterator, WTF::Vector<LineContext>& lineContexts, LayoutUnit& oldClientAfterEdge)
{
LayoutUnit crossAxisStartEdge = lineContexts.isEmpty() ? ZERO_LAYOUT_UNIT : lineContexts[0].crossAxisOffset;
- packFlexLines(iterator, lineContexts);
+ alignFlexLines(iterator, lineContexts);
// If we have a single line flexbox, the line height is all the available space.
// For flex-direction: row, this means we need to use the height, so we do this after calling computeLogicalHeight.
@@ -347,9 +337,9 @@ bool RenderFlexibleBox::isMultiline() const
return style()->flexWrap() != FlexWrapNone;
}
-Length RenderFlexibleBox::preferredLengthForChild(RenderBox* child) const
+Length RenderFlexibleBox::flexBasisForChild(RenderBox* child) const
{
- Length flexLength = child->style()->flexPreferredSize();
+ Length flexLength = child->style()->flexBasis();
if (flexLength.isAuto())
flexLength = isHorizontalFlow() ? child->style()->width() : child->style()->height();
return flexLength;
@@ -589,12 +579,12 @@ LayoutUnit RenderFlexibleBox::mainAxisScrollbarExtentForChild(RenderBox* child)
LayoutUnit RenderFlexibleBox::preferredMainAxisContentExtentForChild(RenderBox* child) const
{
- Length mainAxisLength = preferredLengthForChild(child);
- if (mainAxisLength.isAuto()) {
+ Length flexBasis = flexBasisForChild(child);
+ if (flexBasis.isAuto()) {
LayoutUnit mainAxisExtent = hasOrthogonalFlow(child) ? child->logicalHeight() : child->maxPreferredLogicalWidth();
return mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child);
}
- return std::max(LayoutUnit(0), minimumValueForLength(mainAxisLength, mainAxisContentExtent(), view()));
+ return std::max(LayoutUnit(0), minimumValueForLength(flexBasis, mainAxisContentExtent(), view()));
}
LayoutUnit RenderFlexibleBox::computeAvailableFreeSpace(LayoutUnit preferredMainAxisExtent)
@@ -603,7 +593,7 @@ LayoutUnit RenderFlexibleBox::computeAvailableFreeSpace(LayoutUnit preferredMain
if (!isColumnFlow())
contentExtent = mainAxisContentExtent();
else if (hasOverrideHeight())
- contentExtent = overrideHeight() - (logicalHeight() - contentLogicalHeight());
+ contentExtent = overrideLogicalContentHeight();
else {
LayoutUnit heightResult = computeContentLogicalHeightUsing(style()->logicalHeight());
if (heightResult == -1)
@@ -624,18 +614,18 @@ void RenderFlexibleBox::layoutFlexItems(OrderIterator& iterator, WTF::Vector<Lin
{
OrderedFlexItemList orderedChildren;
LayoutUnit preferredMainAxisExtent;
- float totalPositiveFlexibility;
- float totalWeightedNegativeFlexibility;
+ float totalFlexGrow;
+ float totalWeightedFlexShrink;
LayoutUnit minMaxAppliedMainAxisExtent;
LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
- while (computeNextFlexLine(iterator, orderedChildren, preferredMainAxisExtent, totalPositiveFlexibility, totalWeightedNegativeFlexibility, minMaxAppliedMainAxisExtent)) {
+ while (computeNextFlexLine(iterator, orderedChildren, preferredMainAxisExtent, totalFlexGrow, totalWeightedFlexShrink, minMaxAppliedMainAxisExtent)) {
LayoutUnit availableFreeSpace = computeAvailableFreeSpace(preferredMainAxisExtent);
FlexSign flexSign = (minMaxAppliedMainAxisExtent < preferredMainAxisExtent + availableFreeSpace) ? PositiveFlexibility : NegativeFlexibility;
InflexibleFlexItemSize inflexibleItems;
WTF::Vector<LayoutUnit> childSizes;
- while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeSpace, totalPositiveFlexibility, totalWeightedNegativeFlexibility, inflexibleItems, childSizes)) {
- ASSERT(totalPositiveFlexibility >= 0 && totalWeightedNegativeFlexibility >= 0);
+ while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems, childSizes)) {
+ ASSERT(totalFlexGrow >= 0 && totalWeightedFlexShrink >= 0);
ASSERT(inflexibleItems.size() > 0);
}
@@ -758,7 +748,7 @@ void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, Ord
child->clearOverrideSize();
// Only need to layout here if we will need to get the logicalHeight of the child in computeNextFlexLine.
- if (hasOrthogonalFlow(child) && preferredLengthForChild(child).isAuto()) {
+ if (hasOrthogonalFlow(child) && flexBasisForChild(child).isAuto()) {
if (!relayoutChildren)
child->setChildNeedsLayout(true);
child->layoutIfNeeded();
@@ -804,11 +794,11 @@ LayoutUnit RenderFlexibleBox::adjustChildSizeForMinAndMax(RenderBox* child, Layo
return childSize;
}
-bool RenderFlexibleBox::computeNextFlexLine(OrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, LayoutUnit& minMaxAppliedMainAxisExtent)
+bool RenderFlexibleBox::computeNextFlexLine(OrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalFlexGrow, float& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent)
{
orderedChildren.clear();
preferredMainAxisExtent = 0;
- totalPositiveFlexibility = totalWeightedNegativeFlexibility = 0;
+ totalFlexGrow = totalWeightedFlexShrink = 0;
minMaxAppliedMainAxisExtent = 0;
if (!iterator.currentChild())
@@ -831,8 +821,8 @@ bool RenderFlexibleBox::computeNextFlexLine(OrderIterator& iterator, OrderedFlex
break;
orderedChildren.append(child);
preferredMainAxisExtent += childMainAxisMarginBoxExtent;
- totalPositiveFlexibility += child->style()->positiveFlex();
- totalWeightedNegativeFlexibility += child->style()->negativeFlex() * childMainAxisExtent;
+ totalFlexGrow += child->style()->flexGrow();
+ totalWeightedFlexShrink += child->style()->flexShrink() * childMainAxisExtent;
LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMax(child, childMainAxisExtent, flexboxAvailableContentExtent);
minMaxAppliedMainAxisExtent += childMinMaxAppliedMainAxisExtent - childMainAxisExtent + childMainAxisMarginBoxExtent;
@@ -840,21 +830,21 @@ bool RenderFlexibleBox::computeNextFlexLine(OrderIterator& iterator, OrderedFlex
return true;
}
-void RenderFlexibleBox::freezeViolations(const WTF::Vector<Violation>& violations, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, InflexibleFlexItemSize& inflexibleItems)
+void RenderFlexibleBox::freezeViolations(const WTF::Vector<Violation>& violations, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems)
{
for (size_t i = 0; i < violations.size(); ++i) {
RenderBox* child = violations[i].child;
LayoutUnit childSize = violations[i].childSize;
LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChild(child);
availableFreeSpace -= childSize - preferredChildSize;
- totalPositiveFlexibility -= child->style()->positiveFlex();
- totalWeightedNegativeFlexibility -= child->style()->negativeFlex() * preferredChildSize;
+ totalFlexGrow -= child->style()->flexGrow();
+ totalWeightedFlexShrink -= child->style()->flexShrink() * preferredChildSize;
inflexibleItems.set(child, childSize);
}
}
// Returns true if we successfully ran the algorithm and sized the flex items.
-bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, InflexibleFlexItemSize& inflexibleItems, WTF::Vector<LayoutUnit>& childSizes)
+bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, WTF::Vector<LayoutUnit>& childSizes)
{
childSizes.clear();
LayoutUnit flexboxAvailableContentExtent = mainAxisContentExtent();
@@ -874,10 +864,10 @@ bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedF
else {
LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChild(child);
LayoutUnit childSize = preferredChildSize;
- if (availableFreeSpace > 0 && totalPositiveFlexibility > 0 && flexSign == PositiveFlexibility && isfinite(totalPositiveFlexibility))
- childSize += lroundf(availableFreeSpace * child->style()->positiveFlex() / totalPositiveFlexibility);
- else if (availableFreeSpace < 0 && totalWeightedNegativeFlexibility > 0 && flexSign == NegativeFlexibility && isfinite(totalWeightedNegativeFlexibility))
- childSize += lroundf(availableFreeSpace * child->style()->negativeFlex() * preferredChildSize / totalWeightedNegativeFlexibility);
+ if (availableFreeSpace > 0 && totalFlexGrow > 0 && flexSign == PositiveFlexibility && isfinite(totalFlexGrow))
+ childSize += static_cast<int>(lroundf(availableFreeSpace * child->style()->flexGrow() / totalFlexGrow));
+ else if (availableFreeSpace < 0 && totalWeightedFlexShrink > 0 && flexSign == NegativeFlexibility && isfinite(totalWeightedFlexShrink))
+ childSize += static_cast<int>(lroundf(availableFreeSpace * child->style()->flexShrink() * preferredChildSize / totalWeightedFlexShrink));
LayoutUnit adjustedChildSize = adjustChildSizeForMinAndMax(child, childSize, flexboxAvailableContentExtent);
childSizes.append(adjustedChildSize);
@@ -893,20 +883,20 @@ bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedF
}
if (totalViolation)
- freezeViolations(totalViolation < 0 ? maxViolations : minViolations, availableFreeSpace, totalPositiveFlexibility, totalWeightedNegativeFlexibility, inflexibleItems);
+ freezeViolations(totalViolation < 0 ? maxViolations : minViolations, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems);
else
availableFreeSpace -= usedFreeSpace;
return !totalViolation;
}
-static LayoutUnit initialPackingOffset(LayoutUnit availableFreeSpace, EFlexPack flexPack, unsigned numberOfChildren)
+static LayoutUnit initialJustifyContentOffset(LayoutUnit availableFreeSpace, EJustifyContent justifyContent, unsigned numberOfChildren)
{
- if (flexPack == PackEnd)
+ if (justifyContent == JustifyFlexEnd)
return availableFreeSpace;
- if (flexPack == PackCenter)
+ if (justifyContent == JustifyCenter)
return availableFreeSpace / 2;
- if (flexPack == PackSpaceAround) {
+ if (justifyContent == JustifySpaceAround) {
if (availableFreeSpace > 0 && numberOfChildren)
return availableFreeSpace / (2 * numberOfChildren);
if (availableFreeSpace < 0)
@@ -915,12 +905,12 @@ static LayoutUnit initialPackingOffset(LayoutUnit availableFreeSpace, EFlexPack
return 0;
}
-static LayoutUnit packingSpaceBetweenChildren(LayoutUnit availableFreeSpace, EFlexPack flexPack, unsigned numberOfChildren)
+static LayoutUnit justifyContentSpaceBetweenChildren(LayoutUnit availableFreeSpace, EJustifyContent justifyContent, unsigned numberOfChildren)
{
if (availableFreeSpace > 0 && numberOfChildren > 1) {
- if (flexPack == PackSpaceBetween)
+ if (justifyContent == JustifySpaceBetween)
return availableFreeSpace / (numberOfChildren - 1);
- if (flexPack == PackSpaceAround)
+ if (justifyContent == JustifySpaceAround)
return availableFreeSpace / numberOfChildren;
}
return 0;
@@ -928,11 +918,10 @@ static LayoutUnit packingSpaceBetweenChildren(LayoutUnit availableFreeSpace, EFl
void RenderFlexibleBox::setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize)
{
- // FIXME: Rename setOverrideWidth/setOverrideHeight to setOverrideLogicalWidth/setOverrideLogicalHeight.
if (hasOrthogonalFlow(child))
- child->setOverrideHeight(childPreferredSize);
+ child->setOverrideLogicalContentHeight(childPreferredSize - child->borderAndPaddingLogicalHeight());
else
- child->setOverrideWidth(childPreferredSize);
+ child->setOverrideLogicalContentWidth(childPreferredSize - child->borderAndPaddingLogicalWidth());
}
void RenderFlexibleBox::prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode layoutMode)
@@ -960,10 +949,10 @@ static EAlignItems alignmentForChild(RenderBox* child)
align = child->parent()->style()->alignItems();
if (child->parent()->style()->flexWrap() == FlexWrapReverse) {
- if (align == AlignStart)
- align = AlignEnd;
- else if (align == AlignEnd)
- align = AlignStart;
+ if (align == AlignFlexStart)
+ align = AlignFlexEnd;
+ else if (align == AlignFlexEnd)
+ align = AlignFlexStart;
}
return align;
@@ -975,7 +964,7 @@ void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons
LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, availableFreeSpace);
LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart();
- mainAxisOffset += initialPackingOffset(availableFreeSpace, style()->flexPack(), childSizes.size());
+ mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->justifyContent(), childSizes.size());
if (style()->flexDirection() == FlowRowReverse)
mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizontalScrollbarHeight();
@@ -987,7 +976,7 @@ void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons
RenderBox* child = children[i];
if (child->isPositioned()) {
prepareChildForPositionedLayout(child, mainAxisOffset, crossAxisOffset, FlipForRowReverse);
- mainAxisOffset += packingSpaceBetweenChildren(availableFreeSpace, style()->flexPack(), childSizes.size());
+ mainAxisOffset += justifyContentSpaceBetweenChildren(availableFreeSpace, style()->justifyContent(), childSizes.size());
continue;
}
LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPaddingExtentForChild(child);
@@ -1023,7 +1012,7 @@ void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons
setFlowAwareLocationForChild(child, childLocation);
mainAxisOffset += childMainExtent + flowAwareMarginEndForChild(child);
- mainAxisOffset += packingSpaceBetweenChildren(availableFreeSpace, style()->flexPack(), childSizes.size());
+ mainAxisOffset += justifyContentSpaceBetweenChildren(availableFreeSpace, style()->justifyContent(), childSizes.size());
}
if (isColumnFlow())
@@ -1046,14 +1035,14 @@ void RenderFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children,
// starting from the end of the flexbox. We also don't need to layout anything since we're
// just moving the children to a new position.
LayoutUnit mainAxisOffset = logicalHeight() - flowAwareBorderEnd() - flowAwarePaddingEnd();
- mainAxisOffset -= initialPackingOffset(availableFreeSpace, style()->flexPack(), childSizes.size());
+ mainAxisOffset -= initialJustifyContentOffset(availableFreeSpace, style()->justifyContent(), childSizes.size());
mainAxisOffset -= isHorizontalFlow() ? verticalScrollbarWidth() : horizontalScrollbarHeight();
for (size_t i = 0; i < children.size(); ++i) {
RenderBox* child = children[i];
if (child->isPositioned()) {
child->layer()->setStaticBlockPosition(mainAxisOffset);
- mainAxisOffset -= packingSpaceBetweenChildren(availableFreeSpace, style()->flexPack(), childSizes.size());
+ mainAxisOffset -= justifyContentSpaceBetweenChildren(availableFreeSpace, style()->justifyContent(), childSizes.size());
continue;
}
mainAxisOffset -= mainAxisExtentForChild(child) + flowAwareMarginEndForChild(child);
@@ -1064,17 +1053,17 @@ void RenderFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children,
child->repaintDuringLayoutIfMoved(oldRect);
mainAxisOffset -= flowAwareMarginStartForChild(child);
- mainAxisOffset -= packingSpaceBetweenChildren(availableFreeSpace, style()->flexPack(), childSizes.size());
+ mainAxisOffset -= justifyContentSpaceBetweenChildren(availableFreeSpace, style()->justifyContent(), childSizes.size());
}
}
-static LayoutUnit initialLinePackingOffset(LayoutUnit availableFreeSpace, EFlexLinePack linePack, unsigned numberOfLines)
+static LayoutUnit initialAlignContentOffset(LayoutUnit availableFreeSpace, EAlignContent alignContent, unsigned numberOfLines)
{
- if (linePack == LinePackEnd)
+ if (alignContent == AlignContentFlexEnd)
return availableFreeSpace;
- if (linePack == LinePackCenter)
+ if (alignContent == AlignContentCenter)
return availableFreeSpace / 2;
- if (linePack == LinePackSpaceAround) {
+ if (alignContent == AlignContentSpaceAround) {
if (availableFreeSpace > 0 && numberOfLines)
return availableFreeSpace / (2 * numberOfLines);
if (availableFreeSpace < 0)
@@ -1083,20 +1072,20 @@ static LayoutUnit initialLinePackingOffset(LayoutUnit availableFreeSpace, EFlexL
return 0;
}
-static LayoutUnit linePackingSpaceBetweenChildren(LayoutUnit availableFreeSpace, EFlexLinePack linePack, unsigned numberOfLines)
+static LayoutUnit alignContentSpaceBetweenChildren(LayoutUnit availableFreeSpace, EAlignContent alignContent, unsigned numberOfLines)
{
if (availableFreeSpace > 0 && numberOfLines > 1) {
- if (linePack == LinePackSpaceBetween)
+ if (alignContent == AlignContentSpaceBetween)
return availableFreeSpace / (numberOfLines - 1);
- if (linePack == LinePackSpaceAround || linePack == LinePackStretch)
+ if (alignContent == AlignContentSpaceAround || alignContent == AlignContentStretch)
return availableFreeSpace / numberOfLines;
}
return 0;
}
-void RenderFlexibleBox::packFlexLines(OrderIterator& iterator, WTF::Vector<LineContext>& lineContexts)
+void RenderFlexibleBox::alignFlexLines(OrderIterator& iterator, WTF::Vector<LineContext>& lineContexts)
{
- if (!isMultiline() || style()->flexLinePack() == LinePackStart)
+ if (!isMultiline() || style()->alignContent() == AlignContentFlexStart)
return;
LayoutUnit availableCrossAxisSpace = crossAxisContentExtent();
@@ -1104,16 +1093,16 @@ void RenderFlexibleBox::packFlexLines(OrderIterator& iterator, WTF::Vector<LineC
availableCrossAxisSpace -= lineContexts[i].crossAxisExtent;
RenderBox* child = iterator.first();
- LayoutUnit lineOffset = initialLinePackingOffset(availableCrossAxisSpace, style()->flexLinePack(), lineContexts.size());
+ LayoutUnit lineOffset = initialAlignContentOffset(availableCrossAxisSpace, style()->alignContent(), lineContexts.size());
for (unsigned lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) {
lineContexts[lineNumber].crossAxisOffset += lineOffset;
for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next())
adjustAlignmentForChild(child, lineOffset);
- if (style()->flexLinePack() == LinePackStretch && availableCrossAxisSpace > 0)
+ if (style()->alignContent() == AlignContentStretch && availableCrossAxisSpace > 0)
lineContexts[lineNumber].crossAxisExtent += availableCrossAxisSpace / static_cast<unsigned>(lineContexts.size());
- lineOffset += linePackingSpaceBetweenChildren(availableCrossAxisSpace, style()->flexLinePack(), lineContexts.size());
+ lineOffset += alignContentSpaceBetweenChildren(availableCrossAxisSpace, style()->alignContent(), lineContexts.size());
}
}
@@ -1166,9 +1155,9 @@ void RenderFlexibleBox::alignChildren(OrderIterator& iterator, const WTF::Vector
adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
break;
}
- case AlignStart:
+ case AlignFlexStart:
break;
- case AlignEnd:
+ case AlignFlexEnd:
adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
break;
case AlignCenter:
@@ -1217,7 +1206,7 @@ void RenderFlexibleBox::applyStretchAlignmentToChild(RenderBox* child, LayoutUni
// FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/87905.
if (child->logicalHeight() != logicalHeightBefore) {
- child->setOverrideHeight(child->logicalHeight());
+ child->setOverrideLogicalContentHeight(child->logicalHeight() - child->borderAndPaddingLogicalHeight());
child->setLogicalHeight(0);
child->setChildNeedsLayout(true);
child->layoutIfNeeded();
@@ -1225,7 +1214,7 @@ void RenderFlexibleBox::applyStretchAlignmentToChild(RenderBox* child, LayoutUni
} else if (isColumnFlow() && child->style()->logicalWidth().isAuto() && isMultiline()) {
// FIXME: Handle min-width and max-width.
LayoutUnit childWidth = lineCrossAxisExtent - crossAxisMarginExtentForChild(child);
- child->setOverrideWidth(std::max(ZERO_LAYOUT_UNIT, childWidth));
+ child->setOverrideLogicalContentWidth(std::max(ZERO_LAYOUT_UNIT, childWidth));
child->setChildNeedsLayout(true);
child->layoutIfNeeded();
}
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.h b/Source/WebCore/rendering/RenderFlexibleBox.h
index fd469d328..64b1adbed 100644
--- a/Source/WebCore/rendering/RenderFlexibleBox.h
+++ b/Source/WebCore/rendering/RenderFlexibleBox.h
@@ -59,8 +59,7 @@ private:
NoFlipForRowReverse,
};
- struct OrderHashTraits;
- typedef HashSet<int, DefaultHash<int>::Hash, OrderHashTraits> OrderHashSet;
+ typedef HashSet<float> OrderHashSet;
class OrderIterator;
typedef WTF::HashMap<const RenderBox*, LayoutUnit> InflexibleFlexItemSize;
@@ -74,7 +73,7 @@ private:
bool isLeftToRightFlow() const;
bool isMultiline() const;
Length crossAxisLength() const;
- Length preferredLengthForChild(RenderBox* child) const;
+ Length flexBasisForChild(RenderBox* child) const;
void setCrossAxisExtent(LayoutUnit);
LayoutUnit crossAxisExtentForChild(RenderBox* child);
LayoutUnit mainAxisExtentForChild(RenderBox* child);
@@ -118,17 +117,17 @@ private:
void computeMainAxisPreferredSizes(bool relayoutChildren, OrderHashSet&);
LayoutUnit lineBreakLength();
LayoutUnit adjustChildSizeForMinAndMax(RenderBox*, LayoutUnit childSize, LayoutUnit flexboxAvailableContentExtent);
- bool computeNextFlexLine(OrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, LayoutUnit& minMaxAppliedMainAxisExtent);
+ bool computeNextFlexLine(OrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalFlexGrow, float& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent);
LayoutUnit computeAvailableFreeSpace(LayoutUnit preferredMainAxisExtent);
- bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
- void freezeViolations(const WTF::Vector<Violation>&, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, InflexibleFlexItemSize&);
+ bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
+ void freezeViolations(const WTF::Vector<Violation>&, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize&);
void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode);
void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>&);
void layoutColumnReverse(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace);
- void packFlexLines(OrderIterator&, WTF::Vector<LineContext>&);
+ void alignFlexLines(OrderIterator&, WTF::Vector<LineContext>&);
void alignChildren(OrderIterator&, const WTF::Vector<LineContext>&);
void applyStretchAlignmentToChild(RenderBox*, LayoutUnit lineCrossAxisExtent);
void flipForRightToLeftColumn(OrderIterator&);
diff --git a/Source/WebCore/rendering/RenderFlowThread.cpp b/Source/WebCore/rendering/RenderFlowThread.cpp
index 507d3b395..fdc2e6bff 100644
--- a/Source/WebCore/rendering/RenderFlowThread.cpp
+++ b/Source/WebCore/rendering/RenderFlowThread.cpp
@@ -51,7 +51,7 @@ RenderFlowThread::RenderFlowThread(Node* node)
, m_regionsInvalidated(false)
, m_regionsHaveUniformLogicalWidth(true)
, m_regionsHaveUniformLogicalHeight(true)
- , m_overset(false)
+ , m_overset(true)
, m_regionLayoutUpdateEventTimer(this, &RenderFlowThread::regionLayoutUpdateEventTimerFired)
{
ASSERT(node->document()->cssRegionsEnabled());
@@ -717,9 +717,10 @@ void RenderFlowThread::computeOverflowStateForRegions(LayoutUnit oldClientAfterE
region->setDispatchRegionLayoutUpdateEvent(true);
}
- // With the regions overflow state computed we can also set the overflow for the named flow.
+ // With the regions overflow state computed we can also set the overset flag for the named flow.
+ // If there are no valid regions in the chain, overset is true
RenderRegion* lastReg = lastRegion();
- m_overset = lastReg && (lastReg->regionState() == RenderRegion::RegionOverflow);
+ m_overset = lastReg ? lastReg->regionState() == RenderRegion::RegionOverflow : true;
}
void RenderFlowThread::regionLayoutUpdateEventTimerFired(Timer<RenderFlowThread>*)
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index 7049f8b50..093880e99 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -137,6 +137,12 @@ void RenderImage::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
imageDimensionsChanged(true /* imageSizeChanged */);
m_needsToSetSizeForAltText = false;
}
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ if (diff == StyleDifferenceLayout
+ && (oldStyle->imageResolution() != style()->imageResolution()
+ || oldStyle->imageResolutionSource() != style()->imageResolutionSource()))
+ imageDimensionsChanged(true /* imageSizeChanged */);
+#endif
}
void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
@@ -191,7 +197,11 @@ bool RenderImage::updateIntrinsicSizeIfNeeded(const IntSize& newSize, bool image
void RenderImage::imageDimensionsChanged(bool imageSizeChanged, const IntRect* rect)
{
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ bool intrinsicSizeChanged = updateIntrinsicSizeIfNeeded(m_imageResource->imageSize(style()->effectiveZoom() / style()->imageResolution()), imageSizeChanged);
+#else
bool intrinsicSizeChanged = updateIntrinsicSizeIfNeeded(m_imageResource->imageSize(style()->effectiveZoom()), imageSizeChanged);
+#endif
// In the case of generated image content using :before/:after/content, we might not be
// in the render tree yet. In that case, we just need to update our intrinsic size.
diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp
index b45bdc338..0e0b45321 100644
--- a/Source/WebCore/rendering/RenderInline.cpp
+++ b/Source/WebCore/rendering/RenderInline.cpp
@@ -233,6 +233,30 @@ void RenderInline::updateAlwaysCreateLineBoxes(bool fullLayout)
}
}
+LayoutRect RenderInline::localCaretRect(InlineBox* inlineBox, int, LayoutUnit* extraWidthToEndOfLine)
+{
+ if (firstChild()) {
+ // This condition is possible if the RenderInline is at an editing boundary,
+ // i.e. the VisiblePosition is:
+ // <RenderInline editingBoundary=true>|<RenderText> </RenderText></RenderInline>
+ // FIXME: need to figure out how to make this return a valid rect, note that
+ // there are no line boxes created in the above case.
+ return LayoutRect();
+ }
+
+ ASSERT_UNUSED(inlineBox, !inlineBox);
+
+ if (extraWidthToEndOfLine)
+ *extraWidthToEndOfLine = 0;
+
+ LayoutRect caretRect = localCaretRectForEmptyElement(borderAndPaddingWidth(), 0);
+
+ if (InlineBox* firstBox = firstLineBox())
+ caretRect.moveBy(roundedLayoutPoint(firstBox->topLeft()));
+
+ return caretRect;
+}
+
void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
if (continuation())
diff --git a/Source/WebCore/rendering/RenderInline.h b/Source/WebCore/rendering/RenderInline.h
index 4187f3187..a707a64df 100644
--- a/Source/WebCore/rendering/RenderInline.h
+++ b/Source/WebCore/rendering/RenderInline.h
@@ -84,6 +84,8 @@ public:
void setAlwaysCreateLineBoxes() { m_alwaysCreateLineBoxes = true; }
void updateAlwaysCreateLineBoxes(bool fullLayout);
+ virtual LayoutRect localCaretRect(InlineBox*, int, LayoutUnit* extraWidthToEndOfLine) OVERRIDE;
+
protected:
virtual void willBeDestroyed();
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index e0b56e7e5..94a837800 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -129,6 +129,9 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
: m_inResizeMode(false)
, m_scrollDimensionsDirty(true)
, m_normalFlowListDirty(true)
+ , m_hasSelfPaintingLayerDescendant(false)
+ , m_hasSelfPaintingLayerDescendantDirty(false)
+ , m_isRootLayer(renderer->isRenderView())
, m_usedTransparency(false)
, m_paintingInsideReflection(false)
, m_inOverflowRelayout(false)
@@ -142,7 +145,7 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
, m_has3DTransformedDescendant(false)
#if USE(ACCELERATED_COMPOSITING)
, m_hasCompositingDescendant(false)
- , m_mustOverlapCompositedLayers(false)
+ , m_indirectCompositingReason(NoIndirectCompositingReason)
#endif
, m_containsDirtyOverlayScrollbars(false)
#if !ASSERT_DISABLED
@@ -169,6 +172,8 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
, m_resizer(0)
{
m_isNormalFlowOnly = shouldBeNormalFlowOnly();
+ m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
+
// Non-stacking contexts should have empty z-order lists. As this is already the case,
// there is no need to dirty / recompute these lists.
m_zOrderListsDirty = isStackingContext();
@@ -360,7 +365,7 @@ void RenderLayer::updateLayerPositions(LayoutPoint* offsetFromRoot, UpdateLayerP
}
positionOverflowControls(toSize(roundedIntPoint(offset)));
- updateVisibilityStatus();
+ updateDescendantDependentFlags();
if (flags & UpdatePagination)
updatePagination();
@@ -439,6 +444,30 @@ LayoutRect RenderLayer::repaintRectIncludingNonCompositingDescendants() const
return repaintRect;
}
+void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
+{
+ for (RenderLayer* layer = this; layer; layer = layer->parent()) {
+ if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaintingLayerDescendant())
+ break;
+
+ layer->m_hasSelfPaintingLayerDescendantDirty = false;
+ layer->m_hasSelfPaintingLayerDescendant = true;
+ }
+}
+
+void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
+{
+ for (RenderLayer* layer = this; layer; layer = layer->parent()) {
+ layer->m_hasSelfPaintingLayerDescendantDirty = true;
+ // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
+ // in this case, there is no need to dirty our ancestors further.
+ if (layer->isSelfPaintingLayer()) {
+ ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant());
+ break;
+ }
+ }
+}
+
void RenderLayer::computeRepaintRects(LayoutPoint* offsetFromRoot)
{
ASSERT(!m_visibleContentStatusDirty);
@@ -461,7 +490,7 @@ void RenderLayer::updateLayerPositionsAfterScroll(UpdateLayerPositionsAfterScrol
{
// FIXME: This shouldn't be needed, but there are some corner cases where
// these flags are still dirty. Update so that the check below is valid.
- updateVisibilityStatus();
+ updateDescendantDependentFlags();
// If we have no visible content and no visible descendants, there is no point recomputing
// our rectangles as they will be empty. If our visibility changes, we are expected to
@@ -603,68 +632,78 @@ void RenderLayer::updatePagination()
}
}
-void RenderLayer::setHasVisibleContent(bool b)
+void RenderLayer::setHasVisibleContent()
{
- if (m_hasVisibleContent == b && !m_visibleContentStatusDirty)
+ if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
+ ASSERT(!parent() || parent()->hasVisibleDescendant());
return;
+ }
+
m_visibleContentStatusDirty = false;
- m_hasVisibleContent = b;
- if (m_hasVisibleContent) {
- computeRepaintRects();
- if (!isNormalFlowOnly()) {
- for (RenderLayer* sc = stackingContext(); sc; sc = sc->stackingContext()) {
- sc->dirtyZOrderLists();
- if (sc->hasVisibleContent())
- break;
- }
+ m_hasVisibleContent = true;
+ computeRepaintRects();
+ if (!isNormalFlowOnly()) {
+ // We don't collect invisible layers in z-order lists if we are not in compositing mode.
+ // As we became visible, we need to dirty our stacking contexts ancestors to be properly
+ // collected. FIXME: When compositing, we could skip this dirtying phase.
+ for (RenderLayer* sc = stackingContext(); sc; sc = sc->stackingContext()) {
+ sc->dirtyZOrderLists();
+ if (sc->hasVisibleContent())
+ break;
}
}
+
if (parent())
- parent()->childVisibilityChanged(m_hasVisibleContent);
+ parent()->setAncestorChainHasVisibleDescendant();
}
void RenderLayer::dirtyVisibleContentStatus()
{
m_visibleContentStatusDirty = true;
if (parent())
- parent()->dirtyVisibleDescendantStatus();
+ parent()->dirtyAncestorChainVisibleDescendantStatus();
}
-void RenderLayer::childVisibilityChanged(bool newVisibility)
-{
- if (m_hasVisibleDescendant == newVisibility || m_visibleDescendantStatusDirty)
- return;
- if (newVisibility) {
- RenderLayer* l = this;
- while (l && !l->m_visibleDescendantStatusDirty && !l->m_hasVisibleDescendant) {
- l->m_hasVisibleDescendant = true;
- l = l->parent();
- }
- } else
- dirtyVisibleDescendantStatus();
+void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
+{
+ for (RenderLayer* layer = this; layer; layer = layer->parent()) {
+ if (layer->m_visibleDescendantStatusDirty)
+ break;
+
+ layer->m_visibleDescendantStatusDirty = true;
+ }
}
-void RenderLayer::dirtyVisibleDescendantStatus()
+void RenderLayer::setAncestorChainHasVisibleDescendant()
{
- RenderLayer* l = this;
- while (l && !l->m_visibleDescendantStatusDirty) {
- l->m_visibleDescendantStatusDirty = true;
- l = l->parent();
+ for (RenderLayer* layer = this; layer; layer = layer->parent()) {
+ if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendant())
+ break;
+
+ layer->m_hasVisibleDescendant = true;
+ layer->m_visibleDescendantStatusDirty = false;
}
}
-void RenderLayer::updateVisibilityStatus()
+void RenderLayer::updateDescendantDependentFlags()
{
- if (m_visibleDescendantStatusDirty) {
+ if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty) {
m_hasVisibleDescendant = false;
+ m_hasSelfPaintingLayerDescendant = false;
for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
- child->updateVisibilityStatus();
- if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) {
- m_hasVisibleDescendant = true;
+ child->updateDescendantDependentFlags();
+
+ bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant;
+ bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
+
+ m_hasVisibleDescendant |= hasVisibleDescendant;
+ m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
+
+ if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant)
break;
- }
}
m_visibleDescendantStatusDirty = false;
+ m_hasSelfPaintingLayerDescendantDirty = false;
}
if (m_visibleContentStatusDirty) {
@@ -863,21 +902,20 @@ FloatPoint RenderLayer::perspectiveOrigin() const
RenderLayer* RenderLayer::stackingContext() const
{
RenderLayer* layer = parent();
- while (layer && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot() && layer->renderer()->style()->hasAutoZIndex())
+ while (layer && !layer->isRootLayer() && !layer->renderer()->isRoot() && layer->renderer()->style()->hasAutoZIndex())
layer = layer->parent();
return layer;
}
static inline bool isPositionedContainer(RenderLayer* layer)
{
- RenderObject* o = layer->renderer();
- return o->isRenderView() || o->isPositioned() || o->isRelPositioned() || layer->hasTransform();
+ RenderBoxModelObject* layerRenderer = layer->renderer();
+ return layer->isRootLayer() || layerRenderer->isPositioned() || layerRenderer->isRelPositioned() || layer->hasTransform();
}
static inline bool isFixedPositionedContainer(RenderLayer* layer)
{
- RenderObject* o = layer->renderer();
- return o->isRenderView() || layer->hasTransform();
+ return layer->isRootLayer() || layer->hasTransform();
}
RenderLayer* RenderLayer::enclosingPositionedAncestor() const
@@ -907,7 +945,7 @@ IntRect RenderLayer::scrollableAreaBoundingBox() const
RenderLayer* RenderLayer::enclosingTransformedAncestor() const
{
RenderLayer* curr = parent();
- while (curr && !curr->renderer()->isRenderView() && !curr->transform())
+ while (curr && !curr->isRootLayer() && !curr->transform())
curr = curr->parent();
return curr;
@@ -1056,7 +1094,7 @@ RenderLayer* RenderLayer::clippingRootForPainting() const
const RenderLayer* current = this;
while (current) {
- if (current->renderer()->isRenderView())
+ if (current->isRootLayer())
return const_cast<RenderLayer*>(current);
current = compositingContainer(current);
@@ -1240,10 +1278,13 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
child->dirtyStackingContextZOrderLists();
}
- child->updateVisibilityStatus();
+ child->updateDescendantDependentFlags();
if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
- childVisibilityChanged(true);
-
+ setAncestorChainHasVisibleDescendant();
+
+ if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
+ setAncestorChainHasSelfPaintingLayerDescendant();
+
#if USE(ACCELERATED_COMPOSITING)
compositor()->layerWasAdded(this, child);
#endif
@@ -1280,10 +1321,13 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
oldChild->setNextSibling(0);
oldChild->setParent(0);
- oldChild->updateVisibilityStatus();
+ oldChild->updateDescendantDependentFlags();
if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
- childVisibilityChanged(false);
-
+ dirtyAncestorChainVisibleDescendantStatus();
+
+ if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant())
+ dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
+
return oldChild;
}
@@ -2849,7 +2893,7 @@ static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
// Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC.
// It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
// will do a full repaint().
- if (layer->renderer()->document()->didLayoutWithPendingStylesheets() && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot())
+ if (layer->renderer()->document()->didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isRoot())
return true;
// Avoid painting all layers if the document is in a state where visual updates aren't allowed.
@@ -2879,6 +2923,10 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* context,
}
#endif
+ // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself.
+ if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
+ return;
+
if (shouldSuppressPaintingLayer(this))
return;
@@ -2886,10 +2934,6 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* context,
if (!renderer()->opacity())
return;
- // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself.
- if (!isSelfPaintingLayer() && !firstChild())
- return;
-
if (paintsWithTransparency(paintBehavior))
paintFlags |= PaintLayerHaveTransparency;
@@ -2950,6 +2994,8 @@ void RenderLayer::paintLayerContentsAndReflection(RenderLayer* rootLayer, Graphi
RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
PaintLayerFlags paintFlags)
{
+ ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
+
PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
// Paint the reflection first if we have one.
@@ -2969,6 +3015,8 @@ void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* co
RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
PaintLayerFlags paintFlags)
{
+ ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
+
PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
bool haveTransparency = localPaintFlags & PaintLayerHaveTransparency;
bool isSelfPaintingLayer = this->isSelfPaintingLayer();
@@ -3163,6 +3211,9 @@ void RenderLayer::paintList(Vector<RenderLayer*>* list, RenderLayer* rootLayer,
if (!list)
return;
+ if (!hasSelfPaintingLayerDescendant())
+ return;
+
#if !ASSERT_DISABLED
LayerListMutationDetector mutationChecker(this);
#endif
@@ -3220,12 +3271,12 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
ColumnInfo* colInfo = columnBlock->columnInfo();
unsigned colCount = columnBlock->columnCount(colInfo);
- int currLogicalTopOffset = 0;
+ LayoutUnit currLogicalTopOffset = 0;
for (unsigned i = 0; i < colCount; i++) {
// For each rect, we clip to the rect, and then we adjust our coords.
LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
columnBlock->flipForWritingMode(colRect);
- int logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
+ LayoutUnit logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
LayoutSize offset;
if (isHorizontal) {
if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
@@ -3249,7 +3300,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
// Each strip pushes a clip, since column boxes are specified as being
// like overflow:hidden.
- context->clip(colRect);
+ context->clip(pixelSnappedIntRect(colRect));
if (!colIndex) {
// Apply a translation transform to change where the layer paints.
@@ -3258,7 +3309,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
if (oldHasTransform)
oldTransform = *childLayer->transform();
TransformationMatrix newTransform(oldTransform);
- newTransform.translateRight(offset.width(), offset.height());
+ newTransform.translateRight(roundToInt(offset.width()), roundToInt(offset.height()));
childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
childLayer->paintLayer(rootLayer, context, localDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
@@ -3272,7 +3323,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
LayoutPoint childOffset;
columnLayers[colIndex - 1]->convertToLayerCoords(rootLayer, childOffset);
TransformationMatrix transform;
- transform.translateRight(childOffset.x() + offset.width(), childOffset.y() + offset.height());
+ transform.translateRight(roundToInt(childOffset.x() + offset.width()), roundToInt(childOffset.y() + offset.height()));
// Apply the transform.
context->concatCTM(transform.toAffineTransform());
@@ -3285,7 +3336,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
}
// Move to the next position.
- int blockDelta = isHorizontal ? colRect.height() : colRect.width();
+ LayoutUnit blockDelta = isHorizontal ? colRect.height() : colRect.width();
if (columnBlock->style()->isFlippedBlocksWritingMode())
currLogicalTopOffset += blockDelta;
else
@@ -3315,7 +3366,7 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
// We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
// return ourselves. We do this so mouse events continue getting delivered after a drag has
// exited the WebView, and so hit testing over a scrollbar hits the content document.
- if ((request.active() || request.release()) && renderer()->isRenderView()) {
+ if ((request.active() || request.release()) && isRootLayer()) {
renderer()->updateHitTestResult(result, result.point());
insideLayer = this;
}
@@ -3794,7 +3845,6 @@ void RenderLayer::updateClipRects(const RenderLayer* rootLayer, RenderRegion* re
else
m_clipRectsCache->m_clipRects[clipRectsType] = ClipRects::create(clipRects);
- m_clipRectsCache->m_clipRects[clipRectsType]->ref();
#ifndef NDEBUG
m_clipRectsCache->m_clipRectsRoot[clipRectsType] = rootLayer;
#endif
@@ -3901,7 +3951,7 @@ ClipRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, RenderReg
// Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
if (parentRects.fixed() && rootLayer->renderer() == view && backgroundClipRect != PaintInfo::infiniteRect())
- backgroundClipRect.move(view->frameView()->scrollXForFixedPosition(), view->frameView()->scrollYForFixedPosition());
+ backgroundClipRect.move(view->frameView()->scrollOffsetForFixedPosition());
return backgroundClipRect;
}
@@ -4037,7 +4087,7 @@ bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const Layo
// Always examine the canvas and the root.
// FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
// paints the root's background.
- if (renderer()->isRenderView() || renderer()->isRoot())
+ if (isRootLayer() || renderer()->isRoot())
return true;
// If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
@@ -4537,7 +4587,7 @@ void RenderLayer::updateNormalFlowList()
void RenderLayer::collectLayers(bool includeHiddenLayers, Vector<RenderLayer*>*& posBuffer, Vector<RenderLayer*>*& negBuffer)
{
- updateVisibilityStatus();
+ updateDescendantDependentFlags();
// Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
bool includeHiddenLayer = includeHiddenLayers || (m_hasVisibleContent || (m_hasVisibleDescendant && isStackingContext()));
@@ -4660,7 +4710,7 @@ bool RenderLayer::shouldBeNormalFlowOnly() const
&& !isTransparent();
}
-bool RenderLayer::isSelfPaintingLayer() const
+bool RenderLayer::shouldBeSelfPaintingLayer() const
{
return !isNormalFlowOnly()
|| renderer()->hasReflection()
@@ -4673,6 +4723,21 @@ bool RenderLayer::isSelfPaintingLayer() const
|| renderer()->isRenderIFrame();
}
+void RenderLayer::updateSelfPaintingLayerAfterStyleChange(const RenderStyle*)
+{
+ bool isSelfPaintingLayer = shouldBeSelfPaintingLayer();
+ if (m_isSelfPaintingLayer == isSelfPaintingLayer)
+ return;
+
+ m_isSelfPaintingLayer = isSelfPaintingLayer;
+ if (!parent())
+ return;
+ if (isSelfPaintingLayer)
+ parent()->setAncestorChainHasSelfPaintingLayerDescendant();
+ else
+ parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
+}
+
void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldStyle)
{
if (!oldStyle)
@@ -4753,6 +4818,7 @@ void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle)
m_marquee = 0;
}
+ updateSelfPaintingLayerAfterStyleChange(oldStyle);
updateStackingContextsAfterStyleChange(oldStyle);
updateScrollbarsAfterStyleChange(oldStyle);
@@ -4778,7 +4844,7 @@ void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle)
#endif
#if USE(ACCELERATED_COMPOSITING)
- updateVisibilityStatus();
+ updateDescendantDependentFlags();
updateTransform();
if (compositor()->updateLayerCompositingState(this))
diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h
index ad23af708..28d7e5627 100644
--- a/Source/WebCore/rendering/RenderLayer.h
+++ b/Source/WebCore/rendering/RenderLayer.h
@@ -111,6 +111,7 @@ public:
m_hasRadius = true;
}
void move(LayoutUnit x, LayoutUnit y) { m_rect.move(x, y); }
+ void move(const LayoutSize& size) { m_rect.move(size); }
bool isEmpty() const { return m_rect.isEmpty(); }
bool intersects(const LayoutRect& rect) { return m_rect.intersects(rect); }
@@ -140,7 +141,7 @@ public:
}
ClipRects()
- : m_refCnt(0)
+ : m_refCnt(1)
, m_fixed(false)
{
}
@@ -194,7 +195,7 @@ private:
: m_overflowClipRect(r)
, m_fixedClipRect(r)
, m_posClipRect(r)
- , m_refCnt(0)
+ , m_refCnt(1)
, m_fixed(false)
{
}
@@ -203,7 +204,7 @@ private:
: m_overflowClipRect(other.overflowClipRect())
, m_fixedClipRect(other.fixedClipRect())
, m_posClipRect(other.posClipRect())
- , m_refCnt(0)
+ , m_refCnt(1)
, m_fixed(other.fixed())
{
}
@@ -275,7 +276,7 @@ public:
RenderMarquee* marquee() const { return m_marquee; }
bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
- bool isSelfPaintingLayer() const;
+ bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; }
bool cannotBlitToWindow() const;
@@ -367,8 +368,8 @@ public:
bool inResizeMode() const { return m_inResizeMode; }
void setInResizeMode(bool b) { m_inResizeMode = b; }
- bool isRootLayer() const { return renderer()->isRenderView(); }
-
+ bool isRootLayer() const { return m_isRootLayer; }
+
#if USE(ACCELERATED_COMPOSITING)
RenderLayerCompositor* compositor() const;
@@ -392,6 +393,8 @@ public:
// Providing |cachedOffset| prevents a outlineBoxForRepaint from walking back to the root for each layer in our subtree.
// This is an optimistic optimization that is not guaranteed to succeed.
void updateLayerPositions(LayoutPoint* offsetFromRoot, UpdateLayerPositionsFlags = defaultFlags);
+
+ bool isPaginated() const { return m_isPaginated; }
void updateTransform();
@@ -438,9 +441,14 @@ public:
// ditto for hasVisibleDescendant(), see https://bugs.webkit.org/show_bug.cgi?id=71277
bool hasVisibleContent() const { return m_hasVisibleContent; }
bool hasVisibleDescendant() const { return m_hasVisibleDescendant; }
- void setHasVisibleContent(bool);
+
+ void setHasVisibleContent();
void dirtyVisibleContentStatus();
+ // FIXME: We should ASSERT(!m_hasSelfPaintingLayerDescendantDirty); here but we hit the same bugs as visible content above.
+ // Part of the issue is with subtree relayout: we don't check if our ancestors have some descendant flags dirty, missing some updates.
+ bool hasSelfPaintingLayerDescendant() const { return m_hasSelfPaintingLayerDescendant; }
+
// Gets the nearest enclosing positioned ancestor layer (also includes
// the <html> layer and the root layer).
RenderLayer* enclosingPositionedAncestor() const;
@@ -645,9 +653,12 @@ private:
void updateNormalFlowList();
- bool isStackingContext(const RenderStyle* style) const { return !style->hasAutoZIndex() || renderer()->isRenderView(); }
+ bool isStackingContext(const RenderStyle* style) const { return !style->hasAutoZIndex() || isRootLayer(); }
bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); }
+ void setAncestorChainHasSelfPaintingLayerDescendant();
+ void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
+
void computeRepaintRects(LayoutPoint* offsetFromRoot = 0);
void clearRepaintRects();
@@ -657,6 +668,7 @@ private:
bool shouldRepaintAfterLayout() const;
+ void updateSelfPaintingLayerAfterStyleChange(const RenderStyle* oldStyle);
void updateStackingContextsAfterStyleChange(const RenderStyle* oldStyle);
void updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle);
@@ -729,7 +741,9 @@ private:
bool hasHorizontalOverflow() const;
bool hasVerticalOverflow() const;
- bool shouldBeNormalFlowOnly() const;
+ bool shouldBeNormalFlowOnly() const;
+
+ bool shouldBeSelfPaintingLayer() const;
int scrollPosition(Scrollbar*) const;
@@ -769,9 +783,10 @@ private:
void updateScrollableAreaSet(bool hasOverflow);
- void childVisibilityChanged(bool newVisibility);
- void dirtyVisibleDescendantStatus();
- void updateVisibilityStatus();
+ void dirtyAncestorChainVisibleDescendantStatus();
+ void setAncestorChainHasVisibleDescendant();
+
+ void updateDescendantDependentFlags();
// This flag is computed by RenderLayerCompositor, which knows more about 3d hierarchies than we do.
void setHas3DTransformedDescendant(bool b) { m_has3DTransformedDescendant = b; }
@@ -810,14 +825,23 @@ private:
void drawPlatformResizerImage(GraphicsContext*, IntRect resizerCornerRect);
void updatePagination();
- bool isPaginated() const { return m_isPaginated; }
-
+
#if USE(ACCELERATED_COMPOSITING)
bool hasCompositingDescendant() const { return m_hasCompositingDescendant; }
void setHasCompositingDescendant(bool b) { m_hasCompositingDescendant = b; }
- bool mustOverlapCompositedLayers() const { return m_mustOverlapCompositedLayers; }
- void setMustOverlapCompositedLayers(bool b) { m_mustOverlapCompositedLayers = b; }
+ enum IndirectCompositingReason {
+ NoIndirectCompositingReason,
+ IndirectCompositingForOverlap,
+ IndirectCompositingForBackgroundLayer,
+ IndirectCompositingForGraphicalEffect, // opacity, mask, filter, transform etc.
+ IndirectCompositingForPerspective,
+ IndirectCompositingForPreserve3D
+ };
+
+ void setIndirectCompositingReason(IndirectCompositingReason reason) { m_indirectCompositingReason = reason; }
+ IndirectCompositingReason indirectCompositingReason() const { return static_cast<IndirectCompositingReason>(m_indirectCompositingReason); }
+ bool mustCompositeForIndirectReasons() const { return m_indirectCompositingReason; }
#endif
friend class RenderLayerBacking;
@@ -856,6 +880,15 @@ protected:
bool m_normalFlowListDirty: 1;
bool m_isNormalFlowOnly : 1;
+ bool m_isSelfPaintingLayer : 1;
+
+ // If have no self-painting descendants, we don't have to walk our children during painting. This can lead to
+ // significant savings, especially if the tree has lots of non-self-painting layers grouped together (e.g. table cells).
+ bool m_hasSelfPaintingLayerDescendant : 1;
+ bool m_hasSelfPaintingLayerDescendantDirty : 1;
+
+ const bool m_isRootLayer : 1;
+
bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
// we ended up painting this layer or any descendants (and therefore need to
// blend).
@@ -875,7 +908,7 @@ protected:
// in a preserves3D hierarchy. Hint to do 3D-aware hit testing.
#if USE(ACCELERATED_COMPOSITING)
bool m_hasCompositingDescendant : 1; // In the z-order tree.
- bool m_mustOverlapCompositedLayers : 1;
+ unsigned m_indirectCompositingReason : 3;
#endif
bool m_containsDirtyOverlayScrollbars : 1;
@@ -885,7 +918,7 @@ protected:
// This is an optimization added for <table>.
// Currently cells do not need to update their repaint rectangles when scrolling. This also
// saves a lot of time when scrolling on a table.
- bool m_canSkipRepaintRectsUpdateOnScroll : 1;
+ const bool m_canSkipRepaintRectsUpdateOnScroll : 1;
#if ENABLE(CSS_FILTERS)
bool m_hasFilterInfo : 1;
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index adce4c7ee..f9a818a15 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -51,6 +51,7 @@
#include "RenderEmbeddedObject.h"
#include "RenderVideo.h"
#include "RenderView.h"
+#include "ScrollingCoordinator.h"
#include "StyleResolver.h"
#include "TiledBacking.h"
@@ -165,7 +166,11 @@ void RenderLayerBacking::createPrimaryGraphicsLayer()
m_graphicsLayer = createGraphicsLayer(layerName);
if (m_isMainFrameRenderViewLayer) {
- m_graphicsLayer->setContentsOpaque(true);
+ bool isTransparent = false;
+ if (FrameView* frameView = toRenderView(renderer())->frameView())
+ isTransparent = frameView->isTransparent();
+
+ m_graphicsLayer->setContentsOpaque(!isTransparent);
m_graphicsLayer->setAppliesPageScale();
}
@@ -239,6 +244,10 @@ static bool layerOrAncestorIsTransformed(RenderLayer* layer)
bool RenderLayerBacking::shouldClipCompositedBounds() const
{
+ // Scrollbar layers use this layer for relative positioning, so don't clip.
+ if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
+ return false;
+
if (m_usingTiledCacheLayer)
return true;
@@ -423,7 +432,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
updateLayerFilters(renderer()->style());
#endif
- m_owningLayer->updateVisibilityStatus();
+ m_owningLayer->updateDescendantDependentFlags();
// m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
// descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
@@ -434,6 +443,20 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection());
m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
+ // Register fixed position layers and their containers with the scrolling coordinator.
+ if (Page* page = renderer()->frame()->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
+ if (style->position() == FixedPosition || compositor()->fixedPositionedByAncestor(m_owningLayer))
+ scrollingCoordinator->setLayerIsFixedToContainerLayer(childForSuperlayers(), true);
+ else {
+ if (m_ancestorClippingLayer)
+ scrollingCoordinator->setLayerIsFixedToContainerLayer(m_ancestorClippingLayer.get(), false);
+ scrollingCoordinator->setLayerIsFixedToContainerLayer(m_graphicsLayer.get(), false);
+ }
+ bool isContainer = m_owningLayer->hasTransform();
+ scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer);
+ }
+ }
RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
// We compute everything relative to the enclosing compositing layer.
@@ -591,22 +614,22 @@ void RenderLayerBacking::updateInternalHierarchy()
if (m_clippingLayer) {
m_clippingLayer->removeFromParent();
m_graphicsLayer->addChild(m_clippingLayer.get());
+ }
- // The clip for child layers does not include space for overflow controls, so they exist as
- // siblings of the clipping layer if we have one. Normal children of this layer are set as
- // children of the clipping layer.
- if (m_layerForHorizontalScrollbar) {
- m_layerForHorizontalScrollbar->removeFromParent();
- m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
- }
- if (m_layerForVerticalScrollbar) {
- m_layerForVerticalScrollbar->removeFromParent();
- m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
- }
- if (m_layerForScrollCorner) {
- m_layerForScrollCorner->removeFromParent();
- m_graphicsLayer->addChild(m_layerForScrollCorner.get());
- }
+ // The clip for child layers does not include space for overflow controls, so they exist as
+ // siblings of the clipping layer if we have one. Normal children of this layer are set as
+ // children of the clipping layer.
+ if (m_layerForHorizontalScrollbar) {
+ m_layerForHorizontalScrollbar->removeFromParent();
+ m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
+ }
+ if (m_layerForVerticalScrollbar) {
+ m_layerForVerticalScrollbar->removeFromParent();
+ m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
+ }
+ if (m_layerForScrollCorner) {
+ m_layerForScrollCorner->removeFromParent();
+ m_graphicsLayer->addChild(m_layerForScrollCorner.get());
}
}
@@ -1564,4 +1587,3 @@ double RenderLayerBacking::backingStoreArea() const
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
-
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index c20db84e8..1466e39ba 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -401,11 +401,12 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
// FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
CompositingState compState(updateRoot, m_compositingConsultsOverlap);
bool layersChanged = false;
+ bool saw3DTransform = false;
if (m_compositingConsultsOverlap) {
OverlapMap overlapTestRequestMap;
- computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, compState, layersChanged);
+ computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, compState, layersChanged, saw3DTransform);
} else
- computeCompositingRequirements(0, updateRoot, 0, compState, layersChanged);
+ computeCompositingRequirements(0, updateRoot, 0, compState, layersChanged, saw3DTransform);
needHierarchyUpdate |= layersChanged;
}
@@ -546,6 +547,11 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR
if (layerChanged)
layer->clearClipRectsIncludingDescendants(PaintingClipRects);
+ // If a fixed position layer gained/lost a backing, the scrolling coordinator needs to recalculate whether it can do fast scrolling.
+ if (layerChanged && layer->renderer()->style()->position() == FixedPosition) {
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView->frameView());
+ }
return layerChanged;
}
@@ -716,7 +722,7 @@ void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, Ren
// must be compositing so that its contents render over that child.
// This implies that its positive z-index children must also be compositing.
//
-void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged)
+void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged, bool& descendantHas3DTransform)
{
layer->updateLayerListsIfNeeded();
@@ -741,7 +747,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
mustOverlapCompositedLayers = overlapMap->overlapsLayers(absBounds);
}
- layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
+ layer->setIndirectCompositingReason(mustOverlapCompositedLayers ? RenderLayer::IndirectCompositingForOverlap : RenderLayer::NoIndirectCompositingReason);
// The children of this layer don't need to composite, unless there is
// a compositing layer among them, so start by inheriting the compositing
@@ -777,18 +783,20 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
LayerListMutationDetector mutationChecker(layer);
#endif
+ bool anyDescendantHas3DTransform = false;
+
if (layer->isStackingContext()) {
if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
size_t listSize = negZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
- computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged);
+ computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
// If we have to make a layer for this child, make one now so we can have a contents layer
// (since we need to ensure that the -ve z-order child renders underneath our contents).
if (!willBeComposited && childState.m_subtreeIsCompositing) {
// make layer compositing
- layer->setMustOverlapCompositedLayers(true);
+ layer->setIndirectCompositingReason(RenderLayer::IndirectCompositingForBackgroundLayer);
childState.m_compositingAncestor = layer;
if (overlapMap)
overlapMap->pushCompositingContainer();
@@ -802,7 +810,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
size_t listSize = normalFlowList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
- computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged);
+ computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
}
}
@@ -811,7 +819,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
size_t listSize = posZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
- computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged);
+ computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
}
}
}
@@ -830,11 +838,11 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer())
addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
- // 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 (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
- layer->setMustOverlapCompositedLayers(true);
+ // Now check for reasons to become composited that depend on the state of descendant layers.
+ RenderLayer::IndirectCompositingReason indirectCompositingReason;
+ if (!willBeComposited && canBeComposited(layer)
+ && requiresCompositingForIndirectReason(layer->renderer(), childState.m_subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
+ layer->setIndirectCompositingReason(indirectCompositingReason);
childState.m_compositingAncestor = layer;
if (overlapMap) {
overlapMap->pushCompositingContainer();
@@ -842,11 +850,11 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
}
willBeComposited = true;
}
-
+
ASSERT(willBeComposited == needsToBeComposited(layer));
if (layer->reflectionLayer()) {
// FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
- layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
+ layer->reflectionLayer()->setIndirectCompositingReason(willBeComposited ? RenderLayer::IndirectCompositingForOverlap : RenderLayer::NoIndirectCompositingReason);
}
// Subsequent layers in the parent stacking context also need to composite.
@@ -899,6 +907,8 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
layersChanged = true;
+ descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform();
+
if (overlapMap)
overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer ? ancestorLayer->renderer() : 0);
}
@@ -1417,7 +1427,7 @@ bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
if (!canBeComposited(layer))
return false;
- return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
+ return requiresCompositingLayer(layer) || layer->mustCompositeForIndirectReasons() || (inCompositingMode() && layer->isRootLayer());
}
// Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
@@ -1460,7 +1470,7 @@ bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer* layer, co
|| compositingAncestorLayer->backing()->paintsIntoCompositedAncestor()))
return true;
- return layer->isRootLayer()
+ if (layer->isRootLayer()
|| layer->transform() // note: excludes perspective and transformStyle3D.
|| requiresCompositingForVideo(renderer)
|| requiresCompositingForCanvas(renderer)
@@ -1473,8 +1483,18 @@ bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer* layer, co
|| renderer->isTransparent()
|| renderer->hasMask()
|| renderer->hasReflection()
- || renderer->hasFilter()
- || layer->mustOverlapCompositedLayers();
+ || renderer->hasFilter())
+ return true;
+
+
+ if (layer->mustCompositeForIndirectReasons()) {
+ RenderLayer::IndirectCompositingReason reason = layer->indirectCompositingReason();
+ return reason == RenderLayer::IndirectCompositingForOverlap
+ || reason == RenderLayer::IndirectCompositingForBackgroundLayer
+ || reason == RenderLayer::IndirectCompositingForGraphicalEffect
+ || reason == RenderLayer::IndirectCompositingForPreserve3D; // preserve-3d has to create backing store to ensure that 3d-transformed elements intersect.
+ }
+ return false;
}
#if !LOG_DISABLED
@@ -1486,14 +1506,8 @@ const char* RenderLayerCompositor::reasonForCompositing(const RenderLayer* layer
layer = toRenderBoxModelObject(renderer)->layer();
}
- if (renderer->hasTransform() && renderer->style()->hasPerspective())
- return "perspective";
-
- if (renderer->hasTransform() && (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D))
- return "preserve-3d";
-
- if (renderer->hasTransform())
- return "transform";
+ if (requiresCompositingForTransform(renderer))
+ return "3D transform";
if (requiresCompositingForVideo(renderer))
return "video";
@@ -1523,9 +1537,35 @@ const char* RenderLayerCompositor::reasonForCompositing(const RenderLayer* layer
return "position: fixed";
// This includes layers made composited by requiresCompositingWhenDescendantsAreCompositing().
- if (layer->mustOverlapCompositedLayers())
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForOverlap)
return "overlap/stacking";
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForBackgroundLayer)
+ return "negative z-index children";
+
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForGraphicalEffect) {
+ if (layer->transform())
+ return "transform with composited descendants";
+
+ if (renderer->isTransparent())
+ return "opacity with composited descendants";
+
+ if (renderer->hasMask())
+ return "mask with composited descendants";
+
+ if (renderer->hasReflection())
+ return "reflection with composited descendants";
+
+ if (renderer->hasFilter())
+ return "filter with composited descendants";
+ }
+
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForPerspective)
+ return "perspective";
+
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForPreserve3D)
+ return "preserve-3d";
+
if (inCompositingMode() && layer->isRootLayer())
return "root";
@@ -1576,6 +1616,31 @@ bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer
(layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip());
}
+// Return true if there is an ancestor layer that is fixed positioned to the view.
+// Note that if the ancestor has a stacking context and is fixed position then this method
+// will return false.
+bool RenderLayerCompositor::fixedPositionedByAncestor(const RenderLayer* layer) const
+{
+ if (!layer->isComposited() || !layer->parent())
+ return false;
+
+ const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
+ if (!compositingAncestor)
+ return false;
+
+ const RenderLayer* curr = layer;
+ while (curr) {
+ const RenderLayer* next = curr->parent();
+ if (next == compositingAncestor)
+ return false;
+
+ if (next && next->renderer()->style()->position() == FixedPosition)
+ return true;
+ curr = next;
+ }
+ return false;
+}
+
bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
{
// Need this done first to determine overflow.
@@ -1593,7 +1658,7 @@ bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* render
RenderStyle* style = renderer->style();
// Note that we ask the renderer if it has a transform, because the style may have transforms,
// but the renderer may be an inline that doesn't suppport them.
- return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
+ return renderer->hasTransform() && style->transform().has3DOperation();
}
bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
@@ -1701,11 +1766,35 @@ bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* render
return false;
}
-bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
+bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const
{
- return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection() || renderer->hasFilter();
-}
+ RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
+
+ // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
+ // via compositing so that they also apply to those composited descdendants.
+ if (hasCompositedDescendants && (layer->transform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection() || renderer->hasFilter())) {
+ reason = RenderLayer::IndirectCompositingForGraphicalEffect;
+ return true;
+ }
+
+ // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
+ // will be affected by the preserve-3d or perspective.
+ if (has3DTransformedDescendants) {
+ if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D) {
+ reason = RenderLayer::IndirectCompositingForPreserve3D;
+ return true;
+ }
+ if (renderer->style()->hasPerspective()) {
+ reason = RenderLayer::IndirectCompositingForPerspective;
+ return true;
+ }
+ }
+
+ reason = RenderLayer::NoIndirectCompositingReason;
+ return false;
+}
+
bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const
{
#if ENABLE(CSS_FILTERS)
@@ -1745,7 +1834,7 @@ bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* rendere
// Fixed position elements that are invisible in the current view don't get their own layer.
FrameView* frameView = m_renderView->frameView();
- if (frameView && !layer->absoluteBoundingBox().intersects(IntRect(frameView->scrollXForFixedPosition(), frameView->scrollYForFixedPosition(), frameView->layoutWidth(), frameView->layoutHeight())))
+ if (frameView && !layer->absoluteBoundingBox().intersects(IntRect(IntPoint(frameView->scrollOffsetForFixedPosition()), frameView->layoutSize())))
return false;
return true;
@@ -2099,6 +2188,8 @@ void RenderLayerCompositor::ensureRootLayer()
#ifndef NDEBUG
m_scrollLayer->setName("frame scrolling");
#endif
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
// Hook them up
m_overflowControlsHostLayer->addChild(m_clipLayer.get());
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h
index 7aa725e03..ff24c9648 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.h
+++ b/Source/WebCore/rendering/RenderLayerCompositor.h
@@ -116,6 +116,9 @@ public:
// Whether layer's backing needs a graphics layer to clip z-order children of the given layer.
bool clipsCompositingDescendants(const RenderLayer*) const;
+ // Whether the layer is fixed positioned to the view by an ancestor layer.
+ bool fixedPositionedByAncestor(const RenderLayer*) const;
+
// Whether the given layer needs an extra 'contents' layer.
bool needsContentsCompositingLayer(const RenderLayer*) const;
// Return the bounding box required for compositing layer and its childern, relative to ancestorLayer.
@@ -246,7 +249,7 @@ private:
void updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*);
// Returns true if any layer's compositing changed
- void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged);
+ void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged, bool& descendantHas3DTransform);
// Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer.
void rebuildCompositingLayerTree(RenderLayer*, Vector<GraphicsLayer*>& childGraphicsLayersOfEnclosingLayer, int depth);
@@ -286,10 +289,10 @@ private:
bool requiresCompositingForCanvas(RenderObject*) const;
bool requiresCompositingForPlugin(RenderObject*) const;
bool requiresCompositingForFrame(RenderObject*) const;
- bool requiresCompositingWhenDescendantsAreCompositing(RenderObject*) const;
bool requiresCompositingForFilters(RenderObject*) const;
bool requiresCompositingForScrollableFrame() const;
bool requiresCompositingForPosition(RenderObject*, const RenderLayer*) const;
+ bool requiresCompositingForIndirectReason(RenderObject*, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason&) const;
bool requiresScrollLayer(RootLayerAttachment) const;
bool requiresHorizontalScrollbarLayer() const;
diff --git a/Source/WebCore/rendering/RenderListBox.cpp b/Source/WebCore/rendering/RenderListBox.cpp
index aa591de66..516449fc5 100644
--- a/Source/WebCore/rendering/RenderListBox.cpp
+++ b/Source/WebCore/rendering/RenderListBox.cpp
@@ -358,7 +358,8 @@ static LayoutSize itemOffsetForAlignment(TextRun textRun, RenderStyle* itemStyle
{
ETextAlign actualAlignment = itemStyle->textAlign();
// FIXME: Firefox doesn't respect JUSTIFY. Should we?
- if (actualAlignment == TAAUTO || actualAlignment == JUSTIFY)
+ // FIXME: Handle TAEND here
+ if (actualAlignment == TASTART || actualAlignment == JUSTIFY)
actualAlignment = itemStyle->isLeftToRightDirection() ? LEFT : RIGHT;
LayoutSize offset = LayoutSize(0, itemFont.fontMetrics().ascent());
diff --git a/Source/WebCore/rendering/RenderMarquee.cpp b/Source/WebCore/rendering/RenderMarquee.cpp
index 7cb69e928..2ddffc56f 100644
--- a/Source/WebCore/rendering/RenderMarquee.cpp
+++ b/Source/WebCore/rendering/RenderMarquee.cpp
@@ -230,7 +230,7 @@ void RenderMarquee::updateMarqueeStyle()
// FIXME: Bring these up with the CSS WG.
if (isHorizontal() && m_layer->renderer()->childrenInline()) {
s->setWhiteSpace(NOWRAP);
- s->setTextAlign(TAAUTO);
+ s->setTextAlign(TASTART);
}
}
diff --git a/Source/WebCore/rendering/RenderMediaControlsChromium.cpp b/Source/WebCore/rendering/RenderMediaControlsChromium.cpp
index 72e12c881..7fa55271a 100644
--- a/Source/WebCore/rendering/RenderMediaControlsChromium.cpp
+++ b/Source/WebCore/rendering/RenderMediaControlsChromium.cpp
@@ -74,14 +74,25 @@ static bool paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInf
if (!mediaElement)
return false;
- static Image* soundFull = platformResource("mediaSoundFull");
- static Image* soundNone = platformResource("mediaSoundNone");
- static Image* soundDisabled = platformResource("mediaSoundDisabled");
+ static Image* soundLevel3 = platformResource("mediaplayerSoundLevel3");
+ static Image* soundLevel2 = platformResource("mediaplayerSoundLevel2");
+ static Image* soundLevel1 = platformResource("mediaplayerSoundLevel1");
+ static Image* soundLevel0 = platformResource("mediaplayerSoundLevel0");
+ static Image* soundDisabled = platformResource("mediaplayerSoundDisabled");
if (!hasSource(mediaElement) || !mediaElement->hasAudio())
return paintMediaButton(paintInfo.context, rect, soundDisabled);
- return paintMediaButton(paintInfo.context, rect, mediaElement->muted() ? soundNone: soundFull);
+ if (mediaElement->muted() || mediaElement->volume() <= 0)
+ return paintMediaButton(paintInfo.context, rect, soundLevel0);
+
+ if (mediaElement->volume() <= 0.33)
+ return paintMediaButton(paintInfo.context, rect, soundLevel1);
+
+ if (mediaElement->volume() <= 0.66)
+ return paintMediaButton(paintInfo.context, rect, soundLevel2);
+
+ return paintMediaButton(paintInfo.context, rect, soundLevel3);
}
static bool paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
@@ -90,9 +101,9 @@ static bool paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInf
if (!mediaElement)
return false;
- static Image* mediaPlay = platformResource("mediaPlay");
- static Image* mediaPause = platformResource("mediaPause");
- static Image* mediaPlayDisabled = platformResource("mediaPlayDisabled");
+ static Image* mediaPlay = platformResource("mediaplayerPlay");
+ static Image* mediaPause = platformResource("mediaplayerPause");
+ static Image* mediaPlayDisabled = platformResource("mediaplayerPlayDisabled");
if (!hasSource(mediaElement))
return paintMediaButton(paintInfo.context, rect, mediaPlayDisabled);
@@ -102,10 +113,75 @@ static bool paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInf
static Image* getMediaSliderThumb()
{
- static Image* mediaSliderThumb = platformResource("mediaSliderThumb");
+ static Image* mediaSliderThumb = platformResource("mediaplayerSliderThumb");
return mediaSliderThumb;
}
+static void paintRoundedSliderBackground(const IntRect& rect, const RenderStyle* style, GraphicsContext* context)
+{
+ int borderRadius = rect.height() / 2;
+ IntSize radii(borderRadius, borderRadius);
+ Color sliderBackgroundColor = Color(29, 29, 29);
+ context->save();
+ context->fillRoundedRect(rect, radii, radii, radii, radii, sliderBackgroundColor, ColorSpaceDeviceRGB);
+ context->restore();
+}
+
+static void paintSliderRangeHighlight(const IntRect& rect, const RenderStyle* style, GraphicsContext* context, float startFraction, float widthFraction)
+{
+ if (startFraction < 0)
+ startFraction = 0;
+ if (widthFraction > 1)
+ widthFraction = 1;
+ float endFraction = startFraction + widthFraction;
+ if (endFraction > 1) {
+ widthFraction = widthFraction - startFraction;
+ endFraction = startFraction + widthFraction;
+ }
+
+ // Set rectangle to highlight range.
+ IntRect highlightRect = rect;
+ int startOffset = startFraction * rect.width();
+ int endOffset = rect.width() - endFraction * rect.width();
+ int rangeWidth = widthFraction * rect.width();
+ highlightRect.move(startOffset, 0);
+ highlightRect.setWidth(rangeWidth);
+
+ // Don't bother drawing an empty area.
+ if (highlightRect.isEmpty())
+ return;
+
+ // Calculate border radius; need to avoid being smaller than half the slider height
+ // because of https://bugs.webkit.org/show_bug.cgi?id=30143.
+ int borderRadius = rect.height() / 2;
+ IntSize radii(borderRadius, borderRadius);
+
+ // Calculate white-grey gradient.
+ IntPoint sliderTopLeft = highlightRect.location();
+ IntPoint sliderBottomLeft = sliderTopLeft;
+ sliderBottomLeft.move(0, highlightRect.height());
+ Color startColor = Color(220, 220, 220);
+ Color endColor = Color(240, 240, 240);
+ RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderBottomLeft);
+ gradient->addColorStop(0.0, startColor);
+ gradient->addColorStop(1.0, endColor);
+
+ // Fill highlight rectangle with gradient, potentially rounded if on left or right edge.
+ context->save();
+ context->setFillGradient(gradient);
+
+ if (startOffset < borderRadius && endOffset < borderRadius)
+ context->fillRoundedRect(highlightRect, radii, radii, radii, radii, startColor, ColorSpaceDeviceRGB);
+ else if (startOffset < borderRadius)
+ context->fillRoundedRect(highlightRect, radii, IntSize(0, 0), radii, IntSize(0, 0), startColor, ColorSpaceDeviceRGB);
+ else if (endOffset < borderRadius)
+ context->fillRoundedRect(highlightRect, IntSize(0, 0), radii, IntSize(0, 0), radii, startColor, ColorSpaceDeviceRGB);
+ else
+ context->fillRect(highlightRect);
+
+ context->restore();
+}
+
static bool paintMediaSlider(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
{
HTMLMediaElement* mediaElement = toParentMediaElement(object);
@@ -115,23 +191,10 @@ static bool paintMediaSlider(RenderObject* object, const PaintInfo& paintInfo, c
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->visitedDependentColor(CSSPropertyBorderLeftColor), ColorSpaceDeviceRGB);
- context->setStrokeThickness(style->borderLeftWidth());
- context->setFillColor(style->visitedDependentColor(CSSPropertyBackgroundColor), ColorSpaceDeviceRGB);
- context->drawRect(rect);
- context->restore();
+ paintRoundedSliderBackground(rect, style, context);
// Draw the buffered range. Since the element may have multiple buffered ranges and it'd be
// distracting/'busy' to show all of them, show only the buffered range containing the current play head.
- IntRect bufferedRect = rect;
- bufferedRect.inflate(-style->borderLeftWidth());
-
RefPtr<TimeRanges> bufferedTimeRanges = mediaElement->buffered();
float duration = mediaElement->duration();
float currentTime = mediaElement->currentTime();
@@ -146,27 +209,8 @@ static bool paintMediaSlider(RenderObject* object, const PaintInfo& paintInfo, c
float startFraction = start / duration;
float endFraction = end / duration;
float widthFraction = endFraction - startFraction;
- bufferedRect.move(startFraction * bufferedRect.width(), 0);
- bufferedRect.setWidth(widthFraction * bufferedRect.width());
-
- // Don't bother drawing an empty area.
- if (bufferedRect.isEmpty())
- return true;
-
- IntPoint sliderTopLeft = bufferedRect.location();
- IntPoint sliderBottomLeft = sliderTopLeft;
- sliderBottomLeft.move(0, bufferedRect.height());
-
- RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderBottomLeft);
- Color startColor = object->style()->visitedDependentColor(CSSPropertyColor);
- 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();
+
+ paintSliderRangeHighlight(rect, style, context, startFraction, widthFraction);
return true;
}
@@ -189,6 +233,8 @@ static bool paintMediaSliderThumb(RenderObject* object, const PaintInfo& paintIn
return paintMediaButton(paintInfo.context, rect, mediaSliderThumb);
}
+const int mediaVolumeSliderThumbWidth = 24;
+
static bool paintMediaVolumeSlider(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
{
HTMLMediaElement* mediaElement = toParentMediaElement(object);
@@ -196,55 +242,47 @@ static bool paintMediaVolumeSlider(RenderObject* object, const PaintInfo& paintI
return false;
GraphicsContext* context = paintInfo.context;
- Color originalColor = context->strokeColor();
- if (originalColor != Color::white)
- context->setStrokeColor(Color::white, ColorSpaceDeviceRGB);
+ RenderStyle* style = object->style();
+
+ paintRoundedSliderBackground(rect, style, context);
- int x = rect.x() + rect.width() / 2;
- context->drawLine(IntPoint(x, rect.y()), IntPoint(x, rect.y() + rect.height()));
+ // Calculate volume position for white background rectangle.
+ float volume = mediaElement->volume();
+ if (isnan(volume) || volume < 0)
+ return true;
+ if (volume > 1)
+ volume = 1;
+ if (!hasSource(mediaElement) || !mediaElement->hasAudio() || mediaElement->muted())
+ volume = 0;
+
+ // Calculate the position relative to the center of the thumb.
+ float fillWidth = 0;
+ if (volume > 0) {
+ float thumbCenter = mediaVolumeSliderThumbWidth / 2;
+ float zoomLevel = style->effectiveZoom();
+ float positionWidth = volume * (rect.width() - (zoomLevel * thumbCenter));
+ fillWidth = positionWidth + (zoomLevel * thumbCenter / 2);
+ }
+
+ paintSliderRangeHighlight(rect, style, context, 0.0, fillWidth / rect.width());
- if (originalColor != Color::white)
- context->setStrokeColor(originalColor, ColorSpaceDeviceRGB);
return true;
}
static bool paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
{
- static Image* mediaVolumeSliderThumb = platformResource("mediaVolumeSliderThumb");
- return paintMediaButton(paintInfo.context, rect, mediaVolumeSliderThumb);
-}
-
-static bool paintMediaTimelineContainer(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
-{
- HTMLMediaElement* mediaElement = toParentMediaElement(object);
+ ASSERT(object->node());
+ Node* hostNode = object->node()->shadowAncestorNode();
+ ASSERT(hostNode);
+ HTMLMediaElement* mediaElement = toParentMediaElement(hostNode);
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()->visitedDependentColor(CSSPropertyBorderLeftColor).rgb(), ColorSpaceDeviceRGB);
- 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()->visitedDependentColor(CSSPropertyBorderRightColor).rgb(), ColorSpaceDeviceRGB);
- context->drawLine(IntPoint(rect.x() + rect.width() - 1, rect.y()),
- IntPoint(rect.x() + rect.width() - 1, rect.y() + rect.height()));
-
- context->setStrokeColor(originalColor, ColorSpaceDeviceRGB);
- context->setStrokeThickness(originalThickness);
- context->setStrokeStyle(originalStyle);
- }
- return true;
+ if (!hasSource(mediaElement) || !mediaElement->hasAudio())
+ return true;
+
+ static Image* mediaVolumeSliderThumb = platformResource("mediaplayerVolumeSliderThumb");
+ return paintMediaButton(paintInfo.context, rect, mediaVolumeSliderThumb);
}
static bool paintMediaFullscreenButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
@@ -253,8 +291,8 @@ static bool paintMediaFullscreenButton(RenderObject* object, const PaintInfo& pa
if (!mediaElement)
return false;
- DEFINE_STATIC_LOCAL(Image*, mediaFullscreen, (platformResource("mediaFullscreen")));
- return paintMediaButton(paintInfo.context, rect, mediaFullscreen);
+ static Image* mediaFullscreenButton = platformResource("mediaplayerFullscreen");
+ return paintMediaButton(paintInfo.context, rect, mediaFullscreenButton);
}
bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType part, RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
@@ -274,8 +312,6 @@ bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType
return paintMediaVolumeSlider(object, paintInfo, rect);
case MediaVolumeSliderThumb:
return paintMediaVolumeSliderThumb(object, paintInfo, rect);
- case MediaTimelineContainer:
- return paintMediaTimelineContainer(object, paintInfo, rect);
case MediaEnterFullscreenButton:
case MediaExitFullscreenButton:
return paintMediaFullscreenButton(object, paintInfo, rect);
@@ -283,6 +319,7 @@ bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType
case MediaSeekBackButton:
case MediaSeekForwardButton:
case MediaVolumeSliderContainer:
+ case MediaTimelineContainer:
case MediaCurrentTimeDisplay:
case MediaTimeRemainingDisplay:
case MediaControlsPanel:
@@ -301,24 +338,74 @@ bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType
return false;
}
+const int mediaSliderThumbWidth = 32;
+const int mediaSliderThumbHeight = 24;
+const int mediaVolumeSliderThumbHeight = 24;
+
void RenderMediaControlsChromium::adjustMediaSliderThumbSize(RenderStyle* style)
{
- static Image* mediaSliderThumb = platformResource("mediaSliderThumb");
- static Image* mediaVolumeSliderThumb = platformResource("mediaVolumeSliderThumb");
+ static Image* mediaSliderThumb = platformResource("mediaplayerSliderThumb");
+ static Image* mediaVolumeSliderThumb = platformResource("mediaplayerVolumeSliderThumb");
+ int width = 0;
+ int height = 0;
Image* thumbImage = 0;
- if (style->appearance() == MediaSliderThumbPart)
+ if (style->appearance() == MediaSliderThumbPart) {
thumbImage = mediaSliderThumb;
- else if (style->appearance() == MediaVolumeSliderThumbPart)
+ width = mediaSliderThumbWidth;
+ height = mediaSliderThumbHeight;
+ } else if (style->appearance() == MediaVolumeSliderThumbPart) {
thumbImage = mediaVolumeSliderThumb;
+ width = mediaVolumeSliderThumbWidth;
+ height = mediaVolumeSliderThumbHeight;
+ }
float zoomLevel = style->effectiveZoom();
if (thumbImage) {
- style->setWidth(Length(static_cast<int>(thumbImage->width() * zoomLevel), Fixed));
- style->setHeight(Length(static_cast<int>(thumbImage->height() * zoomLevel), Fixed));
+ style->setWidth(Length(static_cast<int>(width * zoomLevel), Fixed));
+ style->setHeight(Length(static_cast<int>(height * zoomLevel), Fixed));
}
}
+static String formatChromiumMediaControlsTime(float time, float duration)
+{
+ if (!isfinite(time))
+ time = 0;
+ if (!isfinite(duration))
+ duration = 0;
+ int seconds = static_cast<int>(fabsf(time));
+ int hours = seconds / (60 * 60);
+ int minutes = (seconds / 60) % 60;
+ seconds %= 60;
+
+ // duration defines the format of how the time is rendered
+ int durationSecs = static_cast<int>(fabsf(duration));
+ int durationHours = durationSecs / (60 * 60);
+ int durationMins = (durationSecs / 60) % 60;
+
+ if (durationHours || hours)
+ return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
+ if (durationMins > 9)
+ return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
+
+ return String::format("%s%01d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
+}
+
+String RenderMediaControlsChromium::formatMediaControlsTime(float time)
+{
+ return formatChromiumMediaControlsTime(time, time);
+}
+
+String RenderMediaControlsChromium::formatMediaControlsCurrentTime(float currentTime, float duration)
+{
+ return formatChromiumMediaControlsTime(currentTime, duration);
+}
+
+String RenderMediaControlsChromium::formatMediaControlsRemainingTime(float currentTime, float duration)
+{
+ return formatChromiumMediaControlsTime(currentTime - duration, duration);
+}
+
#endif // #if ENABLE(VIDEO)
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderMediaControlsChromium.h b/Source/WebCore/rendering/RenderMediaControlsChromium.h
index 9af93960f..c3b801bf0 100644
--- a/Source/WebCore/rendering/RenderMediaControlsChromium.h
+++ b/Source/WebCore/rendering/RenderMediaControlsChromium.h
@@ -38,6 +38,9 @@ class RenderMediaControlsChromium {
public:
static bool paintMediaControlsPart(MediaControlElementType, RenderObject*, const PaintInfo&, const IntRect&);
static void adjustMediaSliderThumbSize(RenderStyle*);
+ static String formatMediaControlsTime(float time);
+ static String formatMediaControlsCurrentTime(float currentTime, float duration);
+ static String formatMediaControlsRemainingTime(float currentTime, float duration);
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderMenuList.cpp b/Source/WebCore/rendering/RenderMenuList.cpp
index 48146e266..56eccf8a1 100644
--- a/Source/WebCore/rendering/RenderMenuList.cpp
+++ b/Source/WebCore/rendering/RenderMenuList.cpp
@@ -312,9 +312,6 @@ void RenderMenuList::showPopup()
// the actual width of the element to size the popup.
FloatPoint absTopLeft = localToAbsolute(FloatPoint(), false, true);
IntRect absBounds = absoluteBoundingBoxRectIgnoringTransforms();
- int scale = document()->page()->settings()->defaultDeviceScaleFactor();
- if (scale && scale != 1)
- absBounds.scale(scale);
absBounds.setLocation(roundedIntPoint(absTopLeft));
HTMLSelectElement* select = toHTMLSelectElement(node());
m_popup->show(absBounds, document()->view(), select->optionToListIndex(select->selectedIndex()));
diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp
index 258477659..be90dd6ba 100755
--- a/Source/WebCore/rendering/RenderObject.cpp
+++ b/Source/WebCore/rendering/RenderObject.cpp
@@ -389,6 +389,14 @@ RenderObject* RenderObject::previousInPreOrder() const
return parent();
}
+RenderObject* RenderObject::previousInPreOrder(const RenderObject* stayWithin) const
+{
+ if (this == stayWithin)
+ return 0;
+
+ return previousInPreOrder();
+}
+
RenderObject* RenderObject::childAt(unsigned index) const
{
RenderObject* child = firstChild();
@@ -716,20 +724,36 @@ RenderBlock* RenderObject::containingBlock() const
if (!o && isRenderScrollbarPart())
o = toRenderScrollbarPart(this)->rendererOwningScrollbar();
if (!isText() && m_style->position() == FixedPosition) {
- while (o && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock()))
+ while (o) {
+ if (o->isRenderView())
+ break;
+ if (o->hasTransform() && o->isRenderBlock())
+ break;
+#if ENABLE(SVG)
+ // foreignObject is the containing block for its contents.
+ if (o->isSVGForeignObject())
+ break;
+#endif
o = o->parent();
+ }
+ ASSERT(!o->isAnonymousBlock());
} else if (!isText() && m_style->position() == AbsolutePosition) {
- while (o && (o->style()->position() == StaticPosition || (o->isInline() && !o->isReplaced())) && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) {
+ while (o) {
// For relpositioned inlines, we return the nearest non-anonymous enclosing block. We don't try
// to return the inline itself. This allows us to avoid having a positioned objects
// list in all RenderInlines and lets us return a strongly-typed RenderBlock* result
// from this method. The container() method can actually be used to obtain the
// inline directly.
+ if (!o->style()->position() == StaticPosition && !(o->isInline() && !o->isReplaced()))
+ break;
+ if (o->isRenderView())
+ break;
+ if (o->hasTransform() && o->isRenderBlock())
+ break;
+
if (o->style()->position() == RelativePosition && o->isInline() && !o->isReplaced()) {
- RenderBlock* relPositionedInlineContainingBlock = o->containingBlock();
- while (relPositionedInlineContainingBlock->isAnonymousBlock())
- relPositionedInlineContainingBlock = relPositionedInlineContainingBlock->containingBlock();
- return relPositionedInlineContainingBlock;
+ o = o->containingBlock();
+ break;
}
#if ENABLE(SVG)
if (o->isSVGForeignObject()) //foreignObject is the containing block for contents inside it
@@ -738,6 +762,9 @@ RenderBlock* RenderObject::containingBlock() const
o = o->parent();
}
+
+ while (o && o->isAnonymousBlock())
+ o = o->containingBlock();
} else {
while (o && ((o->isInline() && !o->isReplaced()) || !o->isRenderBlock()))
o = o->parent();
@@ -1014,91 +1041,6 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
}
}
-#if !HAVE(PATH_BASED_BORDER_RADIUS_DRAWING)
-void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, int y, float thickness, const IntSize& radius,
- int angleStart, int angleSpan, BoxSide s, Color color,
- EBorderStyle style, bool firstCorner)
-{
- // FIXME: This function should be removed when all ports implement GraphicsContext::clipConvexPolygon()!!
- // At that time, everyone can use RenderObject::drawBoxSideFromPath() instead. This should happen soon.
- if ((style == DOUBLE && thickness / 2 < 3) || ((style == RIDGE || style == GROOVE) && thickness / 2 < 2))
- style = SOLID;
-
- switch (style) {
- case BNONE:
- case BHIDDEN:
- return;
- case DOTTED:
- case DASHED:
- graphicsContext->setStrokeColor(color, m_style->colorSpace());
- graphicsContext->setStrokeStyle(style == DOTTED ? DottedStroke : DashedStroke);
- graphicsContext->setStrokeThickness(thickness);
- graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
- break;
- case DOUBLE: {
- float third = thickness / 3.0f;
- float innerThird = (thickness + 1.0f) / 6.0f;
- int shiftForInner = static_cast<int>(innerThird * 2.5f);
-
- int outerY = y;
- int outerHeight = radius.height() * 2;
- int innerX = x + shiftForInner;
- int innerY = y + shiftForInner;
- int innerWidth = (radius.width() - shiftForInner) * 2;
- int innerHeight = (radius.height() - shiftForInner) * 2;
- if (innerThird > 1 && (s == BSTop || (firstCorner && (s == BSLeft || s == BSRight)))) {
- outerHeight += 2;
- innerHeight += 2;
- }
-
- graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(color, m_style->colorSpace());
- graphicsContext->setStrokeThickness(third);
- graphicsContext->strokeArc(IntRect(x, outerY, radius.width() * 2, outerHeight), angleStart, angleSpan);
- graphicsContext->setStrokeThickness(innerThird > 2 ? innerThird - 1 : innerThird);
- graphicsContext->strokeArc(IntRect(innerX, innerY, innerWidth, innerHeight), angleStart, angleSpan);
- break;
- }
- case GROOVE:
- case RIDGE: {
- Color c2;
- if ((style == RIDGE && (s == BSTop || s == BSLeft)) ||
- (style == GROOVE && (s == BSBottom || s == BSRight)))
- c2 = color.dark();
- else {
- c2 = color;
- color = color.dark();
- }
-
- graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(color, m_style->colorSpace());
- graphicsContext->setStrokeThickness(thickness);
- graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
-
- float halfThickness = (thickness + 1.0f) / 4.0f;
- int shiftForInner = static_cast<int>(halfThickness * 1.5f);
- graphicsContext->setStrokeColor(c2, m_style->colorSpace());
- graphicsContext->setStrokeThickness(halfThickness > 2 ? halfThickness - 1 : halfThickness);
- graphicsContext->strokeArc(IntRect(x + shiftForInner, y + shiftForInner, (radius.width() - shiftForInner) * 2,
- (radius.height() - shiftForInner) * 2), angleStart, angleSpan);
- break;
- }
- case INSET:
- if (s == BSTop || s == BSLeft)
- color = color.dark();
- case OUTSET:
- if (style == OUTSET && (s == BSBottom || s == BSRight))
- color = color.dark();
- case SOLID:
- graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(color, m_style->colorSpace());
- graphicsContext->setStrokeThickness(thickness);
- graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
- break;
- }
-}
-#endif
-
void RenderObject::paintFocusRing(GraphicsContext* context, const LayoutPoint& paintOffset, RenderStyle* style)
{
Vector<IntRect> focusRingRects;
@@ -1107,7 +1049,7 @@ void RenderObject::paintFocusRing(GraphicsContext* context, const LayoutPoint& p
context->drawFocusRing(focusRingRects, style->outlineWidth(), style->outlineOffset(), style->visitedDependentColor(CSSPropertyOutlineColor));
else
addPDFURLRect(context, unionRect(focusRingRects));
-}
+}
void RenderObject::addPDFURLRect(GraphicsContext* context, const LayoutRect& rect)
{
@@ -1847,7 +1789,7 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
if (m_style->visibility() != newStyle->visibility()) {
if (RenderLayer* l = enclosingLayer()) {
if (newStyle->visibility() == VISIBLE)
- l->setHasVisibleContent(true);
+ l->setHasVisibleContent();
else if (l->hasVisibleContent() && (this == l->renderer() || l->renderer()->style()->visibility() != VISIBLE)) {
l->dirtyVisibleContentStatus();
if (diff > StyleDifferenceRepaintLayer)
@@ -2272,8 +2214,14 @@ RenderObject* RenderObject::container(const RenderBoxModelObject* repaintContain
// 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())) {
+#if ENABLE(SVG)
+ // foreignObject is the containing block for its contents.
+ if (o->isSVGForeignObject())
+ break;
+#endif
if (repaintContainerSkipped && o == repaintContainer)
*repaintContainerSkipped = true;
+
o = o->parent();
}
} else if (pos == AbsolutePosition) {
@@ -2281,12 +2229,13 @@ RenderObject* RenderObject::container(const RenderBoxModelObject* repaintContain
// 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())) {
- if (repaintContainerSkipped && o == repaintContainer)
- *repaintContainerSkipped = true;
#if ENABLE(SVG)
if (o->isSVGForeignObject()) // foreignObject is the containing block for contents inside it
break;
#endif
+ if (repaintContainerSkipped && o == repaintContainer)
+ *repaintContainerSkipped = true;
+
o = o->parent();
}
}
diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h
index 58de96b31..23cdbc88c 100644
--- a/Source/WebCore/rendering/RenderObject.h
+++ b/Source/WebCore/rendering/RenderObject.h
@@ -41,10 +41,6 @@
#include <wtf/HashSet.h>
#include <wtf/UnusedParam.h>
-#if USE(CG) || USE(CAIRO) || USE(SKIA) || PLATFORM(QT) || PLATFORM(WX)
-#define HAVE_PATH_BASED_BORDER_RADIUS_DRAWING 1
-#endif
-
namespace WebCore {
class AffineTransform;
@@ -197,6 +193,7 @@ public:
RenderObject* nextInPreOrderAfterChildren() const;
RenderObject* nextInPreOrderAfterChildren(const RenderObject* stayWithin) const;
RenderObject* previousInPreOrder() const;
+ RenderObject* previousInPreOrder(const RenderObject* stayWithin) const;
RenderObject* childAt(unsigned) const;
RenderObject* firstLeafChild() const;
@@ -489,6 +486,9 @@ public:
&& !isRenderFullScreen()
&& !isRenderFullScreenPlaceholder()
#endif
+#if ENABLE(MATHML)
+ && !isRenderMathMLBlock()
+#endif
;
}
bool isAnonymousColumnsBlock() const { return style()->specifiesColumns() && isAnonymousBlock(); }
@@ -552,13 +552,6 @@ public:
inline bool preservesNewline() const;
-#if !HAVE(PATH_BASED_BORDER_RADIUS_DRAWING)
- // FIXME: This function should be removed when all ports implement GraphicsContext::clipConvexPolygon()!!
- // At that time, everyone can use RenderObject::drawBoxSideFromPath() instead. This should happen soon.
- void drawArcForBoxSide(GraphicsContext*, int x, int y, float thickness, const IntSize& radius, int angleStart,
- int angleSpan, BoxSide, Color, EBorderStyle, bool firstCorner);
-#endif
-
// The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect
// any pseudo classes (and therefore has no concept of changing state).
RenderStyle* getCachedPseudoStyle(PseudoId, RenderStyle* parentStyle = 0) const;
@@ -1214,18 +1207,6 @@ inline void adjustFloatRectForAbsoluteZoom(FloatRect& rect, RenderObject* render
rect.scale(1 / zoom, 1 / zoom);
}
-inline void adjustFloatQuadForPageScale(FloatQuad& quad, float pageScale)
-{
- if (pageScale != 1)
- quad.scale(1 / pageScale, 1 / pageScale);
-}
-
-inline void adjustFloatRectForPageScale(FloatRect& rect, float pageScale)
-{
- if (pageScale != 1)
- rect.scale(1 / pageScale, 1 / pageScale);
-}
-
} // namespace WebCore
#ifndef NDEBUG
diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp
index f0cf6aff8..f545297d9 100644
--- a/Source/WebCore/rendering/RenderObjectChildList.cpp
+++ b/Source/WebCore/rendering/RenderObjectChildList.cpp
@@ -194,7 +194,7 @@ void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* n
if (!layer)
layer = owner->enclosingLayer();
if (layer)
- layer->setHasVisibleContent(true);
+ layer->setHasVisibleContent();
}
if (newChild->isListItem())
@@ -261,7 +261,7 @@ void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* c
if (!layer)
layer = owner->enclosingLayer();
if (layer)
- layer->setHasVisibleContent(true);
+ layer->setHasVisibleContent();
}
if (child->isListItem())
diff --git a/Source/WebCore/rendering/RenderReplaced.cpp b/Source/WebCore/rendering/RenderReplaced.cpp
index d290959e1..2555fcd6a 100644
--- a/Source/WebCore/rendering/RenderReplaced.cpp
+++ b/Source/WebCore/rendering/RenderReplaced.cpp
@@ -287,10 +287,9 @@ void RenderReplaced::computeIntrinsicRatioInformationForRenderBox(RenderBox* con
intrinsicRatio = 1;
return;
}
-
- // This code path can't yield percentage intrinsic sizes, assert that.
computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
- ASSERT(!isPercentageIntrinsicSize);
+ if (intrinsicRatio)
+ ASSERT(!isPercentageIntrinsicSize);
}
void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
diff --git a/Source/WebCore/rendering/RenderRubyText.cpp b/Source/WebCore/rendering/RenderRubyText.cpp
index c49b4f694..e9765f28d 100644
--- a/Source/WebCore/rendering/RenderRubyText.cpp
+++ b/Source/WebCore/rendering/RenderRubyText.cpp
@@ -54,7 +54,8 @@ bool RenderRubyText::isChildAllowed(RenderObject* child, RenderStyle*) const
ETextAlign RenderRubyText::textAlignmentForLine(bool endsWithSoftBreak) const
{
ETextAlign textAlign = style()->textAlign();
- if (textAlign != TAAUTO)
+ // FIXME: This check is bogus since user can set the initial value.
+ if (textAlign != RenderStyle::initialTextAlign())
return RenderBlock::textAlignmentForLine(endsWithSoftBreak);
// The default behavior is to allow ruby text to expand if it is shorter than the ruby base.
@@ -64,7 +65,8 @@ ETextAlign RenderRubyText::textAlignmentForLine(bool endsWithSoftBreak) const
void RenderRubyText::adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const
{
ETextAlign textAlign = style()->textAlign();
- if (textAlign != TAAUTO)
+ // FIXME: This check is bogus since user can set the initial value.
+ if (textAlign != RenderStyle::initialTextAlign())
return RenderBlock::adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, logicalWidth);
int maxPreferredLogicalWidth = this->maxPreferredLogicalWidth();
diff --git a/Source/WebCore/rendering/RenderSearchField.cpp b/Source/WebCore/rendering/RenderSearchField.cpp
new file mode 100644
index 000000000..2704cdc03
--- /dev/null
+++ b/Source/WebCore/rendering/RenderSearchField.cpp
@@ -0,0 +1,385 @@
+/**
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "RenderSearchField.h"
+
+#include "CSSFontSelector.h"
+#include "CSSValueKeywords.h"
+#include "Chrome.h"
+#include "Frame.h"
+#include "FrameSelection.h"
+#include "FrameView.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "HitTestResult.h"
+#include "LocalizedStrings.h"
+#include "Page.h"
+#include "PlatformKeyboardEvent.h"
+#include "RenderLayer.h"
+#include "RenderScrollbar.h"
+#include "RenderTheme.h"
+#include "SearchPopupMenu.h"
+#include "Settings.h"
+#include "SimpleFontData.h"
+#include "StyleResolver.h"
+#include "TextControlInnerElements.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// ----------------------------
+
+RenderSearchField::RenderSearchField(Node* node)
+ : RenderTextControlSingleLine(node)
+ , m_searchPopupIsVisible(false)
+ , m_searchPopup(0)
+{
+ ASSERT(node->isHTMLElement());
+ ASSERT(node->toInputElement());
+ ASSERT(node->toInputElement()->isSearchField());
+}
+
+RenderSearchField::~RenderSearchField()
+{
+ if (m_searchPopup) {
+ m_searchPopup->popupMenu()->disconnectClient();
+ m_searchPopup = 0;
+ }
+}
+
+inline HTMLElement* RenderSearchField::resultsButtonElement() const
+{
+ return inputElement()->resultsButtonElement();
+}
+
+inline HTMLElement* RenderSearchField::cancelButtonElement() const
+{
+ return inputElement()->cancelButtonElement();
+}
+
+void RenderSearchField::addSearchResult()
+{
+ HTMLInputElement* input = inputElement();
+ if (input->maxResults() <= 0)
+ return;
+
+ String value = input->value();
+ if (value.isEmpty())
+ return;
+
+ Settings* settings = document()->settings();
+ if (!settings || settings->privateBrowsingEnabled())
+ return;
+
+ int size = static_cast<int>(m_recentSearches.size());
+ for (int i = size - 1; i >= 0; --i) {
+ if (m_recentSearches[i] == value)
+ m_recentSearches.remove(i);
+ }
+
+ m_recentSearches.insert(0, value);
+ while (static_cast<int>(m_recentSearches.size()) > input->maxResults())
+ m_recentSearches.removeLast();
+
+ const AtomicString& name = autosaveName();
+ if (!m_searchPopup)
+ m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
+
+ m_searchPopup->saveRecentSearches(name, m_recentSearches);
+}
+
+void RenderSearchField::showPopup()
+{
+ if (m_searchPopupIsVisible)
+ return;
+
+ if (!m_searchPopup)
+ m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
+
+ if (!m_searchPopup->enabled())
+ return;
+
+ m_searchPopupIsVisible = true;
+
+ const AtomicString& name = autosaveName();
+ m_searchPopup->loadRecentSearches(name, m_recentSearches);
+
+ // Trim the recent searches list if the maximum size has changed since we last saved.
+ HTMLInputElement* input = inputElement();
+ if (static_cast<int>(m_recentSearches.size()) > input->maxResults()) {
+ do {
+ m_recentSearches.removeLast();
+ } while (static_cast<int>(m_recentSearches.size()) > input->maxResults());
+
+ m_searchPopup->saveRecentSearches(name, m_recentSearches);
+ }
+
+ m_searchPopup->popupMenu()->show(pixelSnappedIntRect(absoluteBoundingBoxRect()), document()->view(), -1);
+}
+
+void RenderSearchField::hidePopup()
+{
+ if (m_searchPopup)
+ m_searchPopup->popupMenu()->hide();
+}
+
+LayoutUnit RenderSearchField::computeControlHeight(LayoutUnit lineHeight, LayoutUnit nonContentHeight) const
+{
+ HTMLElement* resultsButton = resultsButtonElement();
+ if (RenderBox* resultsRenderer = resultsButton ? resultsButton->renderBox() : 0) {
+ resultsRenderer->computeLogicalHeight();
+ nonContentHeight = max(nonContentHeight, resultsRenderer->borderAndPaddingHeight() + resultsRenderer->marginHeight());
+ lineHeight = max(lineHeight, resultsRenderer->height());
+ }
+ HTMLElement* cancelButton = cancelButtonElement();
+ if (RenderBox* cancelRenderer = cancelButton ? cancelButton->renderBox() : 0) {
+ cancelRenderer->computeLogicalHeight();
+ nonContentHeight = max(nonContentHeight, cancelRenderer->borderAndPaddingHeight() + cancelRenderer->marginHeight());
+ lineHeight = max(lineHeight, cancelRenderer->height());
+ }
+
+ return lineHeight + nonContentHeight;
+}
+
+void RenderSearchField::updateFromElement()
+{
+ RenderTextControlSingleLine::updateFromElement();
+
+ if (cancelButtonElement())
+ updateCancelButtonVisibility();
+
+ if (m_searchPopupIsVisible)
+ m_searchPopup->popupMenu()->updateFromElement();
+}
+
+void RenderSearchField::updateCancelButtonVisibility() const
+{
+ RenderObject* cancelButtonRenderer = cancelButtonElement()->renderer();
+ if (!cancelButtonRenderer)
+ return;
+
+ const RenderStyle* curStyle = cancelButtonRenderer->style();
+ EVisibility buttonVisibility = visibilityForCancelButton();
+ if (curStyle->visibility() == buttonVisibility)
+ return;
+
+ RefPtr<RenderStyle> cancelButtonStyle = RenderStyle::clone(curStyle);
+ cancelButtonStyle->setVisibility(buttonVisibility);
+ cancelButtonRenderer->setStyle(cancelButtonStyle);
+}
+
+EVisibility RenderSearchField::visibilityForCancelButton() const
+{
+ return (style()->visibility() == HIDDEN || inputElement()->value().isEmpty()) ? HIDDEN : VISIBLE;
+}
+
+const AtomicString& RenderSearchField::autosaveName() const
+{
+ return static_cast<Element*>(node())->getAttribute(autosaveAttr);
+}
+
+// PopupMenuClient methods
+void RenderSearchField::valueChanged(unsigned listIndex, bool fireEvents)
+{
+ ASSERT(static_cast<int>(listIndex) < listSize());
+ HTMLInputElement* input = inputElement();
+ if (static_cast<int>(listIndex) == (listSize() - 1)) {
+ if (fireEvents) {
+ m_recentSearches.clear();
+ const AtomicString& name = autosaveName();
+ if (!name.isEmpty()) {
+ if (!m_searchPopup)
+ m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
+ m_searchPopup->saveRecentSearches(name, m_recentSearches);
+ }
+ }
+ } else {
+ input->setValue(itemText(listIndex));
+ if (fireEvents)
+ input->onSearch();
+ input->select();
+ }
+}
+
+String RenderSearchField::itemText(unsigned listIndex) const
+{
+ int size = listSize();
+ if (size == 1) {
+ ASSERT(!listIndex);
+ return searchMenuNoRecentSearchesText();
+ }
+ if (!listIndex)
+ return searchMenuRecentSearchesText();
+ if (itemIsSeparator(listIndex))
+ return String();
+ if (static_cast<int>(listIndex) == (size - 1))
+ return searchMenuClearRecentSearchesText();
+ return m_recentSearches[listIndex - 1];
+}
+
+String RenderSearchField::itemLabel(unsigned) const
+{
+ return String();
+}
+
+String RenderSearchField::itemIcon(unsigned) const
+{
+ return String();
+}
+
+bool RenderSearchField::itemIsEnabled(unsigned listIndex) const
+{
+ if (!listIndex || itemIsSeparator(listIndex))
+ return false;
+ return true;
+}
+
+PopupMenuStyle RenderSearchField::itemStyle(unsigned) const
+{
+ return menuStyle();
+}
+
+PopupMenuStyle RenderSearchField::menuStyle() const
+{
+ return PopupMenuStyle(style()->visitedDependentColor(CSSPropertyColor), style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->font(), style()->visibility() == VISIBLE,
+ style()->display() == NONE, style()->textIndent(), style()->direction(), isOverride(style()->unicodeBidi()));
+}
+
+int RenderSearchField::clientInsetLeft() const
+{
+ // Inset the menu by the radius of the cap on the left so that
+ // it only runs along the straight part of the bezel.
+ return height() / 2;
+}
+
+int RenderSearchField::clientInsetRight() const
+{
+ // Inset the menu by the radius of the cap on the right so that
+ // it only runs along the straight part of the bezel (unless it needs
+ // to be wider).
+ return height() / 2;
+}
+
+LayoutUnit RenderSearchField::clientPaddingLeft() const
+{
+ LayoutUnit padding = paddingLeft();
+ if (RenderBox* box = innerBlockElement() ? innerBlockElement()->renderBox() : 0)
+ padding += box->x();
+ return padding;
+}
+
+LayoutUnit RenderSearchField::clientPaddingRight() const
+{
+ LayoutUnit padding = paddingRight();
+ if (RenderBox* containerBox = containerElement() ? containerElement()->renderBox() : 0) {
+ if (RenderBox* innerBlockBox = innerBlockElement() ? innerBlockElement()->renderBox() : 0)
+ padding += containerBox->width() - (innerBlockBox->x() + innerBlockBox->width());
+ }
+ return padding;
+}
+
+int RenderSearchField::listSize() const
+{
+ // If there are no recent searches, then our menu will have 1 "No recent searches" item.
+ if (!m_recentSearches.size())
+ return 1;
+ // Otherwise, leave room in the menu for a header, a separator, and the "Clear recent searches" item.
+ return m_recentSearches.size() + 3;
+}
+
+int RenderSearchField::selectedIndex() const
+{
+ return -1;
+}
+
+void RenderSearchField::popupDidHide()
+{
+ m_searchPopupIsVisible = false;
+}
+
+bool RenderSearchField::itemIsSeparator(unsigned listIndex) const
+{
+ // The separator will be the second to last item in our list.
+ return static_cast<int>(listIndex) == (listSize() - 2);
+}
+
+bool RenderSearchField::itemIsLabel(unsigned listIndex) const
+{
+ return !listIndex;
+}
+
+bool RenderSearchField::itemIsSelected(unsigned) const
+{
+ return false;
+}
+
+void RenderSearchField::setTextFromItem(unsigned listIndex)
+{
+ inputElement()->setValue(itemText(listIndex));
+}
+
+FontSelector* RenderSearchField::fontSelector() const
+{
+ return document()->styleResolver()->fontSelector();
+}
+
+HostWindow* RenderSearchField::hostWindow() const
+{
+ return document()->view()->hostWindow();
+}
+
+PassRefPtr<Scrollbar> RenderSearchField::createScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
+{
+ RefPtr<Scrollbar> widget;
+ bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
+ if (hasCustomScrollbarStyle)
+ widget = RenderScrollbar::createCustomScrollbar(scrollableArea, orientation, this->node());
+ else
+ widget = Scrollbar::createNativeScrollbar(scrollableArea, orientation, controlSize);
+ return widget.release();
+}
+
+LayoutUnit RenderSearchField::computeHeightLimit() const
+{
+ return height();
+}
+
+void RenderSearchField::centerContainerIfNeeded(RenderBox* containerRenderer) const
+{
+ if (!containerRenderer)
+ return;
+
+ if (containerRenderer->height() <= contentHeight())
+ return;
+
+ // A quirk for find-in-page box on Safari Windows.
+ // http://webkit.org/b/63157
+ LayoutUnit heightDiff = containerRenderer->height() - contentHeight();
+ containerRenderer->setY(containerRenderer->y() - (heightDiff / 2 + layoutMod(heightDiff, 2)));
+}
+
+}
diff --git a/Source/WebCore/rendering/RenderSearchField.h b/Source/WebCore/rendering/RenderSearchField.h
new file mode 100644
index 000000000..967335d34
--- /dev/null
+++ b/Source/WebCore/rendering/RenderSearchField.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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 RenderSearchField_h
+#define RenderSearchField_h
+
+#include "PopupMenuClient.h"
+#include "RenderTextControlSingleLine.h"
+
+namespace WebCore {
+
+class HTMLInputElement;
+class SearchPopupMenu;
+
+class RenderSearchField : public RenderTextControlSingleLine, private PopupMenuClient {
+public:
+ RenderSearchField(Node*);
+ virtual ~RenderSearchField();
+
+ void updateCancelButtonVisibility() const;
+
+ void addSearchResult();
+ void stopSearchEventTimer();
+
+ bool popupIsVisible() const { return m_searchPopupIsVisible; }
+ void showPopup();
+ void hidePopup();
+
+private:
+ virtual void centerContainerIfNeeded(RenderBox*) const OVERRIDE;
+ virtual LayoutUnit computeControlHeight(LayoutUnit lineHeight, LayoutUnit nonContentHeight) const OVERRIDE;
+ virtual LayoutUnit computeHeightLimit() const OVERRIDE;
+ virtual void updateFromElement() OVERRIDE;
+ EVisibility visibilityForCancelButton() const;
+ const AtomicString& autosaveName() const;
+
+ // PopupMenuClient methods
+ virtual void valueChanged(unsigned listIndex, bool fireEvents = true) OVERRIDE;
+ virtual void selectionChanged(unsigned, bool) OVERRIDE { }
+ virtual void selectionCleared() OVERRIDE { }
+ virtual String itemText(unsigned listIndex) const OVERRIDE;
+ virtual String itemLabel(unsigned listIndex) const OVERRIDE;
+ virtual String itemIcon(unsigned listIndex) const OVERRIDE;
+ virtual String itemToolTip(unsigned) const OVERRIDE { return String(); }
+ virtual String itemAccessibilityText(unsigned) const OVERRIDE { return String(); }
+ virtual bool itemIsEnabled(unsigned listIndex) const OVERRIDE;
+ virtual PopupMenuStyle itemStyle(unsigned listIndex) const OVERRIDE;
+ virtual PopupMenuStyle menuStyle() const OVERRIDE;
+ virtual int clientInsetLeft() const OVERRIDE;
+ virtual int clientInsetRight() const OVERRIDE;
+ virtual LayoutUnit clientPaddingLeft() const OVERRIDE;
+ virtual LayoutUnit clientPaddingRight() const OVERRIDE;
+ virtual int listSize() const OVERRIDE;
+ virtual int selectedIndex() const OVERRIDE;
+ virtual void popupDidHide() OVERRIDE;
+ virtual bool itemIsSeparator(unsigned listIndex) const OVERRIDE;
+ virtual bool itemIsLabel(unsigned listIndex) const OVERRIDE;
+ virtual bool itemIsSelected(unsigned listIndex) const OVERRIDE;
+ virtual bool shouldPopOver() const OVERRIDE { return false; }
+ virtual bool valueShouldChangeOnHotTrack() const OVERRIDE { return false; }
+ virtual void setTextFromItem(unsigned listIndex) OVERRIDE;
+ virtual FontSelector* fontSelector() const OVERRIDE;
+ virtual HostWindow* hostWindow() const OVERRIDE;
+ virtual PassRefPtr<Scrollbar> createScrollbar(ScrollableArea*, ScrollbarOrientation, ScrollbarControlSize) OVERRIDE;
+
+ HTMLElement* resultsButtonElement() const;
+ HTMLElement* cancelButtonElement() const;
+
+ bool m_searchPopupIsVisible;
+ RefPtr<SearchPopupMenu> m_searchPopup;
+ Vector<String> m_recentSearches;
+};
+
+inline RenderSearchField* toRenderSearchField(RenderObject* object)
+{
+ ASSERT(!object || object->isTextField());
+ return static_cast<RenderSearchField*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderSearchField(const RenderSearchField*);
+
+}
+
+#endif
diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp
index 541ef37b5..479e3d6ee 100644
--- a/Source/WebCore/rendering/RenderTable.cpp
+++ b/Source/WebCore/rendering/RenderTable.cpp
@@ -592,11 +592,10 @@ void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs
size_t count = m_collapsedBorders.size();
for (size_t i = 0; i < count; ++i) {
m_currentBorder = &m_collapsedBorders[i];
- for (RenderObject* child = firstChild(); child; child = child->nextSibling())
- if (child->isTableSection()) {
- LayoutPoint childPoint = flipForWritingModeForChild(toRenderTableSection(child), paintOffset);
- child->paint(info, childPoint);
- }
+ for (RenderTableSection* section = bottomSection(); section; section = sectionAbove(section)) {
+ LayoutPoint childPoint = flipForWritingModeForChild(section, paintOffset);
+ section->paint(info, childPoint);
+ }
}
m_currentBorder = 0;
}
@@ -842,113 +841,116 @@ void RenderTable::recalcSections() const
int RenderTable::calcBorderStart() const
{
- if (collapseBorders()) {
- // Determined by the first cell of the first row. See the CSS 2.1 spec, section 17.6.2.
- if (!numEffCols())
- return 0;
+ if (!collapseBorders())
+ return RenderBlock::borderStart();
+
+ // Determined by the first cell of the first row. See the CSS 2.1 spec, section 17.6.2.
+ if (!numEffCols())
+ return 0;
- unsigned borderWidth = 0;
+ unsigned borderWidth = 0;
- const BorderValue& tb = style()->borderStart();
- if (tb.style() == BHIDDEN)
+ const BorderValue& tableStartBorder = style()->borderStart();
+ if (tableStartBorder.style() == BHIDDEN)
+ return 0;
+ if (tableStartBorder.style() > BHIDDEN)
+ borderWidth = tableStartBorder.width();
+
+ if (RenderTableCol* column = colElement(0)) {
+ // FIXME: We don't account for direction on columns and column groups.
+ const BorderValue& columnAdjoiningBorder = column->style()->borderStart();
+ if (columnAdjoiningBorder.style() == BHIDDEN)
return 0;
- if (tb.style() > BHIDDEN)
- borderWidth = tb.width();
+ if (columnAdjoiningBorder.style() > BHIDDEN)
+ borderWidth = max(borderWidth, columnAdjoiningBorder.width());
+ // FIXME: This logic doesn't properly account for the first column in the first column-group case.
+ }
- if (RenderTableCol* colGroup = colElement(0)) {
- const BorderValue& gb = colGroup->style()->borderStart();
- if (gb.style() == BHIDDEN)
- return 0;
- if (gb.style() > BHIDDEN)
- borderWidth = max(borderWidth, gb.width());
- }
-
- if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
- const BorderValue& sb = topNonEmptySection->style()->borderStart();
- if (sb.style() == BHIDDEN)
- return 0;
+ if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
+ const BorderValue& sectionAdjoiningBorder = topNonEmptySection->borderAdjoiningTableStart();
+ if (sectionAdjoiningBorder.style() == BHIDDEN)
+ return 0;
- if (sb.style() > BHIDDEN)
- borderWidth = max(borderWidth, sb.width());
+ if (sectionAdjoiningBorder.style() > BHIDDEN)
+ borderWidth = max(borderWidth, sectionAdjoiningBorder.width());
- const RenderTableSection::CellStruct& cs = topNonEmptySection->cellAt(0, 0);
-
- if (cs.hasCells()) {
- const BorderValue& cb = cs.primaryCell()->style()->borderStart(); // FIXME: Make this work with perpendicualr and flipped cells.
- if (cb.style() == BHIDDEN)
- return 0;
+ if (const RenderTableCell* adjoiningStartCell = topNonEmptySection->firstRowCellAdjoiningTableStart()) {
+ // FIXME: Make this work with perpendicular and flipped cells.
+ const BorderValue& startCellAdjoiningBorder = adjoiningStartCell->borderAdjoiningTableStart();
+ if (startCellAdjoiningBorder.style() == BHIDDEN)
+ return 0;
- const BorderValue& rb = cs.primaryCell()->parent()->style()->borderStart();
- if (rb.style() == BHIDDEN)
- return 0;
+ const BorderValue& firstRowAdjoiningBorder = adjoiningStartCell->row()->borderAdjoiningTableStart();
+ if (firstRowAdjoiningBorder.style() == BHIDDEN)
+ return 0;
- if (cb.style() > BHIDDEN)
- borderWidth = max(borderWidth, cb.width());
- if (rb.style() > BHIDDEN)
- borderWidth = max(borderWidth, rb.width());
- }
+ if (startCellAdjoiningBorder.style() > BHIDDEN)
+ borderWidth = max(borderWidth, startCellAdjoiningBorder.width());
+ if (firstRowAdjoiningBorder.style() > BHIDDEN)
+ borderWidth = max(borderWidth, firstRowAdjoiningBorder.width());
}
- return (borderWidth + (style()->isLeftToRightDirection() ? 0 : 1)) / 2;
}
- return RenderBlock::borderStart();
+ return (borderWidth + (style()->isLeftToRightDirection() ? 0 : 1)) / 2;
}
int RenderTable::calcBorderEnd() const
{
- if (collapseBorders()) {
- // Determined by the last cell of the first row. See the CSS 2.1 spec, section 17.6.2.
- if (!numEffCols())
- return 0;
+ if (!collapseBorders())
+ return RenderBlock::borderEnd();
- unsigned borderWidth = 0;
+ // Determined by the last cell of the first row. See the CSS 2.1 spec, section 17.6.2.
+ if (!numEffCols())
+ return 0;
- const BorderValue& tb = style()->borderEnd();
- if (tb.style() == BHIDDEN)
- return 0;
- if (tb.style() > BHIDDEN)
- borderWidth = tb.width();
+ unsigned borderWidth = 0;
- unsigned endColumn = numEffCols() - 1;
- if (RenderTableCol* colGroup = colElement(endColumn)) {
- const BorderValue& gb = colGroup->style()->borderEnd();
- if (gb.style() == BHIDDEN)
- return 0;
- if (gb.style() > BHIDDEN)
- borderWidth = max(borderWidth, gb.width());
- }
+ const BorderValue& tableEndBorder = style()->borderEnd();
+ if (tableEndBorder.style() == BHIDDEN)
+ return 0;
+ if (tableEndBorder.style() > BHIDDEN)
+ borderWidth = tableEndBorder.width();
+
+ unsigned endColumn = numEffCols() - 1;
+ if (RenderTableCol* column = colElement(endColumn)) {
+ // FIXME: We don't account for direction on columns and column groups.
+ const BorderValue& columnAdjoiningBorder = column->style()->borderEnd();
+ if (columnAdjoiningBorder.style() == BHIDDEN)
+ return 0;
+ if (columnAdjoiningBorder.style() > BHIDDEN)
+ borderWidth = max(borderWidth, columnAdjoiningBorder.width());
+ // FIXME: This logic doesn't properly account for the last column in the last column-group case.
+ }
- if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
- const BorderValue& sb = topNonEmptySection->style()->borderEnd();
- if (sb.style() == BHIDDEN)
- return 0;
+ if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
+ const BorderValue& sectionAdjoiningBorder = topNonEmptySection->borderAdjoiningTableEnd();
+ if (sectionAdjoiningBorder.style() == BHIDDEN)
+ return 0;
- if (sb.style() > BHIDDEN)
- borderWidth = max(borderWidth, sb.width());
+ if (sectionAdjoiningBorder.style() > BHIDDEN)
+ borderWidth = max(borderWidth, sectionAdjoiningBorder.width());
- const RenderTableSection::CellStruct& cs = topNonEmptySection->cellAt(0, endColumn);
-
- if (cs.hasCells()) {
- const BorderValue& cb = cs.primaryCell()->style()->borderEnd(); // FIXME: Make this work with perpendicular and flipped cells.
- if (cb.style() == BHIDDEN)
- return 0;
+ if (const RenderTableCell* adjoiningEndCell = topNonEmptySection->firstRowCellAdjoiningTableEnd()) {
+ // FIXME: Make this work with perpendicular and flipped cells.
+ const BorderValue& endCellAdjoiningBorder = adjoiningEndCell->borderAdjoiningTableEnd();
+ if (endCellAdjoiningBorder.style() == BHIDDEN)
+ return 0;
- const BorderValue& rb = cs.primaryCell()->parent()->style()->borderEnd();
- if (rb.style() == BHIDDEN)
- return 0;
+ const BorderValue& firstRowAdjoiningBorder = adjoiningEndCell->row()->borderAdjoiningTableEnd();
+ if (firstRowAdjoiningBorder.style() == BHIDDEN)
+ return 0;
- if (cb.style() > BHIDDEN)
- borderWidth = max(borderWidth, cb.width());
- if (rb.style() > BHIDDEN)
- borderWidth = max(borderWidth, rb.width());
- }
+ if (endCellAdjoiningBorder.style() > BHIDDEN)
+ borderWidth = max(borderWidth, endCellAdjoiningBorder.width());
+ if (firstRowAdjoiningBorder.style() > BHIDDEN)
+ borderWidth = max(borderWidth, firstRowAdjoiningBorder.width());
}
- return (borderWidth + (style()->isLeftToRightDirection() ? 1 : 0)) / 2;
}
- return RenderBlock::borderEnd();
+ return (borderWidth + (style()->isLeftToRightDirection() ? 1 : 0)) / 2;
}
void RenderTable::recalcBordersInRowDirection()
{
+ // FIXME: We need to compute the collapsed before / after borders in the same fashion.
m_borderStart = calcBorderStart();
m_borderEnd = calcBorderEnd();
}
@@ -1109,6 +1111,21 @@ RenderTableSection* RenderTable::sectionBelow(const RenderTableSection* section,
return toRenderTableSection(nextSection);
}
+RenderTableSection* RenderTable::bottomSection() const
+{
+ recalcSectionsIfNeeded();
+
+ if (m_foot)
+ return m_foot;
+
+ for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
+ if (child->isTableSection())
+ return toRenderTableSection(child);
+ }
+
+ return 0;
+}
+
RenderTableCell* RenderTable::cellAbove(const RenderTableCell* cell) const
{
recalcSectionsIfNeeded();
@@ -1294,4 +1311,22 @@ RenderTable* RenderTable::createAnonymousWithParentRenderer(const RenderObject*
return newTable;
}
+const BorderValue& RenderTable::tableStartBorderAdjoiningCell(const RenderTableCell* cell) const
+{
+ ASSERT(cell->isFirstOrLastCellInRow());
+ if (cell->section()->hasSameDirectionAsTable())
+ return style()->borderStart();
+
+ return style()->borderEnd();
+}
+
+const BorderValue& RenderTable::tableEndBorderAdjoiningCell(const RenderTableCell* cell) const
+{
+ ASSERT(cell->isFirstOrLastCellInRow());
+ if (cell->section()->hasSameDirectionAsTable())
+ return style()->borderEnd();
+
+ return style()->borderStart();
+}
+
}
diff --git a/Source/WebCore/rendering/RenderTable.h b/Source/WebCore/rendering/RenderTable.h
index 7d3049b7a..c3eb0729b 100644
--- a/Source/WebCore/rendering/RenderTable.h
+++ b/Source/WebCore/rendering/RenderTable.h
@@ -143,10 +143,13 @@ public:
// This function returns 0 if the table has no section.
RenderTableSection* topSection() const;
+ RenderTableSection* bottomSection() const;
// This function returns 0 if the table has no non-empty sections.
RenderTableSection* topNonEmptySection() const;
+ unsigned lastColumnIndex() const { return numEffCols() - 1; }
+
void splitColumn(unsigned position, unsigned firstSpan);
void appendColumn(unsigned span);
unsigned numEffCols() const { return m_columns.size(); }
@@ -219,6 +222,9 @@ public:
return createAnonymousWithParentRenderer(parent);
}
+ const BorderValue& tableStartBorderAdjoiningCell(const RenderTableCell*) const;
+ const BorderValue& tableEndBorderAdjoiningCell(const RenderTableCell*) const;
+
protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
diff --git a/Source/WebCore/rendering/RenderTableCell.cpp b/Source/WebCore/rendering/RenderTableCell.cpp
index 950acb4b1..159b54b3b 100644
--- a/Source/WebCore/rendering/RenderTableCell.cpp
+++ b/Source/WebCore/rendering/RenderTableCell.cpp
@@ -193,7 +193,7 @@ void RenderTableCell::layout()
LayoutUnit RenderTableCell::paddingTop() const
{
- LayoutUnit result = computedCSSPaddingTop();
+ int result = computedCSSPaddingTop();
if (!isHorizontalWritingMode())
return result;
return result + (style()->writingMode() == TopToBottomWritingMode ? intrinsicPaddingBefore() : intrinsicPaddingAfter());
@@ -201,7 +201,7 @@ LayoutUnit RenderTableCell::paddingTop() const
LayoutUnit RenderTableCell::paddingBottom() const
{
- LayoutUnit result = computedCSSPaddingBottom();
+ int result = computedCSSPaddingBottom();
if (!isHorizontalWritingMode())
return result;
return result + (style()->writingMode() == TopToBottomWritingMode ? intrinsicPaddingAfter() : intrinsicPaddingBefore());
@@ -209,16 +209,15 @@ LayoutUnit RenderTableCell::paddingBottom() const
LayoutUnit RenderTableCell::paddingLeft() const
{
- LayoutUnit result = computedCSSPaddingLeft();
+ int result = computedCSSPaddingLeft();
if (isHorizontalWritingMode())
return result;
return result + (style()->writingMode() == LeftToRightWritingMode ? intrinsicPaddingBefore() : intrinsicPaddingAfter());
-
}
LayoutUnit RenderTableCell::paddingRight() const
{
- LayoutUnit result = computedCSSPaddingRight();
+ int result = computedCSSPaddingRight();
if (isHorizontalWritingMode())
return result;
return result + (style()->writingMode() == LeftToRightWritingMode ? intrinsicPaddingAfter() : intrinsicPaddingBefore());
@@ -226,18 +225,18 @@ LayoutUnit RenderTableCell::paddingRight() const
LayoutUnit RenderTableCell::paddingBefore() const
{
- return computedCSSPaddingBefore() + intrinsicPaddingBefore();
+ return static_cast<int>(computedCSSPaddingBefore()) + intrinsicPaddingBefore();
}
LayoutUnit RenderTableCell::paddingAfter() const
{
- return computedCSSPaddingAfter() + intrinsicPaddingAfter();
+ return static_cast<int>(computedCSSPaddingAfter()) + intrinsicPaddingAfter();
}
-void RenderTableCell::setOverrideHeightFromRowHeight(LayoutUnit rowHeight)
+void RenderTableCell::setOverrideLogicalContentHeightFromRowHeight(LayoutUnit rowHeight)
{
clearIntrinsicPadding();
- RenderBlock::setOverrideHeight(max<LayoutUnit>(0, rowHeight - borderBefore() - paddingBefore() - borderAfter() - paddingAfter()));
+ setOverrideLogicalContentHeight(max<LayoutUnit>(0, rowHeight - borderAndPaddingLogicalHeight()));
}
LayoutSize RenderTableCell::offsetFromContainer(RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
@@ -468,7 +467,7 @@ CollapsedBorderValue RenderTableCell::computeCollapsedStartBorder(IncludeBorderC
}
} else {
// (7) The table's start border.
- result = chooseBorder(result, CollapsedBorderValue(table->style()->borderStart(), includeColor ? table->style()->visitedDependentColor(startColorProperty) : Color(), BTABLE));
+ result = chooseBorder(result, CollapsedBorderValue(table->tableStartBorderAdjoiningCell(this), includeColor ? table->style()->visitedDependentColor(startColorProperty) : Color(), BTABLE));
if (!result.exists())
return result;
}
@@ -542,7 +541,7 @@ CollapsedBorderValue RenderTableCell::computeCollapsedEndBorder(IncludeBorderCol
}
} else {
// (7) The table's end border.
- result = chooseBorder(result, CollapsedBorderValue(table->style()->borderEnd(), includeColor ? table->style()->visitedDependentColor(endColorProperty) : Color(), BTABLE));
+ result = chooseBorder(result, CollapsedBorderValue(table->tableEndBorderAdjoiningCell(this), includeColor ? table->style()->visitedDependentColor(endColorProperty) : Color(), BTABLE));
if (!result.exists())
return result;
}
diff --git a/Source/WebCore/rendering/RenderTableCell.h b/Source/WebCore/rendering/RenderTableCell.h
index d1b0a28a3..4381555cd 100644
--- a/Source/WebCore/rendering/RenderTableCell.h
+++ b/Source/WebCore/rendering/RenderTableCell.h
@@ -122,7 +122,7 @@ public:
virtual LayoutUnit paddingBefore() const OVERRIDE;
virtual LayoutUnit paddingAfter() const OVERRIDE;
- void setOverrideHeightFromRowHeight(LayoutUnit);
+ void setOverrideLogicalContentHeightFromRowHeight(LayoutUnit);
virtual void scrollbarsChanged(bool horizontalScrollbarChanged, bool verticalScrollbarChanged);
@@ -142,9 +142,33 @@ public:
// on all table parts and writing-mode on cells.
const RenderStyle* styleForCellFlow() const
{
- return table()->style();
+ return section()->style();
}
+ const BorderValue& borderAdjoiningTableStart() const
+ {
+ ASSERT(isFirstOrLastCellInRow());
+ if (section()->hasSameDirectionAsTable())
+ return style()->borderStart();
+
+ return style()->borderEnd();
+ }
+
+ const BorderValue& borderAdjoiningTableEnd() const
+ {
+ ASSERT(isFirstOrLastCellInRow());
+ if (section()->hasSameDirectionAsTable())
+ return style()->borderEnd();
+
+ return style()->borderStart();
+ }
+
+#ifndef NDEBUG
+ bool isFirstOrLastCellInRow() const
+ {
+ return !table()->cellAfter(this) || !table()->cellBefore(this);
+ }
+#endif
protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
diff --git a/Source/WebCore/rendering/RenderTableRow.h b/Source/WebCore/rendering/RenderTableRow.h
index 04696607d..c01cd45ed 100644
--- a/Source/WebCore/rendering/RenderTableRow.h
+++ b/Source/WebCore/rendering/RenderTableRow.h
@@ -66,6 +66,22 @@ public:
return m_rowIndex;
}
+ const BorderValue& borderAdjoiningTableStart() const
+ {
+ if (section()->hasSameDirectionAsTable())
+ return style()->borderStart();
+
+ return style()->borderEnd();
+ }
+
+ const BorderValue& borderAdjoiningTableEnd() const
+ {
+ if (section()->hasSameDirectionAsTable())
+ return style()->borderEnd();
+
+ return style()->borderStart();
+ }
+
private:
virtual RenderObjectChildList* virtualChildren() { return children(); }
virtual const RenderObjectChildList* virtualChildren() const { return children(); }
diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp
index 173085c25..d78a3d6f4 100644
--- a/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/Source/WebCore/rendering/RenderTableSection.cpp
@@ -333,7 +333,7 @@ int RenderTableSection::calcRowLogicalHeight()
LayoutUnit baselineDescent = 0;
// Our base size is the biggest logical height from our cells' styles (excluding row spanning cells).
- m_rowPos[r + 1] = max(m_rowPos[r] + minimumIntValueForLength(m_grid[r].logicalHeight, 0, viewRenderer), 0);
+ m_rowPos[r + 1] = max(m_rowPos[r] + minimumValueForLength(m_grid[r].logicalHeight, 0, viewRenderer).round(), 0);
Row& row = m_grid[r].row;
unsigned totalCols = row.size();
@@ -373,7 +373,7 @@ int RenderTableSection::calcRowLogicalHeight()
if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP || va == SUPER || va == SUB || va == LENGTH) {
LayoutUnit baselinePosition = cell->cellBaselinePosition();
if (baselinePosition > cell->borderBefore() + cell->paddingBefore()) {
- m_grid[r].baseline = max(m_grid[r].baseline, baselinePosition - cell->intrinsicPaddingBefore());
+ m_grid[cellStartRow].baseline = max(m_grid[cellStartRow].baseline, baselinePosition - cell->intrinsicPaddingBefore());
baselineDescent = max(baselineDescent, m_rowPos[cellStartRow] + cellLogicalHeight - (baselinePosition - cell->intrinsicPaddingBefore()));
}
}
@@ -406,6 +406,10 @@ void RenderTableSection::layout()
ASSERT(!needsCellRecalc());
ASSERT(!table()->needsSectionRecalc());
+ // addChild may over-grow m_grid but we don't want to throw away the memory too early as addChild
+ // can be called in a loop (e.g during parsing). Doing it now ensures we have a stable-enough structure.
+ m_grid.shrinkToFit();
+
LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
for (RenderObject* child = children()->firstChild(); child; child = child->nextSibling()) {
if (child->isTableRow()) {
@@ -529,7 +533,6 @@ void RenderTableSection::layoutRows()
m_overflowingCells.clear();
m_forceSlowPaintPathWithOverflowingCell = false;
- int hspacing = table()->hBorderSpacing();
int vspacing = table()->vBorderSpacing();
unsigned nEffCols = table()->numEffCols();
@@ -606,7 +609,7 @@ void RenderTableSection::layoutRows()
// Alignment within a cell is based off the calculated
// height, which becomes irrelevant once the cell has
// been resized based off its percentage.
- cell->setOverrideHeightFromRowHeight(rHeight);
+ cell->setOverrideLogicalContentHeightFromRowHeight(rHeight);
cell->layoutIfNeeded();
// If the baseline moved, we may have to update the data for our row. Find out the new baseline.
@@ -630,9 +633,9 @@ void RenderTableSection::layoutRows()
case TEXT_BOTTOM:
case LENGTH:
case BASELINE: {
- LayoutUnit b = cell->cellBaselinePosition();
- if (b > cell->borderBefore() + cell->paddingBefore())
- intrinsicPaddingBefore = getBaseline(r) - (b - oldIntrinsicPaddingBefore);
+ LayoutUnit baseline = cell->cellBaselinePosition();
+ if (baseline > cell->borderBefore() + cell->paddingBefore())
+ intrinsicPaddingBefore = getBaseline(cell->rowIndex()) - (baseline - oldIntrinsicPaddingBefore);
break;
}
case TOP:
@@ -653,14 +656,7 @@ void RenderTableSection::layoutRows()
LayoutRect oldCellRect(cell->x(), cell->y() , cell->width(), cell->height());
- LayoutPoint cellLocation(0, m_rowPos[rindx]);
- // FIXME: Switch to cell's styleForCellFlow() for consistency with RenderTableCell, once it supports row group.
- if (!style()->isLeftToRightDirection())
- cellLocation.setX(table()->columnPositions()[nEffCols] - table()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + hspacing);
- else
- cellLocation.setX(table()->columnPositions()[c] + hspacing);
- cell->setLogicalLocation(cellLocation);
- view()->addLayoutDelta(oldCellRect.location() - cell->location());
+ setLogicalPositionForCell(cell, c);
if (intrinsicPaddingBefore != oldIntrinsicPaddingBefore || intrinsicPaddingAfter != oldIntrinsicPaddingAfter)
cell->setNeedsLayout(true, MarkOnlyThis);
@@ -1034,77 +1030,120 @@ void RenderTableSection::paintCell(RenderTableCell* cell, PaintInfo& paintInfo,
cell->paint(paintInfo, cellPoint);
}
+LayoutRect RenderTableSection::logicalRectForWritingModeAndDirection(const LayoutRect& rect) const
+{
+ LayoutRect tableAlignedRect(rect);
+
+ flipForWritingMode(tableAlignedRect);
+
+ if (!style()->isHorizontalWritingMode())
+ tableAlignedRect = tableAlignedRect.transposedRect();
+
+ const Vector<int>& columnPos = table()->columnPositions();
+ if (!style()->isLeftToRightDirection())
+ tableAlignedRect.setX(columnPos[columnPos.size() - 1] - tableAlignedRect.maxX());
+
+ return tableAlignedRect;
+}
+
CellSpan RenderTableSection::dirtiedRows(const LayoutRect& damageRect) const
{
if (m_forceSlowPaintPathWithOverflowingCell)
return fullTableRowSpan();
- LayoutUnit before = style()->isHorizontalWritingMode() ? damageRect.y() : damageRect.x();
+ CellSpan coveredRows = spannedRows(damageRect);
- // binary search to find a row
- unsigned startRow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), before) - m_rowPos.begin();
+ // To repaint the border we might need to repaint first or last row even if they are not spanned themselves.
+ if (coveredRows.start() >= m_rowPos.size() - 1 && m_rowPos[m_rowPos.size() - 1] + table()->outerBorderAfter() >= damageRect.y())
+ --coveredRows.start();
- // The binary search above gives us the first row with
- // a y position >= the top of the paint rect. Thus, the previous
- // may need to be repainted as well.
- if (startRow == m_rowPos.size() || (startRow > 0 && (m_rowPos[startRow] > before)))
- --startRow;
+ if (!coveredRows.end() && m_rowPos[0] - table()->outerBorderBefore() <= damageRect.maxY())
+ ++coveredRows.end();
- LayoutUnit after = (style()->isHorizontalWritingMode() ? damageRect.maxY() : damageRect.maxX());
- unsigned endRow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), after) - m_rowPos.begin();
- if (endRow == m_rowPos.size())
- --endRow;
-
- if (!endRow && m_rowPos[0] - table()->outerBorderBefore() <= after)
- ++endRow;
-
- return CellSpan(startRow, endRow);
+ return coveredRows;
}
-
CellSpan RenderTableSection::dirtiedColumns(const LayoutRect& damageRect) const
{
if (m_forceSlowPaintPathWithOverflowingCell)
return fullTableColumnSpan();
- // FIXME: Implement RTL.
- if (!style()->isLeftToRightDirection())
- return fullTableColumnSpan();
+ CellSpan coveredColumns = spannedColumns(damageRect);
- LayoutUnit start = style()->isHorizontalWritingMode() ? damageRect.x() : damageRect.y();
Vector<int>& columnPos = table()->columnPositions();
- unsigned startCol = std::lower_bound(columnPos.begin(), columnPos.end(), start) - columnPos.begin();
- if ((startCol == columnPos.size()) || (startCol > 0 && (columnPos[startCol] > start)))
- --startCol;
+ // To repaint the border we might need to repaint first or last column even if they are not spanned themselves.
+ if (coveredColumns.start() >= columnPos.size() - 1 && columnPos[columnPos.size() - 1] + table()->outerBorderEnd() >= damageRect.x())
+ --coveredColumns.start();
+
+ if (!coveredColumns.end() && columnPos[0] - table()->outerBorderStart() <= damageRect.maxX())
+ ++coveredColumns.end();
+
+ return coveredColumns;
+}
- LayoutUnit end = (style()->isHorizontalWritingMode() ? damageRect.maxX() : damageRect.maxY());
- unsigned endCol = std::lower_bound(columnPos.begin(), columnPos.end(), end) - columnPos.begin();
- if (endCol == columnPos.size())
- --endCol;
+CellSpan RenderTableSection::spannedRows(const LayoutRect& flippedRect) const
+{
+ // Find the first row that starts after rect top.
+ // FIXME: Upper_bound might not be the correct algorithm here since it might skip empty rows, but it is
+ // consistent with behavior in the former point based hit-testing (but inconsistent with spannedColumns).
+ unsigned nextRow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), flippedRect.y()) - m_rowPos.begin();
+
+ if (nextRow == m_rowPos.size())
+ return CellSpan(m_rowPos.size() - 1, m_rowPos.size() - 1); // After all rows.
+
+ unsigned startRow = nextRow > 0 ? nextRow - 1 : 0;
+
+ // Find the first row that starts after rect bottom.
+ unsigned endRow;
+ if (m_rowPos[nextRow] >= flippedRect.maxY())
+ endRow = nextRow;
+ else {
+ endRow = std::upper_bound(m_rowPos.begin() + nextRow, m_rowPos.end(), flippedRect.maxY()) - m_rowPos.begin();
+ if (endRow == m_rowPos.size())
+ endRow = m_rowPos.size() - 1;
+ }
- if (!endCol && columnPos[0] - table()->outerBorderStart() <= end)
- ++endCol;
+ return CellSpan(startRow, endRow);
+}
+
+CellSpan RenderTableSection::spannedColumns(const LayoutRect& flippedRect) const
+{
+ const Vector<int>& columnPos = table()->columnPositions();
+
+ // Find the first columnt that starts after rect left.
+ unsigned nextColumn = std::lower_bound(columnPos.begin(), columnPos.end(), flippedRect.x()) - columnPos.begin();
+
+ if (nextColumn == columnPos.size())
+ return CellSpan(columnPos.size() - 1, columnPos.size() - 1); // After all columns.
+
+ unsigned startColumn = nextColumn > 0 ? nextColumn - 1 : 0;
+
+ // Find the first row that starts after rect right.
+ unsigned endColumn;
+ if (columnPos[nextColumn] >= flippedRect.maxX())
+ endColumn = nextColumn;
+ else {
+ endColumn = std::lower_bound(columnPos.begin() + nextColumn, columnPos.end(), flippedRect.maxX()) - columnPos.begin();
+ if (endColumn == columnPos.size())
+ endColumn = columnPos.size() - 1;
+ }
- return CellSpan(startCol, endCol);
+ return CellSpan(startColumn, endColumn);
}
+
void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
PaintPhase paintPhase = paintInfo.phase;
LayoutRect localRepaintRect = paintInfo.rect;
localRepaintRect.moveBy(-paintOffset);
- if (style()->isFlippedBlocksWritingMode()) {
- if (style()->isHorizontalWritingMode())
- localRepaintRect.setY(height() - localRepaintRect.maxY());
- else
- localRepaintRect.setX(width() - localRepaintRect.maxX());
- }
-
localRepaintRect.inflate(maximalOutlineSize(paintPhase));
- CellSpan dirtiedRows = this->dirtiedRows(localRepaintRect);
- CellSpan dirtiedColumns = this->dirtiedColumns(localRepaintRect);
+ LayoutRect tableAlignedRect = logicalRectForWritingModeAndDirection(localRepaintRect);
+
+ CellSpan dirtiedRows = this->dirtiedRows(tableAlignedRect);
+ CellSpan dirtiedColumns = this->dirtiedColumns(tableAlignedRect);
if (dirtiedColumns.start() < dirtiedColumns.end()) {
if (!m_hasMultipleCellLevels && !m_overflowingCells.size()) {
@@ -1276,6 +1315,18 @@ unsigned RenderTableSection::numColumns() const
return result + 1;
}
+const RenderTableCell* RenderTableSection::firstRowCellAdjoiningTableStart() const
+{
+ unsigned adjoiningStartCellColumnIndex = hasSameDirectionAsTable() ? 0 : table()->lastColumnIndex();
+ return cellAt(0, adjoiningStartCellColumnIndex).primaryCell();
+}
+
+const RenderTableCell* RenderTableSection::firstRowCellAdjoiningTableEnd() const
+{
+ unsigned adjoiningEndCellColumnIndex = hasSameDirectionAsTable() ? table()->lastColumnIndex() : 0;
+ return cellAt(0, adjoiningEndCellColumnIndex).primaryCell();
+}
+
void RenderTableSection::appendColumn(unsigned pos)
{
ASSERT(!m_needsCellRecalc);
@@ -1340,52 +1391,41 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
return false;
}
- LayoutPoint location = pointInContainer - toLayoutSize(adjustedLocation);
- if (style()->isFlippedBlocksWritingMode()) {
- if (style()->isHorizontalWritingMode())
- location.setY(height() - location.y());
- else
- location.setX(width() - location.x());
- }
-
- LayoutUnit offsetInColumnDirection = style()->isHorizontalWritingMode() ? location.y() : location.x();
-
recalcCellsIfNeeded();
- // Find the first row that starts after offsetInColumnDirection.
- unsigned nextRow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), offsetInColumnDirection) - m_rowPos.begin();
- if (nextRow == m_rowPos.size())
- return false;
- // Now set hitRow to the index of the hit row, or 0.
- unsigned hitRow = nextRow > 0 ? nextRow - 1 : 0;
-
- Vector<int>& columnPos = table()->columnPositions();
- LayoutUnit offsetInRowDirection = style()->isHorizontalWritingMode() ? location.x() : location.y();
- if (!style()->isLeftToRightDirection())
- offsetInRowDirection = columnPos[columnPos.size() - 1] - offsetInRowDirection;
+ LayoutRect hitTestRect = result.rectForPoint(pointInContainer);
+ hitTestRect.moveBy(-adjustedLocation);
- unsigned nextColumn = std::lower_bound(columnPos.begin(), columnPos.end(), offsetInRowDirection) - columnPos.begin();
- if (nextColumn == columnPos.size())
- return false;
- unsigned hitColumn = nextColumn > 0 ? nextColumn - 1 : 0;
+ LayoutRect tableAlignedRect = logicalRectForWritingModeAndDirection(hitTestRect);
+ CellSpan rowSpan = spannedRows(tableAlignedRect);
+ CellSpan columnSpan = spannedColumns(tableAlignedRect);
- CellStruct& current = cellAt(hitRow, hitColumn);
+ // Now iterate over the spanned rows and columns.
+ for (unsigned hitRow = rowSpan.start(); hitRow < rowSpan.end(); ++hitRow) {
+ for (unsigned hitColumn = columnSpan.start(); hitColumn < columnSpan.end(); ++hitColumn) {
+ CellStruct& current = cellAt(hitRow, hitColumn);
- // If the cell is empty, there's nothing to do
- if (!current.hasCells())
- return false;
+ // If the cell is empty, there's nothing to do
+ if (!current.hasCells())
+ continue;
- for (unsigned i = current.cells.size() ; i; ) {
- --i;
- RenderTableCell* cell = current.cells[i];
- LayoutPoint cellPoint = flipForWritingModeForChild(cell, adjustedLocation);
- if (static_cast<RenderObject*>(cell)->nodeAtPoint(request, result, pointInContainer, cellPoint, action)) {
- updateHitTestResult(result, toLayoutPoint(pointInContainer - cellPoint));
- return true;
+ for (unsigned i = current.cells.size() ; i; ) {
+ --i;
+ RenderTableCell* cell = current.cells[i];
+ LayoutPoint cellPoint = flipForWritingModeForChild(cell, adjustedLocation);
+ if (static_cast<RenderObject*>(cell)->nodeAtPoint(request, result, pointInContainer, cellPoint, action)) {
+ updateHitTestResult(result, toLayoutPoint(pointInContainer - cellPoint));
+ return true;
+ }
+ }
+ if (!result.isRectBasedTest())
+ break;
}
+ if (!result.isRectBasedTest())
+ break;
}
- return false;
+ return false;
}
void RenderTableSection::removeCachedCollapsedBorders(const RenderTableCell* cell)
@@ -1419,4 +1459,20 @@ RenderTableSection* RenderTableSection::createAnonymousWithParentRenderer(const
return newSection;
}
+void RenderTableSection::setLogicalPositionForCell(RenderTableCell* cell, unsigned effectiveColumn) const
+{
+ LayoutPoint oldCellLocation(cell->x(), cell->y());
+
+ LayoutPoint cellLocation(0, m_rowPos[cell->rowIndex()]);
+ int horizontalBorderSpacing = table()->hBorderSpacing();
+
+ if (!cell->styleForCellFlow()->isLeftToRightDirection())
+ cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - table()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + horizontalBorderSpacing);
+ else
+ cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizontalBorderSpacing);
+
+ cell->setLogicalLocation(cellLocation);
+ view()->addLayoutDelta(oldCellLocation - cell->location());
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderTableSection.h b/Source/WebCore/rendering/RenderTableSection.h
index dcdc13490..289415306 100644
--- a/Source/WebCore/rendering/RenderTableSection.h
+++ b/Source/WebCore/rendering/RenderTableSection.h
@@ -49,6 +49,9 @@ public:
unsigned start() const { return m_start; }
unsigned end() const { return m_end; }
+ unsigned& start() { return m_start; }
+ unsigned& end() { return m_end; }
+
private:
unsigned m_start;
unsigned m_end;
@@ -114,6 +117,30 @@ public:
Length logicalHeight;
};
+ bool hasSameDirectionAsTable() const
+ {
+ return table()->style()->direction() == style()->direction();
+ }
+
+ const BorderValue& borderAdjoiningTableStart() const
+ {
+ if (hasSameDirectionAsTable())
+ return style()->borderStart();
+
+ return style()->borderEnd();
+ }
+
+ const BorderValue& borderAdjoiningTableEnd() const
+ {
+ if (hasSameDirectionAsTable())
+ return style()->borderEnd();
+
+ return style()->borderStart();
+ }
+
+ const RenderTableCell* firstRowCellAdjoiningTableStart() const;
+ const RenderTableCell* firstRowCellAdjoiningTableEnd() const;
+
CellStruct& cellAt(unsigned row, unsigned col) { return m_grid[row].row[col]; }
const CellStruct& cellAt(unsigned row, unsigned col) const { return m_grid[row].row[col]; }
RenderTableCell* primaryCellAt(unsigned row, unsigned col)
@@ -165,6 +192,8 @@ public:
{
return createAnonymousWithParentRenderer(parent);
}
+
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
@@ -183,7 +212,6 @@ private:
virtual void removeChild(RenderObject* oldChild);
- virtual void paint(PaintInfo&, const LayoutPoint&);
virtual void paintCell(RenderTableCell*, PaintInfo&, const LayoutPoint&);
virtual void paintObject(PaintInfo&, const LayoutPoint&);
@@ -202,9 +230,19 @@ private:
CellSpan fullTableRowSpan() const { return CellSpan(0, m_grid.size()); }
CellSpan fullTableColumnSpan() const { return CellSpan(0, table()->columns().size()); }
+ // Flip the rect so it aligns with the coordinates used by the rowPos and columnPos vectors.
+ LayoutRect logicalRectForWritingModeAndDirection(const LayoutRect&) const;
+
CellSpan dirtiedRows(const LayoutRect& repaintRect) const;
CellSpan dirtiedColumns(const LayoutRect& repaintRect) const;
+ // These two functions take a rectangle as input that has been flipped by logicalRectForWritingModeAndDirection.
+ // The returned span of rows or columns is end-exclusive, and empty if start==end.
+ CellSpan spannedRows(const LayoutRect& flippedRect) const;
+ CellSpan spannedColumns(const LayoutRect& flippedRect) const;
+
+ void setLogicalPositionForCell(RenderTableCell*, unsigned effectiveColumn) const;
+
RenderObjectChildList m_children;
Vector<RowStruct> m_grid;
diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp
index 16c1ea172..7ea7d7b43 100644
--- a/Source/WebCore/rendering/RenderText.cpp
+++ b/Source/WebCore/rendering/RenderText.cpp
@@ -53,7 +53,7 @@ using namespace Unicode;
namespace WebCore {
-class SameSizeAsRenderText : public RenderObject {
+struct SameSizeAsRenderText : public RenderObject {
uint32_t bitfields : 16;
float widths[4];
String text;
@@ -687,10 +687,6 @@ LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, Lay
bool rightAligned = false;
switch (cbStyle->textAlign()) {
- case TAAUTO:
- case JUSTIFY:
- rightAligned = !cbStyle->isLeftToRightDirection();
- break;
case RIGHT:
case WEBKIT_RIGHT:
rightAligned = true;
@@ -700,6 +696,7 @@ LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, Lay
case CENTER:
case WEBKIT_CENTER:
break;
+ case JUSTIFY:
case TASTART:
rightAligned = !cbStyle->isLeftToRightDirection();
break;
diff --git a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
index 848fc2119..31f1f2837 100644
--- a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -30,7 +30,6 @@
#include "Frame.h"
#include "FrameSelection.h"
#include "FrameView.h"
-#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "LocalizedStrings.h"
@@ -39,7 +38,6 @@
#include "RenderLayer.h"
#include "RenderScrollbar.h"
#include "RenderTheme.h"
-#include "SearchPopupMenu.h"
#include "Settings.h"
#include "SimpleFontData.h"
#include "StyleResolver.h"
@@ -70,10 +68,8 @@ VisiblePosition RenderTextControlInnerBlock::positionForPoint(const LayoutPoint&
RenderTextControlSingleLine::RenderTextControlSingleLine(Node* node)
: RenderTextControl(node)
- , m_searchPopupIsVisible(false)
, m_shouldDrawCapsLockIndicator(false)
, m_desiredInnerTextHeight(-1)
- , m_searchPopup(0)
{
ASSERT(node->isHTMLElement());
ASSERT(node->toInputElement());
@@ -81,20 +77,6 @@ RenderTextControlSingleLine::RenderTextControlSingleLine(Node* node)
RenderTextControlSingleLine::~RenderTextControlSingleLine()
{
- if (m_searchPopup) {
- m_searchPopup->popupMenu()->disconnectClient();
- m_searchPopup = 0;
- }
-}
-
-inline HTMLElement* RenderTextControlSingleLine::containerElement() const
-{
- return inputElement()->containerElement();
-}
-
-inline HTMLElement* RenderTextControlSingleLine::innerBlockElement() const
-{
- return inputElement()->innerBlockElement();
}
inline HTMLElement* RenderTextControlSingleLine::innerSpinButtonElement() const
@@ -102,88 +84,12 @@ inline HTMLElement* RenderTextControlSingleLine::innerSpinButtonElement() const
return inputElement()->innerSpinButtonElement();
}
-inline HTMLElement* RenderTextControlSingleLine::resultsButtonElement() const
-{
- return inputElement()->resultsButtonElement();
-}
-
-inline HTMLElement* RenderTextControlSingleLine::cancelButtonElement() const
-{
- return inputElement()->cancelButtonElement();
-}
-
RenderStyle* RenderTextControlSingleLine::textBaseStyle() const
{
HTMLElement* innerBlock = innerBlockElement();
return innerBlock ? innerBlock->renderer()->style() : style();
}
-void RenderTextControlSingleLine::addSearchResult()
-{
- HTMLInputElement* input = inputElement();
- if (input->maxResults() <= 0)
- return;
-
- String value = input->value();
- if (value.isEmpty())
- return;
-
- Settings* settings = document()->settings();
- if (!settings || settings->privateBrowsingEnabled())
- return;
-
- int size = static_cast<int>(m_recentSearches.size());
- for (int i = size - 1; i >= 0; --i) {
- if (m_recentSearches[i] == value)
- m_recentSearches.remove(i);
- }
-
- m_recentSearches.insert(0, value);
- while (static_cast<int>(m_recentSearches.size()) > input->maxResults())
- m_recentSearches.removeLast();
-
- const AtomicString& name = autosaveName();
- if (!m_searchPopup)
- m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
-
- m_searchPopup->saveRecentSearches(name, m_recentSearches);
-}
-
-void RenderTextControlSingleLine::showPopup()
-{
- if (m_searchPopupIsVisible)
- return;
-
- if (!m_searchPopup)
- m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
-
- if (!m_searchPopup->enabled())
- return;
-
- m_searchPopupIsVisible = true;
-
- const AtomicString& name = autosaveName();
- m_searchPopup->loadRecentSearches(name, m_recentSearches);
-
- // Trim the recent searches list if the maximum size has changed since we last saved.
- HTMLInputElement* input = inputElement();
- if (static_cast<int>(m_recentSearches.size()) > input->maxResults()) {
- do {
- m_recentSearches.removeLast();
- } while (static_cast<int>(m_recentSearches.size()) > input->maxResults());
-
- m_searchPopup->saveRecentSearches(name, m_recentSearches);
- }
-
- m_searchPopup->popupMenu()->show(pixelSnappedIntRect(absoluteBoundingBoxRect()), document()->view(), -1);
-}
-
-void RenderTextControlSingleLine::hidePopup()
-{
- if (m_searchPopup)
- m_searchPopup->popupMenu()->hide();
-}
-
void RenderTextControlSingleLine::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
RenderTextControl::paint(paintInfo, paintOffset);
@@ -200,6 +106,11 @@ void RenderTextControlSingleLine::paint(PaintInfo& paintInfo, const LayoutPoint&
}
}
+LayoutUnit RenderTextControlSingleLine::computeHeightLimit() const
+{
+ return containerElement() ? contentHeight() : height();
+}
+
void RenderTextControlSingleLine::layout()
{
// FIXME: We should remove the height-related hacks in layout() and
@@ -225,7 +136,7 @@ void RenderTextControlSingleLine::layout()
LayoutUnit desiredHeight = textBlockHeight();
LayoutUnit currentHeight = innerTextRenderer->height();
- LayoutUnit heightLimit = (inputElement()->isSearchField() || !container) ? height() : contentHeight();
+ LayoutUnit heightLimit = computeHeightLimit();
if (currentHeight > heightLimit) {
if (desiredHeight != currentHeight)
setNeedsLayout(true, MarkOnlyThis);
@@ -258,12 +169,8 @@ void RenderTextControlSingleLine::layout()
if (!container && currentHeight != contentHeight()) {
LayoutUnit heightDiff = currentHeight - contentHeight();
innerTextRenderer->setY(innerTextRenderer->y() - (heightDiff / 2 + layoutMod(heightDiff, 2)));
- } else if (inputElement()->isSearchField() && containerRenderer && containerRenderer->height() > contentHeight()) {
- // A quirk for find-in-page box on Safari Windows.
- // http://webkit.org/b/63157
- LayoutUnit heightDiff = containerRenderer->height() - contentHeight();
- containerRenderer->setY(containerRenderer->y() - (heightDiff / 2 + layoutMod(heightDiff, 2)));
- }
+ } else
+ centerContainerIfNeeded(containerRenderer);
// Ignores the paddings for the inner spin button.
if (RenderBox* innerSpinBox = innerSpinButtonElement() ? innerSpinButtonElement()->renderBox() : 0) {
@@ -431,31 +338,12 @@ LayoutUnit RenderTextControlSingleLine::preferredContentWidth(float charWidth) c
LayoutUnit RenderTextControlSingleLine::computeControlHeight(LayoutUnit lineHeight, LayoutUnit nonContentHeight) const
{
- HTMLElement* resultsButton = resultsButtonElement();
- if (RenderBox* resultsRenderer = resultsButton ? resultsButton->renderBox() : 0) {
- resultsRenderer->computeLogicalHeight();
- nonContentHeight = max(nonContentHeight, resultsRenderer->borderAndPaddingHeight() + resultsRenderer->marginHeight());
- lineHeight = max(lineHeight, resultsRenderer->height());
- }
- HTMLElement* cancelButton = cancelButtonElement();
- if (RenderBox* cancelRenderer = cancelButton ? cancelButton->renderBox() : 0) {
- cancelRenderer->computeLogicalHeight();
- nonContentHeight = max(nonContentHeight, cancelRenderer->borderAndPaddingHeight() + cancelRenderer->marginHeight());
- lineHeight = max(lineHeight, cancelRenderer->height());
- }
-
return lineHeight + nonContentHeight;
}
void RenderTextControlSingleLine::updateFromElement()
{
RenderTextControl::updateFromElement();
-
- if (cancelButtonElement())
- updateCancelButtonVisibility();
-
- if (m_searchPopupIsVisible)
- m_searchPopup->popupMenu()->updateFromElement();
}
PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const RenderStyle* startStyle) const
@@ -496,188 +384,12 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerBlockStyle(const
return innerBlockStyle.release();
}
-void RenderTextControlSingleLine::updateCancelButtonVisibility() const
-{
- RenderObject* cancelButtonRenderer = cancelButtonElement()->renderer();
- if (!cancelButtonRenderer)
- return;
-
- const RenderStyle* curStyle = cancelButtonRenderer->style();
- EVisibility buttonVisibility = visibilityForCancelButton();
- if (curStyle->visibility() == buttonVisibility)
- return;
-
- RefPtr<RenderStyle> cancelButtonStyle = RenderStyle::clone(curStyle);
- cancelButtonStyle->setVisibility(buttonVisibility);
- cancelButtonRenderer->setStyle(cancelButtonStyle);
-}
-
-EVisibility RenderTextControlSingleLine::visibilityForCancelButton() const
-{
- return (style()->visibility() == HIDDEN || inputElement()->value().isEmpty()) ? HIDDEN : VISIBLE;
-}
-
bool RenderTextControlSingleLine::textShouldBeTruncated() const
{
return document()->focusedNode() != node()
&& style()->textOverflow() == TextOverflowEllipsis;
}
-const AtomicString& RenderTextControlSingleLine::autosaveName() const
-{
- return static_cast<Element*>(node())->getAttribute(autosaveAttr);
-}
-
-// PopupMenuClient methods
-void RenderTextControlSingleLine::valueChanged(unsigned listIndex, bool fireEvents)
-{
- ASSERT(static_cast<int>(listIndex) < listSize());
- HTMLInputElement* input = inputElement();
- if (static_cast<int>(listIndex) == (listSize() - 1)) {
- if (fireEvents) {
- m_recentSearches.clear();
- const AtomicString& name = autosaveName();
- if (!name.isEmpty()) {
- if (!m_searchPopup)
- m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
- m_searchPopup->saveRecentSearches(name, m_recentSearches);
- }
- }
- } else {
- input->setValue(itemText(listIndex));
- if (fireEvents)
- input->onSearch();
- input->select();
- }
-}
-
-String RenderTextControlSingleLine::itemText(unsigned listIndex) const
-{
- int size = listSize();
- if (size == 1) {
- ASSERT(!listIndex);
- return searchMenuNoRecentSearchesText();
- }
- if (!listIndex)
- return searchMenuRecentSearchesText();
- if (itemIsSeparator(listIndex))
- return String();
- if (static_cast<int>(listIndex) == (size - 1))
- return searchMenuClearRecentSearchesText();
- return m_recentSearches[listIndex - 1];
-}
-
-String RenderTextControlSingleLine::itemLabel(unsigned) const
-{
- return String();
-}
-
-String RenderTextControlSingleLine::itemIcon(unsigned) const
-{
- return String();
-}
-
-bool RenderTextControlSingleLine::itemIsEnabled(unsigned listIndex) const
-{
- if (!listIndex || itemIsSeparator(listIndex))
- return false;
- return true;
-}
-
-PopupMenuStyle RenderTextControlSingleLine::itemStyle(unsigned) const
-{
- return menuStyle();
-}
-
-PopupMenuStyle RenderTextControlSingleLine::menuStyle() const
-{
- return PopupMenuStyle(style()->visitedDependentColor(CSSPropertyColor), style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->font(), style()->visibility() == VISIBLE,
- style()->display() == NONE, style()->textIndent(), style()->direction(), isOverride(style()->unicodeBidi()));
-}
-
-int RenderTextControlSingleLine::clientInsetLeft() const
-{
- // Inset the menu by the radius of the cap on the left so that
- // it only runs along the straight part of the bezel.
- return height() / 2;
-}
-
-int RenderTextControlSingleLine::clientInsetRight() const
-{
- // Inset the menu by the radius of the cap on the right so that
- // it only runs along the straight part of the bezel (unless it needs
- // to be wider).
- return height() / 2;
-}
-
-LayoutUnit RenderTextControlSingleLine::clientPaddingLeft() const
-{
- LayoutUnit padding = paddingLeft();
- if (RenderBox* box = innerBlockElement() ? innerBlockElement()->renderBox() : 0)
- padding += box->x();
- return padding;
-}
-
-LayoutUnit RenderTextControlSingleLine::clientPaddingRight() const
-{
- LayoutUnit padding = paddingRight();
- if (RenderBox* containerBox = containerElement() ? containerElement()->renderBox() : 0) {
- if (RenderBox* innerBlockBox = innerBlockElement() ? innerBlockElement()->renderBox() : 0)
- padding += containerBox->width() - (innerBlockBox->x() + innerBlockBox->width());
- }
- return padding;
-}
-
-int RenderTextControlSingleLine::listSize() const
-{
- // If there are no recent searches, then our menu will have 1 "No recent searches" item.
- if (!m_recentSearches.size())
- return 1;
- // Otherwise, leave room in the menu for a header, a separator, and the "Clear recent searches" item.
- return m_recentSearches.size() + 3;
-}
-
-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.
- return static_cast<int>(listIndex) == (listSize() - 2);
-}
-
-bool RenderTextControlSingleLine::itemIsLabel(unsigned listIndex) const
-{
- return listIndex == 0;
-}
-
-bool RenderTextControlSingleLine::itemIsSelected(unsigned) const
-{
- return false;
-}
-
-void RenderTextControlSingleLine::setTextFromItem(unsigned listIndex)
-{
- inputElement()->setValue(itemText(listIndex));
-}
-
-FontSelector* RenderTextControlSingleLine::fontSelector() const
-{
- return document()->styleResolver()->fontSelector();
-}
-
-HostWindow* RenderTextControlSingleLine::hostWindow() const
-{
- return document()->view()->hostWindow();
-}
-
void RenderTextControlSingleLine::autoscroll()
{
RenderLayer* layer = innerTextElement()->renderBox()->layer();
@@ -741,17 +453,6 @@ bool RenderTextControlSingleLine::logicalScroll(ScrollLogicalDirection direction
return RenderBlock::logicalScroll(direction, granularity, multiplier, stopNode);
}
-PassRefPtr<Scrollbar> RenderTextControlSingleLine::createScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
-{
- RefPtr<Scrollbar> widget;
- bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
- if (hasCustomScrollbarStyle)
- widget = RenderScrollbar::createCustomScrollbar(scrollableArea, orientation, this->node());
- else
- widget = Scrollbar::createNativeScrollbar(scrollableArea, orientation, controlSize);
- return widget.release();
-}
-
HTMLInputElement* RenderTextControlSingleLine::inputElement() const
{
return node()->toInputElement();
diff --git a/Source/WebCore/rendering/RenderTextControlSingleLine.h b/Source/WebCore/rendering/RenderTextControlSingleLine.h
index 6e21c856c..ffc50a33d 100644
--- a/Source/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/Source/WebCore/rendering/RenderTextControlSingleLine.h
@@ -23,32 +23,31 @@
#ifndef RenderTextControlSingleLine_h
#define RenderTextControlSingleLine_h
-#include "PopupMenuClient.h"
+#include "HTMLInputElement.h"
#include "RenderTextControl.h"
namespace WebCore {
class HTMLInputElement;
-class SearchPopupMenu;
-class RenderTextControlSingleLine : public RenderTextControl, private PopupMenuClient {
+class RenderTextControlSingleLine : public RenderTextControl {
public:
RenderTextControlSingleLine(Node*);
virtual ~RenderTextControlSingleLine();
// FIXME: Move create*Style() to their classes.
virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const;
PassRefPtr<RenderStyle> createInnerBlockStyle(const RenderStyle* startStyle) const;
- void updateCancelButtonVisibility() const;
-
- void addSearchResult();
- void stopSearchEventTimer();
-
- bool popupIsVisible() const { return m_searchPopupIsVisible; }
- void showPopup();
- void hidePopup();
void capsLockStateMayHaveChanged();
+protected:
+ virtual void centerContainerIfNeeded(RenderBox*) const { }
+ virtual LayoutUnit computeHeightLimit() const;
+ HTMLElement* containerElement() const;
+ HTMLElement* innerBlockElement() const;
+ HTMLInputElement* inputElement() const;
+ virtual void updateFromElement() OVERRIDE;
+
private:
virtual bool hasControlClip() const;
virtual LayoutRect controlClipRect(const LayoutPoint&) const;
@@ -76,59 +75,28 @@ private:
virtual LayoutUnit preferredContentWidth(float charWidth) const;
virtual LayoutUnit computeControlHeight(LayoutUnit lineHeight, LayoutUnit nonContentHeight) const OVERRIDE;
- virtual void updateFromElement();
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual RenderStyle* textBaseStyle() const;
- EVisibility visibilityForCancelButton() const;
bool textShouldBeTruncated() const;
- const AtomicString& autosaveName() const;
-
- // PopupMenuClient methods
- virtual void valueChanged(unsigned listIndex, bool fireEvents = true) OVERRIDE;
- virtual void selectionChanged(unsigned, bool) OVERRIDE { }
- virtual void selectionCleared() OVERRIDE { }
- virtual String itemText(unsigned listIndex) const OVERRIDE;
- virtual String itemLabel(unsigned listIndex) const OVERRIDE;
- virtual String itemIcon(unsigned listIndex) const OVERRIDE;
- virtual String itemToolTip(unsigned) const OVERRIDE { return String(); }
- virtual String itemAccessibilityText(unsigned) const OVERRIDE { return String(); }
- virtual bool itemIsEnabled(unsigned listIndex) const OVERRIDE;
- virtual PopupMenuStyle itemStyle(unsigned listIndex) const OVERRIDE;
- virtual PopupMenuStyle menuStyle() const OVERRIDE;
- virtual int clientInsetLeft() const OVERRIDE;
- virtual int clientInsetRight() const OVERRIDE;
- virtual LayoutUnit clientPaddingLeft() const OVERRIDE;
- virtual LayoutUnit clientPaddingRight() const OVERRIDE;
- virtual int listSize() const OVERRIDE;
- virtual int selectedIndex() const OVERRIDE;
- virtual void popupDidHide() OVERRIDE;
- virtual bool itemIsSeparator(unsigned listIndex) const OVERRIDE;
- virtual bool itemIsLabel(unsigned listIndex) const OVERRIDE;
- virtual bool itemIsSelected(unsigned listIndex) const OVERRIDE;
- virtual bool shouldPopOver() const OVERRIDE { return false; }
- virtual bool valueShouldChangeOnHotTrack() const OVERRIDE { return false; }
- virtual void setTextFromItem(unsigned listIndex) OVERRIDE;
- virtual FontSelector* fontSelector() const OVERRIDE;
- virtual HostWindow* hostWindow() const OVERRIDE;
- virtual PassRefPtr<Scrollbar> createScrollbar(ScrollableArea*, ScrollbarOrientation, ScrollbarControlSize) OVERRIDE;
-
- HTMLInputElement* inputElement() const;
- HTMLElement* containerElement() const;
- HTMLElement* innerBlockElement() const;
HTMLElement* innerSpinButtonElement() const;
- HTMLElement* resultsButtonElement() const;
- HTMLElement* cancelButtonElement() const;
- bool m_searchPopupIsVisible;
bool m_shouldDrawCapsLockIndicator;
LayoutUnit m_desiredInnerTextHeight;
- RefPtr<SearchPopupMenu> m_searchPopup;
- Vector<String> m_recentSearches;
};
+inline HTMLElement* RenderTextControlSingleLine::containerElement() const
+{
+ return inputElement()->containerElement();
+}
+
+inline HTMLElement* RenderTextControlSingleLine::innerBlockElement() const
+{
+ return inputElement()->innerBlockElement();
+}
+
inline RenderTextControlSingleLine* toRenderTextControlSingleLine(RenderObject* object)
{
ASSERT(!object || object->isTextField());
diff --git a/Source/WebCore/rendering/RenderTheme.cpp b/Source/WebCore/rendering/RenderTheme.cpp
index 585385f1b..e68b893eb 100644
--- a/Source/WebCore/rendering/RenderTheme.cpp
+++ b/Source/WebCore/rendering/RenderTheme.cpp
@@ -202,6 +202,14 @@ void RenderTheme::adjustStyle(StyleResolver* styleResolver, RenderStyle* style,
return adjustMenuListStyle(styleResolver, style, e);
case MenulistButtonPart:
return adjustMenuListButtonStyle(styleResolver, style, e);
+ case MediaPlayButtonPart:
+ case MediaCurrentTimePart:
+ case MediaTimeRemainingPart:
+ case MediaEnterFullscreenButtonPart:
+ case MediaExitFullscreenButtonPart:
+ case MediaMuteButtonPart:
+ case MediaVolumeSliderContainerPart:
+ return adjustMediaControlStyle(styleResolver, style, e);
case MediaSliderPart:
case MediaVolumeSliderPart:
case MediaFullScreenVolumeSliderPart:
@@ -969,16 +977,20 @@ void RenderTheme::adjustMenuListButtonStyle(StyleResolver*, RenderStyle*, Elemen
{
}
+void RenderTheme::adjustMediaControlStyle(StyleResolver*, RenderStyle*, Element*) const
+{
+}
+
void RenderTheme::adjustSliderTrackStyle(StyleResolver*, RenderStyle*, Element*) const
{
}
-void RenderTheme::adjustSliderThumbStyle(StyleResolver*, RenderStyle* style, Element*) const
+void RenderTheme::adjustSliderThumbStyle(StyleResolver*, RenderStyle* style, Element* element) const
{
- adjustSliderThumbSize(style);
+ adjustSliderThumbSize(style, element);
}
-void RenderTheme::adjustSliderThumbSize(RenderStyle*) const
+void RenderTheme::adjustSliderThumbSize(RenderStyle*, Element*) const
{
}
diff --git a/Source/WebCore/rendering/RenderTheme.h b/Source/WebCore/rendering/RenderTheme.h
index e3e71475f..5e56b6df5 100644
--- a/Source/WebCore/rendering/RenderTheme.h
+++ b/Source/WebCore/rendering/RenderTheme.h
@@ -172,7 +172,7 @@ public:
virtual int minimumMenuListSize(RenderStyle*) const { return 0; }
- virtual void adjustSliderThumbSize(RenderStyle*) const;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
virtual int popupInternalPaddingLeft(RenderStyle*) const { return 0; }
virtual int popupInternalPaddingRight(RenderStyle*) const { return 0; }
@@ -198,6 +198,7 @@ public:
virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return false; }
virtual bool usesMediaControlStatusDisplay() { return false; }
virtual bool usesMediaControlVolumeSlider() const { return true; }
+ virtual bool usesVerticalVolumeSlider() const { return true; }
virtual double mediaControlsFadeInDuration() { return 0.1; }
virtual double mediaControlsFadeOutDuration() { return 0.3; }
virtual String formatMediaControlsTime(float time) const;
@@ -305,6 +306,7 @@ protected:
virtual void adjustSearchFieldResultsButtonStyle(StyleResolver*, RenderStyle*, Element*) const;
virtual bool paintSearchFieldResultsButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
+ virtual void adjustMediaControlStyle(StyleResolver*, RenderStyle*, Element*) const;
virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
diff --git a/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp b/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp
index 8b7123088..97f587455 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp
+++ b/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp
@@ -99,4 +99,12 @@ bool RenderThemeChromiumAndroid::paintMediaFullscreenButton(RenderObject* object
#endif
}
+int RenderThemeChromiumAndroid::menuListArrowPadding() const
+{
+ // We cannot use the scrollbar thickness here, as it's width is 0 on Android.
+ // Instead, use the width of the scrollbar down arrow.
+ IntSize scrollbarSize = PlatformSupport::getThemePartSize(PlatformSupport::PartScrollbarDownArrow);
+ return scrollbarSize.width();
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderThemeChromiumAndroid.h b/Source/WebCore/rendering/RenderThemeChromiumAndroid.h
index 3dcd6df93..f7aafaa18 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumAndroid.h
+++ b/Source/WebCore/rendering/RenderThemeChromiumAndroid.h
@@ -41,7 +41,7 @@ public:
virtual bool delegatesMenuListRendering() const OVERRIDE { return true; }
- virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
#if ENABLE(VIDEO)
virtual String extraMediaControlsStyleSheet() OVERRIDE;
@@ -54,10 +54,19 @@ public:
}
#endif
+ virtual Color platformActiveSelectionBackgroundColor() const OVERRIDE
+ {
+ return RenderThemeChromiumAndroid::defaultActiveSelectionBackgroundColor;
+ }
+
+protected:
+ virtual int menuListArrowPadding() const OVERRIDE;
+
private:
virtual ~RenderThemeChromiumAndroid();
static const RGBA32 defaultTapHighlightColor = 0x6633b5e5;
+ static const RGBA32 defaultActiveSelectionBackgroundColor = 0x6633b5e5;
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp b/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp
index 019694f0d..6b7f158ee 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp
+++ b/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp
@@ -146,7 +146,7 @@ Color RenderThemeChromiumLinux::platformInactiveSelectionForegroundColor() const
return m_inactiveSelectionForegroundColor;
}
-void RenderThemeChromiumLinux::adjustSliderThumbSize(RenderStyle* style) const
+void RenderThemeChromiumLinux::adjustSliderThumbSize(RenderStyle* style, Element* element) const
{
IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartSliderThumb);
@@ -157,7 +157,7 @@ void RenderThemeChromiumLinux::adjustSliderThumbSize(RenderStyle* style) const
style->setWidth(Length(size.height(), Fixed));
style->setHeight(Length(size.width(), Fixed));
} else
- RenderThemeChromiumSkia::adjustSliderThumbSize(style);
+ RenderThemeChromiumSkia::adjustSliderThumbSize(style, element);
}
bool RenderThemeChromiumLinux::supportsControlTints() const
diff --git a/Source/WebCore/rendering/RenderThemeChromiumLinux.h b/Source/WebCore/rendering/RenderThemeChromiumLinux.h
index 7e308083f..d75408251 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumLinux.h
+++ b/Source/WebCore/rendering/RenderThemeChromiumLinux.h
@@ -54,7 +54,7 @@ namespace WebCore {
virtual Color platformActiveSelectionForegroundColor() const;
virtual Color platformInactiveSelectionForegroundColor() const;
- virtual void adjustSliderThumbSize(RenderStyle*) const;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
static void setCaretBlinkInterval(double interval);
virtual double caretBlinkIntervalInternal() const;
diff --git a/Source/WebCore/rendering/RenderThemeChromiumMac.h b/Source/WebCore/rendering/RenderThemeChromiumMac.h
index 2b4c8c635..973299a31 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumMac.h
+++ b/Source/WebCore/rendering/RenderThemeChromiumMac.h
@@ -42,7 +42,6 @@ protected:
virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaControlsBackground(RenderObject*, const PaintInfo&, const IntRect&);
virtual String extraMediaControlsStyleSheet();
#if ENABLE(FULLSCREEN_API)
virtual String extraFullScreenStyleSheet();
@@ -55,6 +54,11 @@ protected:
virtual IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&) const OVERRIDE;
virtual bool usesMediaControlStatusDisplay() { return false; }
virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
+ virtual bool usesVerticalVolumeSlider() const { return false; }
+ virtual String formatMediaControlsTime(float time) const;
+ virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const;
+ virtual String formatMediaControlsRemainingTime(float currentTime, float duration) const;
+ virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
#endif
virtual bool usesTestModeFocusRingColor() const;
diff --git a/Source/WebCore/rendering/RenderThemeChromiumMac.mm b/Source/WebCore/rendering/RenderThemeChromiumMac.mm
index a778228c5..1791b09ab 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumMac.mm
+++ b/Source/WebCore/rendering/RenderThemeChromiumMac.mm
@@ -173,11 +173,6 @@ bool RenderThemeChromiumMac::paintMediaSliderTrack(RenderObject* object, const P
return RenderMediaControlsChromium::paintMediaControlsPart(MediaSlider, object, paintInfo, rect);
}
-bool RenderThemeChromiumMac::paintMediaControlsBackground(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
-{
- return RenderMediaControlsChromium::paintMediaControlsPart(MediaTimelineContainer, object, paintInfo, rect);
-}
-
String RenderThemeChromiumMac::extraMediaControlsStyleSheet()
{
return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet));
@@ -228,6 +223,26 @@ IntPoint RenderThemeChromiumMac::volumeSliderOffsetFromMuteButton(RenderBox* mut
{
return RenderTheme::volumeSliderOffsetFromMuteButton(muteButtonBox, size);
}
+
+String RenderThemeChromiumMac::formatMediaControlsTime(float time) const
+{
+ return RenderMediaControlsChromium::formatMediaControlsTime(time);
+}
+
+String RenderThemeChromiumMac::formatMediaControlsCurrentTime(float currentTime, float duration) const
+{
+ return RenderMediaControlsChromium::formatMediaControlsCurrentTime(currentTime, duration);
+}
+
+String RenderThemeChromiumMac::formatMediaControlsRemainingTime(float currentTime, float duration) const
+{
+ return RenderThemeChromiumMac::formatMediaControlsRemainingTime(currentTime, duration);
+}
+
+bool RenderThemeChromiumMac::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ return RenderMediaControlsChromium::paintMediaControlsPart(MediaEnterFullscreenButton, object, paintInfo, rect);
+}
#endif
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp b/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp
index 902dad013..c88066616 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp
+++ b/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp
@@ -378,18 +378,6 @@ bool RenderThemeChromiumSkia::paintSearchFieldResultsButton(RenderObject* magnif
return false;
}
-bool RenderThemeChromiumSkia::paintMediaControlsBackground(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
-{
-#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 PaintInfo& paintInfo, const IntRect& rect)
{
#if ENABLE(VIDEO)
@@ -414,7 +402,7 @@ bool RenderThemeChromiumSkia::paintMediaVolumeSliderTrack(RenderObject* object,
#endif
}
-void RenderThemeChromiumSkia::adjustSliderThumbSize(RenderStyle* style) const
+void RenderThemeChromiumSkia::adjustSliderThumbSize(RenderStyle* style, Element*) const
{
#if ENABLE(VIDEO)
RenderMediaControlsChromium::adjustMediaSliderThumbSize(style);
@@ -471,6 +459,50 @@ bool RenderThemeChromiumSkia::paintMediaMuteButton(RenderObject* object, const P
#endif
}
+String RenderThemeChromiumSkia::formatMediaControlsTime(float time) const
+{
+#if ENABLE(VIDEO)
+ return RenderMediaControlsChromium::formatMediaControlsTime(time);
+#else
+ UNUSED_PARAM(time);
+ return 0;
+#endif
+}
+
+String RenderThemeChromiumSkia::formatMediaControlsCurrentTime(float currentTime, float duration) const
+{
+#if ENABLE(VIDEO)
+ return RenderMediaControlsChromium::formatMediaControlsCurrentTime(currentTime, duration);
+#else
+ UNUSED_PARAM(currentTime);
+ UNUSED_PARAM(duration);
+ return 0;
+#endif
+}
+
+String RenderThemeChromiumSkia::formatMediaControlsRemainingTime(float currentTime, float duration) const
+{
+#if ENABLE(VIDEO)
+ return RenderMediaControlsChromium::formatMediaControlsRemainingTime(currentTime, duration);
+#else
+ UNUSED_PARAM(currentTime);
+ UNUSED_PARAM(duration);
+ return 0;
+#endif
+}
+
+bool RenderThemeChromiumSkia::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
+{
+#if ENABLE(VIDEO)
+ return RenderMediaControlsChromium::paintMediaControlsPart(MediaEnterFullscreenButton, object, paintInfo, rect);
+#else
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(paintInfo);
+ UNUSED_PARAM(rect);
+ return false;
+#endif
+}
+
void RenderThemeChromiumSkia::adjustMenuListStyle(StyleResolver*, RenderStyle* style, WebCore::Element*) const
{
// Height is locked to auto on all browsers.
@@ -519,6 +551,11 @@ double RenderThemeChromiumSkia::caretBlinkIntervalInternal() const
return RenderTheme::caretBlinkInterval();
}
+int RenderThemeChromiumSkia::menuListArrowPadding() const
+{
+ return ScrollbarTheme::theme()->scrollbarThickness();
+}
+
// static
void RenderThemeChromiumSkia::setSizeIfAuto(RenderStyle* style, const IntSize& size)
{
@@ -541,7 +578,7 @@ int RenderThemeChromiumSkia::menuListInternalPadding(RenderStyle* style, int pad
// we don't draw a button, so don't reserve space for it.
const int barType = style->direction() == LTR ? RightPadding : LeftPadding;
if (paddingType == barType && style->appearance() != NoControlPart)
- padding += ScrollbarTheme::theme()->scrollbarThickness();
+ padding += menuListArrowPadding();
return padding;
}
diff --git a/Source/WebCore/rendering/RenderThemeChromiumSkia.h b/Source/WebCore/rendering/RenderThemeChromiumSkia.h
index c5306c12f..745873052 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumSkia.h
+++ b/Source/WebCore/rendering/RenderThemeChromiumSkia.h
@@ -91,14 +91,17 @@ class RenderThemeChromiumSkia : public RenderTheme {
virtual void adjustSearchFieldResultsButtonStyle(StyleResolver*, RenderStyle*, Element*) const;
virtual bool paintSearchFieldResultsButton(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaControlsBackground(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
- virtual void adjustSliderThumbSize(RenderStyle*) const;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual String formatMediaControlsTime(float time) const;
+ virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const;
+ virtual String formatMediaControlsRemainingTime(float currentTime, float duration) const;
+ virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
// MenuList refers to an unstyled menulist (meaning a menulist without
// background-color or border set) and MenuListButton refers to a styled
@@ -127,6 +130,7 @@ class RenderThemeChromiumSkia : public RenderTheme {
#if ENABLE(VIDEO)
// Media controls
virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
+ virtual bool usesVerticalVolumeSlider() const { return false; }
#endif
// Provide a way to pass the default font size from the Settings object
@@ -146,6 +150,8 @@ class RenderThemeChromiumSkia : public RenderTheme {
virtual double caretBlinkIntervalInternal() const;
+ virtual int menuListArrowPadding() const;
+
static void setSizeIfAuto(RenderStyle*, const IntSize&);
#if ENABLE(PROGRESS_TAG)
diff --git a/Source/WebCore/rendering/RenderThemeChromiumWin.cpp b/Source/WebCore/rendering/RenderThemeChromiumWin.cpp
index 444212fd0..e2c41d9dd 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumWin.cpp
+++ b/Source/WebCore/rendering/RenderThemeChromiumWin.cpp
@@ -391,7 +391,7 @@ Color RenderThemeChromiumWin::systemColor(int cssValueId) const
return Color(GetRValue(color), GetGValue(color), GetBValue(color));
}
-void RenderThemeChromiumWin::adjustSliderThumbSize(RenderStyle* style) const
+void RenderThemeChromiumWin::adjustSliderThumbSize(RenderStyle* style, Element* element) const
{
// These sizes match what WinXP draws for various menus.
const int sliderThumbAlongAxis = 11;
@@ -403,7 +403,7 @@ void RenderThemeChromiumWin::adjustSliderThumbSize(RenderStyle* style) const
style->setWidth(Length(sliderThumbAcrossAxis, Fixed));
style->setHeight(Length(sliderThumbAlongAxis, Fixed));
} else
- RenderThemeChromiumSkia::adjustSliderThumbSize(style);
+ RenderThemeChromiumSkia::adjustSliderThumbSize(style, element);
}
bool RenderThemeChromiumWin::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r)
diff --git a/Source/WebCore/rendering/RenderThemeChromiumWin.h b/Source/WebCore/rendering/RenderThemeChromiumWin.h
index 7856d039f..ad9eace89 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumWin.h
+++ b/Source/WebCore/rendering/RenderThemeChromiumWin.h
@@ -61,7 +61,7 @@ namespace WebCore {
virtual void systemFont(int propId, FontDescription&) const;
virtual Color systemColor(int cssValueId) const;
- virtual void adjustSliderThumbSize(RenderStyle*) const;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
// Various paint functions.
virtual bool paintCheckbox(RenderObject*, const PaintInfo&, const IntRect&);
diff --git a/Source/WebCore/rendering/RenderThemeMac.h b/Source/WebCore/rendering/RenderThemeMac.h
index ebbb2352c..2f5f80e8c 100644
--- a/Source/WebCore/rendering/RenderThemeMac.h
+++ b/Source/WebCore/rendering/RenderThemeMac.h
@@ -67,7 +67,7 @@ public:
virtual int minimumMenuListSize(RenderStyle*) const;
- virtual void adjustSliderThumbSize(RenderStyle*) const;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
virtual int popupInternalPaddingLeft(RenderStyle*) const;
virtual int popupInternalPaddingRight(RenderStyle*) const;
diff --git a/Source/WebCore/rendering/RenderThemeMac.mm b/Source/WebCore/rendering/RenderThemeMac.mm
index f6f57b905..e09437db2 100644
--- a/Source/WebCore/rendering/RenderThemeMac.mm
+++ b/Source/WebCore/rendering/RenderThemeMac.mm
@@ -1747,7 +1747,7 @@ const int sliderThumbHeight = 15;
const int mediaSliderThumbWidth = 13;
const int mediaSliderThumbHeight = 14;
-void RenderThemeMac::adjustSliderThumbSize(RenderStyle* style) const
+void RenderThemeMac::adjustSliderThumbSize(RenderStyle* style, Element*) const
{
float zoomLevel = style->effectiveZoom();
if (style->appearance() == SliderThumbHorizontalPart || style->appearance() == SliderThumbVerticalPart) {
@@ -1833,9 +1833,9 @@ bool RenderThemeMac::paintMediaFullscreenButton(RenderObject* o, const PaintInfo
if (!node)
return false;
- if (MediaControlFullscreenButtonElement* btn = static_cast<MediaControlFullscreenButtonElement*>(o->node())) {
+ if (node->isMediaControlElement()) {
LocalCurrentGraphicsContext localContext(paintInfo.context);
- wkDrawMediaUIPart(btn->displayType(), mediaControllerTheme(), localContext.cgContext(), r, getMediaUIPartStateFlags(node));
+ wkDrawMediaUIPart(mediaControlElementType(node), mediaControllerTheme(), localContext.cgContext(), r, getMediaUIPartStateFlags(node));
}
return false;
}
diff --git a/Source/WebCore/rendering/RenderThemeSafari.cpp b/Source/WebCore/rendering/RenderThemeSafari.cpp
index 00a5d7e66..23fd8b193 100644
--- a/Source/WebCore/rendering/RenderThemeSafari.cpp
+++ b/Source/WebCore/rendering/RenderThemeSafari.cpp
@@ -1006,7 +1006,7 @@ bool RenderThemeSafari::paintSliderThumb(RenderObject* o, const PaintInfo& paint
const int sliderThumbWidth = 15;
const int sliderThumbHeight = 15;
-void RenderThemeSafari::adjustSliderThumbSize(RenderStyle* style) const
+void RenderThemeSafari::adjustSliderThumbSize(RenderStyle* style, Element*) const
{
if (style->appearance() == SliderThumbHorizontalPart || style->appearance() == SliderThumbVerticalPart) {
style->setWidth(Length(sliderThumbWidth, Fixed));
diff --git a/Source/WebCore/rendering/RenderThemeSafari.h b/Source/WebCore/rendering/RenderThemeSafari.h
index 05b1fb5ea..cb861e668 100644
--- a/Source/WebCore/rendering/RenderThemeSafari.h
+++ b/Source/WebCore/rendering/RenderThemeSafari.h
@@ -76,7 +76,7 @@ public:
virtual int minimumMenuListSize(RenderStyle*) const;
- virtual void adjustSliderThumbSize(RenderStyle*) const;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
virtual void adjustSliderThumbStyle(StyleResolver*, RenderStyle*, Element*) const;
virtual int popupInternalPaddingLeft(RenderStyle*) const;
diff --git a/Source/WebCore/rendering/RenderThemeWin.cpp b/Source/WebCore/rendering/RenderThemeWin.cpp
index e58bad9e1..403dd98b1 100644
--- a/Source/WebCore/rendering/RenderThemeWin.cpp
+++ b/Source/WebCore/rendering/RenderThemeWin.cpp
@@ -841,7 +841,7 @@ bool RenderThemeWin::paintSliderThumb(RenderObject* o, const PaintInfo& i, const
const int sliderThumbWidth = 7;
const int sliderThumbHeight = 15;
-void RenderThemeWin::adjustSliderThumbSize(RenderStyle* style) const
+void RenderThemeWin::adjustSliderThumbSize(RenderStyle* style, Element*) const
{
ControlPart part = style->appearance();
if (part == SliderThumbVerticalPart) {
diff --git a/Source/WebCore/rendering/RenderThemeWin.h b/Source/WebCore/rendering/RenderThemeWin.h
index d2337c361..b97f30004 100644
--- a/Source/WebCore/rendering/RenderThemeWin.h
+++ b/Source/WebCore/rendering/RenderThemeWin.h
@@ -93,7 +93,7 @@ public:
virtual bool paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r);
virtual bool paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r);
- virtual void adjustSliderThumbSize(RenderStyle*) const;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
virtual bool popupOptionSupportsTextIndent() const { return true; }
diff --git a/Source/WebCore/rendering/RenderThemeWinCE.cpp b/Source/WebCore/rendering/RenderThemeWinCE.cpp
index d89257d04..40349de10 100644
--- a/Source/WebCore/rendering/RenderThemeWinCE.cpp
+++ b/Source/WebCore/rendering/RenderThemeWinCE.cpp
@@ -331,7 +331,7 @@ Color RenderThemeWinCE::systemColor(int cssValueId) const
const int sliderThumbWidth = 7;
const int sliderThumbHeight = 15;
-void RenderThemeWinCE::adjustSliderThumbSize(RenderStyle* style) const
+void RenderThemeWinCE::adjustSliderThumbSize(RenderStyle* style, Element*) const
{
if (style->appearance() == SliderThumbVerticalPart) {
style->setWidth(Length(sliderThumbHeight, Fixed));
diff --git a/Source/WebCore/rendering/RenderThemeWinCE.h b/Source/WebCore/rendering/RenderThemeWinCE.h
index dee237eaf..bde872c6c 100644
--- a/Source/WebCore/rendering/RenderThemeWinCE.h
+++ b/Source/WebCore/rendering/RenderThemeWinCE.h
@@ -89,7 +89,7 @@ namespace WebCore {
virtual bool paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r);
virtual bool paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r);
- virtual void adjustSliderThumbSize(RenderStyle*) const;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
virtual bool popupOptionSupportsTextIndent() const { return true; }
diff --git a/Source/WebCore/rendering/RenderTreeAsText.cpp b/Source/WebCore/rendering/RenderTreeAsText.cpp
index 39319ca1f..59ceebd68 100644
--- a/Source/WebCore/rendering/RenderTreeAsText.cpp
+++ b/Source/WebCore/rendering/RenderTreeAsText.cpp
@@ -374,6 +374,23 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
ts << "]";
}
+
+#if ENABLE(MATHML)
+ // We want to show any layout padding, both CSS padding and intrinsic padding, so we can't just check o.style()->hasPadding().
+ if (o.isRenderMathMLBlock() && (box.paddingTop() || box.paddingRight() || box.paddingBottom() || box.paddingLeft())) {
+ ts << " [";
+ LayoutUnit cssTop = box.computedCSSPaddingTop();
+ LayoutUnit cssRight = box.computedCSSPaddingRight();
+ LayoutUnit cssBottom = box.computedCSSPaddingBottom();
+ LayoutUnit cssLeft = box.computedCSSPaddingLeft();
+ if (box.paddingTop() != cssTop || box.paddingRight() != cssRight || box.paddingBottom() != cssBottom || box.paddingLeft() != cssLeft) {
+ ts << "intrinsic ";
+ if (cssTop || cssRight || cssBottom || cssLeft)
+ ts << "+ CSS ";
+ }
+ ts << "padding: " << roundToInt(box.paddingTop()) << " " << roundToInt(box.paddingRight()) << " " << roundToInt(box.paddingBottom()) << " " << roundToInt(box.paddingLeft()) << "]";
+ }
+#endif
}
if (o.isTableCell()) {
diff --git a/Source/WebCore/rendering/RenderView.cpp b/Source/WebCore/rendering/RenderView.cpp
index aadb9b9b5..d497a33ab 100644
--- a/Source/WebCore/rendering/RenderView.cpp
+++ b/Source/WebCore/rendering/RenderView.cpp
@@ -44,6 +44,10 @@
#include "RenderLayerCompositor.h"
#endif
+#if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
+#include "CustomFilterGlobalContext.h"
+#endif
+
namespace WebCore {
RenderView::RenderView(Node* node, FrameView* view)
@@ -390,7 +394,7 @@ void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, L
}
if (fixed && m_frameView)
- rect.move(m_frameView->scrollXForFixedPosition(), m_frameView->scrollYForFixedPosition());
+ rect.move(m_frameView->scrollOffsetForFixedPosition());
// Apply our transform if we have one (because of full page zooming).
if (!repaintContainer && m_layer && m_layer->transform())
@@ -656,8 +660,7 @@ bool RenderView::shouldUsePrintingLayout() const
if (!printing() || !m_frameView)
return false;
Frame* frame = m_frameView->frame();
- // Only root frame should have special handling for printing.
- return frame && !frame->tree()->parent();
+ return frame && frame->shouldUsePrintingLayout();
}
size_t RenderView::getRetainedWidgets(Vector<RenderWidget*>& renderWidgets)
@@ -899,6 +902,15 @@ void RenderView::willMoveOffscreen()
#endif
}
+#if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
+CustomFilterGlobalContext* RenderView::customFilterGlobalContext()
+{
+ if (!m_customFilterGlobalContext)
+ m_customFilterGlobalContext = adoptPtr(new CustomFilterGlobalContext());
+ return m_customFilterGlobalContext.get();
+}
+#endif
+
void RenderView::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
@@ -946,20 +958,4 @@ void RenderView::setFixedPositionedObjectsNeedLayout()
}
}
-void RenderView::insertFixedPositionedObject(RenderBox* object)
-{
- if (!m_positionedObjects)
- m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
-
- m_positionedObjects->add(object);
-}
-
-void RenderView::removeFixedPositionedObject(RenderBox* object)
-{
- if (!m_positionedObjects)
- return;
-
- m_positionedObjects->remove(object);
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderView.h b/Source/WebCore/rendering/RenderView.h
index e6a5722d8..8e5bc3c5a 100644
--- a/Source/WebCore/rendering/RenderView.h
+++ b/Source/WebCore/rendering/RenderView.h
@@ -37,6 +37,10 @@ class RenderWidget;
class RenderLayerCompositor;
#endif
+#if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
+class CustomFilterGlobalContext;
+#endif
+
class RenderView : public RenderBlock {
public:
RenderView(Node*, FrameView*);
@@ -168,6 +172,10 @@ public:
bool usesCompositing() const;
#endif
+#if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
+ CustomFilterGlobalContext* customFilterGlobalContext();
+#endif
+
IntRect unscaledDocumentRect() const;
LayoutRect backgroundRect(RenderBox* backgroundRenderer) const;
@@ -183,8 +191,6 @@ public:
IntSize viewportSize() const { return document()->viewportSize(); }
void setFixedPositionedObjectsNeedLayout();
- void insertFixedPositionedObject(RenderBox*);
- void removeFixedPositionedObject(RenderBox*);
protected:
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&, ApplyContainerFlipOrNot = ApplyContainerFlip, bool* wasFixed = 0) const;
@@ -276,6 +282,9 @@ private:
#if USE(ACCELERATED_COMPOSITING)
OwnPtr<RenderLayerCompositor> m_compositor;
#endif
+#if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
+ OwnPtr<CustomFilterGlobalContext> m_customFilterGlobalContext;
+#endif
OwnPtr<FlowThreadController> m_flowThreadController;
RefPtr<IntervalArena> m_intervalArena;
};
diff --git a/Source/WebCore/rendering/RenderingAllInOne.cpp b/Source/WebCore/rendering/RenderingAllInOne.cpp
index d17bd313a..1f0a4a38e 100644
--- a/Source/WebCore/rendering/RenderingAllInOne.cpp
+++ b/Source/WebCore/rendering/RenderingAllInOne.cpp
@@ -91,6 +91,7 @@
#include "RenderScrollbar.cpp"
#include "RenderScrollbarPart.cpp"
#include "RenderScrollbarTheme.cpp"
+#include "RenderSearchField.cpp"
#include "RenderSlider.cpp"
#include "RenderTable.cpp"
#include "RenderTableCaption.cpp"
diff --git a/Source/WebCore/rendering/TableLayout.h b/Source/WebCore/rendering/TableLayout.h
index a72bfeff3..750768347 100644
--- a/Source/WebCore/rendering/TableLayout.h
+++ b/Source/WebCore/rendering/TableLayout.h
@@ -42,6 +42,8 @@ public:
virtual void layout() = 0;
protected:
+ const static int tableMaxWidth = 15000;
+
RenderTable* m_table;
};
diff --git a/Source/WebCore/rendering/break_lines.cpp b/Source/WebCore/rendering/break_lines.cpp
index 7522ccb3e..4bba3ce7e 100644
--- a/Source/WebCore/rendering/break_lines.cpp
+++ b/Source/WebCore/rendering/break_lines.cpp
@@ -121,32 +121,21 @@ COMPILE_ASSERT(WTF_ARRAY_LENGTH(asciiLineBreakTable) == asciiLineBreakTableLastC
static inline bool shouldBreakAfter(UChar lastCh, UChar ch, UChar nextCh)
{
- switch (ch) {
- case ideographicComma:
- case ideographicFullStop:
- // FIXME: cases for ideographicComma and ideographicFullStop are a workaround for an issue in Unicode 5.0
- // which is likely to be resolved in Unicode 5.1 <http://bugs.webkit.org/show_bug.cgi?id=17411>.
- // We may want to remove or conditionalize this workaround at some point.
- return true;
- case '-':
- if (isASCIIDigit(nextCh)) {
- // Don't allow line breaking between '-' and a digit if the '-' may mean a minus sign in the context,
- // while allow breaking in 'ABCD-1234' and '1234-5678' which may be in long URLs.
- return isASCIIAlphanumeric(lastCh);
- }
- // Fall through
- default:
- // If both ch and nextCh are ASCII characters, use a lookup table for enhanced speed and for compatibility
- // with other browsers (see comments for asciiLineBreakTable for details).
- if (ch >= asciiLineBreakTableFirstChar && ch <= asciiLineBreakTableLastChar
- && nextCh >= asciiLineBreakTableFirstChar && nextCh <= asciiLineBreakTableLastChar) {
- const unsigned char* tableRow = asciiLineBreakTable[ch - asciiLineBreakTableFirstChar];
- int nextChIndex = nextCh - asciiLineBreakTableFirstChar;
- return tableRow[nextChIndex / 8] & (1 << (nextChIndex % 8));
- }
- // Otherwise defer to the Unicode algorithm by returning false.
- return false;
+ // Don't allow line breaking between '-' and a digit if the '-' may mean a minus sign in the context,
+ // while allow breaking in 'ABCD-1234' and '1234-5678' which may be in long URLs.
+ if (ch == '-' && isASCIIDigit(nextCh))
+ return isASCIIAlphanumeric(lastCh);
+
+ // If both ch and nextCh are ASCII characters, use a lookup table for enhanced speed and for compatibility
+ // with other browsers (see comments for asciiLineBreakTable for details).
+ if (ch >= asciiLineBreakTableFirstChar && ch <= asciiLineBreakTableLastChar
+ && nextCh >= asciiLineBreakTableFirstChar && nextCh <= asciiLineBreakTableLastChar) {
+ const unsigned char* tableRow = asciiLineBreakTable[ch - asciiLineBreakTableFirstChar];
+ int nextChIndex = nextCh - asciiLineBreakTableFirstChar;
+ return tableRow[nextChIndex / 8] & (1 << (nextChIndex % 8));
}
+ // Otherwise defer to the Unicode algorithm by returning false.
+ return false;
}
static inline bool needsLineBreakIterator(UChar ch)
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp b/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp
index d944eda2f..a4f927407 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2012 David Barton (dbarton@mathscribe.com). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -146,10 +147,10 @@ void RenderMathMLBlock::computePreferredLogicalWidths()
RenderBlock::computePreferredLogicalWidths();
}
-RenderMathMLBlock* RenderMathMLBlock::createAlmostAnonymousBlock(EDisplay display)
+RenderMathMLBlock* RenderMathMLBlock::createAnonymousMathMLBlock(EDisplay display)
{
RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), display);
- RenderMathMLBlock* newBlock = new (renderArena()) RenderMathMLBlock(node() /* "almost" anonymous block */);
+ RenderMathMLBlock* newBlock = new (renderArena()) RenderMathMLBlock(document() /* is anonymous */);
newBlock->setStyle(newStyle.release());
return newBlock;
}
@@ -196,6 +197,18 @@ LayoutUnit RenderMathMLBlock::preferredLogicalHeightAfterSizing(RenderObject* ch
return child->style()->fontSize();
}
+const char* RenderMathMLBlock::renderName() const
+{
+ EDisplay display = style()->display();
+ if (display == BLOCK)
+ return isAnonymous() ? "RenderMathMLBlock (anonymous, block)" : "RenderMathMLBlock (block)";
+ if (display == INLINE_BLOCK)
+ return isAnonymous() ? "RenderMathMLBlock (anonymous, inline-block)" : "RenderMathMLBlock (inline-block)";
+ // |display| should be one of the above.
+ ASSERT_NOT_REACHED();
+ return isAnonymous() ? "RenderMathMLBlock (anonymous)" : "RenderMathMLBlock";
+}
+
#if ENABLE(DEBUG_MATH_LAYOUT)
void RenderMathMLBlock::paint(PaintInfo& info, const LayoutPoint& paintOffset)
{
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLBlock.h b/Source/WebCore/rendering/mathml/RenderMathMLBlock.h
index 634d0a6dc..45f729643 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLBlock.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLBlock.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2012 David Barton (dbarton@mathscribe.com). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -79,9 +80,8 @@ public:
virtual void paint(PaintInfo&, const LayoutPoint&);
#endif
- // Create a new RenderBlock, with a new style inheriting from this->style().
- // FIXME: Create a true anonymous block, like RenderBlock::createAnonymousBlock().
- RenderMathMLBlock* createAlmostAnonymousBlock(EDisplay = BLOCK);
+ // Create a new RenderMathMLBlock, with a new style inheriting from this->style().
+ RenderMathMLBlock* createAnonymousMathMLBlock(EDisplay = BLOCK);
protected:
static LayoutUnit getBoxModelObjectHeight(const RenderObject* object)
@@ -104,7 +104,7 @@ protected:
}
private:
- virtual const char* renderName() const { return isAnonymous() ? "RenderMathMLBlock (anonymous)" : "RenderMathMLBlock"; }
+ virtual const char* renderName() const OVERRIDE;
protected:
// Set our logical width to a large value, and compute our children's preferred logical heights.
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp b/Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp
index 351f99e84..68c2b0533 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp
@@ -81,22 +81,19 @@ void RenderMathMLFenced::updateFromElement()
makeFences();
}
-PassRefPtr<RenderStyle> RenderMathMLFenced::createOperatorStyle()
+RenderMathMLOperator* RenderMathMLFenced::createMathMLOperator(UChar uChar)
{
- RefPtr<RenderStyle> newStyle = RenderStyle::create();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(INLINE_BLOCK);
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), INLINE_BLOCK);
newStyle->setPaddingRight(Length(static_cast<int>(gOperatorPadding * style()->fontSize()), Fixed));
- return newStyle.release();
+ RenderMathMLOperator* newOperator = new (renderArena()) RenderMathMLOperator(node() /* "almost anonymous" */, uChar);
+ newOperator->setStyle(newStyle.release());
+ return newOperator;
}
void RenderMathMLFenced::makeFences()
{
- RenderObject* openFence = new (renderArena()) RenderMathMLOperator(node(), m_open);
- openFence->setStyle(createOperatorStyle());
- RenderBlock::addChild(openFence, firstChild());
- m_closeFenceRenderer = new (renderArena()) RenderMathMLOperator(node(), m_close);
- m_closeFenceRenderer->setStyle(createOperatorStyle());
+ RenderBlock::addChild(createMathMLOperator(m_open), firstChild());
+ m_closeFenceRenderer = createMathMLOperator(m_close);
RenderBlock::addChild(m_closeFenceRenderer);
}
@@ -131,15 +128,14 @@ void RenderMathMLFenced::addChild(RenderObject* child, RenderObject* beforeChild
else
separator = (*m_separators.get())[count - 1];
- separatorRenderer = new (renderArena()) RenderMathMLOperator(node(), separator);
- separatorRenderer->setStyle(createOperatorStyle());
+ separatorRenderer = createMathMLOperator(separator);
}
}
// If we have a block, we'll wrap it in an inline-block.
if (child->isBlockFlow() && child->style()->display() != INLINE_BLOCK) {
// Block objects wrapper.
- RenderBlock* block = createAlmostAnonymousBlock(INLINE_BLOCK);
+ RenderMathMLBlock* block = createAnonymousMathMLBlock(INLINE_BLOCK);
block->addChild(child);
child = block;
@@ -158,6 +154,20 @@ void RenderMathMLFenced::addChild(RenderObject* child, RenderObject* beforeChild
}
}
+// FIXME: Change createMathMLOperator() above to create an isAnonymous() operator, and remove this styleDidChange() function.
+void RenderMathMLFenced::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderMathMLBlock::styleDidChange(diff, oldStyle);
+
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->node() == node()) {
+ ASSERT(child->style()->refCount() == 1);
+ child->style()->inheritFrom(style());
+ child->style()->setPaddingRight(Length(static_cast<int>(gOperatorPadding * style()->fontSize()), Fixed));
+ }
+ }
+}
+
}
#endif
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFenced.h b/Source/WebCore/rendering/mathml/RenderMathMLFenced.h
index 75324dcdc..987bb1343 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFenced.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFenced.h
@@ -41,9 +41,11 @@ public:
private:
virtual const char* renderName() const { return "RenderMathMLFenced"; }
- PassRefPtr<RenderStyle> createOperatorStyle();
+ RenderMathMLOperator* createMathMLOperator(UChar);
void makeFences();
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+
UChar m_open;
UChar m_close;
RefPtr<StringImpl> m_separators;
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
index 296548a2e..ffc4f1bc8 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
@@ -50,9 +50,19 @@ RenderMathMLFraction::RenderMathMLFraction(Element* element)
: RenderMathMLBlock(element)
, m_lineThickness(gLineMedium)
{
- setChildrenInline(false);
}
+void RenderMathMLFraction::fixChildStyle(RenderObject* child)
+{
+ ASSERT(child->isAnonymous() && child->style()->refCount() == 1);
+ child->style()->setTextAlign(CENTER);
+ Length pad(static_cast<int>(style()->fontSize() * gHorizontalPad), Fixed);
+ child->style()->setPaddingLeft(pad);
+ child->style()->setPaddingRight(pad);
+}
+
+// FIXME: It's cleaner to only call updateFromElement when an attribute has changed. Move parts
+// of this to fixChildStyle or other methods, and call them when needed.
void RenderMathMLFraction::updateFromElement()
{
// FIXME: mfrac where bevelled=true will need to reorganize the descendants
@@ -100,20 +110,21 @@ void RenderMathMLFraction::updateFromElement()
void RenderMathMLFraction::addChild(RenderObject* child, RenderObject* beforeChild)
{
- RenderBlock* row = createAlmostAnonymousBlock();
-
- row->style()->setTextAlign(CENTER);
- Length pad(static_cast<int>(style()->fontSize() * gHorizontalPad), Fixed);
- row->style()->setPaddingLeft(pad);
- row->style()->setPaddingRight(pad);
-
- // Only add padding for rows as denominators
- bool isNumerator = isEmpty();
- if (!isNumerator)
- row->style()->setPaddingTop(Length(2, Fixed));
+ RenderMathMLBlock* row = createAnonymousMathMLBlock();
RenderBlock::addChild(row, beforeChild);
row->addChild(child);
+
+ fixChildStyle(row);
+ updateFromElement();
+}
+
+void RenderMathMLFraction::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderMathMLBlock::styleDidChange(diff, oldStyle);
+
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling())
+ fixChildStyle(child);
updateFromElement();
}
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFraction.h b/Source/WebCore/rendering/mathml/RenderMathMLFraction.h
index 4756583b6..eedc7f356 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFraction.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFraction.h
@@ -47,6 +47,9 @@ protected:
virtual void layout();
private:
+ void fixChildStyle(RenderObject* child);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+
virtual const char* renderName() const { return "RenderMathMLFraction"; }
float m_lineThickness;
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp b/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
index 50f02be59..1160aa1cf 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
@@ -70,6 +70,14 @@ void RenderMathMLOperator::stretchToHeight(int height)
updateFromElement();
}
+void RenderMathMLOperator::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderMathMLBlock::styleDidChange(diff, oldStyle);
+
+ if (firstChild())
+ updateFromElement();
+}
+
void RenderMathMLOperator::computePreferredLogicalWidths()
{
ASSERT(preferredLogicalWidthsDirty());
@@ -150,6 +158,10 @@ int RenderMathMLOperator::lineHeightForCharacter(UChar character)
return gGlyphLineHeight;
}
+// FIXME: It's cleaner to only call updateFromElement when an attribute has changed. The body of
+// this method should probably be moved to a private stretchHeightChanged or checkStretchHeight
+// method. Probably at the same time, addChild/removeChild methods should be made to work for
+// dynamic DOM changes.
void RenderMathMLOperator::updateFromElement()
{
RenderObject* savedRenderer = node()->renderer();
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLOperator.h b/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
index 5adab8fd1..42ed2bee6 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
@@ -58,6 +58,8 @@ private:
int glyphHeightForCharacter(UChar);
int lineHeightForCharacter(UChar);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+
int m_stretchHeight;
bool m_isStacked;
UChar m_operator;
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h b/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h
index b0270efbb..cbb2c5706 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h
@@ -41,8 +41,6 @@ public:
private:
virtual const char* renderName() const { return "RenderMathMLSquareRoot"; }
-
- virtual bool createsAnonymousWrapper() const OVERRIDE { return true; }
};
}
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp b/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp
index 5342cbd84..da406003a 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp
@@ -63,6 +63,17 @@ RenderBoxModelObject* RenderMathMLSubSup::base() const
return toRenderBoxModelObject(base);
}
+void RenderMathMLSubSup::fixScriptsStyle()
+{
+ ASSERT(m_scripts && m_scripts->style()->refCount() == 1);
+ RenderStyle* scriptsStyle = m_scripts->style();
+ scriptsStyle->setVerticalAlign(TOP);
+ scriptsStyle->setMarginLeft(Length(gSubsupScriptMargin, Fixed));
+ scriptsStyle->setTextAlign(LEFT);
+ // Set this wrapper's font-size for its line-height & baseline position, for its children.
+ scriptsStyle->setBlendedFontSize(static_cast<int>(0.75 * style()->fontSize()));
+}
+
void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild)
{
// Note: The RenderMathMLBlock only allows element children to be added.
@@ -70,20 +81,14 @@ void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild
if (childElement && !childElement->previousElementSibling()) {
// Position 1 is always the base of the msub/msup/msubsup.
- RenderBlock* baseWrapper = createAlmostAnonymousBlock(INLINE_BLOCK);
+ RenderMathMLBlock* baseWrapper = createAnonymousMathMLBlock(INLINE_BLOCK);
RenderMathMLBlock::addChild(baseWrapper, firstChild());
baseWrapper->addChild(child);
// Make sure we have a script block for rendering.
if (m_kind == SubSup && !m_scripts) {
- RefPtr<RenderStyle> scriptsStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), INLINE_BLOCK);
- scriptsStyle->setVerticalAlign(TOP);
- scriptsStyle->setMarginLeft(Length(gSubsupScriptMargin, Fixed));
- scriptsStyle->setTextAlign(LEFT);
- // Set this wrapper's font-size for its line-height & baseline position.
- scriptsStyle->setBlendedFontSize(static_cast<int>(0.75 * style()->fontSize()));
- m_scripts = new (renderArena()) RenderMathMLBlock(node());
- m_scripts->setStyle(scriptsStyle);
+ m_scripts = createAnonymousMathMLBlock(INLINE_BLOCK);
+ fixScriptsStyle();
RenderMathMLBlock::addChild(m_scripts, beforeChild);
}
} else {
@@ -92,7 +97,7 @@ void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild
if (!childElement)
return;
- RenderBlock* script = m_scripts->createAlmostAnonymousBlock();
+ RenderMathMLBlock* script = m_scripts->createAnonymousMathMLBlock();
// The order is always backwards so the first script is the subscript and the superscript
// is last. That means the superscript is the first to render vertically.
@@ -108,6 +113,19 @@ void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild
}
}
+void RenderMathMLSubSup::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderMathMLBlock::styleDidChange(diff, oldStyle);
+
+ if (m_scripts) {
+ fixScriptsStyle();
+ for (RenderObject* script = m_scripts->firstChild(); script; script = script->nextSibling()) {
+ ASSERT(script->isAnonymous() && script->style()->refCount() == 1);
+ script->style()->inheritFrom(m_scripts->style());
+ }
+ }
+}
+
RenderMathMLOperator* RenderMathMLSubSup::unembellishedOperator()
{
RenderBoxModelObject* base = this->base();
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLSubSup.h b/Source/WebCore/rendering/mathml/RenderMathMLSubSup.h
index c88fe663b..f906d48ca 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLSubSup.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLSubSup.h
@@ -44,6 +44,9 @@ protected:
virtual void layout();
private:
+ void fixScriptsStyle();
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+
virtual const char* renderName() const { return "RenderMathMLSubSup"; }
// Omit our subscript and/or superscript. This may return 0 for a non-MathML base (which
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp
index 03c9c31ef..272032db6 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp
@@ -66,7 +66,7 @@ RenderBoxModelObject* RenderMathMLUnderOver::base() const
void RenderMathMLUnderOver::addChild(RenderObject* child, RenderObject* beforeChild)
{
- RenderBlock* row = createAnonymousBlock();
+ RenderMathMLBlock* row = createAnonymousMathMLBlock();
// look through the children for rendered elements counting the blocks so we know what child
// we are adding
@@ -84,7 +84,6 @@ void RenderMathMLUnderOver::addChild(RenderObject* child, RenderObject* beforeCh
break;
case 1:
// the under or over
- // FIXME: text-align: center does not work
row->style()->setTextAlign(CENTER);
if (m_kind == Over) {
// add the over as first
@@ -96,7 +95,6 @@ void RenderMathMLUnderOver::addChild(RenderObject* child, RenderObject* beforeCh
break;
case 2:
// the under or over
- // FIXME: text-align: center does not work
row->style()->setTextAlign(CENTER);
if (m_kind == UnderOver) {
// add the over as first
@@ -115,6 +113,18 @@ void RenderMathMLUnderOver::addChild(RenderObject* child, RenderObject* beforeCh
row->addChild(child);
}
+void RenderMathMLUnderOver::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderMathMLBlock::styleDidChange(diff, oldStyle);
+
+ RenderObject* base = this->base();
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ ASSERT(child->isAnonymous() && child->style()->refCount() == 1);
+ if (child->firstChild() != base)
+ child->style()->setTextAlign(CENTER);
+ }
+}
+
RenderMathMLOperator* RenderMathMLUnderOver::unembellishedOperator()
{
RenderBoxModelObject* base = this->base();
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h
index 3a4f70d76..b450689c9 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h
@@ -38,10 +38,13 @@ public:
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual RenderMathMLOperator* unembellishedOperator();
+
virtual void layout();
virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
private:
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+
virtual const char* renderName() const { return "RenderMathMLUnderOver"; }
// Omit our underscript and/or overscript. This may return 0 for a non-MathML base (which
diff --git a/Source/WebCore/rendering/style/KeyframeList.h b/Source/WebCore/rendering/style/KeyframeList.h
index fb352f9fd..5101b0689 100644
--- a/Source/WebCore/rendering/style/KeyframeList.h
+++ b/Source/WebCore/rendering/style/KeyframeList.h
@@ -62,9 +62,8 @@ private:
class KeyframeList {
public:
- KeyframeList(RenderObject* renderer, const AtomicString& animationName)
+ KeyframeList(RenderObject*, const AtomicString& animationName)
: m_animationName(animationName)
- , m_renderer(renderer)
{
insert(KeyframeValue(0, 0));
insert(KeyframeValue(1, 0));
@@ -92,7 +91,6 @@ private:
AtomicString m_animationName;
Vector<KeyframeValue> m_keyframes; // Kept sorted by key.
HashSet<CSSPropertyID> m_properties; // The properties being animated.
- RenderObject* m_renderer;
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp
index af6736704..36c5ed40e 100644
--- a/Source/WebCore/rendering/style/RenderStyle.cpp
+++ b/Source/WebCore/rendering/style/RenderStyle.cpp
@@ -139,7 +139,6 @@ ALWAYS_INLINE RenderStyle::RenderStyle(bool)
rareNonInheritedData.access()->m_gridItem.init();
rareInheritedData.init();
inherited.init();
-
#if ENABLE(SVG)
m_svgStyle.init();
#endif
@@ -162,9 +161,15 @@ ALWAYS_INLINE RenderStyle::RenderStyle(const RenderStyle& o)
{
}
-void RenderStyle::inheritFrom(const RenderStyle* inheritParent)
+void RenderStyle::inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary isAtShadowBoundary)
{
- rareInheritedData = inheritParent->rareInheritedData;
+ if (isAtShadowBoundary == AtShadowBoundary) {
+ // Even if surrounding content is user-editable, shadow DOM should act as a single unit, and not necessarily be editable
+ EUserModify currentUserModify = userModify();
+ rareInheritedData = inheritParent->rareInheritedData;
+ setUserModify(currentUserModify);
+ } else
+ rareInheritedData = inheritParent->rareInheritedData;
inherited = inheritParent->inherited;
inherited_flags = inheritParent->inherited_flags;
#if ENABLE(SVG)
@@ -396,6 +401,12 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
if (rareNonInheritedData->m_flexibleBox.get() != other->rareNonInheritedData->m_flexibleBox.get()
&& *rareNonInheritedData->m_flexibleBox.get() != *other->rareNonInheritedData->m_flexibleBox.get())
return StyleDifferenceLayout;
+ if (rareNonInheritedData->m_order != other->rareNonInheritedData->m_order
+ || rareNonInheritedData->m_alignContent != other->rareNonInheritedData->m_alignContent
+ || rareNonInheritedData->m_alignItems != other->rareNonInheritedData->m_alignItems
+ || rareNonInheritedData->m_alignSelf != other->rareNonInheritedData->m_alignSelf
+ || rareNonInheritedData->m_justifyContent != other->rareNonInheritedData->m_justifyContent)
+ return StyleDifferenceLayout;
// FIXME: We should add an optimized form of layout that just recomputes visual overflow.
if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get()))
@@ -461,6 +472,10 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
|| rareInheritedData->m_tabSize != other->rareInheritedData->m_tabSize
|| rareInheritedData->m_lineBoxContain != other->rareInheritedData->m_lineBoxContain
|| rareInheritedData->m_lineGrid != other->rareInheritedData->m_lineGrid
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ || rareInheritedData->m_imageResolutionSource != other->rareInheritedData->m_imageResolutionSource
+ || rareInheritedData->m_imageResolution != other->rareInheritedData->m_imageResolution
+#endif
|| rareInheritedData->m_lineSnap != other->rareInheritedData->m_lineSnap
|| rareInheritedData->m_lineAlign != other->rareInheritedData->m_lineAlign)
return StyleDifferenceLayout;
diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h
index 7b1127677..947c6075f 100644
--- a/Source/WebCore/rendering/style/RenderStyle.h
+++ b/Source/WebCore/rendering/style/RenderStyle.h
@@ -390,7 +390,12 @@ public:
static PassRefPtr<RenderStyle> createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay);
static PassRefPtr<RenderStyle> clone(const RenderStyle*);
- void inheritFrom(const RenderStyle* inheritParent);
+ enum IsAtShadowBoundary {
+ AtShadowBoundary,
+ NotAtShadowBoundary,
+ };
+
+ void inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary = NotAtShadowBoundary);
void copyNonInheritedFrom(const RenderStyle*);
PseudoId styleType() const { return static_cast<PseudoId>(noninherited_flags._styleType); }
@@ -402,6 +407,11 @@ public:
const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); }
+#if ENABLE(CSS_VARIABLES)
+ void setVariable(const AtomicString& name, const String& value) { rareInheritedData.access()->m_variables.access()->setVariable(name, value); }
+ const HashMap<AtomicString, String>* variables() { return &(rareInheritedData->m_variables->m_data); }
+#endif
+
bool affectedByHoverRules() const { return noninherited_flags.affectedByHover(); }
bool affectedByActiveRules() const { return noninherited_flags.affectedByActive(); }
bool affectedByDragRules() const { return noninherited_flags.affectedByDrag(); }
@@ -804,18 +814,18 @@ public:
EBoxOrient boxOrient() const { return static_cast<EBoxOrient>(rareNonInheritedData->m_deprecatedFlexibleBox->orient); }
EBoxPack boxPack() const { return static_cast<EBoxPack>(rareNonInheritedData->m_deprecatedFlexibleBox->pack); }
- int order() const { return rareNonInheritedData->m_order; }
- float positiveFlex() const { return rareNonInheritedData->m_flexibleBox->m_positiveFlex; }
- float negativeFlex() const { return rareNonInheritedData->m_flexibleBox->m_negativeFlex; }
- Length flexPreferredSize() const { return rareNonInheritedData->m_flexibleBox->m_preferredSize; }
- EFlexPack flexPack() const { return static_cast<EFlexPack>(rareNonInheritedData->m_flexibleBox->m_flexPack); }
+ float order() const { return rareNonInheritedData->m_order; }
+ float flexGrow() const { return rareNonInheritedData->m_flexibleBox->m_flexGrow; }
+ float flexShrink() const { return rareNonInheritedData->m_flexibleBox->m_flexShrink; }
+ Length flexBasis() const { return rareNonInheritedData->m_flexibleBox->m_flexBasis; }
+ EAlignContent alignContent() const { return static_cast<EAlignContent>(rareNonInheritedData->m_alignContent); }
EAlignItems alignItems() const { return static_cast<EAlignItems>(rareNonInheritedData->m_alignItems); }
EAlignItems alignSelf() const { return static_cast<EAlignItems>(rareNonInheritedData->m_alignSelf); }
EFlexDirection flexDirection() const { return static_cast<EFlexDirection>(rareNonInheritedData->m_flexibleBox->m_flexDirection); }
bool isColumnFlexDirection() const { return flexDirection() == FlowColumn || flexDirection() == FlowColumnReverse; }
bool isReverseFlexDirection() const { return flexDirection() == FlowRowReverse || flexDirection() == FlowColumnReverse; }
EFlexWrap flexWrap() const { return static_cast<EFlexWrap>(rareNonInheritedData->m_flexibleBox->m_flexWrap); }
- EFlexLinePack flexLinePack() const { return static_cast<EFlexLinePack>(rareNonInheritedData->m_flexibleBox->m_flexLinePack); }
+ EJustifyContent justifyContent() const { return static_cast<EJustifyContent>(rareNonInheritedData->m_justifyContent); }
const Vector<Length>& gridColumns() const { return rareNonInheritedData->m_grid->m_gridColumns; }
const Vector<Length>& gridRows() const { return rareNonInheritedData->m_grid->m_gridRows; }
@@ -830,7 +840,9 @@ public:
void getBoxShadowInlineDirectionExtent(LayoutUnit& logicalLeft, LayoutUnit& logicalRight) { getShadowInlineDirectionExtent(boxShadow(), logicalLeft, logicalRight); }
void getBoxShadowBlockDirectionExtent(LayoutUnit& logicalTop, LayoutUnit& logicalBottom) { getShadowBlockDirectionExtent(boxShadow(), logicalTop, logicalBottom); }
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
EBoxDecorationBreak boxDecorationBreak() const { return m_box->boxDecorationBreak(); }
+#endif
StyleReflection* boxReflect() const { return rareNonInheritedData->m_boxReflect.get(); }
EBoxSizing boxSizing() const { return m_box->boxSizing(); }
Length marqueeIncrement() const { return rareNonInheritedData->m_marquee->increment; }
@@ -848,7 +860,6 @@ public:
EWordWrap wordWrap() const { return static_cast<EWordWrap>(rareInheritedData->wordWrap); }
ENBSPMode nbspMode() const { return static_cast<ENBSPMode>(rareInheritedData->nbspMode); }
EKHTMLLineBreak khtmlLineBreak() const { return static_cast<EKHTMLLineBreak>(rareInheritedData->khtmlLineBreak); }
- EMatchNearestMailBlockquoteColor matchNearestMailBlockquoteColor() const { return static_cast<EMatchNearestMailBlockquoteColor>(rareNonInheritedData->matchNearestMailBlockquoteColor); }
const AtomicString& highlight() const { return rareInheritedData->highlight; }
Hyphens hyphens() const { return static_cast<Hyphens>(rareInheritedData->hyphens); }
short hyphenationLimitBefore() const { return rareInheritedData->hyphenationLimitBefore; }
@@ -863,6 +874,7 @@ public:
ColumnAxis axis = columnAxis();
return axis == AutoColumnAxis || isHorizontalWritingMode() == (axis == HorizontalColumnAxis);
}
+ ColumnProgression columnProgression() const { return static_cast<ColumnProgression>(rareNonInheritedData->m_multiCol->m_progression); }
float columnWidth() const { return rareNonInheritedData->m_multiCol->m_width; }
bool hasAutoColumnWidth() const { return rareNonInheritedData->m_multiCol->m_autoWidth; }
unsigned short columnCount() const { return rareNonInheritedData->m_multiCol->m_count; }
@@ -968,6 +980,11 @@ public:
bool isFlippedBlocksWritingMode() const { return writingMode() == RightToLeftWritingMode || writingMode() == BottomToTopWritingMode; }
EImageRendering imageRendering() const { return static_cast<EImageRendering>(rareInheritedData->m_imageRendering); }
+
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ ImageResolutionSource imageResolutionSource() const { return static_cast<ImageResolutionSource>(rareInheritedData->m_imageResolutionSource); }
+ float imageResolution() const { return rareInheritedData->m_imageResolution; }
+#endif
ESpeak speak() const { return static_cast<ESpeak>(rareInheritedData->speak); }
@@ -1135,6 +1152,11 @@ public:
bool setEffectiveZoom(float);
void setImageRendering(EImageRendering v) { SET_VAR(rareInheritedData, m_imageRendering, v) }
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ void setImageResolutionSource(ImageResolutionSource v) { SET_VAR(rareInheritedData, m_imageResolutionSource, v) }
+ void setImageResolution(float f) { SET_VAR(rareInheritedData, m_imageResolution, f) }
+#endif
+
void setWhiteSpace(EWhiteSpace v) { inherited_flags._white_space = v; }
void setWordSpacing(int v) { inherited.access()->font.setWordSpacing(v); }
@@ -1235,7 +1257,9 @@ public:
void setAppearance(ControlPart a) { SET_VAR(rareNonInheritedData, m_appearance, a); }
// For valid values of box-align see http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/#alignment
void setBoxAlign(EBoxAlignment a) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, align, a); }
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
void setBoxDecorationBreak(EBoxDecorationBreak b) { SET_VAR(m_box, m_boxDecorationBreak, b); }
+#endif
void setBoxDirection(EBoxDirection d) { inherited_flags._box_direction = d; }
void setBoxFlex(float f) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, flex, f); }
void setBoxFlexGroup(unsigned int fg) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, flex_group, fg); }
@@ -1246,16 +1270,16 @@ public:
void setBoxShadow(PassOwnPtr<ShadowData>, bool add = false);
void setBoxReflect(PassRefPtr<StyleReflection> reflect) { if (rareNonInheritedData->m_boxReflect != reflect) rareNonInheritedData.access()->m_boxReflect = reflect; }
void setBoxSizing(EBoxSizing s) { SET_VAR(m_box, m_boxSizing, s); }
- void setPositiveFlex(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_positiveFlex, f); }
- void setNegativeFlex(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_negativeFlex, f); }
- void setFlexPreferredSize(Length l) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_preferredSize, l); }
- void setOrder(int o) { SET_VAR(rareNonInheritedData, m_order, o); }
- void setFlexPack(EFlexPack p) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexPack, p); }
+ void setFlexGrow(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexGrow, f); }
+ void setFlexShrink(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexShrink, f); }
+ void setFlexBasis(Length length) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexBasis, length); }
+ void setOrder(float o) { SET_VAR(rareNonInheritedData, m_order, o); }
+ void setAlignContent(EAlignContent p) { SET_VAR(rareNonInheritedData, m_alignContent, p); }
void setAlignItems(EAlignItems a) { SET_VAR(rareNonInheritedData, m_alignItems, a); }
void setAlignSelf(EAlignItems a) { SET_VAR(rareNonInheritedData, m_alignSelf, a); }
void setFlexDirection(EFlexDirection direction) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexDirection, direction); }
void setFlexWrap(EFlexWrap w) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexWrap, w); }
- void setFlexLinePack(EFlexLinePack p) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexLinePack, p); }
+ void setJustifyContent(EJustifyContent p) { SET_VAR(rareNonInheritedData, m_justifyContent, p); }
void setGridColumns(const Vector<Length>& lengths) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridColumns, lengths); }
void setGridRows(const Vector<Length>& lengths) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridRows, lengths); }
void setGridItemColumn(const Length& columnPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridColumn, columnPosition); }
@@ -1276,7 +1300,6 @@ public:
void setWordWrap(EWordWrap b) { SET_VAR(rareInheritedData, wordWrap, b); }
void setNBSPMode(ENBSPMode b) { SET_VAR(rareInheritedData, nbspMode, b); }
void setKHTMLLineBreak(EKHTMLLineBreak b) { SET_VAR(rareInheritedData, khtmlLineBreak, b); }
- void setMatchNearestMailBlockquoteColor(EMatchNearestMailBlockquoteColor c) { SET_VAR(rareNonInheritedData, matchNearestMailBlockquoteColor, c); }
void setHighlight(const AtomicString& h) { SET_VAR(rareInheritedData, highlight, h); }
void setHyphens(Hyphens h) { SET_VAR(rareInheritedData, hyphens, h); }
void setHyphenationLimitBefore(short limit) { SET_VAR(rareInheritedData, hyphenationLimitBefore, limit); }
@@ -1287,6 +1310,7 @@ public:
void setBorderFit(EBorderFit b) { SET_VAR(rareNonInheritedData, m_borderFit, b); }
void setResize(EResize r) { SET_VAR(rareInheritedData, resize, r); }
void setColumnAxis(ColumnAxis axis) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_axis, axis); }
+ void setColumnProgression(ColumnProgression progression) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_progression, progression); }
void setColumnWidth(float f) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoWidth, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_width, f); }
void setHasAutoColumnWidth() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoWidth, true); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_width, 0); }
void setColumnCount(unsigned short c) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoCount, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_count, c); }
@@ -1526,6 +1550,7 @@ public:
static EClear initialClear() { return CNONE; }
static ColorSpace initialColorSpace() { return ColorSpaceDeviceRGB; }
static ColumnAxis initialColumnAxis() { return AutoColumnAxis; }
+ static ColumnProgression initialColumnProgression() { return NormalColumnProgression; }
static TextDirection initialDirection() { return LTR; }
static WritingMode initialWritingMode() { return TopToBottomWritingMode; }
static TextCombine initialTextCombine() { return TextCombineNone; }
@@ -1564,7 +1589,7 @@ public:
static short initialWidows() { return 2; }
static short initialOrphans() { return 2; }
static Length initialLineHeight() { return Length(-100.0, Percent); }
- static ETextAlign initialTextAlign() { return TAAUTO; }
+ static ETextAlign initialTextAlign() { return TASTART; }
static ETextDecoration initialTextDecoration() { return TDNONE; }
static float initialZoom() { return 1.0f; }
static int initialOutlineOffset() { return 0; }
@@ -1580,16 +1605,16 @@ public:
static unsigned int initialBoxOrdinalGroup() { return 1; }
static EBoxSizing initialBoxSizing() { return CONTENT_BOX; }
static StyleReflection* initialBoxReflect() { return 0; }
- static float initialPositiveFlex() { return 1; }
- static float initialNegativeFlex() { return 1; }
- static Length initialFlexPreferredSize() { return Length(Auto); }
- static int initialOrder() { return 0; }
- static EFlexPack initialFlexPack() { return PackStart; }
+ static float initialFlexGrow() { return 0; }
+ static float initialFlexShrink() { return 1; }
+ static Length initialFlexBasis() { return Length(Auto); }
+ static float initialOrder() { return 0; }
+ static EAlignContent initialAlignContent() { return AlignContentStretch; }
static EAlignItems initialAlignItems() { return AlignStretch; }
static EAlignItems initialAlignSelf() { return AlignAuto; }
static EFlexDirection initialFlexDirection() { return FlowRow; }
static EFlexWrap initialFlexWrap() { return FlexWrapNone; }
- static EFlexLinePack initialFlexLinePack() { return LinePackStretch; }
+ static EJustifyContent initialJustifyContent() { return JustifyFlexStart; }
static int initialMarqueeLoopCount() { return -1; }
static int initialMarqueeSpeed() { return 85; }
static Length initialMarqueeIncrement() { return Length(6, Fixed); }
@@ -1605,7 +1630,6 @@ public:
static EWordWrap initialWordWrap() { return NormalWordWrap; }
static ENBSPMode initialNBSPMode() { return NBNORMAL; }
static EKHTMLLineBreak initialKHTMLLineBreak() { return LBNORMAL; }
- static EMatchNearestMailBlockquoteColor initialMatchNearestMailBlockquoteColor() { return BCNORMAL; }
static const AtomicString& initialHighlight() { return nullAtom; }
static ESpeak initialSpeak() { return SpeakNormal; }
static Hyphens initialHyphens() { return HyphensManual; }
@@ -1642,6 +1666,8 @@ public:
static TextEmphasisPosition initialTextEmphasisPosition() { return TextEmphasisPositionOver; }
static LineBoxContain initialLineBoxContain() { return LineBoxContainBlock | LineBoxContainInline | LineBoxContainReplaced; }
static EImageRendering initialImageRendering() { return ImageRenderingAuto; }
+ static ImageResolutionSource initialImageResolutionSource() { return ImageResolutionSpecified; }
+ static float initialImageResolution() { return 1; }
static StyleImage* initialBorderImageSource() { return 0; }
static StyleImage* initialMaskBoxImageSource() { return 0; }
static PrintColorAdjust initialPrintColorAdjust() { return PrintColorAdjustEconomy; }
diff --git a/Source/WebCore/rendering/style/RenderStyleConstants.h b/Source/WebCore/rendering/style/RenderStyleConstants.h
index 73e819489..1a5a57c70 100644
--- a/Source/WebCore/rendering/style/RenderStyleConstants.h
+++ b/Source/WebCore/rendering/style/RenderStyleConstants.h
@@ -173,11 +173,11 @@ enum EBoxDirection { BNORMAL, BREVERSE };
// CSS3 Flexbox Properties
-enum EAlignItems { AlignAuto, AlignStart, AlignEnd, AlignCenter, AlignStretch, AlignBaseline };
-enum EFlexPack { PackStart, PackEnd, PackCenter, PackSpaceBetween, PackSpaceAround };
+enum EAlignContent { AlignContentFlexStart, AlignContentFlexEnd, AlignContentCenter, AlignContentSpaceBetween, AlignContentSpaceAround, AlignContentStretch };
+enum EAlignItems { AlignAuto, AlignFlexStart, AlignFlexEnd, AlignCenter, AlignStretch, AlignBaseline };
enum EFlexDirection { FlowRow, FlowRowReverse, FlowColumn, FlowColumnReverse };
-enum EFlexLinePack { LinePackStart, LinePackEnd, LinePackCenter, LinePackSpaceBetween, LinePackSpaceAround, LinePackStretch };
enum EFlexWrap { FlexWrapNone, FlexWrap, FlexWrapReverse };
+enum EJustifyContent { JustifyFlexStart, JustifyFlexEnd, JustifyCenter, JustifySpaceBetween, JustifySpaceAround };
enum ETextSecurity {
TSNONE, TSDISC, TSCIRCLE, TSSQUARE
@@ -219,10 +219,6 @@ enum EKHTMLLineBreak {
LBNORMAL, AFTER_WHITE_SPACE
};
-enum EMatchNearestMailBlockquoteColor {
- BCNORMAL, MATCH
-};
-
enum EResize {
RESIZE_NONE, RESIZE_BOTH, RESIZE_HORIZONTAL, RESIZE_VERTICAL
};
@@ -335,7 +331,7 @@ enum EWhiteSpace {
// The order of this enum must match the order of the text align values in CSSValueKeywords.in.
enum ETextAlign {
- TAAUTO, LEFT, RIGHT, CENTER, JUSTIFY, WEBKIT_LEFT, WEBKIT_RIGHT, WEBKIT_CENTER, TASTART, TAEND,
+ LEFT, RIGHT, CENTER, JUSTIFY, WEBKIT_LEFT, WEBKIT_RIGHT, WEBKIT_CENTER, TASTART, TAEND,
};
enum ETextTransform {
@@ -454,12 +450,16 @@ enum TextOverflow { TextOverflowClip = 0, TextOverflowEllipsis };
enum EImageRendering { ImageRenderingAuto, ImageRenderingOptimizeSpeed, ImageRenderingOptimizeQuality, ImageRenderingOptimizeContrast };
+enum ImageResolutionSource { ImageResolutionSpecified = 0, ImageResolutionFromImage };
+
enum Order { LogicalOrder = 0, VisualOrder };
enum RegionOverflow { AutoRegionOverflow, BreakRegionOverflow };
enum ColumnAxis { HorizontalColumnAxis, VerticalColumnAxis, AutoColumnAxis };
+enum ColumnProgression { NormalColumnProgression, ReverseColumnProgression };
+
enum LineSnap { LineSnapNone, LineSnapBaseline, LineSnapContain };
enum LineAlign { LineAlignNone, LineAlignEdges };
diff --git a/Source/WebCore/rendering/style/StyleBoxData.cpp b/Source/WebCore/rendering/style/StyleBoxData.cpp
index fb9655c21..3fc00c8dc 100644
--- a/Source/WebCore/rendering/style/StyleBoxData.cpp
+++ b/Source/WebCore/rendering/style/StyleBoxData.cpp
@@ -27,6 +27,14 @@
namespace WebCore {
+struct SameSizeAsStyleBoxData : public RefCounted<SameSizeAsStyleBoxData> {
+ Length length[7];
+ int m_zIndex;
+ uint32_t bitfields;
+};
+
+COMPILE_ASSERT(sizeof(StyleBoxData) == sizeof(SameSizeAsStyleBoxData), StyleBoxData_should_not_grow);
+
StyleBoxData::StyleBoxData()
: m_minWidth(RenderStyle::initialMinSize())
, m_maxWidth(RenderStyle::initialMaxSize())
@@ -35,7 +43,9 @@ StyleBoxData::StyleBoxData()
, m_zIndex(0)
, m_hasAutoZIndex(true)
, m_boxSizing(CONTENT_BOX)
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
, m_boxDecorationBreak(DSLICE)
+#endif
{
}
@@ -51,7 +61,9 @@ StyleBoxData::StyleBoxData(const StyleBoxData& o)
, m_zIndex(o.m_zIndex)
, m_hasAutoZIndex(o.m_hasAutoZIndex)
, m_boxSizing(o.m_boxSizing)
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
, m_boxDecorationBreak(o.m_boxDecorationBreak)
+#endif
{
}
@@ -67,7 +79,10 @@ bool StyleBoxData::operator==(const StyleBoxData& o) const
&& m_zIndex == o.m_zIndex
&& m_hasAutoZIndex == o.m_hasAutoZIndex
&& m_boxSizing == o.m_boxSizing
- && m_boxDecorationBreak == o.m_boxDecorationBreak;
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
+ && m_boxDecorationBreak == o.m_boxDecorationBreak
+#endif
+ ;
}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/style/StyleBoxData.h b/Source/WebCore/rendering/style/StyleBoxData.h
index 2984d176b..86fd6e922 100644
--- a/Source/WebCore/rendering/style/StyleBoxData.h
+++ b/Source/WebCore/rendering/style/StyleBoxData.h
@@ -58,7 +58,9 @@ public:
bool hasAutoZIndex() const { return m_hasAutoZIndex; }
EBoxSizing boxSizing() const { return static_cast<EBoxSizing>(m_boxSizing); }
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
EBoxDecorationBreak boxDecorationBreak() const { return static_cast<EBoxDecorationBreak>(m_boxDecorationBreak); }
+#endif
private:
friend class RenderStyle;
@@ -78,9 +80,11 @@ private:
Length m_verticalAlign;
int m_zIndex;
- bool m_hasAutoZIndex : 1;
+ unsigned m_hasAutoZIndex : 1;
unsigned m_boxSizing : 1; // EBoxSizing
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
unsigned m_boxDecorationBreak : 1; // EBoxDecorationBreak
+#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/style/StyleCachedImage.cpp b/Source/WebCore/rendering/style/StyleCachedImage.cpp
index a7a1996fa..2e3abb943 100644
--- a/Source/WebCore/rendering/style/StyleCachedImage.cpp
+++ b/Source/WebCore/rendering/style/StyleCachedImage.cpp
@@ -97,7 +97,7 @@ void StyleCachedImage::addClient(RenderObject* renderer)
void StyleCachedImage::removeClient(RenderObject* renderer)
{
- m_image->removeClientForRenderer(renderer);
+ m_image->removeClient(renderer);
}
PassRefPtr<Image> StyleCachedImage::image(RenderObject* renderer, const IntSize&) const
diff --git a/Source/WebCore/rendering/style/StyleCachedImageSet.cpp b/Source/WebCore/rendering/style/StyleCachedImageSet.cpp
index f5071d169..c0a9f5e2f 100644
--- a/Source/WebCore/rendering/style/StyleCachedImageSet.cpp
+++ b/Source/WebCore/rendering/style/StyleCachedImageSet.cpp
@@ -108,7 +108,7 @@ void StyleCachedImageSet::addClient(RenderObject* renderer)
void StyleCachedImageSet::removeClient(RenderObject* renderer)
{
- m_bestFitImage->removeClientForRenderer(renderer);
+ m_bestFitImage->removeClient(renderer);
}
PassRefPtr<Image> StyleCachedImageSet::image(RenderObject* renderer, const IntSize&) const
diff --git a/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp b/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp
index 53d7270cb..a7cfac1ed 100644
--- a/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp
+++ b/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp
@@ -31,33 +31,28 @@
namespace WebCore {
StyleFlexibleBoxData::StyleFlexibleBoxData()
- : m_positiveFlex(RenderStyle::initialPositiveFlex())
- , m_negativeFlex(RenderStyle::initialNegativeFlex())
- , m_preferredSize(RenderStyle::initialFlexPreferredSize())
- , m_flexPack(RenderStyle::initialFlexPack())
+ : m_flexGrow(RenderStyle::initialFlexGrow())
+ , m_flexShrink(RenderStyle::initialFlexShrink())
+ , m_flexBasis(RenderStyle::initialFlexBasis())
, m_flexDirection(RenderStyle::initialFlexDirection())
, m_flexWrap(RenderStyle::initialFlexWrap())
- , m_flexLinePack(RenderStyle::initialFlexLinePack())
{
}
StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o)
: RefCounted<StyleFlexibleBoxData>()
- , m_positiveFlex(o.m_positiveFlex)
- , m_negativeFlex(o.m_negativeFlex)
- , m_preferredSize(o.m_preferredSize)
- , m_flexPack(o.m_flexPack)
+ , m_flexGrow(o.m_flexGrow)
+ , m_flexShrink(o.m_flexShrink)
+ , m_flexBasis(o.m_flexBasis)
, m_flexDirection(o.m_flexDirection)
, m_flexWrap(o.m_flexWrap)
- , m_flexLinePack(o.m_flexLinePack)
{
}
bool StyleFlexibleBoxData::operator==(const StyleFlexibleBoxData& o) const
{
- return m_positiveFlex == o.m_positiveFlex && m_negativeFlex == o.m_negativeFlex && m_preferredSize == o.m_preferredSize
- && m_flexPack == o.m_flexPack && m_flexDirection == o.m_flexDirection
- && m_flexWrap == o.m_flexWrap && m_flexLinePack == o.m_flexLinePack;
+ return m_flexGrow == o.m_flexGrow && m_flexShrink == o.m_flexShrink && m_flexBasis == o.m_flexBasis
+ && m_flexDirection == o.m_flexDirection && m_flexWrap == o.m_flexWrap;
}
}
diff --git a/Source/WebCore/rendering/style/StyleFlexibleBoxData.h b/Source/WebCore/rendering/style/StyleFlexibleBoxData.h
index 5eab784dc..6c070d551 100644
--- a/Source/WebCore/rendering/style/StyleFlexibleBoxData.h
+++ b/Source/WebCore/rendering/style/StyleFlexibleBoxData.h
@@ -44,14 +44,12 @@ public:
return !(*this == o);
}
- float m_positiveFlex;
- float m_negativeFlex;
- Length m_preferredSize;
+ float m_flexGrow;
+ float m_flexShrink;
+ Length m_flexBasis;
- unsigned m_flexPack : 3; // EFlexPack
unsigned m_flexDirection : 2; // EFlexDirection
unsigned m_flexWrap : 2; // EFlexWrap
- unsigned m_flexLinePack : 3; // EFlexLinePack
private:
StyleFlexibleBoxData();
diff --git a/Source/WebCore/rendering/style/StyleMultiColData.cpp b/Source/WebCore/rendering/style/StyleMultiColData.cpp
index 96327ff8c..610277c20 100644
--- a/Source/WebCore/rendering/style/StyleMultiColData.cpp
+++ b/Source/WebCore/rendering/style/StyleMultiColData.cpp
@@ -38,6 +38,7 @@ StyleMultiColData::StyleMultiColData()
, m_breakAfter(RenderStyle::initialPageBreak())
, m_breakInside(RenderStyle::initialPageBreak())
, m_axis(RenderStyle::initialColumnAxis())
+ , m_progression(RenderStyle::initialColumnProgression())
{
}
@@ -56,6 +57,7 @@ StyleMultiColData::StyleMultiColData(const StyleMultiColData& o)
, m_breakAfter(o.m_breakAfter)
, m_breakInside(o.m_breakInside)
, m_axis(o.m_axis)
+ , m_progression(o.m_progression)
{
}
@@ -64,7 +66,8 @@ bool StyleMultiColData::operator==(const StyleMultiColData& o) const
return m_width == o.m_width && m_count == o.m_count && m_gap == o.m_gap
&& m_rule == o.m_rule && m_visitedLinkColumnRuleColor == o.m_visitedLinkColumnRuleColor && m_breakBefore == o.m_breakBefore
&& m_autoWidth == o.m_autoWidth && m_autoCount == o.m_autoCount && m_normalGap == o.m_normalGap
- && m_columnSpan == o.m_columnSpan && m_breakAfter == o.m_breakAfter && m_breakInside == o.m_breakInside && m_axis == o.m_axis;
+ && m_columnSpan == o.m_columnSpan && m_breakAfter == o.m_breakAfter && m_breakInside == o.m_breakInside && m_axis == o.m_axis
+ && m_progression == o.m_progression;
}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/style/StyleMultiColData.h b/Source/WebCore/rendering/style/StyleMultiColData.h
index 99300834c..888ae6d56 100644
--- a/Source/WebCore/rendering/style/StyleMultiColData.h
+++ b/Source/WebCore/rendering/style/StyleMultiColData.h
@@ -67,6 +67,7 @@ public:
unsigned m_breakAfter : 2; // EPageBreak
unsigned m_breakInside : 2; // EPageBreak
unsigned m_axis : 2; // ColumnAxis
+ unsigned m_progression : 2; // ColumnProgression
private:
StyleMultiColData();
diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
index 9918e0ede..7fe609c21 100644
--- a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
@@ -30,6 +30,35 @@
namespace WebCore {
+struct SameSizeAsStyleRareInheritedData : public RefCounted<SameSizeAsStyleRareInheritedData> {
+ Color firstColor;
+ float firstFloat;
+ Color colors[5];
+ void* ownPtrs[1];
+ AtomicString atomicStrings[5];
+ void* refPtrs[2];
+ Length lengths[1];
+ float secondFloat;
+ unsigned m_bitfields[2];
+ short pagedMediaShorts[2];
+ unsigned unsigneds[1];
+ short hyphenationShorts[3];
+
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ float imageResolutionFloats;
+#endif
+
+#if ENABLE(TOUCH_EVENTS)
+ Color touchColors;
+#endif
+
+#if ENABLE(CSS_VARIABLES)
+ void* variableDataRefs[1];
+#endif
+};
+
+COMPILE_ASSERT(sizeof(StyleRareInheritedData) == sizeof(SameSizeAsStyleRareInheritedData), StyleRareInheritedData_should_bit_pack);
+
StyleRareInheritedData::StyleRareInheritedData()
: textStrokeWidth(RenderStyle::initialTextStrokeWidth())
, indent(RenderStyle::initialTextIndent())
@@ -58,15 +87,24 @@ StyleRareInheritedData::StyleRareInheritedData()
#if ENABLE(OVERFLOW_SCROLLING)
, useTouchOverflowScrolling(RenderStyle::initialUseTouchOverflowScrolling())
#endif
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ , m_imageResolutionSource(RenderStyle::initialImageResolutionSource())
+#endif
, hyphenationLimitBefore(-1)
, hyphenationLimitAfter(-1)
, hyphenationLimitLines(-1)
, m_lineGrid(RenderStyle::initialLineGrid())
, m_tabSize(RenderStyle::initialTabSize())
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ , m_imageResolution(RenderStyle::initialImageResolution())
+#endif
#if ENABLE(TOUCH_EVENTS)
, tapHighlightColor(RenderStyle::initialTapHighlightColor())
#endif
{
+#if ENABLE(CSS_VARIABLES)
+ m_variables.init();
+#endif
}
StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
@@ -107,6 +145,9 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
#if ENABLE(OVERFLOW_SCROLLING)
, useTouchOverflowScrolling(o.useTouchOverflowScrolling)
#endif
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ , m_imageResolutionSource(o.m_imageResolutionSource)
+#endif
, hyphenationString(o.hyphenationString)
, hyphenationLimitBefore(o.hyphenationLimitBefore)
, hyphenationLimitAfter(o.hyphenationLimitAfter)
@@ -115,9 +156,15 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
, textEmphasisCustomMark(o.textEmphasisCustomMark)
, m_lineGrid(o.m_lineGrid)
, m_tabSize(o.m_tabSize)
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ , m_imageResolution(o.m_imageResolution)
+#endif
#if ENABLE(TOUCH_EVENTS)
, tapHighlightColor(o.tapHighlightColor)
#endif
+#if ENABLE(CSS_VARIABLES)
+ , m_variables(o.m_variables)
+#endif
{
}
@@ -182,7 +229,14 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
&& m_tabSize == o.m_tabSize
&& m_lineGrid == o.m_lineGrid
&& m_imageRendering == o.m_imageRendering
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ && m_imageResolutionSource == o.m_imageResolutionSource
+ && m_imageResolution == o.m_imageResolution
+#endif
&& m_lineSnap == o.m_lineSnap
+#if ENABLE(CSS_VARIABLES)
+ && m_variables == o.m_variables
+#endif
&& m_lineAlign == o.m_lineAlign;
}
diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.h b/Source/WebCore/rendering/style/StyleRareInheritedData.h
index df8879a11..5891af98f 100644
--- a/Source/WebCore/rendering/style/StyleRareInheritedData.h
+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.h
@@ -31,6 +31,11 @@
#include <wtf/PassRefPtr.h>
#include <wtf/text/AtomicString.h>
+#if ENABLE(CSS_VARIABLES)
+#include "DataRef.h"
+#include "StyleVariableData.h"
+#endif
+
namespace WebCore {
class CursorList;
@@ -79,7 +84,7 @@ public:
unsigned wordWrap : 1; // EWordWrap
unsigned nbspMode : 1; // ENBSPMode
unsigned khtmlLineBreak : 1; // EKHTMLLineBreak
- bool textSizeAdjust : 1; // An Apple extension.
+ unsigned textSizeAdjust : 1; // An Apple extension.
unsigned resize : 2; // EResize
unsigned userSelect : 1; // EUserSelect
unsigned colorSpace : 1; // ColorSpace
@@ -96,6 +101,9 @@ public:
#if ENABLE(OVERFLOW_SCROLLING)
unsigned useTouchOverflowScrolling: 1;
#endif
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ unsigned m_imageResolutionSource : 1; // ImageResolutionSource
+#endif
AtomicString hyphenationString;
short hyphenationLimitBefore;
@@ -110,10 +118,18 @@ public:
AtomicString m_lineGrid;
unsigned m_tabSize;
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+ float m_imageResolution;
+#endif
+
#if ENABLE(TOUCH_EVENTS)
Color tapHighlightColor;
#endif
+#if ENABLE(CSS_VARIABLES)
+ DataRef<StyleVariableData> m_variables;
+#endif
+
private:
StyleRareInheritedData();
StyleRareInheritedData(const StyleRareInheritedData&);
diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp
index b4c045619..22b3272e8 100644
--- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp
+++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp
@@ -60,13 +60,14 @@ StyleRareNonInheritedData::StyleRareNonInheritedData()
, m_pageSizeType(PAGE_SIZE_AUTO)
, m_transformStyle3D(RenderStyle::initialTransformStyle3D())
, m_backfaceVisibility(RenderStyle::initialBackfaceVisibility())
+ , m_alignContent(RenderStyle::initialAlignContent())
, m_alignItems(RenderStyle::initialAlignItems())
, m_alignSelf(RenderStyle::initialAlignSelf())
+ , m_justifyContent(RenderStyle::initialJustifyContent())
, userDrag(RenderStyle::initialUserDrag())
, textOverflow(RenderStyle::initialTextOverflow())
, marginBeforeCollapse(MCOLLAPSE)
, marginAfterCollapse(MCOLLAPSE)
- , matchNearestMailBlockquoteColor(RenderStyle::initialMatchNearestMailBlockquoteColor())
, m_appearance(RenderStyle::initialAppearance())
, m_borderFit(RenderStyle::initialBorderFit())
, m_textCombine(RenderStyle::initialTextCombine())
@@ -130,13 +131,14 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited
, m_pageSizeType(o.m_pageSizeType)
, m_transformStyle3D(o.m_transformStyle3D)
, m_backfaceVisibility(o.m_backfaceVisibility)
+ , m_alignContent(o.m_alignContent)
, m_alignItems(o.m_alignItems)
, m_alignSelf(o.m_alignSelf)
+ , m_justifyContent(o.m_justifyContent)
, userDrag(o.userDrag)
, textOverflow(o.textOverflow)
, marginBeforeCollapse(o.marginBeforeCollapse)
, marginAfterCollapse(o.marginAfterCollapse)
- , matchNearestMailBlockquoteColor(o.matchNearestMailBlockquoteColor)
, m_appearance(o.m_appearance)
, m_borderFit(o.m_borderFit)
, m_textCombine(o.m_textCombine)
@@ -206,13 +208,14 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
&& m_pageSizeType == o.m_pageSizeType
&& m_transformStyle3D == o.m_transformStyle3D
&& m_backfaceVisibility == o.m_backfaceVisibility
+ && m_alignContent == o.m_alignContent
&& m_alignItems == o.m_alignItems
&& m_alignSelf == o.m_alignSelf
+ && m_justifyContent == o.m_justifyContent
&& userDrag == o.userDrag
&& textOverflow == o.textOverflow
&& marginBeforeCollapse == o.marginBeforeCollapse
&& marginAfterCollapse == o.marginAfterCollapse
- && matchNearestMailBlockquoteColor == o.matchNearestMailBlockquoteColor
&& m_appearance == o.m_appearance
&& m_borderFit == o.m_borderFit
&& m_textCombine == o.m_textCombine
diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h
index 494bb8d20..94c4c8dfb 100644
--- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h
+++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h
@@ -146,7 +146,7 @@ public:
Color m_visitedLinkBorderTopColor;
Color m_visitedLinkBorderBottomColor;
- int m_order;
+ float m_order;
AtomicString m_flowThread;
AtomicString m_regionThread;
@@ -160,14 +160,15 @@ public:
unsigned m_transformStyle3D : 1; // ETransformStyle3D
unsigned m_backfaceVisibility : 1; // EBackfaceVisibility
+ unsigned m_alignContent : 3; // EAlignContent
unsigned m_alignItems : 3; // EAlignItems
unsigned m_alignSelf : 3; // EAlignItems
+ unsigned m_justifyContent : 3; // EJustifyContent
unsigned userDrag : 2; // EUserDrag
unsigned textOverflow : 1; // Whether or not lines that spill out should be truncated with "..."
unsigned marginBeforeCollapse : 2; // EMarginCollapse
unsigned marginAfterCollapse : 2; // EMarginCollapse
- unsigned matchNearestMailBlockquoteColor : 1; // EMatchNearestMailBlockquoteColor, FIXME: This property needs to be eliminated. It should never have been added.
unsigned m_appearance : 6; // EAppearance
unsigned m_borderFit : 1; // EBorderFit
unsigned m_textCombine : 1; // CSS3 text-combine properties
diff --git a/Source/WebCore/rendering/style/StyleVariableData.h b/Source/WebCore/rendering/style/StyleVariableData.h
new file mode 100644
index 000000000..bb45989f1
--- /dev/null
+++ b/Source/WebCore/rendering/style/StyleVariableData.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 StyleVariableData_h
+#define StyleVariableData_h
+#if ENABLE(CSS_VARIABLES)
+
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/AtomicStringHash.h>
+
+namespace WebCore {
+
+class CursorList;
+class QuotesData;
+class ShadowData;
+
+class StyleVariableData : public RefCounted<StyleVariableData> {
+public:
+ static PassRefPtr<StyleVariableData> create() { return adoptRef(new StyleVariableData()); }
+ PassRefPtr<StyleVariableData> copy() const { return adoptRef(new StyleVariableData(*this)); }
+
+ bool operator==(const StyleVariableData& other) const { return other.m_data == m_data; }
+ bool operator!=(const StyleVariableData& other) const { return !(*this == other); }
+
+ void setVariable(const AtomicString& name, const String& value) { m_data.set(name, value); }
+
+ HashMap<AtomicString, String> m_data;
+private:
+ explicit StyleVariableData() : RefCounted<StyleVariableData>() { }
+ StyleVariableData(const StyleVariableData& other) : RefCounted<StyleVariableData>(), m_data(HashMap<AtomicString, String>(other.m_data)) { }
+};
+
+} // namespace WebCore
+
+#endif /* ENABLE(CSS_VARIABLES) */
+#endif /* StyleVariableData_h */
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
index 7b2866113..380275396 100644
--- a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
@@ -163,11 +163,6 @@ void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, const LayoutP
void RenderSVGContainer::updateCachedBoundaries()
{
- m_objectBoundingBox = FloatRect();
- m_objectBoundingBoxValid = false;
- m_strokeBoundingBox = FloatRect();
- m_repaintBoundingBox = FloatRect();
-
SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox);
SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
index eff707724..454f7aa6d 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
@@ -232,9 +232,7 @@ void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, c
ASSERT(styleResolver);
// Alter font-size to the right on-screen value to avoid scaling the glyphs themselves, except when GeometricPrecision is specified
- AffineTransform ctm;
- SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(renderer, ctm);
- scalingFactor = narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
+ scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(renderer);
if (scalingFactor == 1 || !scalingFactor || style->fontDescription().textRenderingMode() == GeometricPrecision) {
scalingFactor = 1;
scaledFont = style->font();
diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
index c1c27b09a..cf3079c06 100644
--- a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
@@ -171,8 +171,10 @@ bool RenderSVGModelObject::checkIntersection(RenderObject* renderer, const Float
if (!isGraphicsElement(renderer))
return false;
AffineTransform ctm;
- getElementCTM(static_cast<SVGElement*>(renderer->node()), ctm);
- return intersectsAllowingEmpty(rect, ctm.mapRect(renderer->repaintRectInLocalCoordinates()));
+ SVGElement* svgElement = static_cast<SVGElement*>(renderer->node());
+ getElementCTM(svgElement, ctm);
+ ASSERT(svgElement->renderer());
+ return intersectsAllowingEmpty(rect, ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
}
bool RenderSVGModelObject::checkEnclosure(RenderObject* renderer, const FloatRect& rect)
@@ -182,8 +184,10 @@ bool RenderSVGModelObject::checkEnclosure(RenderObject* renderer, const FloatRec
if (!isGraphicsElement(renderer))
return false;
AffineTransform ctm;
- getElementCTM(static_cast<SVGElement*>(renderer->node()), ctm);
- return rect.contains(ctm.mapRect(renderer->repaintRectInLocalCoordinates()));
+ SVGElement* svgElement = static_cast<SVGElement*>(renderer->node());
+ getElementCTM(svgElement, ctm);
+ ASSERT(svgElement->renderer());
+ return rect.contains(ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
index 80760fd48..3e223ed3b 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
@@ -24,6 +24,7 @@
#include "RenderSVGRoot.h"
#include "RenderView.h"
+#include "SVGRenderingContext.h"
#include "SVGResourcesCache.h"
#include "SVGStyledTransformableElement.h"
@@ -170,6 +171,27 @@ void RenderSVGResourceContainer::registerResource()
}
}
+bool RenderSVGResourceContainer::shouldTransformOnTextPainting(RenderObject* object, AffineTransform& resourceTransform)
+{
+ ASSERT_UNUSED(object, object);
+#if USE(CG)
+ UNUSED_PARAM(resourceTransform);
+ return false;
+#else
+ // This method should only be called for RenderObjects that deal with text rendering. Cmp. RenderObject.h's is*() methods.
+ ASSERT(object->isSVGText() || object->isSVGTextPath() || object->isSVGInline());
+
+ // In text drawing, the scaling part of the graphics context CTM is removed, compare SVGInlineTextBox::paintTextWithShadows.
+ // So, we use that scaling factor here, too, and then push it down to pattern or gradient space
+ // in order to keep the pattern or gradient correctly scaled.
+ float scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(object);
+ if (scalingFactor == 1)
+ return false;
+ resourceTransform.scale(scalingFactor);
+ return true;
+#endif
+}
+
// FIXME: This does not belong here.
AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
{
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
index b7473d927..1e8e62de8 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
@@ -38,6 +38,7 @@ public:
virtual bool isSVGResourceContainer() const { return true; }
virtual RenderSVGResourceContainer* toRenderSVGResourceContainer() { return this; }
+ static bool shouldTransformOnTextPainting(RenderObject*, AffineTransform&);
static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform);
void idChanged();
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
index f8f493db8..58e0079b2 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
@@ -166,6 +166,13 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
calculateGradientTransform(gradientTransform);
gradientData->userspaceTransform *= gradientTransform;
+ if (isPaintingText) {
+ // Depending on font scaling factor, we may need to rescale the gradient here since
+ // text painting removes the scale factor from the context.
+ AffineTransform additionalTextTransform;
+ if (shouldTransformOnTextPainting(object, additionalTextTransform))
+ gradientData->userspaceTransform *= additionalTextTransform;
+ }
gradientData->gradient->setGradientSpaceTransform(gradientData->userspaceTransform);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
index 15d647689..b4af99918 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
@@ -133,6 +133,12 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
if (!patternTransform.isIdentity())
patternData->transform = patternTransform * patternData->transform;
+ // Account for text drawing resetting the context to non-scaled, see SVGInlineTextBox::paintTextWithShadows.
+ if (resourceMode & ApplyToTextMode) {
+ AffineTransform additionalTextTransformation;
+ if (shouldTransformOnTextPainting(object, additionalTextTransformation))
+ patternData->transform *= additionalTextTransformation;
+ }
patternData->pattern->setPatternSpaceTransform(patternData->transform);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
index 663245333..58a715309 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
@@ -404,11 +404,6 @@ const RenderObject* RenderSVGRoot::pushMappingToContainer(const RenderBoxModelOb
void RenderSVGRoot::updateCachedBoundaries()
{
- m_objectBoundingBox = FloatRect();
- m_objectBoundingBoxValid = false;
- m_strokeBoundingBox = FloatRect();
- m_repaintBoundingBox = FloatRect();
-
SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox);
SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
m_repaintBoundingBox.inflate(borderAndPaddingWidth());
diff --git a/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp b/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
index c30fad59b..3ed63ddd6 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
@@ -36,7 +36,6 @@ namespace WebCore {
RenderSVGTextPath::RenderSVGTextPath(Node* n)
: RenderSVGInline(n)
- , m_startOffset(0)
, m_exactAlignment(true)
, m_stretchMethod(false)
{
diff --git a/Source/WebCore/rendering/svg/RenderSVGTextPath.h b/Source/WebCore/rendering/svg/RenderSVGTextPath.h
index f1871b0f6..be156ba48 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTextPath.h
+++ b/Source/WebCore/rendering/svg/RenderSVGTextPath.h
@@ -40,8 +40,6 @@ public:
private:
virtual const char* renderName() const { return "RenderSVGTextPath"; }
- float m_startOffset;
-
bool m_exactAlignment : 1;
bool m_stretchMethod : 1;
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 24e9a82f7..9302aef80 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -44,7 +44,7 @@ using namespace std;
namespace WebCore {
-class ExpectedSVGInlineTextBoxSize : public InlineTextBox {
+struct ExpectedSVGInlineTextBoxSize : public InlineTextBox {
float float1;
uint32_t bitfields : 5;
void* pointer;
diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
index 177ce9c44..0bfb0a527 100644
--- a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
@@ -121,6 +121,13 @@ static inline void updateObjectBoundingBox(FloatRect& objectBoundingBox, bool& o
void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox)
{
+ objectBoundingBox = FloatRect();
+ objectBoundingBoxValid = false;
+ strokeBoundingBox = FloatRect();
+
+ // When computing the strokeBoundingBox, we use the repaintRects of the container's children so that the container's stroke includes
+ // the resources applied to the children (such as clips and filters). This allows filters applied to containers to correctly bound
+ // the children, and also improves inlining of SVG content, as the stroke bound is used in that situation also.
for (RenderObject* current = container->firstChild(); current; current = current->nextSibling()) {
if (current->isSVGHiddenContainer())
continue;
@@ -128,14 +135,14 @@ void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* contain
const AffineTransform& transform = current->localToParentTransform();
if (transform.isIdentity()) {
updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, current->objectBoundingBox());
- strokeBoundingBox.unite(current->strokeBoundingBox());
- repaintBoundingBox.unite(current->repaintRectInLocalCoordinates());
+ strokeBoundingBox.unite(current->repaintRectInLocalCoordinates());
} else {
updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, transform.mapRect(current->objectBoundingBox()));
- strokeBoundingBox.unite(transform.mapRect(current->strokeBoundingBox()));
- repaintBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
+ strokeBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
}
}
+
+ repaintBoundingBox = strokeBoundingBox;
}
bool SVGRenderSupport::paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo)
diff --git a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp
index 80f53ef17..e2adb3063 100644
--- a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp
@@ -167,6 +167,15 @@ static AffineTransform& currentContentTransformation()
return s_currentContentTransformation;
}
+float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObject* renderer)
+{
+ ASSERT(renderer);
+
+ AffineTransform ctm;
+ calculateTransformationToOutermostSVGCoordinateSystem(renderer, ctm);
+ return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
+}
+
void SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform)
{
const RenderObject* current = renderer;
diff --git a/Source/WebCore/rendering/svg/SVGRenderingContext.h b/Source/WebCore/rendering/svg/SVGRenderingContext.h
index 4649d9ab7..5d38ce495 100644
--- a/Source/WebCore/rendering/svg/SVGRenderingContext.h
+++ b/Source/WebCore/rendering/svg/SVGRenderingContext.h
@@ -83,6 +83,7 @@ public:
static void renderSubtreeToImageBuffer(ImageBuffer*, RenderObject*, const AffineTransform&);
static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& targetRect, OwnPtr<ImageBuffer>&, bool safeToClear);
+ static float calculateScreenFontSizeScalingFactor(const RenderObject*);
static void calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform);
static IntSize clampedAbsoluteSize(const IntSize&);
static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect);