summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/InlineBox.h7
-rw-r--r--WebCore/rendering/InlineFlowBox.cpp83
-rw-r--r--WebCore/rendering/InlineFlowBox.h4
-rw-r--r--WebCore/rendering/InlineTextBox.cpp5
-rw-r--r--WebCore/rendering/InlineTextBox.h2
-rw-r--r--WebCore/rendering/RenderBlock.cpp45
-rw-r--r--WebCore/rendering/RenderBlock.h7
-rw-r--r--WebCore/rendering/RenderBlockLineLayout.cpp10
-rw-r--r--WebCore/rendering/RenderBox.cpp15
-rw-r--r--WebCore/rendering/RenderBox.h2
-rw-r--r--WebCore/rendering/RenderBoxModelObject.cpp49
-rw-r--r--WebCore/rendering/RenderBoxModelObject.h2
-rw-r--r--WebCore/rendering/RenderEmbeddedObject.cpp6
-rw-r--r--WebCore/rendering/RenderFieldset.cpp2
-rw-r--r--WebCore/rendering/RenderFieldset.h2
-rw-r--r--WebCore/rendering/RenderFlexibleBox.cpp19
-rw-r--r--WebCore/rendering/RenderIFrame.cpp1
-rw-r--r--WebCore/rendering/RenderImage.cpp13
-rw-r--r--WebCore/rendering/RenderImage.h2
-rw-r--r--WebCore/rendering/RenderLayer.cpp43
-rw-r--r--WebCore/rendering/RenderLayer.h33
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp2
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp33
-rw-r--r--WebCore/rendering/RenderLayerCompositor.h7
-rw-r--r--WebCore/rendering/RenderListItem.cpp1
-rw-r--r--WebCore/rendering/RenderObject.cpp8
-rw-r--r--WebCore/rendering/RenderObject.h17
-rw-r--r--WebCore/rendering/RenderReplaced.cpp1
-rw-r--r--WebCore/rendering/RenderReplica.cpp1
-rw-r--r--WebCore/rendering/RenderRubyRun.cpp66
-rw-r--r--WebCore/rendering/RenderRubyRun.h3
-rw-r--r--WebCore/rendering/RenderSVGResource.h3
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.cpp4
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.cpp18
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.h4
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.cpp8
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.h2
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.cpp8
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.h2
-rw-r--r--WebCore/rendering/RenderSVGResourceSolidColor.cpp11
-rw-r--r--WebCore/rendering/RenderSVGResourceSolidColor.h2
-rw-r--r--WebCore/rendering/RenderSlider.cpp1
-rw-r--r--WebCore/rendering/RenderTable.cpp2
-rw-r--r--WebCore/rendering/RenderTableRow.cpp1
-rw-r--r--WebCore/rendering/RenderTableSection.cpp1
-rw-r--r--WebCore/rendering/RenderText.cpp2
-rw-r--r--WebCore/rendering/RenderTextControl.cpp6
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp20
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.h4
-rw-r--r--WebCore/rendering/RenderThemeChromiumSkia.cpp3
-rw-r--r--WebCore/rendering/RenderView.cpp30
-rw-r--r--WebCore/rendering/RenderView.h8
-rw-r--r--WebCore/rendering/RootInlineBox.cpp39
-rw-r--r--WebCore/rendering/RootInlineBox.h7
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp2
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp10
-rw-r--r--WebCore/rendering/TextControlInnerElements.cpp9
-rw-r--r--WebCore/rendering/TextControlInnerElements.h1
-rw-r--r--WebCore/rendering/break_lines.cpp4
-rw-r--r--WebCore/rendering/style/RenderStyle.h5
-rw-r--r--WebCore/rendering/svg/RenderSVGPath.cpp23
-rw-r--r--WebCore/rendering/svg/SVGInlineTextBox.cpp10
-rw-r--r--WebCore/rendering/svg/SVGInlineTextBox.h2
63 files changed, 534 insertions, 209 deletions
diff --git a/WebCore/rendering/InlineBox.h b/WebCore/rendering/InlineBox.h
index c5f1997..991a3ff 100644
--- a/WebCore/rendering/InlineBox.h
+++ b/WebCore/rendering/InlineBox.h
@@ -120,6 +120,13 @@ public:
else
adjustPosition(0, delta);
}
+ void adjustBlockDirectionPosition(int delta)
+ {
+ if (isHorizontal())
+ adjustPosition(0, delta);
+ else
+ adjustPosition(delta, 0);
+ }
virtual void paint(PaintInfo&, int tx, int ty);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty);
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index e67c751..ee9fe9f 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -32,6 +32,9 @@
#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderListMarker.h"
+#include "RenderRubyBase.h"
+#include "RenderRubyRun.h"
+#include "RenderRubyText.h"
#include "RenderTableCell.h"
#include "RootInlineBox.h"
#include "Text.h"
@@ -620,7 +623,8 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
}
}
-void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop, FontBaseline baselineType)
+void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop,
+ int& lineTopIncludingMargins, int& lineBottomIncludingMargins, bool& containsRuby, FontBaseline baselineType)
{
if (isRootInlineBox())
setLogicalTop(top + maxAscent - baselinePosition(baselineType)); // Place our root box.
@@ -633,7 +637,8 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
// line-height).
bool isInlineFlow = curr->isInlineFlowBox();
if (isInlineFlow)
- static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom, setLineTop, baselineType);
+ static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom, setLineTop,
+ lineTopIncludingMargins, lineBottomIncludingMargins, containsRuby, baselineType);
bool childAffectsTopBottomPos = true;
if (curr->logicalTop() == PositionTop)
@@ -648,6 +653,10 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
}
int newLogicalTop = curr->logicalTop();
+ int newLogicalTopIncludingMargins;
+ int boxHeight = curr->logicalHeight();
+ int boxHeightIncludingMargins = boxHeight;
+
if (curr->isText() || curr->isInlineFlowBox()) {
const Font& font = curr->renderer()->style(m_firstLine)->font();
newLogicalTop += curr->baselinePosition(baselineType) - font.ascent(baselineType);
@@ -656,21 +665,43 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
newLogicalTop -= boxObject->style(m_firstLine)->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() :
boxObject->borderRight() + boxObject->paddingRight();
}
+ newLogicalTopIncludingMargins = newLogicalTop;
} else if (!curr->renderer()->isBR()) {
RenderBox* box = toRenderBox(curr->renderer());
- newLogicalTop += box->style(m_firstLine)->isHorizontalWritingMode() ? box->marginTop() : box->marginRight();
+ newLogicalTopIncludingMargins = newLogicalTop;
+ int overSideMargin = curr->isHorizontal() ? box->marginTop() : box->marginRight();
+ int underSideMargin = curr->isHorizontal() ? box->marginBottom() : box->marginLeft();
+ newLogicalTop += overSideMargin;
+ boxHeightIncludingMargins += overSideMargin + underSideMargin;
}
curr->setLogicalTop(newLogicalTop);
if (childAffectsTopBottomPos) {
- int boxHeight = curr->logicalHeight();
+ if (curr->renderer()->isRubyRun()) {
+ // Treat the leading on the first and last lines of ruby runs as not being part of the overall lineTop/lineBottom.
+ // Really this is a workaround hack for the fact that ruby should have been done as line layout and not done using
+ // inline-block.
+ containsRuby = true;
+ RenderRubyRun* rubyRun = static_cast<RenderRubyRun*>(curr->renderer());
+ if (RenderRubyBase* rubyBase = rubyRun->rubyBase()) {
+ int bottomRubyBaseLeading = (curr->logicalHeight() - rubyBase->logicalBottom()) + rubyBase->logicalHeight() - (rubyBase->lastRootBox() ? rubyBase->lastRootBox()->lineBottom() : 0);
+ int topRubyBaseLeading = rubyBase->logicalTop() + (rubyBase->firstRootBox() ? rubyBase->firstRootBox()->lineTop() : 0);
+ newLogicalTop += !renderer()->style()->isFlippedLinesWritingMode() ? topRubyBaseLeading : bottomRubyBaseLeading;
+ boxHeight -= (topRubyBaseLeading + bottomRubyBaseLeading);
+ }
+ }
+
if (!setLineTop) {
setLineTop = true;
lineTop = newLogicalTop;
- } else
+ lineTopIncludingMargins = min(lineTop, newLogicalTopIncludingMargins);
+ } else {
lineTop = min(lineTop, newLogicalTop);
+ lineTopIncludingMargins = min(lineTop, min(lineTopIncludingMargins, newLogicalTopIncludingMargins));
+ }
lineBottom = max(lineBottom, newLogicalTop + boxHeight);
+ lineBottomIncludingMargins = max(lineBottom, max(lineBottomIncludingMargins, newLogicalTopIncludingMargins + boxHeightIncludingMargins));
}
}
@@ -682,13 +713,17 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
if (!setLineTop) {
setLineTop = true;
lineTop = logicalTop();
- } else
+ lineTopIncludingMargins = lineTop;
+ } else {
lineTop = min(lineTop, logicalTop());
+ lineTopIncludingMargins = min(lineTop, lineTopIncludingMargins);
+ }
lineBottom = max(lineBottom, logicalTop() + logicalHeight());
+ lineBottomIncludingMargins = max(lineBottom, lineBottomIncludingMargins);
}
if (renderer()->style()->isFlippedLinesWritingMode())
- flipLinesInBlockDirection(lineTop, lineBottom);
+ flipLinesInBlockDirection(lineTopIncludingMargins, lineBottomIncludingMargins);
}
}
@@ -1170,6 +1205,40 @@ void InlineFlowBox::clearTruncation()
box->clearTruncation();
}
+int InlineFlowBox::computeBlockDirectionRubyAdjustment(int allowedPosition) const
+{
+ int result = 0;
+ for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+ if (curr->renderer()->isPositioned())
+ continue; // Positioned placeholders don't affect calculations.
+
+ if (curr->isInlineFlowBox())
+ result = max(result, static_cast<InlineFlowBox*>(curr)->computeBlockDirectionRubyAdjustment(allowedPosition));
+
+ if (curr->renderer()->isReplaced() && curr->renderer()->isRubyRun()) {
+ RenderRubyRun* rubyRun = static_cast<RenderRubyRun*>(curr->renderer());
+ RenderRubyText* rubyText = rubyRun->rubyText();
+ if (!rubyText)
+ continue;
+
+ if (!rubyRun->style()->isFlippedLinesWritingMode()) {
+ int topOfFirstRubyTextLine = rubyText->logicalTop() + (rubyText->firstRootBox() ? rubyText->firstRootBox()->lineTop() : 0);
+ if (topOfFirstRubyTextLine >= 0)
+ continue;
+ topOfFirstRubyTextLine += curr->logicalTop();
+ result = max(result, allowedPosition - topOfFirstRubyTextLine);
+ } else {
+ int bottomOfLastRubyTextLine = rubyText->logicalTop() + (rubyText->lastRootBox() ? rubyText->lastRootBox()->lineBottom() : rubyText->logicalHeight());
+ if (bottomOfLastRubyTextLine <= curr->logicalHeight())
+ continue;
+ bottomOfLastRubyTextLine += curr->logicalTop();
+ result = max(result, bottomOfLastRubyTextLine - allowedPosition);
+ }
+ }
+ }
+ return result;
+}
+
#ifndef NDEBUG
void InlineFlowBox::checkConsistency() const
diff --git a/WebCore/rendering/InlineFlowBox.h b/WebCore/rendering/InlineFlowBox.h
index e3127af..6e06a75 100644
--- a/WebCore/rendering/InlineFlowBox.h
+++ b/WebCore/rendering/InlineFlowBox.h
@@ -160,10 +160,12 @@ public:
bool strictMode, GlyphOverflowAndFallbackFontsMap&, FontBaseline, VerticalPositionCache&);
void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
int maxPositionTop, int maxPositionBottom);
- void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop, FontBaseline);
+ void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop,
+ int& lineTopIncludingMargins, int& lineBottomIncludingMargins, bool& containsRuby, FontBaseline);
void flipLinesInBlockDirection(int lineTop, int lineBottom);
void computeBlockDirectionOverflow(int lineTop, int lineBottom, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
bool requiresIdeographicBaseline(const GlyphOverflowAndFallbackFontsMap&) const;
+ int computeBlockDirectionRubyAdjustment(int allowedPosition) const;
void removeChild(InlineBox* child);
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 575bdf2..d055185 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -1085,10 +1085,11 @@ unsigned InlineTextBox::caretMaxRenderedOffset() const
int InlineTextBox::textPos() const
{
+ // When computing the width of a text run, RenderBlock::computeInlineDirectionPositionsForLine() doesn't include the actual offset
+ // from the containing block edge in its measurement. textPos() should be consistent so the text are rendered in the same width.
if (logicalLeft() == 0)
return 0;
- RenderBlock* blockElement = renderer()->containingBlock();
- return logicalLeft() - blockElement->borderStart() - blockElement->paddingStart();
+ return logicalLeft() - root()->logicalLeft();
}
int InlineTextBox::offsetForPosition(int lineOffset, bool includePartialGlyphs) const
diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h
index bc2219b..c97a061 100644
--- a/WebCore/rendering/InlineTextBox.h
+++ b/WebCore/rendering/InlineTextBox.h
@@ -119,7 +119,7 @@ public:
private:
virtual unsigned caretMaxRenderedOffset() const;
- int textPos() const;
+ int textPos() const; // returns the x position relative to the left start of the text line.
public:
virtual int offsetForPosition(int x, bool includePartialGlyphs = true) const;
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index aadc1d4..208a1b9 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -1262,6 +1262,8 @@ void RenderBlock::layoutBlock(bool relayoutChildren, int pageHeight)
if (view()->layoutState()->m_pageHeight)
setPageY(view()->layoutState()->pageY(y()));
+ updateLayerTransform();
+
// Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not.
updateScrollInfoAfterLayout();
@@ -1780,10 +1782,9 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogica
MarginInfo marginInfo(this, beforeEdge, afterEdge);
// Fieldsets need to find their legend and position it inside the border of the object.
- // The legend then gets skipped during normal layout.
- // FIXME: Make fieldsets work with block-flow.
- // https://bugs.webkit.org/show_bug.cgi?id=46785
- RenderObject* legend = layoutLegend(relayoutChildren);
+ // The legend then gets skipped during normal layout. The same is true for ruby text.
+ // It doesn't get included in the normal layout process but is instead skipped.
+ RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
int previousFloatLogicalBottom = 0;
maxFloatLogicalBottom = 0;
@@ -1794,8 +1795,8 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogica
RenderBox* child = next;
next = child->nextSiblingBox();
- if (legend == child)
- continue; // Skip the legend, since it has already been positioned up in the fieldset's border.
+ if (childToExclude == child)
+ continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
// Make sure we layout children if they need it.
// FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
@@ -2007,6 +2008,8 @@ bool RenderBlock::layoutOnlyPositionedObjects()
layoutPositionedObjects(false);
statePusher.pop();
+
+ updateLayerTransform();
updateScrollInfoAfterLayout();
@@ -2039,7 +2042,7 @@ void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
r->setChildNeedsLayout(true, false);
// If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
- //if (relayoutChildren && (r->style()->paddingLeft().isPercent() || r->style()->paddingRight().isPercent()))
+ if (relayoutChildren && (r->style()->paddingStart().isPercent() || r->style()->paddingEnd().isPercent()))
r->setPreferredLogicalWidthsDirty(true, false);
if (!r->needsLayout())
@@ -2232,7 +2235,7 @@ void RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
// Avoid painting descendants of the root element 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 (document()->didLayoutWithPendingStylesheets() && !isRenderView())
+ if (document()->mayCauseFlashOfUnstyledContent() && !isRenderView())
return;
if (childrenInline())
@@ -4744,11 +4747,22 @@ void RenderBlock::computePreferredLogicalWidths()
m_minPreferredLogicalWidth = 0;
}
+ int scrollbarWidth = 0;
+ if (hasOverflowClip() && style()->overflowY() == OSCROLL) {
+ layer()->setHasVerticalScrollbar(true);
+ scrollbarWidth = verticalScrollbarWidth();
+ m_maxPreferredLogicalWidth += scrollbarWidth;
+ }
+
if (isTableCell()) {
Length w = toRenderTableCell(this)->styleOrColLogicalWidth();
- if (w.isFixed() && w.value() > 0)
+ if (w.isFixed() && w.value() > 0) {
m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(w.value()));
+ scrollbarWidth = 0;
+ }
}
+
+ m_minPreferredLogicalWidth += scrollbarWidth;
}
if (style()->logicalMinWidth().isFixed() && style()->logicalMinWidth().value() > 0) {
@@ -4761,14 +4775,9 @@ void RenderBlock::computePreferredLogicalWidths()
m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
}
- int toAdd = 0;
- toAdd = borderAndPaddingLogicalWidth();
-
- if (hasOverflowClip() && style()->overflowY() == OSCROLL)
- toAdd += verticalScrollbarWidth();
-
- m_minPreferredLogicalWidth += toAdd;
- m_maxPreferredLogicalWidth += toAdd;
+ int borderAndPadding = borderAndPaddingLogicalWidth();
+ m_minPreferredLogicalWidth += borderAndPadding;
+ m_maxPreferredLogicalWidth += borderAndPadding;
setPreferredLogicalWidthsDirty(false);
}
@@ -5245,7 +5254,7 @@ bool RenderBlock::hasLineIfEmpty() const
if (node()->isContentEditable() && node()->rootEditableElement() == node())
return true;
- if (node()->isShadowNode() && (node()->shadowParentNode()->hasTagName(inputTag) || node()->shadowParentNode()->hasTagName(textareaTag)))
+ if (node()->isShadowNode() && (node()->shadowParentNode()->hasTagName(inputTag)))
return true;
return false;
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 645c0ec..5153218 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -298,6 +298,8 @@ protected:
}
#endif
+ void addOverflowFromBlockChildren();
+
private:
virtual RenderObjectChildList* virtualChildren() { return children(); }
virtual const RenderObjectChildList* virtualChildren() const { return children(); }
@@ -336,8 +338,8 @@ private:
virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby.
- // Called to lay out the legend for a fieldset.
- virtual RenderObject* layoutLegend(bool /*relayoutChildren*/) { return 0; }
+ // Called to lay out the legend for a fieldset or the ruby text of a ruby run.
+ virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/) { return 0; }
struct FloatWithRect {
FloatWithRect(RenderBox* f)
@@ -468,7 +470,6 @@ private:
int afterSideLayoutOverflowForLine(RootInlineBox*) const;
// End of functions defined in RenderBlockLineLayout.cpp.
- void addOverflowFromBlockChildren();
void addOverflowFromFloats();
void paintFloats(PaintInfo&, int tx, int ty, bool preservePhase = false);
diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp
index 127ffe0..878d1ab 100644
--- a/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -1043,8 +1043,16 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
}
}
+ // Expand the last line to accommodate Ruby in flipped lines writing modes (the Ruby is on
+ // the after side in this case).
+ int lastLineRubyAdjustment = 0;
+ if (lastRootBox() && style()->isFlippedLinesWritingMode()) {
+ int lowestAllowedPosition = max(lastRootBox()->lineBottom(), logicalHeight() + paddingAfter());
+ lastLineRubyAdjustment = lastRootBox()->computeBlockDirectionRubyAdjustment(lowestAllowedPosition);
+ }
+
// Now add in the bottom border/padding.
- setLogicalHeight(logicalHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
+ setLogicalHeight(logicalHeight() + lastLineRubyAdjustment + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
if (!firstLineBox() && hasLineIfEmpty())
setLogicalHeight(logicalHeight() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 41e2cd5..f0618ea 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -459,11 +459,9 @@ void RenderBox::absoluteQuads(Vector<FloatQuad>& quads)
IntRect RenderBox::applyLayerTransformToRect(const IntRect& rect) const
{
- if (layer() && layer()->hasTransform()) {
+ if (hasLayer() && layer()->hasTransform()) {
TransformationMatrix transform;
- transform.makeIdentity();
transform.translate(rect.x(), rect.y());
- layer()->updateTransform();
transform.multLeft(layer()->currentTransform());
return transform.mapRect(IntRect(0, 0, rect.width(), rect.height()));
}
@@ -475,6 +473,13 @@ IntRect RenderBox::transformedFrameRect() const
return applyLayerTransformToRect(frameRect());
}
+void RenderBox::updateLayerTransform()
+{
+ // Transform-origin depends on box size, so we need to update the layer transform after layout.
+ if (hasLayer())
+ layer()->updateTransform();
+}
+
IntRect RenderBox::absoluteContentBox() const
{
IntRect rect = contentBoxRect();
@@ -774,8 +779,8 @@ void RenderBox::paintRootBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
// CSS2 14.2:
// The background of the box generated by the root element covers the entire canvas including
// its margins.
- int bx = tx - marginLeft();
- int by = ty - marginTop();
+ int bx = tx - marginLeft() + view()->leftLayoutOverflow();
+ int by = ty - marginTop() + view()->topLayoutOverflow();
int bw = max(w + marginLeft() + marginRight() + borderLeft() + borderRight(), rw);
int bh = max(h + marginTop() + marginBottom() + borderTop() + borderBottom(), rh);
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index 091796b..cc559a3 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -157,6 +157,8 @@ public:
void addOverflowFromChild(RenderBox* child) { addOverflowFromChild(child, IntSize(child->x(), child->y())); }
void addOverflowFromChild(RenderBox* child, const IntSize& delta);
void clearLayoutOverflow();
+
+ void updateLayerTransform();
void blockDirectionOverflow(bool isLineHorizontal, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow,
int& logicalTopVisualOverflow, int& logicalBottomVisualOverflow);
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index 1580b49..bd19165 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -50,12 +50,14 @@ bool RenderBoxModelObject::s_layerWasSelfPainting = false;
static const double cInterpolationCutoff = 800. * 800.;
static const double cLowQualityTimeThreshold = 0.500; // 500 ms
-typedef HashMap<RenderBoxModelObject*, IntSize> LastPaintSizeMap;
+typedef pair<RenderBoxModelObject*, const void*> LastPaintSizeMapKey;
+typedef HashMap<LastPaintSizeMapKey, IntSize> LastPaintSizeMap;
class ImageQualityController : public Noncopyable {
public:
ImageQualityController();
- bool shouldPaintAtLowQuality(GraphicsContext*, RenderBoxModelObject*, Image*, const IntSize&);
+ bool shouldPaintAtLowQuality(GraphicsContext*, RenderBoxModelObject*, Image*, const void* layer, const IntSize&);
+ void keyDestroyed(LastPaintSizeMapKey key);
void objectDestroyed(RenderBoxModelObject*);
private:
@@ -73,21 +75,31 @@ ImageQualityController::ImageQualityController()
{
}
-void ImageQualityController::objectDestroyed(RenderBoxModelObject* object)
+void ImageQualityController::keyDestroyed(LastPaintSizeMapKey key)
{
- m_lastPaintSizeMap.remove(object);
+ m_lastPaintSizeMap.remove(key);
if (m_lastPaintSizeMap.isEmpty()) {
m_animatedResizeIsActive = false;
m_timer.stop();
}
}
+void ImageQualityController::objectDestroyed(RenderBoxModelObject* object)
+{
+ Vector<LastPaintSizeMapKey> keysToDie;
+ for (LastPaintSizeMap::iterator it = m_lastPaintSizeMap.begin(); it != m_lastPaintSizeMap.end(); ++it)
+ if (it->first.first == object)
+ keysToDie.append(it->first);
+ for (Vector<LastPaintSizeMapKey>::iterator it = keysToDie.begin(); it != keysToDie.end(); ++it)
+ keyDestroyed(*it);
+}
+
void ImageQualityController::highQualityRepaintTimerFired(Timer<ImageQualityController>*)
{
if (m_animatedResizeIsActive) {
m_animatedResizeIsActive = false;
for (LastPaintSizeMap::iterator it = m_lastPaintSizeMap.begin(); it != m_lastPaintSizeMap.end(); ++it)
- it->first->repaint();
+ it->first.first->repaint();
}
}
@@ -96,7 +108,7 @@ void ImageQualityController::restartTimer()
m_timer.startOneShot(cLowQualityTimeThreshold);
}
-bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, RenderBoxModelObject* object, Image* image, const IntSize& size)
+bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, RenderBoxModelObject* object, Image* image, const void *layer, const IntSize& size)
{
// If the image is not a bitmap image, then none of this is relevant and we just paint at high
// quality.
@@ -108,14 +120,15 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R
IntSize imageSize(image->width(), image->height());
// Look ourselves up in the hashtable.
- LastPaintSizeMap::iterator i = m_lastPaintSizeMap.find(object);
+ LastPaintSizeMapKey key(object, layer);
+ LastPaintSizeMap::iterator i = m_lastPaintSizeMap.find(key);
const AffineTransform& currentTransform = context->getCTM();
bool contextIsScaled = !currentTransform.isIdentityOrTranslationOrFlipped();
if (!contextIsScaled && imageSize == size) {
// There is no scale in effect. If we had a scale in effect before, we can just remove this object from the list.
if (i != m_lastPaintSizeMap.end())
- m_lastPaintSizeMap.remove(object);
+ m_lastPaintSizeMap.remove(key);
return false;
}
@@ -128,7 +141,7 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R
}
// If an animated resize is active, paint in low quality and kick the timer ahead.
if (m_animatedResizeIsActive) {
- m_lastPaintSizeMap.set(object, size);
+ m_lastPaintSizeMap.set(key, size);
restartTimer();
return true;
}
@@ -137,19 +150,19 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R
// size and set the timer.
if (i == m_lastPaintSizeMap.end() || size == i->second) {
restartTimer();
- m_lastPaintSizeMap.set(object, size);
+ m_lastPaintSizeMap.set(key, size);
return false;
}
// If the timer is no longer active, draw at high quality and don't
// set the timer.
if (!m_timer.isActive()) {
- objectDestroyed(object);
+ keyDestroyed(key);
return false;
}
// This object has been resized to two different sizes while the timer
// is active, so draw at low quality, set the flag for animated resizes and
// the object to the list for high quality redraw.
- m_lastPaintSizeMap.set(object, size);
+ m_lastPaintSizeMap.set(key, size);
m_animatedResizeIsActive = true;
restartTimer();
return true;
@@ -183,9 +196,9 @@ void RenderBoxModelObject::setSelectionState(SelectionState s)
cb->setSelectionState(s);
}
-bool RenderBoxModelObject::shouldPaintAtLowQuality(GraphicsContext* context, Image* image, const IntSize& size)
+bool RenderBoxModelObject::shouldPaintAtLowQuality(GraphicsContext* context, Image* image, const void* layer, const IntSize& size)
{
- return imageQualityController()->shouldPaintAtLowQuality(context, this, image, size);
+ return imageQualityController()->shouldPaintAtLowQuality(context, this, image, layer, size);
}
RenderBoxModelObject::RenderBoxModelObject(Node* node)
@@ -684,7 +697,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this;
Image* image = bg->image(clientForBackgroundImage, tileSize);
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, tileSize);
+ bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, bgLayer, tileSize);
context->drawTiledImage(image, style()->colorSpace(), destRect, phase, tileSize, compositeOp, useLowQualityScaling);
}
}
@@ -1051,7 +1064,6 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
graphicsContext->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight);
graphicsContext->clipOutRoundedRect(innerBorderRect, innerTopLeft, innerTopRight, innerBottomLeft, innerBottomRight);
roundedPath.addRoundedRect(borderRect, topLeft, topRight, bottomLeft, bottomRight);
- graphicsContext->addPath(roundedPath);
}
}
@@ -1792,13 +1804,10 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
} else
path.addRect(holeRect);
- context->beginPath();
- context->addPath(path);
-
context->setFillRule(RULE_EVENODD);
context->setFillColor(fillColor, s->colorSpace());
context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
- context->fillPath();
+ context->fillPath(path);
context->restore();
}
diff --git a/WebCore/rendering/RenderBoxModelObject.h b/WebCore/rendering/RenderBoxModelObject.h
index f502424..988d61a 100644
--- a/WebCore/rendering/RenderBoxModelObject.h
+++ b/WebCore/rendering/RenderBoxModelObject.h
@@ -122,7 +122,7 @@ public:
protected:
void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize);
- bool shouldPaintAtLowQuality(GraphicsContext*, Image*, const IntSize&);
+ bool shouldPaintAtLowQuality(GraphicsContext*, Image*, const void*, const IntSize&);
private:
virtual bool isBoxModelObject() const { return true; }
diff --git a/WebCore/rendering/RenderEmbeddedObject.cpp b/WebCore/rendering/RenderEmbeddedObject.cpp
index 16613a5..294ffec 100644
--- a/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -166,11 +166,9 @@ void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
context->save();
context->clip(contentRect);
- context->beginPath();
- context->addPath(path);
context->setAlpha(m_missingPluginIndicatorIsPressed ? replacementTextPressedRoundedRectOpacity : replacementTextRoundedRectOpacity);
context->setFillColor(m_missingPluginIndicatorIsPressed ? replacementTextRoundedRectPressedColor() : Color::white, style()->colorSpace());
- context->fillPath();
+ context->fillPath(path);
float labelX = roundf(replacementTextRect.location().x() + (replacementTextRect.size().width() - textWidth) / 2);
float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - font.height()) / 2 + font.ascent());
@@ -223,6 +221,8 @@ void RenderEmbeddedObject::layout()
m_overflow.clear();
addShadowOverflow();
+ updateLayerTransform();
+
if (!widget() && frameView())
frameView()->addWidgetToUpdate(this);
diff --git a/WebCore/rendering/RenderFieldset.cpp b/WebCore/rendering/RenderFieldset.cpp
index 12386e9..c83396c 100644
--- a/WebCore/rendering/RenderFieldset.cpp
+++ b/WebCore/rendering/RenderFieldset.cpp
@@ -63,7 +63,7 @@ void RenderFieldset::computePreferredLogicalWidths()
}
}
-RenderObject* RenderFieldset::layoutLegend(bool relayoutChildren)
+RenderObject* RenderFieldset::layoutSpecialExcludedChild(bool relayoutChildren)
{
RenderBox* legend = findLegend();
if (legend) {
diff --git a/WebCore/rendering/RenderFieldset.h b/WebCore/rendering/RenderFieldset.h
index bada78c..b340794 100644
--- a/WebCore/rendering/RenderFieldset.h
+++ b/WebCore/rendering/RenderFieldset.h
@@ -38,7 +38,7 @@ private:
virtual const char* renderName() const { return "RenderFieldSet"; }
virtual bool isFieldset() const { return true; }
- virtual RenderObject* layoutLegend(bool relayoutChildren);
+ virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren);
virtual void computePreferredLogicalWidths();
virtual bool avoidsFloats() const { return true; }
diff --git a/WebCore/rendering/RenderFlexibleBox.cpp b/WebCore/rendering/RenderFlexibleBox.cpp
index 841442b..2257d68 100644
--- a/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/WebCore/rendering/RenderFlexibleBox.cpp
@@ -185,6 +185,13 @@ void RenderFlexibleBox::computePreferredLogicalWidths()
m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
}
+ if (hasOverflowClip() && style()->overflowY() == OSCROLL) {
+ layer()->setHasVerticalScrollbar(true);
+ int scrollbarWidth = verticalScrollbarWidth();
+ m_maxPreferredLogicalWidth += scrollbarWidth;
+ m_minPreferredLogicalWidth += scrollbarWidth;
+ }
+
if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
@@ -195,13 +202,9 @@ void RenderFlexibleBox::computePreferredLogicalWidths()
m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value()));
}
- int toAdd = borderAndPaddingWidth();
-
- if (hasOverflowClip() && style()->overflowY() == OSCROLL)
- toAdd += verticalScrollbarWidth();
-
- m_minPreferredLogicalWidth += toAdd;
- m_maxPreferredLogicalWidth += toAdd;
+ int borderAndPadding = borderAndPaddingLogicalWidth();
+ m_minPreferredLogicalWidth += borderAndPadding;
+ m_maxPreferredLogicalWidth += borderAndPadding;
setPreferredLogicalWidthsDirty(false);
}
@@ -286,6 +289,8 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM
statePusher.pop();
+ updateLayerTransform();
+
if (view()->layoutState()->m_pageHeight)
setPageY(view()->layoutState()->pageY(y()));
diff --git a/WebCore/rendering/RenderIFrame.cpp b/WebCore/rendering/RenderIFrame.cpp
index a2cf66c..6961a57 100644
--- a/WebCore/rendering/RenderIFrame.cpp
+++ b/WebCore/rendering/RenderIFrame.cpp
@@ -248,6 +248,7 @@ void RenderIFrame::layout()
m_overflow.clear();
addShadowOverflow();
+ updateLayerTransform();
setNeedsLayout(false);
}
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index 48f21f1..7db8838 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -332,10 +332,10 @@ void RenderImage::paint(PaintInfo& paintInfo, int tx, int ty)
RenderReplaced::paint(paintInfo, tx, ty);
if (paintInfo.phase == PaintPhaseOutline)
- paintFocusRings(paintInfo, style());
+ paintFocusRing(paintInfo, style());
}
-void RenderImage::paintFocusRings(PaintInfo& paintInfo, const RenderStyle* style)
+void RenderImage::paintFocusRing(PaintInfo& paintInfo, const RenderStyle* style)
{
// Don't draw focus rings if printing.
if (document()->printing() || !frame()->selection()->isFocusedAndActive())
@@ -367,10 +367,9 @@ void RenderImage::paintFocusRings(PaintInfo& paintInfo, const RenderStyle* style
HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(areas->item(k));
if (focusedNode != areaElement)
continue;
-
- Vector<Path> focusRingPaths;
- focusRingPaths.append(areaElement->getPath(this));
- paintInfo.context->drawFocusRing(focusRingPaths, style->outlineWidth(), style->outlineOffset(), style->visitedDependentColor(CSSPropertyOutlineColor));
+
+ RenderStyle* styleToUse = areaElement->computedStyle();
+ paintInfo.context->drawFocusRing(areaElement->getPath(this), styleToUse->outlineWidth(), styleToUse->outlineOffset(), styleToUse->visitedDependentColor(CSSPropertyOutlineColor));
break;
}
}
@@ -386,7 +385,7 @@ void RenderImage::paintIntoRect(GraphicsContext* context, const IntRect& rect)
HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, m_imageResource->image(), rect.size());
+ bool useLowQualityScaling = shouldPaintAtLowQuality(context, m_imageResource->image(), 0, rect.size());
context->drawImage(m_imageResource->image(rect.width(), rect.height()), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
}
diff --git a/WebCore/rendering/RenderImage.h b/WebCore/rendering/RenderImage.h
index 86f5621..16ae7ec 100644
--- a/WebCore/rendering/RenderImage.h
+++ b/WebCore/rendering/RenderImage.h
@@ -57,7 +57,7 @@ protected:
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
virtual void paintIntoRect(GraphicsContext*, const IntRect&);
- void paintFocusRings(PaintInfo&, const RenderStyle*);
+ void paintFocusRing(PaintInfo&, const RenderStyle*);
virtual void paint(PaintInfo&, int tx, int ty);
bool isLogicalWidthSpecified() const;
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 2d2559c..27ff32f 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -143,8 +143,8 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
, m_height(0)
, m_scrollX(0)
, m_scrollY(0)
- , m_scrollOriginX(0)
, m_scrollLeftOverflow(0)
+ , m_scrollTopOverflow(0)
, m_scrollWidth(0)
, m_scrollHeight(0)
, m_inResizeMode(false)
@@ -249,6 +249,15 @@ bool RenderLayer::hasAcceleratedCompositing() const
#endif
}
+bool RenderLayer::canRender3DTransforms() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ return compositor()->canRender3DTransforms();
+#else
+ return false;
+#endif
+}
+
void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags, IntPoint* cachedOffset)
{
if (flags & DoFullRepaint) {
@@ -310,8 +319,6 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags, IntPoint
updateVisibilityStatus();
- updateTransform();
-
if (flags & UpdatePagination)
updatePagination();
else
@@ -429,7 +436,7 @@ void RenderLayer::updateTransform()
ASSERT(box);
m_transform->makeIdentity();
box->style()->applyTransform(*m_transform, box->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
- makeMatrixRenderable(*m_transform, hasAcceleratedCompositing());
+ makeMatrixRenderable(*m_transform, canRender3DTransforms());
}
if (had3DTransform != has3DTransform())
@@ -446,7 +453,7 @@ TransformationMatrix RenderLayer::currentTransform() const
TransformationMatrix currTransform;
RefPtr<RenderStyle> style = renderer()->animation()->getAnimatedStyleForRenderer(renderer());
style->applyTransform(currTransform, renderBox()->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
- makeMatrixRenderable(currTransform, hasAcceleratedCompositing());
+ makeMatrixRenderable(currTransform, canRender3DTransforms());
return currTransform;
}
#endif
@@ -1341,11 +1348,12 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
// complicated (since it will involve testing whether our layer
// is either occluded by another layer or clipped by an enclosing
// layer or contains fixed backgrounds, etc.).
- int newScrollX = x - m_scrollOriginX;
- if (m_scrollY == y && m_scrollX == newScrollX)
+ int newScrollX = x - m_scrollOrigin.x();
+ int newScrollY = y - m_scrollOrigin.y();
+ if (m_scrollY == newScrollY && m_scrollX == newScrollX)
return;
m_scrollX = newScrollX;
- m_scrollY = y;
+ m_scrollY = newScrollY;
// Update the positions of our child layers. Don't have updateLayerPositions() update
// compositing layers, because we need to do a deep update from the compositing ancestor.
@@ -1999,22 +2007,26 @@ void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
m_scrollDimensionsDirty = false;
- bool ltr = renderer()->style()->isLeftToRightDirection();
-
int clientWidth = box->clientWidth();
int clientHeight = box->clientHeight();
- m_scrollLeftOverflow = ltr ? 0 : min(0, box->leftmostPosition(true, false) - box->borderLeft());
+ bool hasLeftOverflow = (!box->style()->isHorizontalWritingMode() || !box->style()->isLeftToRightDirection()) && box->style()->writingMode() != LeftToRightWritingMode;
+ bool hasTopOverflow = (box->style()->isHorizontalWritingMode() || !box->style()->isLeftToRightDirection()) && box->style()->writingMode() != TopToBottomWritingMode;
+
+ m_scrollLeftOverflow = !hasLeftOverflow ? 0 : min(0, box->leftmostPosition(true, false) - box->borderLeft());
+ m_scrollTopOverflow = !hasTopOverflow ? 0 : min(0, box->topmostPosition(true, false) - box->borderTop());
- int rightPos = ltr ?
+ int rightPos = !hasLeftOverflow ?
box->rightmostPosition(true, false) - box->borderLeft() :
clientWidth - m_scrollLeftOverflow;
- int bottomPos = box->lowestPosition(true, false) - box->borderTop();
+ int bottomPos = !hasTopOverflow ?
+ box->lowestPosition(true, false) - box->borderTop() :
+ clientHeight - m_scrollTopOverflow;
m_scrollWidth = max(rightPos, clientWidth);
m_scrollHeight = max(bottomPos, clientHeight);
- m_scrollOriginX = ltr ? 0 : m_scrollWidth - clientWidth;
+ m_scrollOrigin = IntPoint(!hasLeftOverflow ? 0 : m_scrollWidth - clientWidth, !hasTopOverflow ? 0 : m_scrollHeight - clientHeight);
if (needHBar)
*needHBar = rightPos > clientWidth;
@@ -2028,7 +2040,6 @@ void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOve
m_horizontalOverflow = horizontalOverflow;
m_verticalOverflow = verticalOverflow;
m_overflowStatusDirty = false;
-
return;
}
@@ -2399,7 +2410,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Avoid painting layers 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 (renderer()->document()->didLayoutWithPendingStylesheets() && !renderer()->isRenderView() && !renderer()->isRoot())
+ if (renderer()->document()->mayCauseFlashOfUnstyledContent() && !renderer()->isRenderView() && !renderer()->isRoot())
return;
// If this layer is totally invisible then there is nothing to paint.
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index be3ddc6..db4da64 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -249,14 +249,14 @@ public:
// Scrolling methods for layers that can scroll their overflow.
void scrollByRecursively(int xDelta, int yDelta);
- IntSize scrolledContentOffset() const { return IntSize(scrollXOffset() + m_scrollLeftOverflow, scrollYOffset()); }
+ IntSize scrolledContentOffset() const { return IntSize(scrollXOffset() + m_scrollLeftOverflow, scrollYOffset() + m_scrollTopOverflow); }
- int scrollXOffset() const { return m_scrollX + m_scrollOriginX; }
- int scrollYOffset() const { return m_scrollY; }
+ int scrollXOffset() const { return m_scrollX + m_scrollOrigin.x(); }
+ int scrollYOffset() const { return m_scrollY + m_scrollOrigin.y(); }
void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true);
- void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY); }
- void scrollToYOffset(int y) { scrollToOffset(m_scrollX + m_scrollOriginX, y); }
+ void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY + m_scrollOrigin.y()); }
+ void scrollToYOffset(int y) { scrollToOffset(m_scrollX + m_scrollOrigin.x(), y); }
void scrollRectToVisible(const IntRect&, bool scrollToAnchor = false, const ScrollAlignment& alignX = ScrollAlignment::alignCenterIfNeeded, const ScrollAlignment& alignY = ScrollAlignment::alignCenterIfNeeded);
IntRect getRectToExpose(const IntRect& visibleRect, const IntRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
@@ -308,7 +308,9 @@ public:
// Returns true if the accelerated compositing is enabled
bool hasAcceleratedCompositing() const;
-
+
+ bool canRender3DTransforms() const;
+
void updateLayerPosition();
enum UpdateLayerPositionsFlag {
@@ -642,9 +644,22 @@ protected:
// Our scroll offsets if the view is scrolled.
int m_scrollX;
int m_scrollY;
- int m_scrollOriginX; // only non-zero for rtl content
- int m_scrollLeftOverflow; // only non-zero for rtl content
-
+
+ // There are 8 possible combinations of writing mode and direction. Scroll origin (and its corresponding left/top overflow)
+ // will be non-zero in the x or y axis if there is any reversed direction or writing-mode. The combinations are:
+ // writing-mode / direction scrollOrigin.x() set scrollOrigin.y() set
+ // horizontal-tb / ltr NO NO
+ // horizontal-tb / rtl YES NO
+ // horizontal-bt / ltr NO YES
+ // horizontal-bt / rtl YES YES
+ // vertical-lr / ltr NO NO
+ // vertical-lr / rtl NO YES
+ // vertical-rl / ltr YES NO
+ // vertical-rl / rtl YES YES
+ IntPoint m_scrollOrigin;
+ int m_scrollLeftOverflow;
+ int m_scrollTopOverflow;
+
// The width/height of our scrolled area.
int m_scrollWidth;
int m_scrollHeight;
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 215b41f..48aa3ec 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -132,7 +132,7 @@ void RenderLayerBacking::updateLayerTransform(const RenderStyle* style)
TransformationMatrix t;
if (m_owningLayer->hasTransform()) {
style->applyTransform(t, toRenderBox(renderer())->borderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
- makeMatrixRenderable(t, compositor()->hasAcceleratedCompositing());
+ makeMatrixRenderable(t, compositor()->canRender3DTransforms());
}
m_graphicsLayer->setTransform(t);
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index e6ea32a..638c628 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -100,6 +100,7 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
, m_rootPlatformLayer(0)
, m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
, m_hasAcceleratedCompositing(true)
+ , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
, m_showDebugBorders(false)
, m_showRepaintCounter(false)
, m_compositingConsultsOverlap(true)
@@ -136,7 +137,7 @@ void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
bool hasAcceleratedCompositing = false;
bool showDebugBorders = false;
bool showRepaintCounter = false;
-
+
if (Settings* settings = m_renderView->document()->settings()) {
hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
showDebugBorders = settings->showDebugBorders();
@@ -148,18 +149,26 @@ void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
if (hasAcceleratedCompositing) {
Frame* frame = m_renderView->frameView()->frame();
Page* page = frame ? frame->page() : 0;
- if (page)
- hasAcceleratedCompositing = page->chrome()->client()->allowsAcceleratedCompositing();
+ if (page) {
+ ChromeClient* chromeClient = page->chrome()->client();
+ m_compositingTriggers = chromeClient->allowedCompositingTriggers();
+ hasAcceleratedCompositing = m_compositingTriggers;
+ }
}
if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter)
setCompositingLayersNeedRebuild();
-
+
m_hasAcceleratedCompositing = hasAcceleratedCompositing;
m_showDebugBorders = showDebugBorders;
m_showRepaintCounter = showRepaintCounter;
}
+bool RenderLayerCompositor::canRender3DTransforms() const
+{
+ return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
+}
+
void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
{
if (inCompositingMode())
@@ -1223,7 +1232,7 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c
|| requiresCompositingForCanvas(renderer)
|| requiresCompositingForPlugin(renderer)
|| requiresCompositingForIFrame(renderer)
- || renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden
+ || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
|| clipsCompositingDescendants(layer)
|| requiresCompositingForAnimation(renderer);
}
@@ -1279,6 +1288,9 @@ bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer
bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
{
+ if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
+ return false;
+
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.
@@ -1287,6 +1299,8 @@ bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* render
bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
{
+ if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
+ return false;
#if ENABLE(VIDEO)
if (renderer->isVideo()) {
RenderVideo* video = toRenderVideo(renderer);
@@ -1313,6 +1327,9 @@ bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer)
bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
{
+ if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
+ return false;
+
if (renderer->isCanvas()) {
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
@@ -1322,6 +1339,9 @@ bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer)
bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
{
+ if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
+ return false;
+
bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
|| (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing());
if (!composite)
@@ -1366,6 +1386,9 @@ bool RenderLayerCompositor::requiresCompositingForIFrame(RenderObject* renderer)
bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
{
+ if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
+ return false;
+
if (AnimationController* animController = renderer->animation()) {
return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
|| animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
diff --git a/WebCore/rendering/RenderLayerCompositor.h b/WebCore/rendering/RenderLayerCompositor.h
index ad1e2e1..e741dec 100644
--- a/WebCore/rendering/RenderLayerCompositor.h
+++ b/WebCore/rendering/RenderLayerCompositor.h
@@ -26,6 +26,7 @@
#ifndef RenderLayerCompositor_h
#define RenderLayerCompositor_h
+#include "ChromeClient.h"
#include "RenderLayer.h"
#include "RenderLayerBacking.h"
@@ -67,7 +68,9 @@ public:
// Returns true if the accelerated compositing is enabled
bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; }
-
+
+ bool canRender3DTransforms() const;
+
bool showDebugBorders() const { return m_showDebugBorders; }
bool showRepaintCounter() const { return m_showRepaintCounter; }
@@ -237,6 +240,8 @@ private:
Timer<RenderLayerCompositor> m_updateCompositingLayersTimer;
bool m_hasAcceleratedCompositing;
+ ChromeClient::CompositingTriggerFlags m_compositingTriggers;
+
bool m_showDebugBorders;
bool m_showRepaintCounter;
bool m_compositingConsultsOverlap;
diff --git a/WebCore/rendering/RenderListItem.cpp b/WebCore/rendering/RenderListItem.cpp
index 2b64f04..ba107064 100644
--- a/WebCore/rendering/RenderListItem.cpp
+++ b/WebCore/rendering/RenderListItem.cpp
@@ -273,6 +273,7 @@ void RenderListItem::positionListMarker()
}
}
} else {
+ markerLogicalLeft = m_marker->logicalLeft() + paddingStart() + borderStart() + m_marker->marginEnd();
int rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false);
markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + m_marker->marginEnd();
m_marker->inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft);
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 503b0a3..c1b1f35 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -31,6 +31,7 @@
#include "Chrome.h"
#include "CSSStyleSelector.h"
#include "DashArray.h"
+#include "EditingBoundary.h"
#include "FloatQuad.h"
#include "Frame.h"
#include "FrameView.h"
@@ -958,8 +959,7 @@ void RenderObject::drawBoxSideFromPath(GraphicsContext* graphicsContext, IntRect
lineDash.append(patWidth);
lineDash.append(whiteSpaceWidth);
graphicsContext->setLineDash(lineDash, patWidth);
- graphicsContext->addPath(borderPath);
- graphicsContext->strokePath();
+ graphicsContext->strokePath(borderPath);
return;
}
case DOUBLE: {
@@ -2642,10 +2642,10 @@ VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affini
if (!node->isContentEditable()) {
// If it can be found, we prefer a visually equivalent position that is editable.
Position position(node, offset);
- Position candidate = position.downstream(Position::CanCrossEditingBoundary);
+ Position candidate = position.downstream(CanCrossEditingBoundary);
if (candidate.node()->isContentEditable())
return VisiblePosition(candidate, affinity);
- candidate = position.upstream(Position::CanCrossEditingBoundary);
+ candidate = position.upstream(CanCrossEditingBoundary);
if (candidate.node()->isContentEditable())
return VisiblePosition(candidate, affinity);
}
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index bfc62fe..e16ad46 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -1002,14 +1002,6 @@ inline int adjustForAbsoluteZoom(int value, RenderObject* renderer)
return adjustForAbsoluteZoom(value, renderer->style());
}
-inline void adjustIntRectForAbsoluteZoom(IntRect& rect, RenderObject* renderer)
-{
- rect.setX(adjustForAbsoluteZoom(rect.x(), renderer));
- rect.setY(adjustForAbsoluteZoom(rect.y(), renderer));
- rect.setWidth(adjustForAbsoluteZoom(rect.width(), renderer));
- rect.setHeight(adjustForAbsoluteZoom(rect.height(), renderer));
-}
-
inline FloatPoint adjustFloatPointForAbsoluteZoom(const FloatPoint& point, RenderObject* renderer)
{
// The result here is in floats, so we don't need the truncation hack from the integer version above.
@@ -1027,6 +1019,15 @@ inline void adjustFloatQuadForAbsoluteZoom(FloatQuad& quad, RenderObject* render
quad.setP4(adjustFloatPointForAbsoluteZoom(quad.p4(), renderer));
}
+inline void adjustFloatRectForAbsoluteZoom(FloatRect& rect, RenderObject* renderer)
+{
+ RenderStyle* style = renderer->style();
+ rect.setX(adjustFloatForAbsoluteZoom(rect.x(), style));
+ rect.setY(adjustFloatForAbsoluteZoom(rect.y(), style));
+ rect.setWidth(adjustFloatForAbsoluteZoom(rect.width(), style));
+ rect.setHeight(adjustFloatForAbsoluteZoom(rect.height(), style));
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/WebCore/rendering/RenderReplaced.cpp b/WebCore/rendering/RenderReplaced.cpp
index b1a7711..9a809fc 100644
--- a/WebCore/rendering/RenderReplaced.cpp
+++ b/WebCore/rendering/RenderReplaced.cpp
@@ -80,6 +80,7 @@ void RenderReplaced::layout()
m_overflow.clear();
addShadowOverflow();
+ updateLayerTransform();
repainter.repaintAfterLayout();
setNeedsLayout(false);
diff --git a/WebCore/rendering/RenderReplica.cpp b/WebCore/rendering/RenderReplica.cpp
index 4b11f40..c099d9d 100644
--- a/WebCore/rendering/RenderReplica.cpp
+++ b/WebCore/rendering/RenderReplica.cpp
@@ -49,6 +49,7 @@ RenderReplica::~RenderReplica()
void RenderReplica::layout()
{
setFrameRect(parentBox()->borderBoxRect());
+ updateLayerTransform();
setNeedsLayout(false);
}
diff --git a/WebCore/rendering/RenderRubyRun.cpp b/WebCore/rendering/RenderRubyRun.cpp
index a83a3e2..5c92c04 100644
--- a/WebCore/rendering/RenderRubyRun.cpp
+++ b/WebCore/rendering/RenderRubyRun.cpp
@@ -220,17 +220,65 @@ RenderRubyRun* RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby
RefPtr<RenderStyle> newStyle = RenderStyle::create();
newStyle->inheritFrom(parentRuby->style());
newStyle->setDisplay(INLINE_BLOCK);
- if (parentRuby->style()->isFlippedLinesWritingMode()) {
- // Ruby text is always in the line direction, so invert our block flow relative to the parent to
- // ensure that the Ruby ends up on the correct side.
- if (parentRuby->style()->isHorizontalWritingMode())
- newStyle->setWritingMode(TopToBottomWritingMode);
- else
- newStyle->setWritingMode(RightToLeftWritingMode);
- }
-
rr->setStyle(newStyle.release());
return rr;
}
+RenderObject* RenderRubyRun::layoutSpecialExcludedChild(bool relayoutChildren)
+{
+ // Don't bother positioning the RenderRubyRun yet.
+ RenderRubyText* rt = rubyText();
+ if (!rt)
+ return 0;
+ if (relayoutChildren)
+ rt->setChildNeedsLayout(true, false);
+ rt->layoutIfNeeded();
+ return rt;
+}
+
+void RenderRubyRun::layout()
+{
+ RenderBlock::layout();
+
+ // Place the RenderRubyText such that its bottom is flush with the lineTop of the first line of the RenderRubyBase.
+ RenderRubyText* rt = rubyText();
+ if (!rt)
+ return;
+
+ int lastLineRubyTextBottom = rt->logicalHeight();
+ int firstLineRubyTextTop = 0;
+ RootInlineBox* rootBox = rt->lastRootBox();
+ if (rootBox) {
+ // In order to align, we have to ignore negative leading.
+ firstLineRubyTextTop = rt->firstRootBox()->logicalTopLayoutOverflow();
+ lastLineRubyTextBottom = rootBox->logicalBottomLayoutOverflow();
+ }
+
+ if (!style()->isFlippedLinesWritingMode()) {
+ int firstLineTop = 0;
+ if (RenderRubyBase* rb = rubyBase()) {
+ RootInlineBox* rootBox = rb->firstRootBox();
+ if (rootBox)
+ firstLineTop = rootBox->logicalTopLayoutOverflow();
+ firstLineTop += rb->logicalTop();
+ }
+
+ rt->setLogicalTop(-lastLineRubyTextBottom + firstLineTop);
+ } else {
+ int lastLineBottom = logicalHeight();
+ if (RenderRubyBase* rb = rubyBase()) {
+ RootInlineBox* rootBox = rb->lastRootBox();
+ if (rootBox)
+ lastLineBottom = rootBox->logicalBottomLayoutOverflow();
+ lastLineBottom += rb->logicalTop();
+ }
+
+ rt->setLogicalTop(-firstLineRubyTextTop + lastLineBottom);
+ }
+
+ // Update our overflow to account for the new RenderRubyText position.
+ m_overflow.clear();
+ addOverflowFromBlockChildren();
+}
+
} // namespace WebCore
diff --git a/WebCore/rendering/RenderRubyRun.h b/WebCore/rendering/RenderRubyRun.h
index 222ddb6..d844bff 100644
--- a/WebCore/rendering/RenderRubyRun.h
+++ b/WebCore/rendering/RenderRubyRun.h
@@ -55,6 +55,9 @@ public:
RenderRubyBase* rubyBase() const;
RenderRubyBase* rubyBaseSafe(); // creates the base if it doesn't already exist
+ virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren);
+ virtual void layout();
+
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual void removeChild(RenderObject* child);
diff --git a/WebCore/rendering/RenderSVGResource.h b/WebCore/rendering/RenderSVGResource.h
index 0230e98..6fc2dae 100644
--- a/WebCore/rendering/RenderSVGResource.h
+++ b/WebCore/rendering/RenderSVGResource.h
@@ -48,6 +48,7 @@ enum RenderSVGResourceMode {
class Color;
class FloatRect;
class GraphicsContext;
+class Path;
class RenderObject;
class RenderStyle;
class RenderSVGResourceSolidColor;
@@ -61,7 +62,7 @@ public:
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) = 0;
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) = 0;
- virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short) { }
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short, const Path*) { }
virtual FloatRect resourceBoundingBox(RenderObject*) = 0;
virtual RenderSVGResourceType resourceType() const = 0;
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
index e7b9fbb..25ed1c3 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.cpp
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -151,9 +151,7 @@ bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const
// The SVG specification wants us to clip everything, if clip-path doesn't have a child.
if (clipPath.isEmpty())
clipPath.addRect(FloatRect());
- context->beginPath();
- context->addPath(clipPath);
- context->clipPath(clipRule);
+ context->clipPath(clipPath, clipRule);
return true;
}
diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp
index 50cf68e..38d2357 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.cpp
+++ b/WebCore/rendering/RenderSVGResourceFilter.cpp
@@ -88,13 +88,13 @@ void RenderSVGResourceFilter::removeClientFromCache(RenderObject* client, bool m
markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}
-PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives()
+PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(Filter* filter)
{
SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
// Add effects to the builder
- RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create();
+ RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(filter);
for (Node* node = filterElement->firstChild(); node; node = node->nextSibling()) {
if (!node->isSVGElement())
continue;
@@ -104,7 +104,7 @@ PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives()
continue;
SVGFilterPrimitiveStandardAttributes* effectElement = static_cast<SVGFilterPrimitiveStandardAttributes*>(element);
- RefPtr<FilterEffect> effect = effectElement->build(builder.get());
+ RefPtr<FilterEffect> effect = effectElement->build(builder.get(), filter);
if (!effect) {
builder->clearEffects();
return 0;
@@ -179,7 +179,7 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
filterData->filter = SVGFilter::create(filterData->shearFreeAbsoluteTransform, absoluteDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode);
// Create all relevant filter primitives.
- filterData->builder = buildPrimitives();
+ filterData->builder = buildPrimitives(filterData->filter.get());
if (!filterData->builder)
return false;
@@ -227,8 +227,12 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
absoluteDrawingRegion.scale(scale.width(), scale.height());
OwnPtr<ImageBuffer> sourceGraphic;
- if (!SVGImageBufferTools::createImageBuffer(absoluteDrawingRegion, absoluteDrawingRegion, sourceGraphic, ColorSpaceLinearRGB))
+ if (!SVGImageBufferTools::createImageBuffer(absoluteDrawingRegion, absoluteDrawingRegion, sourceGraphic, ColorSpaceLinearRGB)) {
+ ASSERT(!m_filter.contains(object));
+ filterData->savedContext = context;
+ m_filter.set(object, filterData.leakPtr());
return false;
+ }
GraphicsContext* sourceGraphicContext = sourceGraphic->context();
ASSERT(sourceGraphicContext);
@@ -250,7 +254,7 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
return true;
}
-void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode)
+void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode, const Path*)
{
ASSERT(object);
ASSERT(context);
@@ -286,7 +290,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
// second drawing.
if (!filterData->builded) {
filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release());
- lastEffect->apply(filterData->filter.get());
+ lastEffect->apply();
#if !PLATFORM(CG)
ImageBuffer* resultImage = lastEffect->resultImage();
if (resultImage)
diff --git a/WebCore/rendering/RenderSVGResourceFilter.h b/WebCore/rendering/RenderSVGResourceFilter.h
index c64f5c6..5950c44 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.h
+++ b/WebCore/rendering/RenderSVGResourceFilter.h
@@ -70,11 +70,11 @@ public:
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
- virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*);
virtual FloatRect resourceBoundingBox(RenderObject*);
- PassRefPtr<SVGFilterBuilder> buildPrimitives();
+ PassRefPtr<SVGFilterBuilder> buildPrimitives(Filter*);
SVGUnitTypes::SVGUnitType filterUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->filterUnits()); }
SVGUnitTypes::SVGUnitType primitiveUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->primitiveUnits()); }
diff --git a/WebCore/rendering/RenderSVGResourceGradient.cpp b/WebCore/rendering/RenderSVGResourceGradient.cpp
index a757147..b76e7f8 100644
--- a/WebCore/rendering/RenderSVGResourceGradient.cpp
+++ b/WebCore/rendering/RenderSVGResourceGradient.cpp
@@ -230,7 +230,7 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
return true;
}
-void RenderSVGResourceGradient::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode)
+void RenderSVGResourceGradient::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode, const Path* path)
{
ASSERT(context);
ASSERT(resourceMode != ApplyToDefaultMode);
@@ -258,11 +258,11 @@ void RenderSVGResourceGradient::postApplyResource(RenderObject* object, Graphics
#else
UNUSED_PARAM(object);
#endif
- } else {
+ } else if (path) {
if (resourceMode & ApplyToFillMode)
- context->fillPath();
+ context->fillPath(*path);
else if (resourceMode & ApplyToStrokeMode)
- context->strokePath();
+ context->strokePath(*path);
}
context->restore();
diff --git a/WebCore/rendering/RenderSVGResourceGradient.h b/WebCore/rendering/RenderSVGResourceGradient.h
index bc0b864..1c7f52d 100644
--- a/WebCore/rendering/RenderSVGResourceGradient.h
+++ b/WebCore/rendering/RenderSVGResourceGradient.h
@@ -51,7 +51,7 @@ public:
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
- virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*);
virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
protected:
diff --git a/WebCore/rendering/RenderSVGResourcePattern.cpp b/WebCore/rendering/RenderSVGResourcePattern.cpp
index d2e4563..83754ad 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.cpp
+++ b/WebCore/rendering/RenderSVGResourcePattern.cpp
@@ -182,16 +182,16 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
return true;
}
-void RenderSVGResourcePattern::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode)
+void RenderSVGResourcePattern::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode, const Path* path)
{
ASSERT(context);
ASSERT(resourceMode != ApplyToDefaultMode);
- if (!(resourceMode & ApplyToTextMode)) {
+ if (path && !(resourceMode & ApplyToTextMode)) {
if (resourceMode & ApplyToFillMode)
- context->fillPath();
+ context->fillPath(*path);
else if (resourceMode & ApplyToStrokeMode)
- context->strokePath();
+ context->strokePath(*path);
}
context->restore();
diff --git a/WebCore/rendering/RenderSVGResourcePattern.h b/WebCore/rendering/RenderSVGResourcePattern.h
index ba4aec4..ee3fb23 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.h
+++ b/WebCore/rendering/RenderSVGResourcePattern.h
@@ -53,7 +53,7 @@ public:
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
- virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*);
virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
diff --git a/WebCore/rendering/RenderSVGResourceSolidColor.cpp b/WebCore/rendering/RenderSVGResourceSolidColor.cpp
index 8228c80..f9449bb 100644
--- a/WebCore/rendering/RenderSVGResourceSolidColor.cpp
+++ b/WebCore/rendering/RenderSVGResourceSolidColor.cpp
@@ -75,17 +75,18 @@ bool RenderSVGResourceSolidColor::applyResource(RenderObject* object, RenderStyl
return true;
}
-void RenderSVGResourceSolidColor::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode)
+void RenderSVGResourceSolidColor::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode, const Path* path)
{
ASSERT(context);
ASSERT(resourceMode != ApplyToDefaultMode);
- if (!(resourceMode & ApplyToTextMode)) {
+ if (path && !(resourceMode & ApplyToTextMode)) {
if (resourceMode & ApplyToFillMode)
- context->fillPath();
+ context->fillPath(*path);
else if (resourceMode & ApplyToStrokeMode)
- context->strokePath();
+ context->strokePath(*path);
}
+<<<<<<< HEAD
#if PLATFORM(SKIA) && !PLATFORM(ANDROID)
// FIXME: Move this into the GraphicsContext
@@ -97,6 +98,8 @@ void RenderSVGResourceSolidColor::postApplyResource(RenderObject*, GraphicsConte
context->platformContext()->setFillShader(0);
context->platformContext()->setStrokeShader(0);
#endif
+=======
+>>>>>>> webkit.org at r73109
}
}
diff --git a/WebCore/rendering/RenderSVGResourceSolidColor.h b/WebCore/rendering/RenderSVGResourceSolidColor.h
index 44109db..72de3b2 100644
--- a/WebCore/rendering/RenderSVGResourceSolidColor.h
+++ b/WebCore/rendering/RenderSVGResourceSolidColor.h
@@ -37,7 +37,7 @@ public:
virtual void removeClientFromCache(RenderObject*, bool = true) { }
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
- virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*);
virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index d680bc7..72e46cb 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -281,6 +281,7 @@ void RenderSlider::layout()
setSize(baseSize);
computeLogicalWidth();
computeLogicalHeight();
+ updateLayerTransform();
if (thumb) {
if (oldSize != size())
diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp
index de10680..147baa4 100644
--- a/WebCore/rendering/RenderTable.cpp
+++ b/WebCore/rendering/RenderTable.cpp
@@ -443,6 +443,8 @@ void RenderTable::layout()
// FIXME: Only pass true if width or height changed.
layoutPositionedObjects(true);
+ updateLayerTransform();
+
// Add overflow from borders.
int rightBorderOverflow = width() + (collapsing ? outerBorderRight() - borderRight() : 0);
int leftBorderOverflow = collapsing ? borderLeft() - outerBorderLeft() : 0;
diff --git a/WebCore/rendering/RenderTableRow.cpp b/WebCore/rendering/RenderTableRow.cpp
index 98544a6..3dd4017 100644
--- a/WebCore/rendering/RenderTableRow.cpp
+++ b/WebCore/rendering/RenderTableRow.cpp
@@ -145,6 +145,7 @@ void RenderTableRow::layout()
}
statePusher.pop();
+ // RenderTableSection::layoutRows will set our logical height and width later, so it calls updateLayerTransform().
setNeedsLayout(false);
}
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index 30620d2..534fe81 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -579,6 +579,7 @@ int RenderTableSection::layoutRows(int toAdd)
rowRenderer->setLocation(0, m_rowPos[r]);
rowRenderer->setLogicalWidth(logicalWidth());
rowRenderer->setLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing);
+ rowRenderer->updateLayerTransform();
}
for (int c = 0; c < nEffCols; c++) {
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index 7635d07..0d1bd91 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -429,7 +429,7 @@ VisiblePosition RenderText::positionForPoint(const IntPoint& point)
// at the y coordinate of the first line or above
// and the x coordinate is to the left of the first text box left edge
offset = firstTextBox()->offsetForPosition(pointLineDirection);
- return createVisiblePosition(offset + firstTextBox()->start(), DOWNSTREAM);
+ return createVisiblePosition(offset + firstTextBox()->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
}
if (lastTextBox() && pointBlockDirection >= lastTextBox()->root()->selectionTop() && pointLineDirection >= lastTextBox()->logicalRight()) {
// at the y coordinate of the last line or below
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index 9b9e51a..2040f10 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -490,11 +490,11 @@ static const char* fontFamiliesWithInvalidCharWidth[] = {
bool RenderTextControl::hasValidAvgCharWidth(AtomicString family)
{
static HashSet<AtomicString>* fontFamiliesWithInvalidCharWidthMap = 0;
-
+
if (!fontFamiliesWithInvalidCharWidthMap) {
fontFamiliesWithInvalidCharWidthMap = new HashSet<AtomicString>;
-
- for (unsigned i = 0; i < sizeof(fontFamiliesWithInvalidCharWidth) / sizeof(fontFamiliesWithInvalidCharWidth[0]); i++)
+
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(fontFamiliesWithInvalidCharWidth); ++i)
fontFamiliesWithInvalidCharWidthMap->add(AtomicString(fontFamiliesWithInvalidCharWidth[i]));
}
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index da85863..8ba37e9 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -589,16 +589,15 @@ int RenderTextControlSingleLine::preferredDecorationWidthRight() const
void RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
{
if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0) {
- toRenderBlock(resultsRenderer)->computeLogicalHeight();
+ resultsRenderer->computeLogicalHeight();
setHeight(max(height(),
resultsRenderer->borderTop() + resultsRenderer->borderBottom() +
resultsRenderer->paddingTop() + resultsRenderer->paddingBottom() +
resultsRenderer->marginTop() + resultsRenderer->marginBottom()));
lineHeight = max(lineHeight, resultsRenderer->height());
}
-
if (RenderBox* cancelRenderer = m_cancelButton ? m_cancelButton->renderBox() : 0) {
- toRenderBlock(cancelRenderer)->computeLogicalHeight();
+ cancelRenderer->computeLogicalHeight();
setHeight(max(height(),
cancelRenderer->borderTop() + cancelRenderer->borderBottom() +
cancelRenderer->paddingTop() + cancelRenderer->paddingBottom() +
@@ -670,6 +669,21 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded()
}
}
+#if ENABLE(INPUT_SPEECH)
+void RenderTextControlSingleLine::speechAttributeChanged()
+{
+ // The inner text element of this renderer has different styles depending on whether the
+ // speech button is visible or not. So when the speech attribute changes, we reset the
+ // whole thing and recreate to get the right styles and layout.
+ if (m_speechButton)
+ m_speechButton->detach();
+ setChildrenInline(true);
+ RenderStyle* parentStyle = m_innerBlock ? m_innerBlock->renderer()->style() : style();
+ setStyle(createInnerTextStyle(parentStyle));
+ updateFromElement();
+}
+#endif
+
void RenderTextControlSingleLine::updateFromElement()
{
createSubtreeIfNeeded();
diff --git a/WebCore/rendering/RenderTextControlSingleLine.h b/WebCore/rendering/RenderTextControlSingleLine.h
index 26987fd..d51d7f3 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/WebCore/rendering/RenderTextControlSingleLine.h
@@ -59,6 +59,10 @@ public:
// Decoration width outside of the text field.
int decorationWidthRight() const;
+#if ENABLE(INPUT_SPEECH)
+ void speechAttributeChanged();
+#endif
+
private:
int preferredDecorationWidthRight() const;
virtual bool hasControlClip() const;
diff --git a/WebCore/rendering/RenderThemeChromiumSkia.cpp b/WebCore/rendering/RenderThemeChromiumSkia.cpp
index d90bbc2..7f664eb 100644
--- a/WebCore/rendering/RenderThemeChromiumSkia.cpp
+++ b/WebCore/rendering/RenderThemeChromiumSkia.cpp
@@ -127,7 +127,8 @@ RenderThemeChromiumSkia::~RenderThemeChromiumSkia()
// Use the Windows style sheets to match their metrics.
String RenderThemeChromiumSkia::extraDefaultStyleSheet()
{
- return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet));
+ return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet)) +
+ String(themeChromiumSkiaUserAgentStyleSheet, sizeof(themeChromiumSkiaUserAgentStyleSheet));
}
String RenderThemeChromiumSkia::extraQuirksStyleSheet()
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index 8672ff4..7ed44d4 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -142,7 +142,9 @@ void RenderView::layout()
// Reset overflow and then replace it with docWidth and docHeight.
m_overflow.clear();
- addLayoutOverflow(IntRect(0, 0, docWidth(), docHeight()));
+ int leftOverflow = docLeft();
+ int topOverflow = docTop();
+ addLayoutOverflow(IntRect(leftOverflow, topOverflow, docWidth(leftOverflow), docHeight(topOverflow)));
ASSERT(layoutDelta() == IntSize());
ASSERT(m_layoutStateDisableCount == 0);
@@ -654,9 +656,18 @@ IntRect RenderView::viewRect() const
return IntRect();
}
-int RenderView::docHeight() const
+int RenderView::docTop() const
{
- int h = lowestPosition();
+ // Clip out top overflow in vertical LTR pages or horizontal-tb pages.
+ if ((!style()->isHorizontalWritingMode() && style()->isLeftToRightDirection()) || style()->writingMode() == TopToBottomWritingMode)
+ return 0;
+ return std::min(0, topmostPosition());
+}
+
+int RenderView::docHeight(int topOverflow) const
+{
+ int h = ((!style()->isHorizontalWritingMode() && style()->isLeftToRightDirection()) || style()->writingMode() == TopToBottomWritingMode) ?
+ lowestPosition() : height() - topOverflow;
// FIXME: This doesn't do any margin collapsing.
// Instead of this dh computation we should keep the result
@@ -671,9 +682,18 @@ int RenderView::docHeight() const
return h;
}
-int RenderView::docWidth() const
+int RenderView::docLeft() const
+{
+ // Clip out left overflow in horizontal LTR pages or vertical-lr pages.
+ if ((style()->isHorizontalWritingMode() && style()->isLeftToRightDirection()) || style()->writingMode() == LeftToRightWritingMode)
+ return 0;
+ return std::min(0, leftmostPosition());
+}
+
+int RenderView::docWidth(int leftOverflow) const
{
- int w = rightmostPosition();
+ int w = ((style()->isHorizontalWritingMode() && style()->isLeftToRightDirection()) || style()->writingMode() == LeftToRightWritingMode) ?
+ rightmostPosition() : width() - leftOverflow;
for (RenderBox* c = firstChildBox(); c; c = c->nextSiblingBox()) {
int dw = c->width() + c->marginLeft() + c->marginRight();
diff --git a/WebCore/rendering/RenderView.h b/WebCore/rendering/RenderView.h
index 81cb686..99b6a5e 100644
--- a/WebCore/rendering/RenderView.h
+++ b/WebCore/rendering/RenderView.h
@@ -175,12 +175,20 @@ protected:
private:
bool shouldRepaint(const IntRect& r) const;
+<<<<<<< HEAD
#ifdef ANDROID_FLATTEN_FRAMESET
public: // used by layout function
#endif
int docHeight() const;
int docWidth() const;
+=======
+
+ int docTop() const;
+ int docHeight(int topOverflow) const;
+ int docLeft() const;
+ int docWidth(int leftOverflow) const;
+>>>>>>> webkit.org at r73109
// These functions may only be accessed by LayoutStateMaintainer.
bool pushLayoutState(RenderBox* renderer, const IntSize& offset, int pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
diff --git a/WebCore/rendering/RootInlineBox.cpp b/WebCore/rendering/RootInlineBox.cpp
index cdc6525..da7d037 100644
--- a/WebCore/rendering/RootInlineBox.cpp
+++ b/WebCore/rendering/RootInlineBox.cpp
@@ -48,6 +48,7 @@ RootInlineBox::RootInlineBox(RenderBlock* block)
, m_paginationStrut(0)
, m_blockLogicalHeight(0)
, m_baselineType(AlphabeticBaseline)
+ , m_containsRuby(false)
{
setIsHorizontal(block->style()->isHorizontalWritingMode());
}
@@ -199,9 +200,10 @@ bool RootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
void RootInlineBox::adjustPosition(int dx, int dy)
{
InlineFlowBox::adjustPosition(dx, dy);
- m_lineTop += dy;
- m_lineBottom += dy;
- m_blockLogicalHeight += dy;
+ int blockDirectionDelta = isHorizontal() ? dy : dx;
+ m_lineTop += blockDirectionDelta;
+ m_lineBottom += blockDirectionDelta;
+ m_blockLogicalHeight += blockDirectionDelta;
}
void RootInlineBox::childRemoved(InlineBox* box)
@@ -244,11 +246,25 @@ int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAn
int maxHeight = maxAscent + maxDescent;
int lineTop = heightOfBlock;
int lineBottom = heightOfBlock;
+ int lineTopIncludingMargins = heightOfBlock;
+ int lineBottomIncludingMargins = heightOfBlock;
bool setLineTop = false;
- placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, setLineTop, m_baselineType);
+ bool containsRuby = false;
+ placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, setLineTop,
+ lineTopIncludingMargins, lineBottomIncludingMargins, containsRuby, m_baselineType);
computeBlockDirectionOverflow(lineTop, lineBottom, noQuirksMode, textBoxDataMap);
setLineTopBottomPositions(lineTop, lineBottom);
+ m_containsRuby = containsRuby;
+
+ int rubyAdjustment = blockDirectionRubyAdjustment();
+ if (rubyAdjustment) {
+ // FIXME: Need to handle pagination here. We might have to move to the next page/column as a result of the
+ // ruby expansion.
+ adjustBlockDirectionPosition(rubyAdjustment);
+ heightOfBlock += rubyAdjustment;
+ }
+
// Detect integer overflow.
if (heightOfBlock > numeric_limits<int>::max() - maxHeight)
return numeric_limits<int>::max();
@@ -256,6 +272,21 @@ int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAn
return heightOfBlock + maxHeight;
}
+int RootInlineBox::blockDirectionRubyAdjustment() const
+{
+ if (!renderer()->style()->isFlippedLinesWritingMode()) {
+ if (!containsRuby())
+ return 0;
+ int highestAllowedPosition = prevRootBox() ? min(prevRootBox()->lineBottom(), lineTop()) : block()->borderBefore();
+ return computeBlockDirectionRubyAdjustment(highestAllowedPosition);
+ } else if (prevRootBox() && prevRootBox()->containsRuby()) {
+ // We have to compute the Ruby expansion for the previous line to see how much we should move.
+ int lowestAllowedPosition = max(prevRootBox()->lineBottom(), lineTop());
+ return prevRootBox()->computeBlockDirectionRubyAdjustment(lowestAllowedPosition);
+ }
+ return 0;
+}
+
GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
int selTop, int selHeight, const PaintInfo* paintInfo)
{
diff --git a/WebCore/rendering/RootInlineBox.h b/WebCore/rendering/RootInlineBox.h
index 851b4b1..42ad4da 100644
--- a/WebCore/rendering/RootInlineBox.h
+++ b/WebCore/rendering/RootInlineBox.h
@@ -128,10 +128,14 @@ public:
FontBaseline baselineType() const { return m_baselineType; }
+ bool containsRuby() const { return m_containsRuby; }
+
private:
bool hasEllipsisBox() const { return m_hasEllipsisBoxOrHyphen; }
void setHasEllipsisBox(bool hasEllipsisBox) { m_hasEllipsisBoxOrHyphen = hasEllipsisBox; }
+ int blockDirectionRubyAdjustment() const;
+
// Where this line ended. The exact object and the position within that object are stored so that
// we can create an InlineIterator beginning just after the end of this line.
RenderObject* m_lineBreakObj;
@@ -153,6 +157,9 @@ private:
// Whether or not this line uses alphabetic or ideographic baselines by default.
FontBaseline m_baselineType;
+ // If the line contains any ruby runs, then this will be true.
+ bool m_containsRuby : 1;
+
WTF::Unicode::Direction m_lineBreakBidiStatusEor : 5;
WTF::Unicode::Direction m_lineBreakBidiStatusLastStrong : 5;
WTF::Unicode::Direction m_lineBreakBidiStatusLast : 5;
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index 608cf4d..cbde49b 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -148,7 +148,7 @@ void SVGRenderSupport::finishRenderSVGContent(RenderObject* object, PaintInfo& p
SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
if (resources) {
if (RenderSVGResourceFilter* filter = resources->filter()) {
- filter->postApplyResource(object, paintInfo.context, ApplyToDefaultMode);
+ filter->postApplyResource(object, paintInfo.context, ApplyToDefaultMode, /* path */0);
paintInfo.context = savedContext;
}
}
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index b9a854d..9393fd6 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -415,7 +415,8 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGPath& path)
} else if (svgElement->hasTagName(SVGNames::pathTag)) {
SVGPathElement* element = static_cast<SVGPathElement*>(svgElement);
String pathString;
- SVGPathParserFactory::self()->buildStringFromSVGPathSegList(element->pathSegList(), pathString, UnalteredParsing);
+ // FIXME: We should switch to UnalteredParsing here - this will affect the path dumping output of dozens of tests.
+ SVGPathParserFactory::self()->buildStringFromByteStream(element->pathByteStream(), pathString, NormalizedParsing);
writeNameAndQuotedValue(ts, "data", pathString);
} else
ASSERT_NOT_REACHED();
@@ -558,10 +559,13 @@ void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int i
writeNameValuePair(ts, "filterUnits", filter->filterUnits());
writeNameValuePair(ts, "primitiveUnits", filter->primitiveUnits());
ts << "\n";
- if (RefPtr<SVGFilterBuilder> builder = filter->buildPrimitives()) {
+ // Creating a placeholder filter which is passed to the builder.
+ FloatRect dummyRect;
+ RefPtr<SVGFilter> dummyFilter = SVGFilter::create(AffineTransform(), dummyRect, dummyRect, dummyRect, true);
+ if (RefPtr<SVGFilterBuilder> builder = filter->buildPrimitives(dummyFilter.get())) {
if (FilterEffect* lastEffect = builder->lastEffect())
lastEffect->externalRepresentation(ts, indent + 1);
- }
+ }
#endif
} else if (resource->resourceType() == ClipperResourceType) {
RenderSVGResourceClipper* clipper = static_cast<RenderSVGResourceClipper*>(resource);
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index fba523e..92c51ee 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -41,6 +41,7 @@
#include "RenderTextControlSingleLine.h"
#include "ScrollbarTheme.h"
#include "SpeechInput.h"
+#include "SpeechInputEvent.h"
namespace WebCore {
@@ -51,6 +52,7 @@ public:
RenderTextControlInnerBlock(Node* node, bool isMultiLine) : RenderBlock(node), m_multiLine(isMultiLine) { }
private:
+ virtual bool hasLineIfEmpty() const { return true; }
virtual VisiblePosition positionForPoint(const IntPoint&);
bool m_multiLine;
@@ -112,11 +114,6 @@ void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<Render
parent->renderer()->addChild(renderer);
}
-bool TextControlInnerElement::isSpellCheckingEnabled() const
-{
- return m_shadowParent && m_shadowParent->isSpellCheckingEnabled();
-}
-
// ----------------------------
inline TextControlInnerTextElement::TextControlInnerTextElement(Document* document, HTMLElement* shadowParent)
@@ -478,7 +475,7 @@ void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputR
// here, we take a temporary reference.
RefPtr<HTMLInputElement> holdRef(input);
input->setValue(results.isEmpty() ? "" : results[0]->utterance());
- input->dispatchWebkitSpeechChangeEvent();
+ input->dispatchEvent(SpeechInputEvent::create(eventNames().webkitspeechchangeEvent, results));
renderer()->repaint();
}
diff --git a/WebCore/rendering/TextControlInnerElements.h b/WebCore/rendering/TextControlInnerElements.h
index 51c9aff..5af98ed 100644
--- a/WebCore/rendering/TextControlInnerElements.h
+++ b/WebCore/rendering/TextControlInnerElements.h
@@ -49,7 +49,6 @@ private:
virtual bool isMouseFocusable() const { return false; }
virtual bool isShadowNode() const { return m_shadowParent.get(); }
virtual ContainerNode* shadowParentNode() { return m_shadowParent.get(); }
- virtual bool isSpellCheckingEnabled() const;
void setShadowParentNode(HTMLElement* shadowParent) { m_shadowParent = shadowParent; }
RefPtr<HTMLElement> m_shadowParent;
diff --git a/WebCore/rendering/break_lines.cpp b/WebCore/rendering/break_lines.cpp
index 054cd43..16bfcc2 100644
--- a/WebCore/rendering/break_lines.cpp
+++ b/WebCore/rendering/break_lines.cpp
@@ -28,6 +28,7 @@
#include "CharacterNames.h"
#include "TextBreakIterator.h"
+#include <wtf/StdLibExtras.h>
#if PLATFORM(MAC)
#include <CoreServices/CoreServices.h>
@@ -114,8 +115,7 @@ static const unsigned char asciiLineBreakTable[][(asciiLineBreakTableLastChar -
#undef DI
#undef AL
-COMPILE_ASSERT(sizeof(asciiLineBreakTable) / sizeof(asciiLineBreakTable[0]) == asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar + 1,
- TestLineBreakTableConsistency);
+COMPILE_ASSERT(WTF_ARRAY_LENGTH(asciiLineBreakTable) == asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar + 1, TestLineBreakTableConsistency);
static inline bool shouldBreakAfter(UChar ch, UChar nextCh)
{
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index c206acd..ad66660 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -1382,6 +1382,11 @@ inline int adjustForAbsoluteZoom(int value, const RenderStyle* style)
return roundForImpreciseConversion<int, INT_MAX, INT_MIN>(value / zoomFactor);
}
+inline float adjustFloatForAbsoluteZoom(float value, const RenderStyle* style)
+{
+ return value / style->effectiveZoom();
+}
+
} // namespace WebCore
#endif // RenderStyle_h
diff --git a/WebCore/rendering/svg/RenderSVGPath.cpp b/WebCore/rendering/svg/RenderSVGPath.cpp
index 483303f..0c8ac0c 100644
--- a/WebCore/rendering/svg/RenderSVGPath.cpp
+++ b/WebCore/rendering/svg/RenderSVGPath.cpp
@@ -148,19 +148,17 @@ void RenderSVGPath::layout()
void RenderSVGPath::fillAndStrokePath(GraphicsContext* context)
{
- context->beginPath();
RenderStyle* style = this->style();
Color fallbackColor;
if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(this, style, fallbackColor)) {
- context->addPath(m_path);
if (fillPaintingResource->applyResource(this, style, context, ApplyToFillMode))
- fillPaintingResource->postApplyResource(this, context, ApplyToFillMode);
+ fillPaintingResource->postApplyResource(this, context, ApplyToFillMode, &m_path);
else if (fallbackColor.isValid()) {
RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
fallbackResource->setColor(fallbackColor);
if (fallbackResource->applyResource(this, style, context, ApplyToFillMode))
- fallbackResource->postApplyResource(this, context, ApplyToFillMode);
+ fallbackResource->postApplyResource(this, context, ApplyToFillMode, &m_path);
}
}
@@ -169,30 +167,31 @@ void RenderSVGPath::fillAndStrokePath(GraphicsContext* context)
if (!strokePaintingResource)
return;
+ Path path;
+
+ bool nonScalingStroke = style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE;
bool restoreContext = false;
- if (style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE) {
+ if (nonScalingStroke) {
SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
AffineTransform nonScalingStrokeTransform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate);
if (!nonScalingStrokeTransform.isInvertible())
return;
- Path transformedPath = m_path;
- transformedPath.transform(nonScalingStrokeTransform);
+ path = m_path;
+ path.transform(nonScalingStrokeTransform);
context->save();
context->concatCTM(nonScalingStrokeTransform.inverse());
- context->addPath(transformedPath);
restoreContext = true;
- } else
- context->addPath(m_path);
+ }
if (strokePaintingResource->applyResource(this, style, context, ApplyToStrokeMode))
- strokePaintingResource->postApplyResource(this, context, ApplyToStrokeMode);
+ strokePaintingResource->postApplyResource(this, context, ApplyToStrokeMode, nonScalingStroke ? &path : &m_path);
else if (fallbackColor.isValid()) {
RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
fallbackResource->setColor(fallbackColor);
if (fallbackResource->applyResource(this, style, context, ApplyToStrokeMode))
- fallbackResource->postApplyResource(this, context, ApplyToStrokeMode);
+ fallbackResource->postApplyResource(this, context, ApplyToStrokeMode, nonScalingStroke ? &path : &m_path);
}
if (restoreContext)
diff --git a/WebCore/rendering/svg/SVGInlineTextBox.cpp b/WebCore/rendering/svg/SVGInlineTextBox.cpp
index d1f660a..5d0278b 100644
--- a/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -318,14 +318,14 @@ bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, Render
return true;
}
-void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context)
+void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context, const Path* path)
{
ASSERT(m_paintingResource);
RenderObject* parentRenderer = parent()->renderer();
ASSERT(parentRenderer);
- m_paintingResource->postApplyResource(parentRenderer, context, m_paintingResourceMode);
+ m_paintingResource->postApplyResource(parentRenderer, context, m_paintingResourceMode, path);
m_paintingResource = 0;
}
@@ -344,7 +344,7 @@ bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& c
void SVGInlineTextBox::restoreGraphicsContextAfterTextPainting(GraphicsContext*& context, TextRun& textRun)
{
- releasePaintingResource(context);
+ releasePaintingResource(context, /* path */0);
#if ENABLE(SVG_FONTS)
textRun.setActivePaintingResource(0);
@@ -500,11 +500,9 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextD
path.addRect(FloatRect(fragment.x, y, fragment.width, thickness));
context->save();
- context->beginPath();
- context->addPath(path);
if (acquirePaintingResource(context, decorationRenderer, decorationStyle))
- releasePaintingResource(context);
+ releasePaintingResource(context, &path);
context->restore();
}
diff --git a/WebCore/rendering/svg/SVGInlineTextBox.h b/WebCore/rendering/svg/SVGInlineTextBox.h
index 8e82dda..acc5e9f 100644
--- a/WebCore/rendering/svg/SVGInlineTextBox.h
+++ b/WebCore/rendering/svg/SVGInlineTextBox.h
@@ -68,7 +68,7 @@ private:
TextRun constructTextRun(RenderStyle*, const SVGTextFragment&) const;
bool acquirePaintingResource(GraphicsContext*&, RenderObject*, RenderStyle*);
- void releasePaintingResource(GraphicsContext*&);
+ void releasePaintingResource(GraphicsContext*&, const Path*);
bool prepareGraphicsContextForTextPainting(GraphicsContext*&, TextRun&, RenderStyle*);
void restoreGraphicsContextAfterTextPainting(GraphicsContext*&, TextRun&);