summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-06-15 19:36:43 +0100
committerBen Murdoch <benm@google.com>2010-06-16 14:52:28 +0100
commit545e470e52f0ac6a3a072bf559c796b42c6066b6 (patch)
treec0c14763654d84d37577dde512c3d3b4699a9e86 /WebCore/rendering
parent719298a66237d38ea5c05f1547123ad8aacbc237 (diff)
downloadexternal_webkit-545e470e52f0ac6a3a072bf559c796b42c6066b6.zip
external_webkit-545e470e52f0ac6a3a072bf559c796b42c6066b6.tar.gz
external_webkit-545e470e52f0ac6a3a072bf559c796b42c6066b6.tar.bz2
Merge webkit.org at r61121: Initial merge by git.
Change-Id: Icd6db395c62285be384d137164d95d7466c98760
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/HitTestRequest.h12
-rw-r--r--WebCore/rendering/InlineTextBox.cpp14
-rw-r--r--WebCore/rendering/LayoutState.cpp7
-rw-r--r--WebCore/rendering/PointerEventsHitRules.cpp5
-rw-r--r--WebCore/rendering/PointerEventsHitRules.h3
-rw-r--r--WebCore/rendering/RenderApplet.cpp2
-rw-r--r--WebCore/rendering/RenderBlock.cpp340
-rw-r--r--WebCore/rendering/RenderBlock.h10
-rw-r--r--WebCore/rendering/RenderBlockLineLayout.cpp1
-rw-r--r--WebCore/rendering/RenderBox.cpp2
-rw-r--r--WebCore/rendering/RenderDataGrid.cpp2
-rw-r--r--WebCore/rendering/RenderFileUploadControl.cpp25
-rw-r--r--WebCore/rendering/RenderFrameSet.cpp4
-rw-r--r--WebCore/rendering/RenderIFrame.cpp1
-rw-r--r--WebCore/rendering/RenderImage.cpp3
-rw-r--r--WebCore/rendering/RenderInline.cpp5
-rw-r--r--WebCore/rendering/RenderLayer.cpp14
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp9
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp14
-rw-r--r--WebCore/rendering/RenderLineBoxList.cpp3
-rw-r--r--WebCore/rendering/RenderListBox.cpp10
-rw-r--r--WebCore/rendering/RenderMenuList.h2
-rw-r--r--WebCore/rendering/RenderMeter.cpp15
-rw-r--r--WebCore/rendering/RenderMeter.h2
-rw-r--r--WebCore/rendering/RenderObject.cpp19
-rw-r--r--WebCore/rendering/RenderObject.h5
-rw-r--r--WebCore/rendering/RenderPath.cpp62
-rw-r--r--WebCore/rendering/RenderPath.h2
-rw-r--r--WebCore/rendering/RenderProgress.cpp32
-rw-r--r--WebCore/rendering/RenderProgress.h4
-rw-r--r--WebCore/rendering/RenderSVGContainer.cpp18
-rw-r--r--WebCore/rendering/RenderSVGImage.cpp25
-rw-r--r--WebCore/rendering/RenderSVGResource.h2
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.cpp41
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.h4
-rw-r--r--WebCore/rendering/RenderSVGResourceContainer.h19
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.cpp4
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.h2
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.cpp42
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.h3
-rw-r--r--WebCore/rendering/RenderSVGResourceMarker.h2
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.cpp16
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.h2
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.cpp43
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.h8
-rw-r--r--WebCore/rendering/RenderSVGResourceSolidColor.h2
-rw-r--r--WebCore/rendering/RenderSVGText.cpp41
-rw-r--r--WebCore/rendering/RenderSVGText.h3
-rw-r--r--WebCore/rendering/RenderSlider.cpp23
-rw-r--r--WebCore/rendering/RenderTextControl.cpp10
-rw-r--r--WebCore/rendering/RenderTextControlMultiLine.cpp2
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp5
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.h2
-rw-r--r--WebCore/rendering/RenderTheme.cpp24
-rw-r--r--WebCore/rendering/RenderTheme.h7
-rw-r--r--WebCore/rendering/RenderThemeChromiumSkia.cpp111
-rw-r--r--WebCore/rendering/RenderThemeChromiumSkia.h14
-rw-r--r--WebCore/rendering/RenderThemeChromiumWin.cpp20
-rw-r--r--WebCore/rendering/RenderThemeMac.h11
-rw-r--r--WebCore/rendering/RenderThemeMac.mm103
-rw-r--r--WebCore/rendering/RenderTreeAsText.cpp1
-rw-r--r--WebCore/rendering/RenderWidget.cpp3
-rw-r--r--WebCore/rendering/RootInlineBox.cpp4
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp126
-rw-r--r--WebCore/rendering/SVGRenderSupport.h10
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp11
-rw-r--r--WebCore/rendering/SVGRootInlineBox.cpp8
-rw-r--r--WebCore/rendering/ShadowElement.cpp48
-rw-r--r--WebCore/rendering/ShadowElement.h68
-rw-r--r--WebCore/rendering/style/RenderStyle.cpp3
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.cpp33
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.h8
-rw-r--r--WebCore/rendering/style/SVGRenderStyleDefs.h5
73 files changed, 1135 insertions, 431 deletions
diff --git a/WebCore/rendering/HitTestRequest.h b/WebCore/rendering/HitTestRequest.h
index ca1445a..97d8680 100644
--- a/WebCore/rendering/HitTestRequest.h
+++ b/WebCore/rendering/HitTestRequest.h
@@ -27,11 +27,12 @@ namespace WebCore {
class HitTestRequest {
public:
enum RequestType {
- ReadOnly = 0x1,
- Active = 0x2,
- MouseMove = 0x4,
- MouseUp = 0x8,
- IgnoreClipping = 0x10
+ ReadOnly = 1 << 1,
+ Active = 1 << 2,
+ MouseMove = 1 << 3,
+ MouseUp = 1 << 4,
+ IgnoreClipping = 1 << 5,
+ SVGClipContent = 1 << 6
};
HitTestRequest(int requestType)
@@ -44,6 +45,7 @@ public:
bool mouseMove() const { return m_requestType & MouseMove; }
bool mouseUp() const { return m_requestType & MouseUp; }
bool ignoreClipping() const { return m_requestType & IgnoreClipping; }
+ bool svgClipContent() const { return m_requestType & SVGClipContent; }
private:
int m_requestType;
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 0933ae4..2fc5823 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -382,8 +382,8 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
GraphicsContext* context = paintInfo.context;
// Determine whether or not we have composition underlines to draw.
- bool containsComposition = renderer()->node() && renderer()->document()->frame()->editor()->compositionNode() == renderer()->node();
- bool useCustomUnderlines = containsComposition && renderer()->document()->frame()->editor()->compositionUsesCustomUnderlines();
+ bool containsComposition = renderer()->node() && renderer()->frame()->editor()->compositionNode() == renderer()->node();
+ bool useCustomUnderlines = containsComposition && renderer()->frame()->editor()->compositionUsesCustomUnderlines();
// Set our font.
RenderStyle* styleToUse = renderer()->style(m_firstLine);
@@ -401,8 +401,8 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
if (containsComposition && !useCustomUnderlines)
paintCompositionBackground(context, tx, ty, styleToUse, font,
- renderer()->document()->frame()->editor()->compositionStart(),
- renderer()->document()->frame()->editor()->compositionEnd());
+ renderer()->frame()->editor()->compositionStart(),
+ renderer()->frame()->editor()->compositionEnd());
paintDocumentMarkers(context, tx, ty, styleToUse, font, true);
@@ -531,7 +531,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
paintDocumentMarkers(context, tx, ty, styleToUse, font, false);
if (useCustomUnderlines) {
- const Vector<CompositionUnderline>& underlines = renderer()->document()->frame()->editor()->customCompositionUnderlines();
+ const Vector<CompositionUnderline>& underlines = renderer()->frame()->editor()->customCompositionUnderlines();
size_t numUnderlines = underlines.size();
for (size_t index = 0; index < numUnderlines; ++index) {
@@ -634,7 +634,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, int tx,
void InlineTextBox::paintCustomHighlight(int tx, int ty, const AtomicString& type)
{
- Frame* frame = renderer()->document()->frame();
+ Frame* frame = renderer()->frame();
if (!frame)
return;
Page* page = frame->page();
@@ -818,7 +818,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, co
renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
// Optionally highlight the text
- if (renderer()->document()->frame()->markedTextMatchesAreHighlighted()) {
+ if (renderer()->frame()->markedTextMatchesAreHighlighted()) {
Color color = marker.activeMatch ?
renderer()->theme()->platformActiveTextSearchHighlightColor() :
renderer()->theme()->platformInactiveTextSearchHighlightColor();
diff --git a/WebCore/rendering/LayoutState.cpp b/WebCore/rendering/LayoutState.cpp
index c94e77b..18c3da7 100644
--- a/WebCore/rendering/LayoutState.cpp
+++ b/WebCore/rendering/LayoutState.cpp
@@ -90,6 +90,13 @@ LayoutState::LayoutState(RenderObject* root)
RenderObject* container = root->container();
FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), false, true);
m_offset = IntSize(absContentPoint.x(), absContentPoint.y());
+
+ if (container->hasOverflowClip()) {
+ RenderLayer* layer = toRenderBoxModelObject(container)->layer();
+ m_clipped = true;
+ m_clipRect = IntRect(toPoint(m_offset), layer->size());
+ m_offset -= layer->scrolledContentOffset();
+ }
}
#ifndef NDEBUG
diff --git a/WebCore/rendering/PointerEventsHitRules.cpp b/WebCore/rendering/PointerEventsHitRules.cpp
index ababcfd..cc5aae4 100644
--- a/WebCore/rendering/PointerEventsHitRules.cpp
+++ b/WebCore/rendering/PointerEventsHitRules.cpp
@@ -22,13 +22,16 @@
namespace WebCore {
-PointerEventsHitRules::PointerEventsHitRules(EHitTesting hitTesting, EPointerEvents pointerEvents)
+PointerEventsHitRules::PointerEventsHitRules(EHitTesting hitTesting, const HitTestRequest& request, EPointerEvents pointerEvents)
: requireVisible(false)
, requireFill(false)
, requireStroke(false)
, canHitStroke(false)
, canHitFill(false)
{
+ if (request.svgClipContent())
+ pointerEvents = PE_FILL;
+
if (hitTesting == SVG_PATH_HITTESTING) {
switch (pointerEvents)
{
diff --git a/WebCore/rendering/PointerEventsHitRules.h b/WebCore/rendering/PointerEventsHitRules.h
index c17c19c..72fbc45 100644
--- a/WebCore/rendering/PointerEventsHitRules.h
+++ b/WebCore/rendering/PointerEventsHitRules.h
@@ -20,6 +20,7 @@
#ifndef PointerEventsHitRules_h
#define PointerEventsHitRules_h
+#include "HitTestRequest.h"
#include "RenderStyleConstants.h"
namespace WebCore {
@@ -32,7 +33,7 @@ public:
SVG_TEXT_HITTESTING
};
- PointerEventsHitRules(EHitTesting, EPointerEvents);
+ PointerEventsHitRules(EHitTesting, const HitTestRequest&, EPointerEvents);
bool requireVisible;
bool requireFill;
diff --git a/WebCore/rendering/RenderApplet.cpp b/WebCore/rendering/RenderApplet.cpp
index 7411c54..a1689a5 100644
--- a/WebCore/rendering/RenderApplet.cpp
+++ b/WebCore/rendering/RenderApplet.cpp
@@ -70,7 +70,7 @@ void RenderApplet::createWidgetIfNecessary()
}
}
- Frame* frame = document()->frame();
+ Frame* frame = this->frame();
ASSERT(frame);
setWidget(frame->loader()->createJavaAppletWidget(IntSize(contentWidth, contentHeight), element, m_args));
}
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 5ac57f0..f60b13c 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -36,6 +36,7 @@
#include "RenderFlexibleBox.h"
#include "RenderImage.h"
#include "RenderInline.h"
+#include "RenderLayer.h"
#include "RenderMarquee.h"
#include "RenderReplica.h"
#include "RenderTableCell.h"
@@ -234,6 +235,16 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
{
RenderBox::styleDidChange(diff, oldStyle);
+ if (!isAnonymousBlock()) {
+ // Ensure that all of our continuation blocks pick up the new style.
+ for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
+ RenderBoxModelObject* nextCont = currCont->continuation();
+ currCont->setContinuation(0);
+ currCont->setStyle(style());
+ currCont->setContinuation(nextCont);
+ }
+ }
+
// FIXME: We could save this call when the change only affected non-inherited properties
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isAnonymousBlock()) {
@@ -268,6 +279,68 @@ void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
return children()->updateBeforeAfterContent(this, pseudoId);
}
+RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
+{
+ if (beforeChild && beforeChild->parent() == this)
+ return this;
+
+ RenderBlock* curr = toRenderBlock(continuation());
+ RenderBlock* nextToLast = this;
+ RenderBlock* last = this;
+ while (curr) {
+ if (beforeChild && beforeChild->parent() == curr) {
+ if (curr->firstChild() == beforeChild)
+ return last;
+ return curr;
+ }
+
+ nextToLast = last;
+ last = curr;
+ curr = toRenderBlock(curr->continuation());
+ }
+
+ if (!beforeChild && !last->firstChild())
+ return nextToLast;
+ return last;
+}
+
+void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
+{
+ RenderBlock* flow = continuationBefore(beforeChild);
+ ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
+ RenderBoxModelObject* beforeChildParent = 0;
+ if (beforeChild)
+ beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
+ else {
+ RenderBoxModelObject* cont = flow->continuation();
+ if (cont)
+ beforeChildParent = cont;
+ else
+ beforeChildParent = flow;
+ }
+
+ if (newChild->isFloatingOrPositioned())
+ return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
+
+ // A continuation always consists of two potential candidates: a block or an anonymous
+ // column span box holding column span children.
+ bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
+ bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
+ bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
+
+ if (flow == beforeChildParent)
+ return flow->addChildIgnoringContinuation(newChild, beforeChild);
+
+ // The goal here is to match up if we can, so that we can coalesce and create the
+ // minimal # of continuations needed for the inline.
+ if (childIsNormal == bcpIsNormal)
+ return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
+ if (flowIsNormal == childIsNormal)
+ return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
+ return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
+}
+
+
void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
{
ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
@@ -314,12 +387,158 @@ void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, Render
return;
}
+RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
+{
+ for (RenderObject* curr = this; curr; curr = curr->parent()) {
+ if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
+ || curr->isInlineBlockOrInlineTable())
+ return 0;
+
+ RenderBlock* currBlock = toRenderBlock(curr);
+ if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
+ return currBlock;
+
+ if (currBlock->isAnonymousColumnSpanBlock())
+ return 0;
+ }
+ return 0;
+}
+
+RenderBlock* RenderBlock::clone() const
+{
+ RenderBlock* o = new (renderArena()) RenderBlock(node());
+ o->setStyle(style());
+ o->setChildrenInline(childrenInline());
+ return o;
+}
+
+void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
+ RenderBlock* middleBlock,
+ RenderObject* beforeChild, RenderBoxModelObject* oldCont)
+{
+ // Create a clone of this inline.
+ RenderBlock* cloneBlock = clone();
+ cloneBlock->setContinuation(oldCont);
+
+ // Now take all of the children from beforeChild to the end and remove
+ // them from |this| and place them in the clone.
+ if (!beforeChild && isAfterContent(lastChild()))
+ beforeChild = lastChild();
+ moveChildrenTo(cloneBlock, beforeChild, 0);
+
+ // Hook |clone| up as the continuation of the middle block.
+ middleBlock->setContinuation(cloneBlock);
+
+ // We have been reparented and are now under the fromBlock. We need
+ // to walk up our block parent chain until we hit the containing anonymous columns block.
+ // Once we hit the anonymous columns block we're done.
+ RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
+ RenderBoxModelObject* currChild = this;
+
+ while (curr && curr != fromBlock) {
+ ASSERT(curr->isRenderBlock() && !curr->isAnonymousBlock());
+
+ RenderBlock* blockCurr = toRenderBlock(curr);
+
+ // Create a new clone.
+ RenderBlock* cloneChild = cloneBlock;
+ cloneBlock = blockCurr->clone();
+
+ // Insert our child clone as the first child.
+ cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
+
+ // Hook the clone up as a continuation of |curr|. Note we do encounter
+ // anonymous blocks possibly as we walk up the block chain. When we split an
+ // anonymous block, there's no need to do any continuation hookup, since we haven't
+ // actually split a real element.
+ if (!blockCurr->isAnonymousBlock()) {
+ oldCont = blockCurr->continuation();
+ blockCurr->setContinuation(cloneBlock);
+ cloneBlock->setContinuation(oldCont);
+ }
+
+ // Someone may have indirectly caused a <q> to split. When this happens, the :after content
+ // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after
+ // content gets properly destroyed.
+ if (document()->usesBeforeAfterRules())
+ blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
+
+ // Now we need to take all of the children starting from the first child
+ // *after* currChild and append them all to the clone.
+ RenderObject* afterContent = isAfterContent(cloneBlock->lastChild()) ? cloneBlock->lastChild() : 0;
+ blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, afterContent);
+
+ // Keep walking up the chain.
+ currChild = curr;
+ curr = toRenderBoxModelObject(curr->parent());
+ }
+
+ // Now we are at the columns block level. We need to put the clone into the toBlock.
+ toBlock->children()->appendChildNode(toBlock, cloneBlock);
+
+ // Now take all the children after currChild and remove them from the fromBlock
+ // and put them in the toBlock.
+ fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0);
+}
+
+void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
+ RenderObject* newChild, RenderBoxModelObject* oldCont)
+{
+ RenderBlock* pre = 0;
+ RenderBlock* block = containingColumnsBlock();
+
+ // Delete our line boxes before we do the inline split into continuations.
+ block->deleteLineBoxTree();
+
+ bool madeNewBeforeBlock = false;
+ if (block->isAnonymousColumnsBlock()) {
+ // We can reuse this block and make it the preBlock of the next continuation.
+ pre = block;
+ pre->removePositionedObjects(0);
+ block = toRenderBlock(block->parent());
+ } else {
+ // No anonymous block available for use. Make one.
+ pre = block->createAnonymousColumnsBlock();
+ pre->setChildrenInline(false);
+ madeNewBeforeBlock = true;
+ }
+
+ RenderBlock* post = block->createAnonymousColumnsBlock();
+ post->setChildrenInline(false);
+
+ RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
+ if (madeNewBeforeBlock)
+ block->children()->insertChildNode(block, pre, boxFirst);
+ block->children()->insertChildNode(block, newBlockBox, boxFirst);
+ block->children()->insertChildNode(block, post, boxFirst);
+ block->setChildrenInline(false);
+
+ if (madeNewBeforeBlock)
+ block->moveChildrenTo(pre, boxFirst, 0);
+
+ splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
+
+ // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
+ // time in makeChildrenNonInline by just setting this explicitly up front.
+ newBlockBox->setChildrenInline(false);
+
+ // We delayed adding the newChild until now so that the |newBlockBox| would be fully
+ // connected, thus allowing newChild access to a renderArena should it need
+ // to wrap itself in additional boxes (e.g., table construction).
+ newBlockBox->addChild(newChild);
+
+ // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
+ // get deleted properly. Because objects moves from the pre block into the post block, we want to
+ // make new line boxes instead of leaving the old line boxes around.
+ pre->setNeedsLayoutAndPrefWidthsRecalc();
+ block->setNeedsLayoutAndPrefWidthsRecalc();
+ post->setNeedsLayoutAndPrefWidthsRecalc();
+}
+
RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
{
while (beforeChild->parent() != this) {
RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
- ASSERT(blockToSplit->isAnonymousBlock() && !blockToSplit->continuation());
-
if (blockToSplit->firstChild() != beforeChild) {
// We have to split the parentBlock into two blocks.
RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit);
@@ -333,7 +552,6 @@ RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeC
} else
beforeChild = blockToSplit;
}
-
return beforeChild;
}
@@ -346,10 +564,10 @@ void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, R
// Delete the block's line boxes before we do the split.
block->deleteLineBoxTree();
-
+
if (beforeChild && beforeChild->parent() != this)
beforeChild = splitAnonymousBlocksAroundChild(beforeChild);
-
+
if (beforeChild != firstChild()) {
pre = block->createAnonymousColumnsBlock();
pre->setChildrenInline(block->childrenInline());
@@ -391,19 +609,24 @@ void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, R
post->setNeedsLayoutAndPrefWidthsRecalc();
}
-static RenderBlock* columnsBlockForSpanningElement(RenderBlock* block, RenderObject* newChild)
+RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
{
- // FIXME: The style of this function may seem weird.
- // This function is the gateway for the addition of column-span support. Support will be added in three stages:
+ // FIXME: This function is the gateway for the addition of column-span support. It will
+ // be added to in three stages:
// (1) Immediate children of a multi-column block can span.
// (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
// (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
// cross the streams and have to cope with both types of continuations mixed together).
- // This function currently only supports (1).
- if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned()
- && !newChild->isInline() && !block->isAnonymousColumnSpanBlock() && block->style()->specifiesColumns())
- return block;
- return 0;
+ // This function currently supports (1) and (2).
+ RenderBlock* columnsBlockAncestor = 0;
+ if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned()
+ && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
+ if (style()->specifiesColumns())
+ columnsBlockAncestor = this;
+ else
+ columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false);
+ }
+ return columnsBlockAncestor;
}
void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
@@ -418,26 +641,34 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
}
// Check for a spanning element in columns.
- RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(this, newChild);
+ RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
if (columnsBlockAncestor) {
- ASSERT(columnsBlockAncestor == this);
-
- // We are placing a column-span element inside a block. We have to perform a split of this
- // block's children. This involves creating an anonymous block box to hold
- // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
- // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
+ // We are placing a column-span element inside a block.
RenderBlock* newBox = createAnonymousColumnSpanBlock();
- // Someone may have put the spanning element inside an element with generated content, causing a split. When this happens,
- // the :after content has to move into the last anonymous block. Call updateBeforeAfterContent to ensure that our :after
- // content gets properly destroyed.
- bool isLastChild = (beforeChild == lastChild());
- if (document()->usesBeforeAfterRules())
- children()->updateBeforeAfterContent(this, AFTER);
- if (isLastChild && beforeChild != lastChild())
- beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
- // point to be 0. It's just a straight append now.
+ if (columnsBlockAncestor != this) {
+ // We are nested inside a multi-column element and are being split by the span. We have to break up
+ // our block into continuations.
+ RenderBoxModelObject* oldContinuation = continuation();
+ setContinuation(newBox);
+
+ // Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content
+ // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that our :after
+ // content gets properly destroyed.
+ bool isLastChild = (beforeChild == lastChild());
+ if (document()->usesBeforeAfterRules())
+ children()->updateBeforeAfterContent(this, AFTER);
+ if (isLastChild && beforeChild != lastChild())
+ beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
+ // point to be 0. It's just a straight append now.
+
+ splitFlow(beforeChild, newBox, newChild, oldContinuation);
+ return;
+ }
+ // We have to perform a split of this block's children. This involves creating an anonymous block box to hold
+ // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
+ // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
return;
}
@@ -521,7 +752,14 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
- if (!isAnonymous() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
+ if (continuation() && !isAnonymousBlock())
+ return addChildToContinuation(newChild, beforeChild);
+ return addChildIgnoringContinuation(newChild, beforeChild);
+}
+
+void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
+{
+ if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
return addChildToAnonymousColumnBlocks(newChild, beforeChild);
return addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
}
@@ -1885,11 +2123,13 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
PaintInfo info(paintInfo);
info.phase = newPhase;
info.paintingRoot = paintingRootForChildren(paintInfo);
- bool isPrinting = document()->printing();
+ bool checkPageBreaks = document()->printing() && !document()->settings()->paginateDuringLayoutEnabled();
+ bool checkColumnBreaks = !checkPageBreaks && !view()->printRect().isEmpty() && !document()->settings()->paginateDuringLayoutEnabled();
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
// Check for page-break-before: always, and if it's set, break and bail.
- if (isPrinting && !childrenInline() && child->style()->pageBreakBefore() == PBALWAYS
+ bool checkBeforeAlways = !childrenInline() && (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS || checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS);
+ if (checkBeforeAlways
&& (ty + child->y()) > paintInfo.rect.y()
&& (ty + child->y()) < paintInfo.rect.bottom()) {
view()->setBestTruncatedAt(ty + child->y(), this, true);
@@ -1897,7 +2137,8 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
}
// Check for page-break-inside: avoid, and it it's set, break and bail.
- if (isPrinting && !childrenInline() && child->style()->pageBreakInside() == PBAVOID
+ bool checkInsideAvoid = !childrenInline() && (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID || checkColumnBreaks && child->style()->columnBreakInside() == PBAVOID);
+ if (checkInsideAvoid
&& ty + child->y() > paintInfo.rect.y()
&& ty + child->y() < paintInfo.rect.bottom()
&& ty + child->y() + child->height() > paintInfo.rect.bottom()) {
@@ -1909,7 +2150,8 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
child->paint(info, tx, ty);
// Check for page-break-after: always, and if it's set, break and bail.
- if (isPrinting && !childrenInline() && child->style()->pageBreakAfter() == PBALWAYS
+ bool checkAfterAlways = !childrenInline() && (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS || checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS);
+ if (checkAfterAlways
&& (ty + child->y() + child->height()) > paintInfo.rect.y()
&& (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginBottom()), this, true);
@@ -1920,10 +2162,10 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
{
- SelectionController* selection = type == CursorCaret ? document()->frame()->selection() : document()->frame()->dragCaretController();
+ SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->dragCaretController();
// Paint the caret if the SelectionController says so or if caret browsing is enabled
- bool caretBrowsing = document()->frame()->settings() && document()->frame()->settings()->caretBrowsingEnabled();
+ bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
RenderObject* caretPainter = selection->caretRenderer();
if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
// Convert the painting offset into the local coordinate system of this renderer,
@@ -1931,9 +2173,9 @@ void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType typ
offsetForContents(tx, ty);
if (type == CursorCaret)
- document()->frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
+ frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
else
- document()->frame()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
+ frame()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
}
}
@@ -2082,7 +2324,7 @@ RenderBlock* RenderBlock::blockElementContinuation() const
RenderBlock* nextContinuation = toRenderBlock(m_continuation);
if (nextContinuation->isAnonymousBlock())
return nextContinuation->blockElementContinuation();
- return 0;
+ return nextContinuation;
}
static ContinuationOutlineTableMap* continuationOutlineTable()
@@ -3209,6 +3451,12 @@ void RenderBlock::clearFloats()
m_floatingObjects->clear();
}
+ // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
+ // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
+ // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
+ if (!parent() || !parent()->isRenderBlock())
+ return;
+
// Attempt to locate a previous sibling with overhanging floats. We skip any elements that are
// out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
// to avoid floats.
@@ -3777,16 +4025,15 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint&
}
}
- Settings* settings = document()->settings();
- bool useWindowsBehavior = settings && settings->editingBehavior() == EditingWindowsBehavior;
+ bool moveCaretToBoundary = document()->frame()->editor()->behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
- if (useWindowsBehavior && !closestBox && lastRootBoxWithChildren) {
+ if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
// y coordinate is below last root line box, pretend we hit it
closestBox = lastRootBoxWithChildren->closestLeafChildForXPos(pointInContents.x());
}
if (closestBox) {
- if (!useWindowsBehavior && pointInContents.y() < firstRootBoxWithChildren->lineTop() - verticalLineClickFudgeFactor) {
+ if (moveCaretToBoundary && pointInContents.y() < firstRootBoxWithChildren->lineTop() - verticalLineClickFudgeFactor) {
// y coordinate is above first root line box, so return the start of the first
return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
}
@@ -3797,7 +4044,7 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint&
if (lastRootBoxWithChildren) {
// We hit this case for Mac behavior when the Y coordinate is below the last box.
- ASSERT(!useWindowsBehavior);
+ ASSERT(moveCaretToBoundary);
return VisiblePosition(positionForBox(lastRootBoxWithChildren->lastLeafChild(), false), DOWNSTREAM);
}
@@ -3932,7 +4179,8 @@ void RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
bool destroyColumns = !firstChild()
|| (count == 1 && style()->hasAutoColumnWidth())
|| firstChild()->isAnonymousColumnsBlock()
- || firstChild()->isAnonymousColumnSpanBlock();
+ || firstChild()->isAnonymousColumnSpanBlock()
+ || document()->settings()->paginateDuringLayoutEnabled();
if (destroyColumns) {
if (hasColumns()) {
delete gColumnInfoMap->take(this);
@@ -3997,7 +4245,7 @@ int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
if (computeIntrinsicHeight && requestedColumnHeight >= 0)
colHeight = requestedColumnHeight;
else if (computeIntrinsicHeight)
- colHeight = availableHeight / desiredColumnCount + columnSlop;
+ colHeight = min(availableHeight, availableHeight / desiredColumnCount + columnSlop);
else
colHeight = availableHeight;
int originalColHeight = colHeight;
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 7d9e2fc..8c61e2c 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -243,6 +243,8 @@ private:
virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
+ void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
+ void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild);
void addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild);
virtual void addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild = 0);
@@ -410,6 +412,14 @@ private:
void updateScrollInfoAfterLayout();
RenderObject* splitAnonymousBlocksAroundChild(RenderObject* beforeChild);
+ void splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
+ RenderObject* beforeChild, RenderBoxModelObject* oldCont);
+ void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
+ RenderObject* newChild, RenderBoxModelObject* oldCont);
+ RenderBlock* clone() const;
+ RenderBlock* continuationBefore(RenderObject* beforeChild);
+ RenderBlock* containingColumnsBlock(bool allowAnonymousColumnBlock = true);
+ RenderBlock* columnsBlockForSpanningElement(RenderObject* newChild);
struct FloatingObject : Noncopyable {
enum Type {
diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp
index 96b4c6e..2cf3865 100644
--- a/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -29,6 +29,7 @@
#include "Logging.h"
#include "RenderArena.h"
#include "RenderInline.h"
+#include "RenderLayer.h"
#include "RenderListMarker.h"
#include "RenderView.h"
#include "TrailingFloatsRootInlineBox.h"
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index caadbf0..c845ba7 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -858,7 +858,7 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, bool behindText)
{
- Frame* frame = document()->frame();
+ Frame* frame = this->frame();
if (!frame)
return;
Page* page = frame->page();
diff --git a/WebCore/rendering/RenderDataGrid.cpp b/WebCore/rendering/RenderDataGrid.cpp
index 00cbd7c..916d253 100644
--- a/WebCore/rendering/RenderDataGrid.cpp
+++ b/WebCore/rendering/RenderDataGrid.cpp
@@ -182,7 +182,7 @@ void RenderDataGrid::invalidateScrollbarRect(Scrollbar*, const IntRect&)
bool RenderDataGrid::isActive() const
{
- Page* page = document()->frame()->page();
+ Page* page = frame()->page();
return page && page->focusController()->isActive();
}
diff --git a/WebCore/rendering/RenderFileUploadControl.cpp b/WebCore/rendering/RenderFileUploadControl.cpp
index d4d73bc..f42a657 100644
--- a/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/WebCore/rendering/RenderFileUploadControl.cpp
@@ -28,6 +28,7 @@
#include "GraphicsContext.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include "ShadowElement.h"
#include "Icon.h"
#include "LocalizedStrings.h"
#include "Page.h"
@@ -50,30 +51,6 @@ const int iconFilenameSpacing = 2;
const int defaultWidthNumChars = 34;
const int buttonShadowHeight = 2;
-class ShadowInputElement : public HTMLInputElement {
-public:
- static PassRefPtr<ShadowInputElement> create(Node* shadowParent);
-
-private:
- ShadowInputElement(Node* shadowParent);
-
- virtual bool isShadowNode() const { return true; }
- virtual Node* shadowParentNode() { return m_shadowParent; }
-
- Node* m_shadowParent;
-};
-
-inline ShadowInputElement::ShadowInputElement(Node* shadowParent)
- : HTMLInputElement(inputTag, shadowParent->document())
- , m_shadowParent(shadowParent)
-{
-}
-
-inline PassRefPtr<ShadowInputElement> ShadowInputElement::create(Node* shadowParent)
-{
- return new ShadowInputElement(shadowParent);
-}
-
RenderFileUploadControl::RenderFileUploadControl(HTMLInputElement* input)
: RenderBlock(input)
, m_button(0)
diff --git a/WebCore/rendering/RenderFrameSet.cpp b/WebCore/rendering/RenderFrameSet.cpp
index 3ab2fff..600d65e 100644
--- a/WebCore/rendering/RenderFrameSet.cpp
+++ b/WebCore/rendering/RenderFrameSet.cpp
@@ -749,7 +749,7 @@ void RenderFrameSet::positionFramesWithFlattening()
bool RenderFrameSet::flattenFrameSet() const
{
- return document()->frame() && document()->frame()->settings()->frameFlatteningEnabled();
+ return frame() && frame()->settings()->frameFlatteningEnabled();
}
void RenderFrameSet::startResizing(GridAxis& axis, int position)
@@ -817,7 +817,7 @@ void RenderFrameSet::setIsResizing(bool isResizing)
if (ancestor->isFrameSet())
toRenderFrameSet(ancestor)->m_isChildResizing = isResizing;
}
- if (Frame* frame = document()->frame())
+ if (Frame* frame = this->frame())
frame->eventHandler()->setResizingFrameSet(isResizing ? frameSet() : 0);
}
diff --git a/WebCore/rendering/RenderIFrame.cpp b/WebCore/rendering/RenderIFrame.cpp
index 146e028..8421c9e 100644
--- a/WebCore/rendering/RenderIFrame.cpp
+++ b/WebCore/rendering/RenderIFrame.cpp
@@ -27,6 +27,7 @@
#include "RenderIFrame.h"
#include "FrameView.h"
+#include "HTMLNames.h"
#include "HTMLIFrameElement.h"
#include "RenderView.h"
#include "Settings.h"
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index 2e376e7..98b0f47 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -36,6 +36,7 @@
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "Page.h"
+#include "RenderLayer.h"
#include "RenderTheme.h"
#include "RenderView.h"
#include "SelectionController.h"
@@ -451,7 +452,7 @@ void RenderImage::paint(PaintInfo& paintInfo, int tx, int ty)
void RenderImage::paintFocusRings(PaintInfo& paintInfo, const RenderStyle* style)
{
// Don't draw focus rings if printing.
- if (document()->printing() || !document()->frame()->selection()->isFocusedAndActive())
+ if (document()->printing() || !frame()->selection()->isFocusedAndActive())
return;
if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp
index 7531f93..e91822e 100644
--- a/WebCore/rendering/RenderInline.cpp
+++ b/WebCore/rendering/RenderInline.cpp
@@ -30,6 +30,7 @@
#include "Page.h"
#include "RenderArena.h"
#include "RenderBlock.h"
+#include "RenderLayer.h"
#include "RenderView.h"
#include "TransformState.h"
#include "VisiblePosition.h"
@@ -1114,8 +1115,8 @@ void RenderInline::addDashboardRegions(Vector<DashboardRegionValue>& regions)
region.bounds.setX(absPos.x() + region.bounds.x());
region.bounds.setY(absPos.y() + region.bounds.y());
- if (document()->frame()) {
- float pageScaleFactor = document()->frame()->page()->chrome()->scaleFactor();
+ if (frame()) {
+ float pageScaleFactor = frame()->page()->chrome()->scaleFactor();
if (pageScaleFactor != 1.0f) {
region.bounds.scale(pageScaleFactor);
region.clip.scale(pageScaleFactor);
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 3eab1f8..5d206dd 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -189,7 +189,7 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
RenderLayer::~RenderLayer()
{
if (inResizeMode() && !renderer()->documentBeingDestroyed()) {
- if (Frame* frame = renderer()->document()->frame())
+ if (Frame* frame = renderer()->frame())
frame->eventHandler()->resizeLayerDestroyed();
}
@@ -1216,7 +1216,7 @@ static inline int adjustedScrollDelta(int beginningDelta) {
void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint)
{
- Frame* frame = renderer()->document()->frame();
+ Frame* frame = renderer()->frame();
if (!frame)
return;
@@ -1267,7 +1267,7 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
nextRenderer = nextRenderer->parent();
}
- Frame* frame = renderer()->document()->frame();
+ Frame* frame = renderer()->frame();
if (frame)
frame->eventHandler()->updateAutoscrollRenderer();
}
@@ -1347,7 +1347,7 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
IntRect rectForRepaint = renderer()->clippedOverflowRectForRepaint(repaintContainer);
- Frame* frame = renderer()->document()->frame();
+ Frame* frame = renderer()->frame();
if (frame) {
// The caret rect needs to be invalidated after scrolling
frame->selection()->setNeedsLayout();
@@ -1538,7 +1538,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
void RenderLayer::autoscroll()
{
- Frame* frame = renderer()->document()->frame();
+ Frame* frame = renderer()->frame();
if (!frame)
return;
@@ -1645,7 +1645,7 @@ void RenderLayer::valueChanged(Scrollbar*)
bool RenderLayer::isActive() const
{
- Page* page = renderer()->document()->frame()->page();
+ Page* page = renderer()->frame()->page();
return page && page->focusController()->isActive();
}
@@ -3896,7 +3896,7 @@ void showLayerTree(const WebCore::RenderLayer* layer)
if (!layer)
return;
- if (WebCore::Frame* frame = layer->renderer()->document()->frame()) {
+ if (WebCore::Frame* frame = layer->renderer()->frame()) {
WebCore::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses);
fprintf(stderr, "%s\n", output.utf8().data());
}
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 97c5544..b55a474 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -1029,7 +1029,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
#if ENABLE(INSPECTOR)
static InspectorTimelineAgent* inspectorTimelineAgent(RenderObject* renderer)
{
- Frame* frame = renderer->document()->frame();
+ Frame* frame = renderer->frame();
if (!frame)
return 0;
Page* page = frame->page();
@@ -1252,10 +1252,9 @@ String RenderLayerBacking::nameForLayer() const
String name = renderer()->renderName();
if (Node* node = renderer()->node()) {
if (node->isElementNode())
- name += " " + static_cast<Element *>(node)->tagName();
-
- if (node->isHTMLElement() && static_cast<HTMLElement *>(node)->hasID())
- name += " \'" + static_cast<Element *>(node)->getIDAttribute() + "\'";
+ name += " " + static_cast<Element*>(node)->tagName();
+ if (node->hasID())
+ name += " \'" + static_cast<Element*>(node)->getIdAttribute() + "\'";
}
if (m_owningLayer->isReflection())
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index ff6e3b2..f68623b 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -29,19 +29,16 @@
#include "RenderLayerCompositor.h"
#include "AnimationController.h"
+#include "CSSPropertyNames.h"
#include "Chrome.h"
#include "ChromeClient.h"
-#include "CSSPropertyNames.h"
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsLayer.h"
-#include "HitTestResult.h"
#include "HTMLCanvasElement.h"
#include "HTMLIFrameElement.h"
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-#include "HTMLMediaElement.h"
#include "HTMLNames.h"
-#endif
+#include "HitTestResult.h"
#include "NodeList.h"
#include "Page.h"
#include "RenderEmbeddedObject.h"
@@ -52,6 +49,10 @@
#include "RenderView.h"
#include "Settings.h"
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "HTMLMediaElement.h"
+#endif
+
#if PROFILE_LAYER_REBUILD
#include <wtf/CurrentTime.h>
#endif
@@ -1439,7 +1440,8 @@ void RenderLayerCompositor::detachRootPlatformLayer()
else
m_rootPlatformLayer->removeFromParent();
- m_renderView->document()->ownerElement()->setNeedsStyleRecalc(SyntheticStyleChange);
+ if (Element* ownerElement = m_renderView->document()->ownerElement())
+ ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
break;
}
case RootLayerAttachedViaChromeClient: {
diff --git a/WebCore/rendering/RenderLineBoxList.cpp b/WebCore/rendering/RenderLineBoxList.cpp
index 92952b7..2d3ee7e 100644
--- a/WebCore/rendering/RenderLineBoxList.cpp
+++ b/WebCore/rendering/RenderLineBoxList.cpp
@@ -37,6 +37,7 @@
#include "RenderInline.h"
#include "RenderView.h"
#include "RootInlineBox.h"
+#include "Settings.h" // FIXME: This include can be removed when paginateDuringLayoutEnabled is taken out.
using namespace std;
@@ -162,7 +163,7 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::Pain
return;
RenderView* v = renderer->view();
- bool usePrintRect = !v->printRect().isEmpty();
+ bool usePrintRect = !v->printRect().isEmpty() && !renderer->document()->settings()->paginateDuringLayoutEnabled();
// We can check the first box and last box and avoid painting if we don't
// intersect. This is a quick short-circuit that we can take to avoid walking any lines.
diff --git a/WebCore/rendering/RenderListBox.cpp b/WebCore/rendering/RenderListBox.cpp
index 1c21af4..2ecc2d0 100644
--- a/WebCore/rendering/RenderListBox.cpp
+++ b/WebCore/rendering/RenderListBox.cpp
@@ -314,7 +314,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, in
Color textColor = element->renderStyle() ? element->renderStyle()->visitedDependentColor(CSSPropertyColor) : style()->visitedDependentColor(CSSPropertyColor);
if (optionElement && optionElement->selected()) {
- if (document()->frame()->selection()->isFocusedAndActive() && document()->focusedNode() == node())
+ if (frame()->selection()->isFocusedAndActive() && document()->focusedNode() == node())
textColor = theme()->activeListBoxSelectionForegroundColor();
// Honor the foreground color for disabled items
else if (!element->disabled())
@@ -350,7 +350,7 @@ void RenderListBox::paintItemBackground(PaintInfo& paintInfo, int tx, int ty, in
Color backColor;
if (optionElement && optionElement->selected()) {
- if (document()->frame()->selection()->isFocusedAndActive() && document()->focusedNode() == node())
+ if (frame()->selection()->isFocusedAndActive() && document()->focusedNode() == node())
backColor = theme()->activeListBoxSelectionBackgroundColor();
else
backColor = theme()->inactiveListBoxSelectionBackgroundColor();
@@ -408,7 +408,7 @@ void RenderListBox::panScroll(const IntPoint& panStartMousePosition)
// FIXME: This doesn't work correctly with transforms.
FloatPoint absOffset = localToAbsolute();
- IntPoint currentMousePosition = document()->frame()->eventHandler()->currentMousePosition();
+ IntPoint currentMousePosition = frame()->eventHandler()->currentMousePosition();
// We need to check if the current mouse position is out of the window. When the mouse is out of the window, the position is incoherent
static IntPoint previousMousePosition;
if (currentMousePosition.y() < 0)
@@ -466,7 +466,7 @@ int RenderListBox::scrollToward(const IntPoint& destination)
void RenderListBox::autoscroll()
{
- IntPoint pos = document()->frame()->view()->windowToContents(document()->frame()->eventHandler()->currentMousePosition());
+ IntPoint pos = frame()->view()->windowToContents(frame()->eventHandler()->currentMousePosition());
int endIndex = scrollToward(pos);
if (endIndex >= 0) {
@@ -613,7 +613,7 @@ IntRect RenderListBox::controlClipRect(int tx, int ty) const
bool RenderListBox::isActive() const
{
- Page* page = document()->frame()->page();
+ Page* page = frame()->page();
return page && page->focusController()->isActive();
}
diff --git a/WebCore/rendering/RenderMenuList.h b/WebCore/rendering/RenderMenuList.h
index 5ee8588..9e51996 100644
--- a/WebCore/rendering/RenderMenuList.h
+++ b/WebCore/rendering/RenderMenuList.h
@@ -101,6 +101,8 @@ private:
virtual bool valueShouldChangeOnHotTrack() const { return true; }
virtual bool shouldPopOver() const { return !POPUP_MENU_PULLS_DOWN; }
virtual void valueChanged(unsigned listIndex, bool fireOnChange = true);
+ virtual void selectionChanged(unsigned, bool) {}
+ virtual void selectionCleared() {}
virtual FontSelector* fontSelector() const;
virtual HostWindow* hostWindow() const;
virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize);
diff --git a/WebCore/rendering/RenderMeter.cpp b/WebCore/rendering/RenderMeter.cpp
index 9dc6a26..d443ceb 100644
--- a/WebCore/rendering/RenderMeter.cpp
+++ b/WebCore/rendering/RenderMeter.cpp
@@ -19,11 +19,13 @@
*/
#include "config.h"
+
#if ENABLE(METER_TAG)
#include "RenderMeter.h"
#include "HTMLMeterElement.h"
+#include "HTMLNames.h"
#include "RenderTheme.h"
using namespace std;
@@ -37,6 +39,18 @@ RenderMeter::RenderMeter(HTMLMeterElement* element)
{
}
+void RenderMeter::calcWidth()
+{
+ RenderBox::calcWidth();
+ setWidth(theme()->meterSizeForBounds(this, frameRect()).width());
+}
+
+void RenderMeter::calcHeight()
+{
+ RenderBox::calcHeight();
+ setHeight(theme()->meterSizeForBounds(this, frameRect()).height());
+}
+
void RenderMeter::layout()
{
ASSERT(needsLayout());
@@ -59,4 +73,5 @@ void RenderMeter::updateFromElement()
}
} // namespace WebCore
+
#endif
diff --git a/WebCore/rendering/RenderMeter.h b/WebCore/rendering/RenderMeter.h
index 2fc7844..fd95adb 100644
--- a/WebCore/rendering/RenderMeter.h
+++ b/WebCore/rendering/RenderMeter.h
@@ -38,6 +38,8 @@ private:
virtual bool isMeter() const { return true; }
virtual void layout();
virtual void updateFromElement();
+ virtual void calcWidth();
+ virtual void calcHeight();
};
inline RenderMeter* toRenderMeter(RenderObject* object)
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 2893d67..e9e9ffc 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -42,6 +42,7 @@
#include "RenderFlexibleBox.h"
#include "RenderImageGeneratedContent.h"
#include "RenderInline.h"
+#include "RenderLayer.h"
#include "RenderListItem.h"
#include "RenderRuby.h"
#include "RenderRubyText.h"
@@ -222,7 +223,7 @@ RenderObject::RenderObject(Node* node)
RenderObject::~RenderObject()
{
- ASSERT(!node() || documentBeingDestroyed() || !document()->frame()->view() || document()->frame()->view()->layoutRoot() != this);
+ ASSERT(!node() || documentBeingDestroyed() || !frame()->view() || frame()->view()->layoutRoot() != this);
#ifndef NDEBUG
ASSERT(!m_hasAXObject);
renderObjectCounter.decrement();
@@ -1389,7 +1390,7 @@ Color RenderObject::selectionBackgroundColor() const
if (pseudoStyle && pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
color = pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).blendWithWhite();
else
- color = document()->frame()->selection()->isFocusedAndActive() ?
+ color = frame()->selection()->isFocusedAndActive() ?
theme()->activeSelectionBackgroundColor() :
theme()->inactiveSelectionBackgroundColor();
}
@@ -1408,7 +1409,7 @@ Color RenderObject::selectionForegroundColor() const
if (!color.isValid())
color = pseudoStyle->visitedDependentColor(CSSPropertyColor);
} else
- color = document()->frame()->selection()->isFocusedAndActive() ?
+ color = frame()->selection()->isFocusedAndActive() ?
theme()->activeSelectionForegroundColor() :
theme()->inactiveSelectionForegroundColor();
@@ -1948,9 +1949,9 @@ void RenderObject::destroy()
// FIXME: RenderObject::destroy should not get called with a renderer whose document
// has a null frame, so we assert this. However, we don't want release builds to crash which is why we
// check that the frame is not null.
- ASSERT(document()->frame());
- if (document()->frame() && document()->frame()->eventHandler()->autoscrollRenderer() == this)
- document()->frame()->eventHandler()->stopAutoscrollTimer(true);
+ ASSERT(frame());
+ if (frame() && frame()->eventHandler()->autoscrollRenderer() == this)
+ frame()->eventHandler()->stopAutoscrollTimer(true);
if (m_hasCounterNodeMap)
RenderCounter::destroyCounterNodes(this);
@@ -2276,8 +2277,8 @@ void RenderObject::addDashboardRegions(Vector<DashboardRegionValue>& regions)
region.bounds.setX(absPos.x() + styleRegion.offset.left().value());
region.bounds.setY(absPos.y() + styleRegion.offset.top().value());
- if (document()->frame()) {
- float pageScaleFactor = document()->frame()->page()->chrome()->scaleFactor();
+ if (frame()) {
+ float pageScaleFactor = frame()->page()->chrome()->scaleFactor();
if (pageScaleFactor != 1.0f) {
region.bounds.scale(pageScaleFactor);
region.clip.scale(pageScaleFactor);
@@ -2382,7 +2383,7 @@ void RenderObject::adjustRectForOutlineAndShadow(IntRect& rect) const
AnimationController* RenderObject::animation() const
{
- return document()->frame()->animation();
+ return frame()->animation();
}
void RenderObject::imageChanged(CachedImage* image, const IntRect* rect)
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 3ff38ab..9f1e8dd 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -66,6 +66,7 @@ class RenderSVGResourceContainer;
* three phases invoked on them during this phase.
*/
+// FIXME: These enums should move to their own header since they're used by other headers.
enum PaintPhase {
PaintPhaseBlockBackground,
PaintPhaseChildBlockBackground,
@@ -450,9 +451,11 @@ public:
bool isRooted(RenderView** = 0);
Node* node() const { return m_isAnonymous ? 0 : m_node; }
- Document* document() const { return m_node->document(); }
void setNode(Node* node) { m_node = node; }
+ Document* document() const { return m_node->document(); }
+ Frame* frame() const { return document()->frame(); }
+
bool hasOutlineAnnotation() const;
bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); }
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index ccb9562..238a4e6 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -5,6 +5,7 @@
2009 Google, Inc.
2009 Dirk Schulze <krit@webkit.org>
Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ 2009 Jeff Schiller <codedread@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -30,6 +31,7 @@
#include "FloatPoint.h"
#include "FloatQuad.h"
#include "GraphicsContext.h"
+#include "HitTestRequest.h"
#include "PointerEventsHitRules.h"
#include "RenderSVGContainer.h"
#include "RenderSVGResourceFilter.h"
@@ -71,7 +73,7 @@ RenderPath::RenderPath(SVGStyledTransformableElement* node)
{
}
-bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill) const
+bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill, WindRule fillRule) const
{
if (!m_fillBoundingBox.contains(point))
return false;
@@ -79,7 +81,7 @@ bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill) const
if (requiresFill && !RenderSVGResource::fillPaintingResource(this, style()))
return false;
- return m_path.contains(point, style()->svgStyle()->fillRule());
+ return m_path.contains(point, fillRule);
}
bool RenderPath::strokeContains(const FloatPoint& point, bool requiresStroke) const
@@ -130,16 +132,28 @@ void RenderPath::layout()
static inline void fillAndStrokePath(const Path& path, GraphicsContext* context, RenderPath* object)
{
context->beginPath();
+ RenderStyle* style = object->style();
- if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(object, object->style())) {
+ if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(object, style)) {
context->addPath(path);
- if (fillPaintingResource->applyResource(object, object->style(), context, ApplyToFillMode))
+ if (fillPaintingResource->applyResource(object, style, context, ApplyToFillMode))
fillPaintingResource->postApplyResource(object, context, ApplyToFillMode);
}
- if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(object, object->style())) {
- context->addPath(path);
- if (strokePaintingResource->applyResource(object, object->style(), context, ApplyToStrokeMode))
+ if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(object, style)) {
+ if (style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE) {
+ SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
+ AffineTransform transform = element->getScreenCTM();
+ if (!transform.isInvertible())
+ return;
+
+ Path transformedPath = path;
+ context->concatCTM(transform.inverse());
+ transformedPath.transform(transform);
+ context->addPath(transformedPath);
+ } else
+ context->addPath(path);
+ if (strokePaintingResource->applyResource(object, style, context, ApplyToStrokeMode))
strokePaintingResource->postApplyResource(object, context, ApplyToStrokeMode);
}
}
@@ -195,7 +209,7 @@ void RenderPath::addFocusRingRects(Vector<IntRect>& rects, int, int)
rects.append(rect);
}
-bool RenderPath::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
+bool RenderPath::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
// We only draw in the forground phase, so we only hit-test then.
if (hitTestAction != HitTestForeground)
@@ -203,17 +217,22 @@ bool RenderPath::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result,
FloatPoint localPoint = m_localTransform.inverse().mapPoint(pointInParent);
- PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_PATH_HITTESTING, style()->pointerEvents());
+ if (!pointInClippingArea(this, localPoint))
+ return false;
+ PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_PATH_HITTESTING, request, style()->pointerEvents());
bool isVisible = (style()->visibility() == VISIBLE);
if (isVisible || !hitRules.requireVisible) {
- if ((hitRules.canHitStroke && (style()->svgStyle()->hasStroke() || !hitRules.requireStroke) && strokeContains(localPoint, hitRules.requireStroke))
- || (hitRules.canHitFill && (style()->svgStyle()->hasFill() || !hitRules.requireFill) && fillContains(localPoint, hitRules.requireFill))) {
+ const SVGRenderStyle* svgStyle = style()->svgStyle();
+ WindRule fillRule = svgStyle->fillRule();
+ if (request.svgClipContent())
+ fillRule = svgStyle->clipRule();
+ if ((hitRules.canHitStroke && (svgStyle->hasStroke() || !hitRules.requireStroke) && strokeContains(localPoint, hitRules.requireStroke))
+ || (hitRules.canHitFill && (svgStyle->hasFill() || !hitRules.requireFill) && fillContains(localPoint, hitRules.requireFill, fillRule))) {
updateHitTestResult(result, roundedIntPoint(localPoint));
return true;
}
}
-
return false;
}
@@ -297,23 +316,8 @@ void RenderPath::updateCachedBoundaries()
}
// Cache smallest possible repaint rectangle
-
- // FIXME: We need to be careful here. We assume that there is no resource, if the rect is empty.
- FloatRect rect = filterBoundingBoxForRenderer(this);
- if (rect.isEmpty())
- m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
- else
- m_repaintBoundingBox = rect;
-
- rect = clipperBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_repaintBoundingBox.intersect(rect);
-
- rect = maskerBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_repaintBoundingBox.intersect(rect);
-
- svgStyle->inflateForShadow(m_repaintBoundingBox);
+ m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
+ intersectRepaintRectWithResources(this, m_repaintBoundingBox);
}
}
diff --git a/WebCore/rendering/RenderPath.h b/WebCore/rendering/RenderPath.h
index 5509057..3748f39 100644
--- a/WebCore/rendering/RenderPath.h
+++ b/WebCore/rendering/RenderPath.h
@@ -47,7 +47,7 @@ public:
private:
// Hit-detection seperated for the fill and the stroke
- bool fillContains(const FloatPoint&, bool requiresFill = true) const;
+ bool fillContains(const FloatPoint&, bool requiresFill = true, WindRule fillRule = RULE_NONZERO) const;
bool strokeContains(const FloatPoint&, bool requiresStroke = true) const;
virtual FloatRect objectBoundingBox() const { return m_fillBoundingBox; }
diff --git a/WebCore/rendering/RenderProgress.cpp b/WebCore/rendering/RenderProgress.cpp
index ac3fb15..e4e045d 100644
--- a/WebCore/rendering/RenderProgress.cpp
+++ b/WebCore/rendering/RenderProgress.cpp
@@ -23,8 +23,8 @@
#if ENABLE(PROGRESS_TAG)
#include "RenderProgress.h"
-
-#include "HTMLDivElement.h"
+#include "ShadowElement.h"
+#include "HTMLNames.h"
#include "HTMLProgressElement.h"
#include "RenderTheme.h"
#include "RenderView.h"
@@ -35,32 +35,6 @@ using namespace std;
namespace WebCore {
-using namespace HTMLNames;
-
-class ProgressValueElement : public HTMLDivElement {
-public:
- static PassRefPtr<ProgressValueElement> create(Node* shadowParent);
-
-private:
- ProgressValueElement(Node* shadowParent);
-
- virtual bool isShadowNode() const { return true; }
- virtual Node* shadowParentNode() { return m_shadowParent; }
-
- Node* m_shadowParent;
-};
-
-inline ProgressValueElement::ProgressValueElement(Node* shadowParent)
- : HTMLDivElement(divTag, shadowParent->document())
- , m_shadowParent(shadowParent)
-{
-}
-
-inline PassRefPtr<ProgressValueElement> ProgressValueElement::create(Node* shadowParent)
-{
- return new ProgressValueElement(shadowParent);
-}
-
RenderProgress::RenderProgress(HTMLProgressElement* element)
: RenderBlock(element)
, m_position(-1)
@@ -144,7 +118,7 @@ void RenderProgress::updateValuePartState()
{
bool needLayout = !style()->hasAppearance() || m_valuePart;
if (!style()->hasAppearance() && !m_valuePart) {
- m_valuePart = ProgressValueElement::create(node());
+ m_valuePart = ShadowBlockElement::create(node());
RefPtr<RenderStyle> styleForValuePart = createStyleForValuePart(style());
m_valuePart->setRenderer(m_valuePart->createRenderer(renderArena(), styleForValuePart.get()));
m_valuePart->renderer()->setStyle(styleForValuePart.release());
diff --git a/WebCore/rendering/RenderProgress.h b/WebCore/rendering/RenderProgress.h
index 1137e99..4d1a88f 100644
--- a/WebCore/rendering/RenderProgress.h
+++ b/WebCore/rendering/RenderProgress.h
@@ -27,7 +27,7 @@
namespace WebCore {
class HTMLProgressElement;
-class ProgressValueElement;
+class ShadowBlockElement;
class RenderProgress : public RenderBlock {
public:
@@ -63,7 +63,7 @@ private:
double m_animationDuration;
bool m_animating;
Timer<RenderProgress> m_animationTimer;
- RefPtr<ProgressValueElement> m_valuePart;
+ RefPtr<ShadowBlockElement> m_valuePart;
};
inline RenderProgress* toRenderProgress(RenderObject* object)
diff --git a/WebCore/rendering/RenderSVGContainer.cpp b/WebCore/rendering/RenderSVGContainer.cpp
index 56846a9..66889ac 100644
--- a/WebCore/rendering/RenderSVGContainer.cpp
+++ b/WebCore/rendering/RenderSVGContainer.cpp
@@ -146,20 +146,7 @@ FloatRect RenderSVGContainer::strokeBoundingBox() const
FloatRect RenderSVGContainer::repaintRectInLocalCoordinates() const
{
FloatRect repaintRect = computeContainerBoundingBox(this, true);
-
- FloatRect rect = filterBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- repaintRect = rect;
-
- rect = clipperBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- repaintRect.intersect(rect);
-
- rect = maskerBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- repaintRect.intersect(rect);
-
- style()->svgStyle()->inflateForShadow(repaintRect);
+ intersectRepaintRectWithResources(this, repaintRect);
return repaintRect;
}
@@ -172,6 +159,9 @@ bool RenderSVGContainer::nodeAtFloatPoint(const HitTestRequest& request, HitTest
FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
+ if (!pointInClippingArea(this, localPoint))
+ return false;
+
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
if (child->nodeAtFloatPoint(request, result, localPoint, hitTestAction)) {
updateHitTestResult(result, roundedIntPoint(localPoint));
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index 006142c..d1a3037 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -112,17 +112,19 @@ void RenderSVGImage::destroy()
RenderImage::destroy();
}
-bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
+bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
// We only draw in the forground phase, so we only hit-test then.
if (hitTestAction != HitTestForeground)
return false;
- PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_IMAGE_HITTESTING, style()->pointerEvents());
-
+ PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_IMAGE_HITTESTING, request, style()->pointerEvents());
bool isVisible = (style()->visibility() == VISIBLE);
if (isVisible || !hitRules.requireVisible) {
FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
+
+ if (!pointInClippingArea(this, localPoint))
+ return false;
if (hitRules.canHitFill) {
if (m_localBounds.contains(localPoint)) {
@@ -153,22 +155,7 @@ FloatRect RenderSVGImage::repaintRectInLocalCoordinates() const
return m_cachedLocalRepaintRect;
m_cachedLocalRepaintRect = m_localBounds;
-
- // FIXME: We need to be careful here. We assume that there is no filter,
- // clipper or masker if the rects are empty.
- FloatRect rect = filterBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_cachedLocalRepaintRect = rect;
-
- rect = clipperBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_cachedLocalRepaintRect.intersect(rect);
-
- rect = maskerBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_cachedLocalRepaintRect.intersect(rect);
-
- style()->svgStyle()->inflateForShadow(m_cachedLocalRepaintRect);
+ intersectRepaintRectWithResources(this, m_cachedLocalRepaintRect);
return m_cachedLocalRepaintRect;
}
diff --git a/WebCore/rendering/RenderSVGResource.h b/WebCore/rendering/RenderSVGResource.h
index 5334025..a14a972 100644
--- a/WebCore/rendering/RenderSVGResource.h
+++ b/WebCore/rendering/RenderSVGResource.h
@@ -61,7 +61,7 @@ public:
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) = 0;
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short) { }
- virtual FloatRect resourceBoundingBox(const FloatRect&) = 0;
+ virtual FloatRect resourceBoundingBox(RenderObject*) = 0;
virtual RenderSVGResourceType resourceType() const = 0;
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
index 7957df4..450c5d6 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.cpp
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -27,6 +27,8 @@
#include "AffineTransform.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
+#include "HitTestRequest.h"
+#include "HitTestResult.h"
#include "ImageBuffer.h"
#include "IntRect.h"
#include "RenderObject.h"
@@ -266,12 +268,49 @@ void RenderSVGResourceClipper::calculateClipContentRepaintRect()
}
}
-FloatRect RenderSVGResourceClipper::resourceBoundingBox(const FloatRect& objectBoundingBox)
+bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint)
{
+ FloatPoint point = nodeAtPoint;
+ if (!pointInClippingArea(this, point))
+ return false;
+
+ if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ AffineTransform transform;
+ transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ point = transform.inverse().mapPoint(point);
+ }
+
+ for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
+ RenderObject* renderer = childNode->renderer();
+ if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
+ continue;
+ if (!renderer->isRenderPath() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer())
+ continue;
+ IntPoint hitPoint;
+ HitTestResult result(hitPoint);
+ if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipContent), result, point, HitTestForeground))
+ return true;
+ }
+
+ return false;
+}
+
+FloatRect RenderSVGResourceClipper::resourceBoundingBox(RenderObject* object)
+{
+ // Save the reference to the calling object for relayouting it on changing resource properties.
+ if (!m_clipper.contains(object))
+ m_clipper.set(object, new ClipperData);
+
+ // Resource was not layouted yet. Give back the boundingBox of the object.
+ if (selfNeedsLayout())
+ return object->objectBoundingBox();
+
if (m_clipBoundaries.isEmpty())
calculateClipContentRepaintRect();
if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ FloatRect objectBoundingBox = object->objectBoundingBox();
AffineTransform transform;
transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
diff --git a/WebCore/rendering/RenderSVGResourceClipper.h b/WebCore/rendering/RenderSVGResourceClipper.h
index d8e2eed..78ec75b 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.h
+++ b/WebCore/rendering/RenderSVGResourceClipper.h
@@ -51,9 +51,11 @@ public:
virtual void invalidateClient(RenderObject*);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
- virtual FloatRect resourceBoundingBox(const FloatRect&);
+ virtual FloatRect resourceBoundingBox(RenderObject*);
virtual RenderSVGResourceType resourceType() const { return ClipperResourceType; }
+
+ bool hitTestClipContent(const FloatRect&, const FloatPoint&);
SVGUnitTypes::SVGUnitType clipPathUnits() const { return toUnitType(static_cast<SVGClipPathElement*>(node())->clipPathUnits()); }
diff --git a/WebCore/rendering/RenderSVGResourceContainer.h b/WebCore/rendering/RenderSVGResourceContainer.h
index b63575d..54617bb 100644
--- a/WebCore/rendering/RenderSVGResourceContainer.h
+++ b/WebCore/rendering/RenderSVGResourceContainer.h
@@ -23,6 +23,8 @@
#if ENABLE(SVG)
#include "RenderSVGHiddenContainer.h"
+
+#include "SVGStyledTransformableElement.h"
#include "RenderSVGResource.h"
namespace WebCore {
@@ -33,7 +35,8 @@ public:
RenderSVGResourceContainer(SVGStyledElement* node)
: RenderSVGHiddenContainer(node)
, RenderSVGResource()
- , m_id(node->getIDAttribute())
+ // FIXME: Should probably be using getIdAttribute rather than idForStyleResolution.
+ , m_id(node->hasID() ? node->idForStyleResolution() : nullAtom)
{
ASSERT(node->document());
node->document()->accessSVGExtensions()->addResource(m_id, this);
@@ -55,7 +58,8 @@ public:
// Remove old id, that is guaranteed to be present in cache
extensions->removeResource(m_id);
- m_id = static_cast<Element*>(node())->getIDAttribute();
+ // FIXME: Should probably be using getIdAttribute rather than idForStyleResolution.
+ m_id = node()->hasID() ? static_cast<Element*>(node())->idForStyleResolution() : nullAtom;
// It's possible that an element is referencing us with the new id, and has to be notified that we're existing now
if (extensions->isPendingResource(m_id)) {
@@ -80,6 +84,17 @@ public:
virtual bool drawsContents() { return false; }
virtual RenderSVGResourceContainer* toRenderSVGResourceContainer() { return this; }
+
+ static AffineTransform transformOnNonScalingStroke(RenderObject* object, const AffineTransform resourceTransform)
+ {
+ if (!object->isRenderPath())
+ return resourceTransform;
+
+ SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
+ AffineTransform transform = resourceTransform;
+ transform.multiply(element->getScreenCTM());
+ return transform;
+ }
private:
AtomicString m_id;
diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp
index e197d5b..b0220a9 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.cpp
+++ b/WebCore/rendering/RenderSVGResourceFilter.cpp
@@ -279,10 +279,10 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
filterData->sourceGraphicBuffer.clear();
}
-FloatRect RenderSVGResourceFilter::resourceBoundingBox(const FloatRect& objectBoundingBox)
+FloatRect RenderSVGResourceFilter::resourceBoundingBox(RenderObject* object)
{
if (SVGFilterElement* element = static_cast<SVGFilterElement*>(node()))
- return element->filterBoundingBox(objectBoundingBox);
+ return element->filterBoundingBox(object->objectBoundingBox());
return FloatRect();
}
diff --git a/WebCore/rendering/RenderSVGResourceFilter.h b/WebCore/rendering/RenderSVGResourceFilter.h
index 4d875c0..105b256 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.h
+++ b/WebCore/rendering/RenderSVGResourceFilter.h
@@ -70,7 +70,7 @@ public:
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
- virtual FloatRect resourceBoundingBox(const FloatRect&);
+ virtual FloatRect resourceBoundingBox(RenderObject*);
PassOwnPtr<SVGFilterBuilder> buildPrimitives();
diff --git a/WebCore/rendering/RenderSVGResourceGradient.cpp b/WebCore/rendering/RenderSVGResourceGradient.cpp
index 6c9d784..e715f6f 100644
--- a/WebCore/rendering/RenderSVGResourceGradient.cpp
+++ b/WebCore/rendering/RenderSVGResourceGradient.cpp
@@ -159,17 +159,35 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
GradientData* gradientData = m_gradient.get(object);
+ bool isPaintingText = resourceMode & ApplyToTextMode;
+
// Create gradient object
- if (!gradientData->gradient)
+ if (!gradientData->gradient) {
buildGradient(gradientData, gradientElement);
+ // CG platforms will handle the gradient space transform for text after applying the
+ // resource, so don't apply it here. For non-CG platforms, we want the text bounding
+ // box applied to the gradient space transform now, so the gradient shader can use it.
+#if PLATFORM(CG)
+ if (gradientData->boundingBoxMode && !isPaintingText) {
+#else
+ if (gradientData->boundingBoxMode) {
+#endif
+ FloatRect objectBoundingBox = object->objectBoundingBox();
+ gradientData->userspaceTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ gradientData->userspaceTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ }
+
+ gradientData->userspaceTransform.multiply(gradientData->transform);
+ gradientData->gradient->setGradientSpaceTransform(gradientData->userspaceTransform);
+ }
+
if (!gradientData->gradient)
return false;
// Draw gradient
context->save();
- bool isPaintingText = resourceMode & ApplyToTextMode;
if (isPaintingText) {
#if PLATFORM(CG)
if (!createMaskAndSwapContextForTextGradient(context, m_savedContext, m_imageBuffer, object)) {
@@ -181,24 +199,6 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
context->setTextDrawingMode(resourceMode & ApplyToFillMode ? cTextFill : cTextStroke);
}
- AffineTransform transform;
-
- // CG platforms will handle the gradient space transform for text after applying the
- // resource, so don't apply it here. For non-CG platforms, we want the text bounding
- // box applied to the gradient space transform now, so the gradient shader can use it.
-#if PLATFORM(CG)
- if (gradientData->boundingBoxMode && !isPaintingText) {
-#else
- if (gradientData->boundingBoxMode) {
-#endif
- FloatRect objectBoundingBox = object->objectBoundingBox();
- transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
- transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
- }
-
- transform.multiply(gradientData->transform);
- gradientData->gradient->setGradientSpaceTransform(transform);
-
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
@@ -207,6 +207,8 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
context->setFillGradient(gradientData->gradient);
context->setFillRule(svgStyle->fillRule());
} else if (resourceMode & ApplyToStrokeMode) {
+ if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
+ gradientData->gradient->setGradientSpaceTransform(transformOnNonScalingStroke(object, gradientData->userspaceTransform));
context->setAlpha(svgStyle->strokeOpacity());
context->setStrokeGradient(gradientData->gradient);
applyStrokeStyleToContext(context, style, object);
diff --git a/WebCore/rendering/RenderSVGResourceGradient.h b/WebCore/rendering/RenderSVGResourceGradient.h
index 4d848af..b01af6d 100644
--- a/WebCore/rendering/RenderSVGResourceGradient.h
+++ b/WebCore/rendering/RenderSVGResourceGradient.h
@@ -39,6 +39,7 @@ struct GradientData {
RefPtr<Gradient> gradient;
bool boundingBoxMode;
+ AffineTransform userspaceTransform;
AffineTransform transform;
};
@@ -54,7 +55,7 @@ public:
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
- virtual FloatRect resourceBoundingBox(const FloatRect&) { return FloatRect(); }
+ virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
protected:
void addStops(GradientData*, const Vector<Gradient::ColorStop>&) const;
diff --git a/WebCore/rendering/RenderSVGResourceMarker.h b/WebCore/rendering/RenderSVGResourceMarker.h
index fe848a9..533a03b 100644
--- a/WebCore/rendering/RenderSVGResourceMarker.h
+++ b/WebCore/rendering/RenderSVGResourceMarker.h
@@ -58,7 +58,7 @@ public:
AffineTransform markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const;
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short) { return false; }
- virtual FloatRect resourceBoundingBox(const FloatRect&) { return FloatRect(); }
+ virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
FloatPoint referencePoint() const;
float angle() const;
diff --git a/WebCore/rendering/RenderSVGResourceMasker.cpp b/WebCore/rendering/RenderSVGResourceMasker.cpp
index 2bfb283..ea79439 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -210,12 +210,22 @@ void RenderSVGResourceMasker::calculateMaskContentRepaintRect()
}
}
-FloatRect RenderSVGResourceMasker::resourceBoundingBox(const FloatRect& objectBoundingBox)
+FloatRect RenderSVGResourceMasker::resourceBoundingBox(RenderObject* object)
{
+ // Save the reference to the calling object for relayouting it on changing resource properties.
+ if (!m_masker.contains(object))
+ m_masker.set(object, new MaskerData);
+
+ // Resource was not layouted yet. Give back clipping rect of the mask.
+ SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
+ FloatRect objectBoundingBox = object->objectBoundingBox();
+ FloatRect maskBoundaries = maskElement->maskBoundingBox(objectBoundingBox);
+ if (selfNeedsLayout())
+ return maskBoundaries;
+
if (m_maskBoundaries.isEmpty())
calculateMaskContentRepaintRect();
- SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
if (!maskElement)
return FloatRect();
@@ -227,7 +237,7 @@ FloatRect RenderSVGResourceMasker::resourceBoundingBox(const FloatRect& objectBo
maskRect = transform.mapRect(maskRect);
}
- maskRect.intersect(maskElement->maskBoundingBox(objectBoundingBox));
+ maskRect.intersect(maskBoundaries);
return maskRect;
}
diff --git a/WebCore/rendering/RenderSVGResourceMasker.h b/WebCore/rendering/RenderSVGResourceMasker.h
index 2de5f3f..f6301cb 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.h
+++ b/WebCore/rendering/RenderSVGResourceMasker.h
@@ -57,7 +57,7 @@ public:
virtual void invalidateClient(RenderObject*);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
- virtual FloatRect resourceBoundingBox(const FloatRect&);
+ virtual FloatRect resourceBoundingBox(RenderObject*);
SVGUnitTypes::SVGUnitType maskUnits() const { return toUnitType(static_cast<SVGMaskElement*>(node())->maskUnits()); }
SVGUnitTypes::SVGUnitType maskContentUnits() const { return toUnitType(static_cast<SVGMaskElement*>(node())->maskContentUnits()); }
diff --git a/WebCore/rendering/RenderSVGResourcePattern.cpp b/WebCore/rendering/RenderSVGResourcePattern.cpp
index 8302030..040b2e2 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.cpp
+++ b/WebCore/rendering/RenderSVGResourcePattern.cpp
@@ -90,25 +90,19 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
PatternData* patternData = m_pattern.get(object);
if (!patternData->pattern) {
- FloatRect patternBoundaries;
- AffineTransform patternTransform;
// Create tile image
- OwnPtr<ImageBuffer> tileImage = createTileImage(patternBoundaries, patternTransform, patternElement, object);
+ OwnPtr<ImageBuffer> tileImage = createTileImage(patternData, patternElement, object);
if (!tileImage)
return false;
// Create pattern object
- buildPattern(patternData, patternBoundaries, tileImage.release());
+ buildPattern(patternData, tileImage.release());
if (!patternData->pattern)
return false;
- // Compute pattern transformation
- AffineTransform transform;
- transform.translate(patternBoundaries.x(), patternBoundaries.y());
- transform.multiply(patternTransform);
- patternData->pattern->setPatternSpaceTransform(transform);
+ patternData->pattern->setPatternSpaceTransform(patternData->transform);
}
// Draw pattern
@@ -122,6 +116,8 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
context->setFillPattern(patternData->pattern);
context->setFillRule(svgStyle->fillRule());
} else if (resourceMode & ApplyToStrokeMode) {
+ if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
+ patternData->pattern->setPatternSpaceTransform(transformOnNonScalingStroke(object, patternData->transform));
context->setAlpha(svgStyle->strokeOpacity());
context->setStrokePattern(patternData->pattern);
applyStrokeStyleToContext(context, style, object);
@@ -212,8 +208,7 @@ FloatRect RenderSVGResourcePattern::calculatePatternBoundariesIncludingOverflow(
return patternBoundariesIncludingOverflow;
}
-PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(FloatRect& patternBoundaries,
- AffineTransform& patternTransform,
+PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(PatternData* patternData,
const SVGPatternElement* patternElement,
RenderObject* object) const
{
@@ -224,8 +219,8 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(FloatRect& pat
return 0;
FloatRect objectBoundingBox = object->objectBoundingBox();
- patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement);
- patternTransform = attributes.patternTransform();
+ FloatRect patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement);
+ AffineTransform patternTransform = attributes.patternTransform();
AffineTransform viewBoxCTM = patternElement->viewBoxToViewTransform(patternElement->viewBox(),
patternElement->preserveAspectRatio(),
@@ -276,11 +271,17 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(FloatRect& pat
renderSubtreeToImage(tileImage.get(), node->renderer());
}
+ patternData->boundaries = patternBoundaries;
+
+ // Compute pattern transformation
+ patternData->transform.translate(patternBoundaries.x(), patternBoundaries.y());
+ patternData->transform.multiply(patternTransform);
+
context->restore();
return tileImage.release();
}
-void RenderSVGResourcePattern::buildPattern(PatternData* patternData, const FloatRect& patternBoundaries, PassOwnPtr<ImageBuffer> tileImage) const
+void RenderSVGResourcePattern::buildPattern(PatternData* patternData, PassOwnPtr<ImageBuffer> tileImage) const
{
if (!tileImage->image()) {
patternData->pattern = 0;
@@ -288,14 +289,14 @@ void RenderSVGResourcePattern::buildPattern(PatternData* patternData, const Floa
}
IntRect tileRect = tileImage->image()->rect();
- if (tileRect.width() <= patternBoundaries.width() && tileRect.height() <= patternBoundaries.height()) {
+ if (tileRect.width() <= patternData->boundaries.width() && tileRect.height() <= patternData->boundaries.height()) {
patternData->pattern = Pattern::create(tileImage->image(), true, true);
return;
}
// Draw the first cell of the pattern manually to support overflow="visible" on all platforms.
- int tileWidth = static_cast<int>(patternBoundaries.width() + 0.5f);
- int tileHeight = static_cast<int>(patternBoundaries.height() + 0.5f);
+ int tileWidth = static_cast<int>(patternData->boundaries.width() + 0.5f);
+ int tileHeight = static_cast<int>(patternData->boundaries.height() + 0.5f);
// Don't create ImageBuffers with image size of 0
if (!tileWidth || !tileHeight) {
@@ -310,14 +311,14 @@ void RenderSVGResourcePattern::buildPattern(PatternData* patternData, const Floa
int numX = static_cast<int>(ceilf(tileRect.width() / tileWidth)) + 1;
newTileImageContext->save();
- newTileImageContext->translate(-patternBoundaries.width() * numX, -patternBoundaries.height() * numY);
+ newTileImageContext->translate(-patternData->boundaries.width() * numX, -patternData->boundaries.height() * numY);
for (int i = numY; i > 0; --i) {
- newTileImageContext->translate(0, patternBoundaries.height());
+ newTileImageContext->translate(0, patternData->boundaries.height());
for (int j = numX; j > 0; --j) {
- newTileImageContext->translate(patternBoundaries.width(), 0);
+ newTileImageContext->translate(patternData->boundaries.width(), 0);
newTileImageContext->drawImage(tileImage->image(), style()->colorSpace(), tileRect, tileRect);
}
- newTileImageContext->translate(-patternBoundaries.width() * numX, 0);
+ newTileImageContext->translate(-patternData->boundaries.width() * numX, 0);
}
newTileImageContext->restore();
diff --git a/WebCore/rendering/RenderSVGResourcePattern.h b/WebCore/rendering/RenderSVGResourcePattern.h
index 4129934..690b0de 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.h
+++ b/WebCore/rendering/RenderSVGResourcePattern.h
@@ -38,6 +38,8 @@ namespace WebCore {
struct PatternData {
RefPtr<Pattern> pattern;
+ FloatRect boundaries;
+ AffineTransform transform;
};
struct PatternAttributes;
@@ -54,14 +56,14 @@ public:
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
- virtual FloatRect resourceBoundingBox(const FloatRect&) { return FloatRect(); }
+ virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
static RenderSVGResourceType s_resourceType;
private:
- PassOwnPtr<ImageBuffer> createTileImage(FloatRect& patternBoundaries, AffineTransform& patternTransform, const SVGPatternElement*, RenderObject*) const;
- void buildPattern(PatternData*, const FloatRect& patternBoundaries, PassOwnPtr<ImageBuffer> tileImage) const;
+ PassOwnPtr<ImageBuffer> createTileImage(PatternData*, const SVGPatternElement*, RenderObject*) const;
+ void buildPattern(PatternData*, PassOwnPtr<ImageBuffer> tileImage) const;
FloatRect calculatePatternBoundariesIncludingOverflow(PatternAttributes&, const FloatRect& objectBoundingBox,
const AffineTransform& viewBoxCTM, const FloatRect& patternBoundaries) const;
diff --git a/WebCore/rendering/RenderSVGResourceSolidColor.h b/WebCore/rendering/RenderSVGResourceSolidColor.h
index a4de62d..ad7fd27 100644
--- a/WebCore/rendering/RenderSVGResourceSolidColor.h
+++ b/WebCore/rendering/RenderSVGResourceSolidColor.h
@@ -38,7 +38,7 @@ public:
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
- virtual FloatRect resourceBoundingBox(const FloatRect&) { return FloatRect(); }
+ virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
static RenderSVGResourceType s_resourceType;
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp
index 966196b..072b6d1 100644
--- a/WebCore/rendering/RenderSVGText.cpp
+++ b/WebCore/rendering/RenderSVGText.cpp
@@ -33,6 +33,7 @@
#include "FloatConversion.h"
#include "FloatQuad.h"
#include "GraphicsContext.h"
+#include "HitTestRequest.h"
#include "PointerEventsHitRules.h"
#include "RenderLayer.h"
#include "RenderSVGRoot.h"
@@ -98,12 +99,16 @@ RootInlineBox* RenderSVGText::createRootInlineBox()
bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
- PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, style()->pointerEvents());
+ PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, style()->pointerEvents());
bool isVisible = (style()->visibility() == VISIBLE);
if (isVisible || !hitRules.requireVisible) {
if ((hitRules.canHitStroke && (style()->svgStyle()->hasStroke() || !hitRules.requireStroke))
|| (hitRules.canHitFill && (style()->svgStyle()->hasFill() || !hitRules.requireFill))) {
FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
+
+ if (!pointInClippingArea(this, localPoint))
+ return false;
+
return RenderBlock::nodeAtPoint(request, result, (int)localPoint.x(), (int)localPoint.y(), 0, 0, hitTestAction);
}
}
@@ -186,7 +191,7 @@ FloatRect RenderSVGText::objectBoundingBox() const
FloatRect RenderSVGText::strokeBoundingBox() const
{
- FloatRect repaintRect = objectBoundingBox();
+ FloatRect strokeRect = objectBoundingBox();
// SVG needs to include the strokeWidth(), not the textStrokeWidth().
if (style()->svgStyle()->hasStroke()) {
@@ -202,33 +207,31 @@ FloatRect RenderSVGText::strokeBoundingBox() const
}
#endif
- repaintRect.inflate(strokeWidth);
+ strokeRect.inflate(strokeWidth);
}
- return repaintRect;
+ return strokeRect;
}
FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
{
FloatRect repaintRect = strokeBoundingBox();
+ intersectRepaintRectWithResources(this, repaintRect);
- // FIXME: We need to be careful here. We assume that there is no filter,
- // clipper or masker if the rects are empty.
- FloatRect rect = filterBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- repaintRect = rect;
-
- rect = clipperBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- repaintRect.intersect(rect);
-
- rect = maskerBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- repaintRect.intersect(rect);
+ return repaintRect;
+}
- style()->svgStyle()->inflateForShadow(repaintRect);
+// Fix for <rdar://problem/8048875>. We should not render :first-line CSS Style
+// in a SVG text element context.
+RenderBlock* RenderSVGText::firstLineBlock() const
+{
+ return 0;
+}
- return repaintRect;
+// Fix for <rdar://problem/8048875>. We should not render :first-letter CSS Style
+// in a SVG text element context.
+void RenderSVGText::updateFirstLetter()
+{
}
}
diff --git a/WebCore/rendering/RenderSVGText.h b/WebCore/rendering/RenderSVGText.h
index 66f7eb3..162c958 100644
--- a/WebCore/rendering/RenderSVGText.h
+++ b/WebCore/rendering/RenderSVGText.h
@@ -71,6 +71,9 @@ private:
virtual RootInlineBox* createRootInlineBox();
+ virtual RenderBlock* firstLineBlock() const;
+ virtual void updateFirstLetter();
+
bool m_needsTransformUpdate : 1;
AffineTransform m_localTransform;
};
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index aed8a8c..60b2369 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -28,14 +28,14 @@
#include "EventNames.h"
#include "Frame.h"
#include "HTMLInputElement.h"
-#include "HTMLDivElement.h"
#include "HTMLNames.h"
-#include "HTMLParser.h"
+#include "LegacyHTMLTreeConstructor.h"
#include "MediaControlElements.h"
#include "MouseEvent.h"
#include "RenderLayer.h"
#include "RenderTheme.h"
#include "RenderView.h"
+#include "ShadowElement.h"
#include "StepRange.h"
#include <wtf/MathExtras.h>
@@ -47,8 +47,6 @@ using std::min;
namespace WebCore {
-using namespace HTMLNames;
-
static const int defaultTrackLength = 129;
// Returns a value between 0 and 1.
@@ -59,7 +57,7 @@ static double sliderPosition(HTMLInputElement* element)
}
// FIXME: Could share code with the SliderDivElement class in RenderProgress.
-class SliderThumbElement : public HTMLDivElement {
+class SliderThumbElement : public ShadowBlockElement {
public:
static PassRefPtr<SliderThumbElement> create(Node* shadowParent);
@@ -71,17 +69,12 @@ public:
private:
SliderThumbElement(Node* shadowParent);
- virtual bool isShadowNode() const { return true; }
- virtual Node* shadowParentNode() { return m_shadowParent; }
-
FloatPoint m_offsetToThumb;
- Node* m_shadowParent;
bool m_inDragMode;
};
inline SliderThumbElement::SliderThumbElement(Node* shadowParent)
- : HTMLDivElement(divTag, shadowParent->document())
- , m_shadowParent(shadowParent)
+ : ShadowBlockElement(shadowParent)
, m_inDragMode(false)
{
}
@@ -94,7 +87,7 @@ inline PassRefPtr<SliderThumbElement> SliderThumbElement::create(Node* shadowPar
void SliderThumbElement::defaultEventHandler(Event* event)
{
if (!event->isMouseEvent()) {
- HTMLDivElement::defaultEventHandler(event);
+ ShadowBlockElement::defaultEventHandler(event);
return;
}
@@ -118,7 +111,7 @@ void SliderThumbElement::defaultEventHandler(Event* event)
}
m_inDragMode = true;
- document()->frame()->eventHandler()->setCapturingMouseEventsNode(m_shadowParent);
+ document()->frame()->eventHandler()->setCapturingMouseEventsNode(shadowParentNode());
event->setDefaultHandled();
return;
}
@@ -144,7 +137,7 @@ void SliderThumbElement::defaultEventHandler(Event* event)
}
}
- HTMLDivElement::defaultEventHandler(event);
+ ShadowBlockElement::defaultEventHandler(event);
}
void SliderThumbElement::detach()
@@ -153,7 +146,7 @@ void SliderThumbElement::detach()
if (Frame* frame = document()->frame())
frame->eventHandler()->setCapturingMouseEventsNode(0);
}
- HTMLDivElement::detach();
+ ShadowBlockElement::detach();
}
RenderSlider::RenderSlider(HTMLInputElement* element)
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index 7724619..d1c8039 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -169,7 +169,7 @@ void RenderTextControl::setInnerTextValue(const String& innerTextValue)
String value = innerTextValue;
if (value != text() || !m_innerText->hasChildNodes()) {
if (value != text()) {
- if (Frame* frame = document()->frame()) {
+ if (Frame* frame = this->frame()) {
frame->editor()->clearUndoRedoOperations();
if (AXObjectCache::accessibilityEnabled())
@@ -201,7 +201,7 @@ void RenderTextControl::setLastChangeWasUserEdit(bool lastChangeWasUserEdit)
int RenderTextControl::selectionStart()
{
- Frame* frame = document()->frame();
+ Frame* frame = this->frame();
if (!frame)
return 0;
return indexForVisiblePosition(frame->selection()->start());
@@ -209,7 +209,7 @@ int RenderTextControl::selectionStart()
int RenderTextControl::selectionEnd()
{
- Frame* frame = document()->frame();
+ Frame* frame = this->frame();
if (!frame)
return 0;
return indexForVisiblePosition(frame->selection()->end());
@@ -255,7 +255,7 @@ void RenderTextControl::setSelectionRange(int start, int end)
}
VisibleSelection newSelection = VisibleSelection(startPosition, endPosition);
- if (Frame* frame = document()->frame())
+ if (Frame* frame = this->frame())
frame->selection()->setSelection(newSelection);
}
@@ -545,7 +545,7 @@ void RenderTextControl::selectionChanged(bool userTriggered)
{
cacheSelection(selectionStart(), selectionEnd());
- if (Frame* frame = document()->frame()) {
+ if (Frame* frame = this->frame()) {
if (frame->selection()->isRange() && userTriggered)
node()->dispatchEvent(Event::create(eventNames().selectEvent, true, false));
}
diff --git a/WebCore/rendering/RenderTextControlMultiLine.cpp b/WebCore/rendering/RenderTextControlMultiLine.cpp
index 76bf612..976d1ac 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -57,7 +57,7 @@ void RenderTextControlMultiLine::subtreeHasChanged()
node()->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
- if (Frame* frame = document()->frame())
+ if (Frame* frame = this->frame())
frame->textDidChangeInTextArea(textArea);
}
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index 20f33c3..d3892e9 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -27,13 +27,14 @@
#include "EventNames.h"
#include "Frame.h"
#include "FrameView.h"
-#include "HitTestResult.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include "HitTestResult.h"
#include "InputElement.h"
#include "LocalizedStrings.h"
#include "MouseEvent.h"
#include "PlatformKeyboardEvent.h"
+#include "RenderLayer.h"
#include "RenderScrollbar.h"
#include "RenderTheme.h"
#include "SearchPopupMenu.h"
@@ -171,7 +172,7 @@ void RenderTextControlSingleLine::subtreeHasChanged()
startSearchEventTimer();
if (!wasChanged && node()->focused()) {
- if (Frame* frame = document()->frame())
+ if (Frame* frame = this->frame())
frame->textFieldDidBeginEditing(static_cast<Element*>(node()));
}
diff --git a/WebCore/rendering/RenderTextControlSingleLine.h b/WebCore/rendering/RenderTextControlSingleLine.h
index b093954..dff9e5f 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/WebCore/rendering/RenderTextControlSingleLine.h
@@ -108,6 +108,8 @@ private:
// PopupMenuClient methods
virtual void valueChanged(unsigned listIndex, bool fireEvents = true);
+ virtual void selectionChanged(unsigned, bool) {}
+ virtual void selectionCleared() {}
virtual String itemText(unsigned listIndex) const;
virtual String itemToolTip(unsigned) const { return String(); }
virtual String itemAccessibilityText(unsigned) const { return String(); }
diff --git a/WebCore/rendering/RenderTheme.cpp b/WebCore/rendering/RenderTheme.cpp
index c37de8d..2b5efc9 100644
--- a/WebCore/rendering/RenderTheme.cpp
+++ b/WebCore/rendering/RenderTheme.cpp
@@ -226,6 +226,10 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El
#endif
#if ENABLE(METER_TAG)
case MeterPart:
+ case RelevancyLevelIndicatorPart:
+ case ContinuousCapacityLevelIndicatorPart:
+ case DiscreteCapacityLevelIndicatorPart:
+ case RatingLevelIndicatorPart:
return adjustMeterStyle(selector, style, e);
#endif
default:
@@ -288,6 +292,10 @@ bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInf
return paintMenuList(o, paintInfo, r);
#if ENABLE(METER_TAG)
case MeterPart:
+ case RelevancyLevelIndicatorPart:
+ case ContinuousCapacityLevelIndicatorPart:
+ case DiscreteCapacityLevelIndicatorPart:
+ case RatingLevelIndicatorPart:
return paintMeter(o, paintInfo, r);
#endif
#if ENABLE(PROGRESS_TAG)
@@ -386,6 +394,10 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const RenderObject::PaintInfo
case MenulistPart:
#if ENABLE(METER_TAG)
case MeterPart:
+ case RelevancyLevelIndicatorPart:
+ case ContinuousCapacityLevelIndicatorPart:
+ case DiscreteCapacityLevelIndicatorPart:
+ case RatingLevelIndicatorPart:
#endif
#if ENABLE(PROGRESS_TAG)
case ProgressBarPart:
@@ -427,6 +439,10 @@ bool RenderTheme::paintDecorations(RenderObject* o, const RenderObject::PaintInf
case MenulistPart:
#if ENABLE(METER_TAG)
case MeterPart:
+ case RelevancyLevelIndicatorPart:
+ case ContinuousCapacityLevelIndicatorPart:
+ case DiscreteCapacityLevelIndicatorPart:
+ case RatingLevelIndicatorPart:
#endif
#if ENABLE(PROGRESS_TAG)
case ProgressBarPart:
@@ -897,8 +913,16 @@ void RenderTheme::adjustMeterStyle(CSSStyleSelector*, RenderStyle* style, Elemen
style->setBoxShadow(0);
}
+IntSize RenderTheme::meterSizeForBounds(const RenderMeter*, const IntRect& bounds) const
+{
+ return bounds.size();
+}
+
bool RenderTheme::paintMeter(RenderObject* renderObject, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
+ if (!renderObject->isMeter())
+ return true;
+
// Some platforms do not have a native gauge widget, so we draw here a default implementation.
RenderMeter* renderMeter = toRenderMeter(renderObject);
RenderStyle* style = renderObject->style();
diff --git a/WebCore/rendering/RenderTheme.h b/WebCore/rendering/RenderTheme.h
index a4514a5..2d196c7 100644
--- a/WebCore/rendering/RenderTheme.h
+++ b/WebCore/rendering/RenderTheme.h
@@ -39,6 +39,9 @@ namespace WebCore {
class Element;
class PopupMenu;
class RenderMenuList;
+#if ENABLE(METER_TAG)
+class RenderMeter;
+#endif
#if ENABLE(PROGRESS_TAG)
class RenderProgress;
#endif
@@ -190,6 +193,10 @@ public:
virtual String formatMediaControlsRemainingTime(float currentTime, float duration) const;
#endif
+#if ENABLE(METER_TAG)
+ virtual IntSize meterSizeForBounds(const RenderMeter*, const IntRect&) const;
+#endif
+
protected:
// The platform selection color.
virtual Color platformActiveSelectionBackgroundColor() const;
diff --git a/WebCore/rendering/RenderThemeChromiumSkia.cpp b/WebCore/rendering/RenderThemeChromiumSkia.cpp
index 0956e38..e3afd1f 100644
--- a/WebCore/rendering/RenderThemeChromiumSkia.cpp
+++ b/WebCore/rendering/RenderThemeChromiumSkia.cpp
@@ -26,6 +26,7 @@
#include "ChromiumBridge.h"
#include "CSSValueKeywords.h"
+#include "CurrentTime.h"
#include "GraphicsContext.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
@@ -35,6 +36,7 @@
#include "RenderBox.h"
#include "RenderMediaControlsChromium.h"
#include "RenderObject.h"
+#include "RenderProgress.h"
#include "RenderSlider.h"
#include "ScrollbarTheme.h"
#include "TimeRanges.h"
@@ -768,4 +770,113 @@ int RenderThemeChromiumSkia::menuListInternalPadding(RenderStyle* style, int pad
return padding;
}
+#if ENABLE(PROGRESS_TAG)
+
+//
+// Following values are come from default of GTK+
+//
+static const int progressDeltaPixelsPerSecond = 100;
+static const int progressActivityBlocks = 5;
+static const int progressAnimationFrmaes = 10;
+static const double progressAnimationInterval = 0.125;
+
+IntRect RenderThemeChromiumSkia::determinateProgressValueRectFor(RenderProgress* renderProgress, const IntRect& rect) const
+{
+ int dx = rect.width() * renderProgress->position();
+ if (renderProgress->style()->direction() == RTL)
+ return IntRect(rect.x() + rect.width() - dx, rect.y(), dx, rect.height());
+ return IntRect(rect.x(), rect.y(), dx, rect.height());
+}
+
+IntRect RenderThemeChromiumSkia::indeterminateProgressValueRectFor(RenderProgress* renderProgress, const IntRect& rect) const
+{
+
+ int valueWidth = rect.width() / progressActivityBlocks;
+ int movableWidth = rect.width() - valueWidth;
+ if (movableWidth <= 0)
+ return IntRect();
+
+ double progress = renderProgress->animationProgress();
+ if (progress < 0.5)
+ return IntRect(rect.x() + progress * 2 * movableWidth, rect.y(), valueWidth, rect.height());
+ return IntRect(rect.x() + (1.0 - progress) * 2 * movableWidth, rect.y(), valueWidth, rect.height());
+}
+
+double RenderThemeChromiumSkia::animationRepeatIntervalForProgressBar(RenderProgress*) const
+{
+ return progressAnimationInterval;
+}
+
+double RenderThemeChromiumSkia::animationDurationForProgressBar(RenderProgress* renderProgress) const
+{
+ return progressAnimationInterval * progressAnimationFrmaes * 2; // "2" for back and forth
+}
+
+bool RenderThemeChromiumSkia::paintProgressBar(RenderObject* renderObject, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
+{
+ static Image* barImage = Image::loadPlatformResource("linuxProgressBar").releaseRef();
+ static Image* valueImage = Image::loadPlatformResource("linuxProgressValue").releaseRef();
+ static Image* leftBorderImage = Image::loadPlatformResource("linuxProgressBorderLeft").releaseRef();
+ static Image* rightBorderImage = Image::loadPlatformResource("linuxProgressBorderRight").releaseRef();
+ ASSERT(barImage->height() == valueImage->height());
+
+ if (!renderObject->isProgress())
+ return true;
+
+ paintInfo.context->platformContext()->setImageResamplingHint(barImage->size(), rect.size());
+
+ RenderProgress* renderProgress = toRenderProgress(renderObject);
+ double tileScale = static_cast<double>(rect.height()) / barImage->height();
+ IntSize barTileSize(static_cast<int>(barImage->width() * tileScale), rect.height());
+ ColorSpace colorSpace = renderObject->style()->colorSpace();
+
+ paintInfo.context->drawTiledImage(barImage, colorSpace, rect, IntPoint(0, 0), barTileSize);
+
+ IntRect valueRect = progressValueRectFor(renderProgress, rect);
+ if (valueRect.width()) {
+
+ IntSize valueTileSize(static_cast<int>(valueImage->width() * tileScale), valueRect.height());
+ int leftOffset = valueRect.x() - rect.x();
+ int roundedLeftOffset= (leftOffset / valueTileSize.width()) * valueTileSize.width();
+ int dstLeftValueWidth = roundedLeftOffset - leftOffset + (leftOffset % valueImage->width()) ? valueTileSize.width() : 0;
+
+ IntRect dstLeftValueRect(valueRect.x(), valueRect.y(), dstLeftValueWidth, valueRect.height());
+ int srcLeftValueWidth = dstLeftValueWidth / tileScale;
+ IntRect srcLeftValueRect(valueImage->width() - srcLeftValueWidth, 0, srcLeftValueWidth, valueImage->height());
+ paintInfo.context->drawImage(valueImage, colorSpace, dstLeftValueRect, srcLeftValueRect);
+
+ int rightOffset = valueRect.right() - rect.x();
+ int roundedRightOffset = (rightOffset / valueTileSize.width()) * valueTileSize.width();
+ int dstRightValueWidth = rightOffset - roundedRightOffset;
+ IntRect dstRightValueRect(rect.x() + roundedRightOffset, valueRect.y(), dstRightValueWidth, valueTileSize.height());
+ int srcRightValueWidth = dstRightValueWidth / tileScale;
+ IntRect srcRightValueRect(0, 0, srcRightValueWidth, valueImage->height());
+ paintInfo.context->drawImage(valueImage, colorSpace, dstRightValueRect, srcRightValueRect);
+
+ IntRect alignedValueRect(dstLeftValueRect.right(), dstLeftValueRect.y(),
+ dstRightValueRect.x() - dstLeftValueRect.right(), dstLeftValueRect.height());
+ paintInfo.context->drawTiledImage(valueImage, colorSpace, alignedValueRect, IntPoint(0, 0), valueTileSize);
+ }
+
+ int dstLeftBorderWidth = leftBorderImage->width() * tileScale;
+ IntRect dstLeftBorderRect(rect.x(), rect.y(), dstLeftBorderWidth, rect.height());
+ paintInfo.context->drawImage(leftBorderImage, colorSpace, dstLeftBorderRect, leftBorderImage->rect());
+
+ int dstRightBorderWidth = rightBorderImage->width() * tileScale;
+ IntRect dstRightBorderRect(rect.right() - dstRightBorderWidth, rect.y(), dstRightBorderWidth, rect.height());
+ paintInfo.context->drawImage(rightBorderImage, colorSpace, dstRightBorderRect, rightBorderImage->rect());
+
+ paintInfo.context->platformContext()->clearImageResamplingHint();
+
+ return false;
+}
+
+
+IntRect RenderThemeChromiumSkia::progressValueRectFor(RenderProgress* renderProgress, const IntRect& rect) const
+{
+ return renderProgress->isDeterminate() ? determinateProgressValueRectFor(renderProgress, rect) : indeterminateProgressValueRectFor(renderProgress, rect);
+}
+
+#endif
+
} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeChromiumSkia.h b/WebCore/rendering/RenderThemeChromiumSkia.h
index dc920b1cf..56c315e 100644
--- a/WebCore/rendering/RenderThemeChromiumSkia.h
+++ b/WebCore/rendering/RenderThemeChromiumSkia.h
@@ -32,6 +32,8 @@
namespace WebCore {
+class RenderProgress;
+
class RenderThemeChromiumSkia : public RenderTheme {
public:
RenderThemeChromiumSkia();
@@ -117,6 +119,12 @@ namespace WebCore {
virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+#if ENABLE(PROGRESS_TAG)
+ virtual double animationRepeatIntervalForProgressBar(RenderProgress*) const;
+ virtual double animationDurationForProgressBar(RenderProgress*) const;
+ virtual bool paintProgressBar(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+#endif
+
// These methods define the padding for the MenuList's inner block.
virtual int popupInternalPaddingLeft(RenderStyle*) const;
virtual int popupInternalPaddingRight(RenderStyle*) const;
@@ -145,6 +153,12 @@ namespace WebCore {
virtual double caretBlinkIntervalInternal() const;
+#if ENABLE(PROGRESS_TAG)
+ IntRect determinateProgressValueRectFor(RenderProgress*, const IntRect&) const;
+ IntRect indeterminateProgressValueRectFor(RenderProgress*, const IntRect&) const;
+ IntRect progressValueRectFor(RenderProgress*, const IntRect&) const;
+#endif
+
private:
int menuListInternalPadding(RenderStyle*, int paddingType) const;
bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*);
diff --git a/WebCore/rendering/RenderThemeChromiumWin.cpp b/WebCore/rendering/RenderThemeChromiumWin.cpp
index cc7570c..d82fddc 100644
--- a/WebCore/rendering/RenderThemeChromiumWin.cpp
+++ b/WebCore/rendering/RenderThemeChromiumWin.cpp
@@ -679,21 +679,13 @@ void RenderThemeChromiumWin::adjustProgressBarStyle(CSSStyleSelector*, RenderSty
bool RenderThemeChromiumWin::paintProgressBar(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
- RenderProgress* renderProgress = toRenderProgress(o);
-
- IntRect valueRect;
- if (renderProgress->isDeterminate()) {
- int dx = r.width() * renderProgress->position();
- if (renderProgress->style()->direction() == RTL)
- valueRect = IntRect(r.x() + r.width() - dx, r.y(), dx, r.height());
- else
- valueRect = IntRect(r.x(), r.y(), dx, r.height());
- } else {
- // For indeterminate bar, valueRect is ignored and it is computed by the theme engine
- // because the animation is a platform detail and WebKit doesn't need to know how.
- valueRect = IntRect(0, 0, 0, 0);
- }
+ if (!o->isProgress())
+ return true;
+ RenderProgress* renderProgress = toRenderProgress(o);
+ // For indeterminate bar, valueRect is ignored and it is computed by the theme engine
+ // because the animation is a platform detail and WebKit doesn't need to know how.
+ IntRect valueRect = renderProgress->isDeterminate() ? determinateProgressValueRectFor(renderProgress, r) : IntRect(0, 0, 0, 0);
double animatedSeconds = renderProgress->animationStartTime() ? WTF::currentTime() - renderProgress->animationStartTime() : 0;
ThemePainter painter(i.context, r);
ChromiumBridge::paintProgressBar(painter.context(), r, valueRect, renderProgress->isDeterminate(), animatedSeconds);
diff --git a/WebCore/rendering/RenderThemeMac.h b/WebCore/rendering/RenderThemeMac.h
index cb604b9..7cb4e3b 100644
--- a/WebCore/rendering/RenderThemeMac.h
+++ b/WebCore/rendering/RenderThemeMac.h
@@ -80,6 +80,11 @@ public:
virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+#if ENABLE(METER_TAG)
+ virtual IntSize meterSizeForBounds(const RenderMeter*, const IntRect&) const;
+ virtual bool paintMeter(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+#endif
+
#if ENABLE(PROGRESS_TAG)
// Returns the repeat interval of the animation for the progress bar.
virtual double animationRepeatIntervalForProgressBar(RenderProgress*) const;
@@ -201,12 +206,18 @@ private:
NSSliderCell* sliderThumbHorizontal() const;
NSSliderCell* sliderThumbVertical() const;
+#if ENABLE(METER_TAG)
+ NSLevelIndicatorStyle levelIndicatorStyleFor(ControlPart) const;
+ NSLevelIndicatorCell* levelIndicatorFor(const RenderMeter*) const;
+#endif
+
private:
mutable RetainPtr<NSPopUpButtonCell> m_popupButton;
mutable RetainPtr<NSSearchFieldCell> m_search;
mutable RetainPtr<NSMenu> m_searchMenuTemplate;
mutable RetainPtr<NSSliderCell> m_sliderThumbHorizontal;
mutable RetainPtr<NSSliderCell> m_sliderThumbVertical;
+ mutable RetainPtr<NSLevelIndicatorCell> m_levelIndicator;
bool m_isSliderThumbHorizontalPressed;
bool m_isSliderThumbVerticalPressed;
diff --git a/WebCore/rendering/RenderThemeMac.mm b/WebCore/rendering/RenderThemeMac.mm
index f1de775..d0289de 100644
--- a/WebCore/rendering/RenderThemeMac.mm
+++ b/WebCore/rendering/RenderThemeMac.mm
@@ -51,6 +51,11 @@
#import "RenderProgress.h"
+#if ENABLE(METER_TAG)
+#include "RenderMeter.h"
+#include "HTMLMeterElement.h"
+#endif
+
#ifdef BUILDING_ON_TIGER
typedef int NSInteger;
typedef unsigned NSUInteger;
@@ -801,7 +806,100 @@ bool RenderThemeMac::paintMenuList(RenderObject* o, const RenderObject::PaintInf
return false;
}
-
+
+#if ENABLE(METER_TAG)
+
+IntSize RenderThemeMac::meterSizeForBounds(const RenderMeter* renderMeter, const IntRect& bounds) const
+{
+ if (NoControlPart == renderMeter->style()->appearance())
+ return bounds.size();
+
+ NSLevelIndicatorCell* cell = levelIndicatorFor(renderMeter);
+ // Makes enough room for cell's intrinsic size.
+ NSSize cellSize = [cell cellSizeForBounds:IntRect(IntPoint(), bounds.size())];
+ return IntSize(bounds.width() < cellSize.width ? cellSize.width : bounds.width(),
+ bounds.height() < cellSize.height ? cellSize.height : bounds.height());
+}
+
+bool RenderThemeMac::paintMeter(RenderObject* renderObject, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
+{
+ if (!renderObject->isMeter())
+ return true;
+
+ // Becaue NSLevelIndicatorCell doesn't support vertical gauge, we use a portable version
+ if (rect.width() < rect.height())
+ return RenderTheme::paintMeter(renderObject, paintInfo, rect);
+
+ NSLevelIndicatorCell* cell = levelIndicatorFor(toRenderMeter(renderObject));
+ paintInfo.context->save();
+ [cell drawWithFrame:rect inView:documentViewFor(renderObject)];
+ [cell setControlView:nil];
+ paintInfo.context->restore();
+
+ return false;
+}
+
+NSLevelIndicatorStyle RenderThemeMac::levelIndicatorStyleFor(ControlPart part) const
+{
+ switch (part) {
+ case RelevancyLevelIndicatorPart:
+ return NSRelevancyLevelIndicatorStyle;
+ case DiscreteCapacityLevelIndicatorPart:
+ return NSDiscreteCapacityLevelIndicatorStyle;
+ case RatingLevelIndicatorPart:
+ return NSRatingLevelIndicatorStyle;
+ case MeterPart:
+ case ContinuousCapacityLevelIndicatorPart:
+ default:
+ return NSContinuousCapacityLevelIndicatorStyle;
+ }
+
+}
+
+NSLevelIndicatorCell* RenderThemeMac::levelIndicatorFor(const RenderMeter* renderMeter) const
+{
+ RenderStyle* style = renderMeter->style();
+ ASSERT(style->appearance() != NoControlPart);
+
+ if (!m_levelIndicator)
+ m_levelIndicator.adoptNS([[NSLevelIndicatorCell alloc] initWithLevelIndicatorStyle:NSContinuousCapacityLevelIndicatorStyle]);
+ NSLevelIndicatorCell* cell = m_levelIndicator.get();
+
+ HTMLMeterElement* element = static_cast<HTMLMeterElement*>(renderMeter->node());
+ double value = element->value();
+
+ // Because NSLevelIndicatorCell does not support optimum-in-the-middle type coloring,
+ // we explicitly control the color instead giving low and high value to NSLevelIndicatorCell as is.
+ switch (element->gaugeRegion()) {
+ case HTMLMeterElement::GaugeRegionOptimum:
+ // Make meter the green
+ [cell setWarningValue:value + 1];
+ [cell setCriticalValue:value + 2];
+ break;
+ case HTMLMeterElement::GaugeRegionSuboptimal:
+ // Make the meter yellow
+ [cell setWarningValue:value - 1];
+ [cell setCriticalValue:value + 1];
+ break;
+ case HTMLMeterElement::GaugeRegionEvenLessGood:
+ // Make the meter red
+ [cell setWarningValue:value - 2];
+ [cell setCriticalValue:value - 1];
+ break;
+ }
+
+ [cell setLevelIndicatorStyle:levelIndicatorStyleFor(style->appearance())];
+ [cell setBaseWritingDirection:style->direction() == LTR ? NSWritingDirectionLeftToRight : NSWritingDirectionRightToLeft];
+ [cell setMinValue:element->min()];
+ [cell setMaxValue:element->max()];
+ RetainPtr<NSNumber> valueObject = [NSNumber numberWithDouble:value];
+ [cell setObjectValue:valueObject.get()];
+
+ return cell;
+}
+
+#endif
+
#if ENABLE(PROGRESS_TAG)
double RenderThemeMac::animationRepeatIntervalForProgressBar(RenderProgress*) const
@@ -820,6 +918,9 @@ void RenderThemeMac::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Ele
bool RenderThemeMac::paintProgressBar(RenderObject* renderObject, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
+ if (!renderObject->isProgress())
+ return true;
+
RenderProgress* renderProgress = toRenderProgress(renderObject);
HIThemeTrackDrawInfo trackInfo;
trackInfo.version = 0;
diff --git a/WebCore/rendering/RenderTreeAsText.cpp b/WebCore/rendering/RenderTreeAsText.cpp
index cf76f0b..b05d97a 100644
--- a/WebCore/rendering/RenderTreeAsText.cpp
+++ b/WebCore/rendering/RenderTreeAsText.cpp
@@ -38,6 +38,7 @@
#include "RenderBR.h"
#include "RenderFileUploadControl.h"
#include "RenderInline.h"
+#include "RenderLayer.h"
#include "RenderListItem.h"
#include "RenderListMarker.h"
#include "RenderPart.h"
diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp
index e477676..2556bbb 100644
--- a/WebCore/rendering/RenderWidget.cpp
+++ b/WebCore/rendering/RenderWidget.cpp
@@ -27,6 +27,7 @@
#include "AnimationController.h"
#include "GraphicsContext.h"
#include "HitTestResult.h"
+#include "RenderLayer.h"
#include "RenderView.h"
#include "RenderWidgetProtector.h"
@@ -333,7 +334,7 @@ void RenderWidget::updateWidgetPosition()
#ifndef ANDROID_FLATTEN_IFRAME
// if the frame bounds got changed, or if view needs layout (possibly indicating
// content size is wrong) we have to do a layout to set the right widget size
- if (m_widget->isFrameView()) {
+ if (m_widget && m_widget->isFrameView()) {
FrameView* frameView = static_cast<FrameView*>(m_widget.get());
if (boundsChanged || frameView->needsLayout())
frameView->layout();
diff --git a/WebCore/rendering/RootInlineBox.cpp b/WebCore/rendering/RootInlineBox.cpp
index 691179d..24e49c6 100644
--- a/WebCore/rendering/RootInlineBox.cpp
+++ b/WebCore/rendering/RootInlineBox.cpp
@@ -126,7 +126,7 @@ void RootInlineBox::paintEllipsisBox(RenderObject::PaintInfo& paintInfo, int tx,
void RootInlineBox::addHighlightOverflow()
{
- Frame* frame = renderer()->document()->frame();
+ Frame* frame = renderer()->frame();
if (!frame)
return;
Page* page = frame->page();
@@ -145,7 +145,7 @@ void RootInlineBox::paintCustomHighlight(RenderObject::PaintInfo& paintInfo, int
if (!renderer()->shouldPaintWithinRoot(paintInfo) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
return;
- Frame* frame = renderer()->document()->frame();
+ Frame* frame = renderer()->frame();
if (!frame)
return;
Page* page = frame->page();
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index 2600512..2ae90de 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -32,6 +32,7 @@
#include "Document.h"
#include "ImageBuffer.h"
#include "NodeRenderStyle.h"
+#include "RenderLayer.h"
#include "RenderObject.h"
#include "RenderSVGContainer.h"
#include "RenderSVGResource.h"
@@ -81,7 +82,7 @@ void SVGRenderBase::mapLocalToContainer(const RenderObject* object, RenderBoxMod
object->parent()->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
}
-bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& repaintRect, RenderSVGResourceFilter*& filter, RenderSVGResourceFilter* rootFilter)
+bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& repaintRect, RenderSVGResourceFilter*& filter)
{
#if !ENABLE(FILTERS)
UNUSED_PARAM(filter);
@@ -99,7 +100,7 @@ bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
- // Setup transparency layers before setting up filters!
+ // Setup transparency layers before setting up SVG resources!
float opacity = style->opacity();
if (opacity < 1.0f) {
paintInfo.context->clip(repaintRect);
@@ -112,43 +113,35 @@ bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
paintInfo.context->beginTransparencyLayer(1.0f);
}
-#if ENABLE(FILTERS)
- AtomicString filterId(svgStyle->filterResource());
-#endif
-
- AtomicString clipperId(svgStyle->clipperResource());
- AtomicString maskerId(svgStyle->maskerResource());
-
Document* document = object->document();
-#if ENABLE(FILTERS)
- RenderSVGResourceFilter* newFilter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, filterId);
- if (newFilter == rootFilter) {
- // Catch <text filter="url(#foo)">Test<tspan filter="url(#foo)">123</tspan></text>.
- // The filter is NOT meant to be applied twice in that case!
- filter = 0;
- filterId = String();
- } else
- filter = newFilter;
-#endif
-
- if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, maskerId)) {
- if (!masker->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
- return false;
- } else if (!maskerId.isEmpty())
- svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
+ if (svgStyle->hasMasker()) {
+ AtomicString maskerId(svgStyle->maskerResource());
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, maskerId)) {
+ if (!masker->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
+ return false;
+ } else
+ svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
+ }
- if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, clipperId))
- clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode);
- else if (!clipperId.isEmpty())
- svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);
+ if (svgStyle->hasClipper()) {
+ AtomicString clipperId(svgStyle->clipperResource());
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, clipperId))
+ clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode);
+ else
+ svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);
+ }
#if ENABLE(FILTERS)
- if (filter) {
- if (!filter->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
- return false;
- } else if (!filterId.isEmpty())
- svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
+ if (svgStyle->hasFilter()) {
+ AtomicString filterId(svgStyle->filterResource());
+ filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, filterId);
+ if (filter) {
+ if (!filter->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
+ return false;
+ } else
+ svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
+ }
#endif
return true;
@@ -280,31 +273,33 @@ bool SVGRenderBase::isOverflowHidden(const RenderObject* object)
return object->style()->overflowX() == OHIDDEN;
}
-FloatRect SVGRenderBase::filterBoundingBoxForRenderer(const RenderObject* object) const
+void SVGRenderBase::intersectRepaintRectWithResources(const RenderObject* object, FloatRect& repaintRect) const
{
+ ASSERT(object);
+ ASSERT(object->style());
+ const SVGRenderStyle* svgStyle = object->style()->svgStyle();
+ if (!svgStyle)
+ return;
+
+ RenderObject* renderer = const_cast<RenderObject*>(object);
#if ENABLE(FILTERS)
- if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object->document(), object->style()->svgStyle()->filterResource()))
- return filter->resourceBoundingBox(object->objectBoundingBox());
-#else
- UNUSED_PARAM(object);
+ if (svgStyle->hasFilter()) {
+ if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object->document(), svgStyle->filterResource()))
+ repaintRect = filter->resourceBoundingBox(renderer);
+ }
#endif
- return FloatRect();
-}
-
-FloatRect SVGRenderBase::clipperBoundingBoxForRenderer(const RenderObject* object) const
-{
- if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object->document(), object->style()->svgStyle()->clipperResource()))
- return clipper->resourceBoundingBox(object->objectBoundingBox());
-
- return FloatRect();
-}
-FloatRect SVGRenderBase::maskerBoundingBoxForRenderer(const RenderObject* object) const
-{
- if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskerResource()))
- return masker->resourceBoundingBox(object->objectBoundingBox());
-
- return FloatRect();
+ if (svgStyle->hasClipper()) {
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object->document(), svgStyle->clipperResource()))
+ repaintRect.intersect(clipper->resourceBoundingBox(renderer));
+ }
+
+ if (svgStyle->hasMasker()) {
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), svgStyle->maskerResource()))
+ repaintRect.intersect(masker->resourceBoundingBox(renderer));
+ }
+
+ svgStyle->inflateForShadow(repaintRect);
}
static inline void invalidatePaintingResource(SVGPaint* paint, RenderObject* object)
@@ -320,6 +315,27 @@ static inline void invalidatePaintingResource(SVGPaint* paint, RenderObject* obj
paintingResource->invalidateClient(object);
}
+bool pointInClippingArea(const RenderObject* object, const FloatPoint& point)
+{
+ ASSERT(object);
+ ASSERT(object->style());
+
+ Document* document = object->document();
+ ASSERT(document);
+
+ const SVGRenderStyle* svgStyle = object->style()->svgStyle();
+ ASSERT(svgStyle);
+
+ // We just take clippers into account to determine if a point is on the node. The Specification may
+ // change later and we also need to check maskers.
+ if (svgStyle->hasClipper()) {
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, svgStyle->clipperResource()))
+ return clipper->hitTestClipContent(object->objectBoundingBox(), point);
+ }
+
+ return true;
+}
+
void deregisterFromResources(RenderObject* object)
{
ASSERT(object);
diff --git a/WebCore/rendering/SVGRenderSupport.h b/WebCore/rendering/SVGRenderSupport.h
index b8a014a..e961c73 100644
--- a/WebCore/rendering/SVGRenderSupport.h
+++ b/WebCore/rendering/SVGRenderSupport.h
@@ -46,7 +46,7 @@ public:
// FIXME: These are only public for SVGRootInlineBox.
// It's unclear if these should be exposed or not. SVGRootInlineBox may
// pass the wrong RenderObject* and boundingBox to these functions.
- static bool prepareToRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, const FloatRect& boundingBox, RenderSVGResourceFilter*&, RenderSVGResourceFilter* rootFilter = 0);
+ static bool prepareToRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, const FloatRect& boundingBox, RenderSVGResourceFilter*&);
static void finishRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, RenderSVGResourceFilter*&, GraphicsContext* savedContext);
// Layout all children of the passed render object
@@ -58,10 +58,8 @@ public:
// strokeBoundingBox() includes the marker boundaries for a RenderPath object
virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
- // returns the bounding box of filter, clipper, marker and masker (or the empty rect if no filter) in local coordinates
- FloatRect filterBoundingBoxForRenderer(const RenderObject*) const;
- FloatRect clipperBoundingBoxForRenderer(const RenderObject*) const;
- FloatRect maskerBoundingBoxForRenderer(const RenderObject*) const;
+ // Calculates the repaintRect in combination with filter, clipper and masker in local coordinates.
+ void intersectRepaintRectWithResources(const RenderObject*, FloatRect&) const;
protected:
static IntRect clippedOverflowRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer);
@@ -81,6 +79,8 @@ void applyTransformToPaintInfo(RenderObject::PaintInfo&, const AffineTransform&
// This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.
void renderSubtreeToImage(ImageBuffer*, RenderObject*);
+bool pointInClippingArea(const RenderObject*, const FloatPoint&);
+
void deregisterFromResources(RenderObject*);
void clampImageBufferSizeToViewport(FrameView*, IntSize& imageBufferSize);
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index 8668780..2a71dee 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -351,7 +351,7 @@ static void writeSVGPaintingResource(TextStream& ts, RenderSVGResource* resource
else if (resource->resourceType() == RadialGradientResourceType)
ts << "[type=RADIAL-GRADIENT]";
- ts << " [id=\"" << static_cast<SVGElement*>(node)->getIDAttribute() << "\"]";
+ ts << " [id=\"" << static_cast<SVGElement*>(node)->getIdAttribute() << "\"]";
}
static void writeStyle(TextStream& ts, const RenderObject& object)
@@ -581,7 +581,7 @@ void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int i
writeStandardPrefix(ts, object, indent);
Element* element = static_cast<Element*>(object.node());
- const AtomicString& id = element->getIDAttribute();
+ const AtomicString& id = element->getIdAttribute();
writeNameAndQuotedValue(ts, "id", id);
RenderSVGResourceContainer* resource = const_cast<RenderObject&>(object).toRenderSVGResourceContainer();
@@ -734,6 +734,7 @@ void writeResources(TextStream& ts, const RenderObject& object, int indent)
const RenderStyle* style = object.style();
const SVGRenderStyle* svgStyle = style->svgStyle();
+ RenderObject& renderer = const_cast<RenderObject&>(object);
if (!svgStyle->maskerResource().isEmpty()) {
if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskerResource())) {
writeIndent(ts, indent);
@@ -741,7 +742,7 @@ void writeResources(TextStream& ts, const RenderObject& object, int indent)
writeNameAndQuotedValue(ts, "masker", svgStyle->maskerResource());
ts << " ";
writeStandardPrefix(ts, *masker, 0);
- ts << " " << masker->resourceBoundingBox(object.objectBoundingBox()) << "\n";
+ ts << " " << masker->resourceBoundingBox(&renderer) << "\n";
}
}
if (!svgStyle->clipperResource().isEmpty()) {
@@ -751,7 +752,7 @@ void writeResources(TextStream& ts, const RenderObject& object, int indent)
writeNameAndQuotedValue(ts, "clipPath", svgStyle->clipperResource());
ts << " ";
writeStandardPrefix(ts, *clipper, 0);
- ts << " " << clipper->resourceBoundingBox(object.objectBoundingBox()) << "\n";
+ ts << " " << clipper->resourceBoundingBox(&renderer) << "\n";
}
}
#if ENABLE(FILTERS)
@@ -762,7 +763,7 @@ void writeResources(TextStream& ts, const RenderObject& object, int indent)
writeNameAndQuotedValue(ts, "filter", svgStyle->filterResource());
ts << " ";
writeStandardPrefix(ts, *filter, 0);
- ts << " " << filter->resourceBoundingBox(object.objectBoundingBox()) << "\n";
+ ts << " " << filter->resourceBoundingBox(&renderer) << "\n";
}
}
#endif
diff --git a/WebCore/rendering/SVGRootInlineBox.cpp b/WebCore/rendering/SVGRootInlineBox.cpp
index 8760fe5..6b750be 100644
--- a/WebCore/rendering/SVGRootInlineBox.cpp
+++ b/WebCore/rendering/SVGRootInlineBox.cpp
@@ -73,14 +73,13 @@ RenderSVGRoot* findSVGRootObject(RenderObject* start)
// Helper class for paint()
struct SVGRootInlineBoxPaintWalker {
- SVGRootInlineBoxPaintWalker(SVGRootInlineBox* rootBox, RenderSVGResourceFilter* rootFilter, RenderObject::PaintInfo paintInfo, int tx, int ty)
+ SVGRootInlineBoxPaintWalker(SVGRootInlineBox* rootBox, RenderObject::PaintInfo paintInfo, int tx, int ty)
: m_rootBox(rootBox)
, m_chunkStarted(false)
, m_paintInfo(paintInfo)
, m_savedInfo(paintInfo)
, m_boundingBox(tx + rootBox->x(), ty + rootBox->y(), rootBox->width(), rootBox->height())
, m_filter(0)
- , m_rootFilter(rootFilter)
, m_fillPaintingResource(0)
, m_strokePaintingResource(0)
, m_fillPaintingResourceObject(0)
@@ -143,7 +142,7 @@ struct SVGRootInlineBoxPaintWalker {
// FIXME: Why is this done here instead of in RenderSVGText?
if (!flowBox->isRootInlineBox())
- SVGRenderBase::prepareToRenderSVGContent(object, m_paintInfo, m_boundingBox, m_filter, m_rootFilter);
+ SVGRenderBase::prepareToRenderSVGContent(object, m_paintInfo, m_boundingBox, m_filter);
}
void chunkEndCallback(InlineBox* box)
@@ -403,7 +402,6 @@ private:
FloatRect m_boundingBox;
RenderSVGResourceFilter* m_filter;
- RenderSVGResourceFilter* m_rootFilter;
RenderSVGResource* m_fillPaintingResource;
RenderSVGResource* m_strokePaintingResource;
@@ -431,7 +429,7 @@ void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
// Initialize text rendering
if (SVGRenderBase::prepareToRenderSVGContent(renderer(), paintInfo, boundingBox, filter)) {
// Render text, chunk-by-chunk
- SVGRootInlineBoxPaintWalker walkerCallback(this, filter, paintInfo, tx, ty);
+ SVGRootInlineBoxPaintWalker walkerCallback(this, paintInfo, tx, ty);
SVGTextChunkWalker<SVGRootInlineBoxPaintWalker> walker(&walkerCallback,
&SVGRootInlineBoxPaintWalker::chunkPortionCallback,
&SVGRootInlineBoxPaintWalker::chunkStartCallback,
diff --git a/WebCore/rendering/ShadowElement.cpp b/WebCore/rendering/ShadowElement.cpp
new file mode 100644
index 0000000..dea9233
--- /dev/null
+++ b/WebCore/rendering/ShadowElement.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "ShadowElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+PassRefPtr<ShadowBlockElement> ShadowBlockElement::create(Node* shadowParent)
+{
+ return new ShadowBlockElement(shadowParent);
+}
+
+ShadowBlockElement::ShadowBlockElement(Node* shadowParent)
+ : ShadowElement<HTMLDivElement>(HTMLNames::divTag, shadowParent)
+{
+}
+
+PassRefPtr<ShadowInputElement> ShadowInputElement::create(Node* shadowParent)
+{
+ return new ShadowInputElement(shadowParent);
+}
+
+ShadowInputElement::ShadowInputElement(Node* shadowParent)
+ : ShadowElement<HTMLInputElement>(HTMLNames::inputTag, shadowParent)
+{
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/ShadowElement.h b/WebCore/rendering/ShadowElement.h
new file mode 100644
index 0000000..90030ee
--- /dev/null
+++ b/WebCore/rendering/ShadowElement.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ShadowElement_h
+#define ShadowElement_h
+
+#include "HTMLDivElement.h"
+#include "HTMLInputElement.h"
+
+namespace WebCore {
+
+template<class BaseElement>
+class ShadowElement : public BaseElement {
+protected:
+ ShadowElement(const QualifiedName& name, Node* shadowParent)
+ : BaseElement(name, shadowParent->document())
+ , m_shadowParent(shadowParent)
+ {}
+
+ virtual bool isShadowNode() const { return true; }
+ virtual Node* shadowParentNode() { return m_shadowParent; }
+
+private:
+ Node* m_shadowParent;
+};
+
+class ShadowBlockElement : public ShadowElement<HTMLDivElement> {
+public:
+ static PassRefPtr<ShadowBlockElement> create(Node*);
+protected:
+ ShadowBlockElement(Node*);
+};
+
+class ShadowInputElement : public ShadowElement<HTMLInputElement> {
+public:
+ static PassRefPtr<ShadowInputElement> create(Node*);
+protected:
+ ShadowInputElement(Node*);
+};
+
+} // namespace WebCore
+
+#endif // ShadowElement_h
diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp
index 220e657..af4e055 100644
--- a/WebCore/rendering/style/RenderStyle.cpp
+++ b/WebCore/rendering/style/RenderStyle.cpp
@@ -916,11 +916,12 @@ const Animation* RenderStyle::transitionForProperty(int property) const
void RenderStyle::setBlendedFontSize(int size)
{
+ FontSelector* currentFontSelector = font().fontSelector();
FontDescription desc(fontDescription());
desc.setSpecifiedSize(size);
desc.setComputedSize(size);
setFontDescription(desc);
- font().update(font().fontSelector());
+ font().update(currentFontSelector);
}
void RenderStyle::getBoxShadowExtent(int &top, int &right, int &bottom, int &left) const
diff --git a/WebCore/rendering/style/SVGRenderStyle.cpp b/WebCore/rendering/style/SVGRenderStyle.cpp
index 042b8f7..f4e6cb5 100644
--- a/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -1,6 +1,6 @@
/*
Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
+ 2004, 2005, 2010 Rob Buis <buis@kde.org>
Copyright (C) Research In Motion Limited 2010. All rights reserved.
Based on khtml code by:
@@ -146,14 +146,14 @@ float SVGRenderStyle::cssPrimitiveToLength(const RenderObject* item, CSSValue* v
return primitive->computeLengthFloat(const_cast<RenderStyle*>(item->style()), item->document()->documentElement()->renderStyle());
}
-static void getSVGShadowExtent(ShadowData* shadow, int& top, int& right, int& bottom, int& left)
+static void getSVGShadowExtent(ShadowData* shadow, float& top, float& right, float& bottom, float& left)
{
- top = 0;
- right = 0;
- bottom = 0;
- left = 0;
+ top = 0.0f;
+ right = 0.0f;
+ bottom = 0.0f;
+ left = 0.0f;
- int blurAndSpread = shadow->blur() + shadow->spread();
+ float blurAndSpread = shadow->blur() + shadow->spread();
top = min(top, shadow->y() - blurAndSpread);
right = max(right, shadow->x() + blurAndSpread);
@@ -178,21 +178,14 @@ void SVGRenderStyle::inflateForShadow(FloatRect& repaintRect) const
if (!svgShadow)
return;
- int shadowTop;
- int shadowRight;
- int shadowBottom;
- int shadowLeft;
+ float shadowTop;
+ float shadowRight;
+ float shadowBottom;
+ float shadowLeft;
getSVGShadowExtent(svgShadow, shadowTop, shadowRight, shadowBottom, shadowLeft);
- int overflowLeft = repaintRect.x() + shadowLeft;
- int overflowRight = repaintRect.right() + shadowRight;
- int overflowTop = repaintRect.y() + shadowTop;
- int overflowBottom = repaintRect.bottom() + shadowBottom;
-
- repaintRect.setX(overflowLeft);
- repaintRect.setY(overflowTop);
- repaintRect.setWidth(overflowRight - overflowLeft);
- repaintRect.setHeight(overflowBottom - overflowTop);
+ repaintRect.move(shadowLeft, shadowTop);
+ repaintRect.setSize(repaintRect.size() + FloatSize(shadowRight - shadowLeft, shadowBottom - shadowTop));
}
}
diff --git a/WebCore/rendering/style/SVGRenderStyle.h b/WebCore/rendering/style/SVGRenderStyle.h
index 3d6a7da..b0bef61 100644
--- a/WebCore/rendering/style/SVGRenderStyle.h
+++ b/WebCore/rendering/style/SVGRenderStyle.h
@@ -58,6 +58,7 @@ public:
SVG_RS_DEFINE_ATTRIBUTE(EAlignmentBaseline, AlignmentBaseline, alignmentBaseline, AB_AUTO)
SVG_RS_DEFINE_ATTRIBUTE(EDominantBaseline, DominantBaseline, dominantBaseline, DB_AUTO)
SVG_RS_DEFINE_ATTRIBUTE(EBaselineShift, BaselineShift, baselineShift, BS_BASELINE)
+ SVG_RS_DEFINE_ATTRIBUTE(EVectorEffect, VectorEffect, vectorEffect, VE_NONE)
SVG_RS_DEFINE_ATTRIBUTE_INHERITED(LineCap, CapStyle, capStyle, ButtCap)
SVG_RS_DEFINE_ATTRIBUTE_INHERITED(WindRule, ClipRule, clipRule, RULE_NONZERO)
@@ -108,6 +109,9 @@ public:
SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, inheritedResources, markerEnd, MarkerEndResource, markerEndResource, String())
// convenience
+ bool hasClipper() const { return !clipperResource().isEmpty(); }
+ bool hasMasker() const { return !maskerResource().isEmpty(); }
+ bool hasFilter() const { return !filterResource().isEmpty(); }
bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); }
bool hasStroke() const { return strokePaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
bool hasFill() const { return fillPaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
@@ -165,7 +169,8 @@ protected:
unsigned _alignmentBaseline : 4; // EAlignmentBaseline
unsigned _dominantBaseline : 4; // EDominantBaseline
unsigned _baselineShift : 2; // EBaselineShift
- // 22 bits unused
+ unsigned _vectorEffect: 1; // EVectorEffect
+ // 21 bits unused
} f;
uint32_t _niflags;
};
@@ -210,6 +215,7 @@ private:
svg_noninherited_flags.f._alignmentBaseline = initialAlignmentBaseline();
svg_noninherited_flags.f._dominantBaseline = initialDominantBaseline();
svg_noninherited_flags.f._baselineShift = initialBaselineShift();
+ svg_noninherited_flags.f._vectorEffect = initialVectorEffect();
}
};
diff --git a/WebCore/rendering/style/SVGRenderStyleDefs.h b/WebCore/rendering/style/SVGRenderStyleDefs.h
index e0354e6..207cefa 100644
--- a/WebCore/rendering/style/SVGRenderStyleDefs.h
+++ b/WebCore/rendering/style/SVGRenderStyleDefs.h
@@ -121,6 +121,11 @@ namespace WebCore {
DB_IDEOGRAPHIC, DB_ALPHABETIC, DB_HANGING, DB_MATHEMATICAL,
DB_CENTRAL, DB_MIDDLE, DB_TEXT_AFTER_EDGE, DB_TEXT_BEFORE_EDGE
};
+
+ enum EVectorEffect {
+ VE_NONE,
+ VE_NON_SCALING_STROKE
+ };
class CSSValue;
class CSSValueList;