summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/InlineTextBox.h1
-rw-r--r--WebCore/rendering/RenderApplet.h2
-rw-r--r--WebCore/rendering/RenderBlock.cpp8
-rw-r--r--WebCore/rendering/RenderBox.cpp10
-rw-r--r--WebCore/rendering/RenderBoxModelObject.cpp2
-rw-r--r--WebCore/rendering/RenderEmbeddedObject.cpp4
-rw-r--r--WebCore/rendering/RenderInputSpeech.cpp12
-rw-r--r--WebCore/rendering/RenderRubyRun.cpp32
-rw-r--r--WebCore/rendering/RenderSVGAllInOne.cpp1
-rw-r--r--WebCore/rendering/RenderSVGGradientStop.cpp4
-rw-r--r--WebCore/rendering/RenderSVGImage.cpp2
-rw-r--r--WebCore/rendering/RenderSVGImage.h15
-rw-r--r--WebCore/rendering/RenderSVGResource.cpp2
-rw-r--r--WebCore/rendering/RenderSVGResource.h4
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.cpp11
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.h4
-rw-r--r--WebCore/rendering/RenderSVGResourceContainer.cpp27
-rw-r--r--WebCore/rendering/RenderSVGResourceContainer.h3
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.cpp13
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.h4
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.cpp67
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.h4
-rw-r--r--WebCore/rendering/RenderSVGResourceMarker.cpp11
-rw-r--r--WebCore/rendering/RenderSVGResourceMarker.h4
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.cpp104
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.h16
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.cpp24
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.h4
-rw-r--r--WebCore/rendering/RenderSVGResourceSolidColor.h4
-rw-r--r--WebCore/rendering/RenderTableSection.cpp107
-rw-r--r--WebCore/rendering/RenderText.cpp2
-rw-r--r--WebCore/rendering/RenderTextControl.cpp7
-rw-r--r--WebCore/rendering/RenderTheme.h1
-rw-r--r--WebCore/rendering/RenderThemeChromiumMac.h3
-rw-r--r--WebCore/rendering/RenderThemeChromiumMac.mm14
-rw-r--r--WebCore/rendering/RenderThemeMac.mm3
-rw-r--r--WebCore/rendering/RenderTreeAsText.cpp2
-rw-r--r--WebCore/rendering/RenderVideo.cpp13
-rw-r--r--WebCore/rendering/RenderView.cpp2
-rw-r--r--WebCore/rendering/SVGImageBufferTools.cpp73
-rw-r--r--WebCore/rendering/SVGImageBufferTools.h49
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp29
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp3
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.h3
-rw-r--r--WebCore/rendering/SVGResources.cpp38
-rw-r--r--WebCore/rendering/SVGResources.h2
-rw-r--r--WebCore/rendering/SVGResourcesCache.cpp2
-rw-r--r--WebCore/rendering/TextControlInnerElements.cpp46
-rw-r--r--WebCore/rendering/TextControlInnerElements.h17
-rw-r--r--WebCore/rendering/style/BindingURI.h2
-rw-r--r--WebCore/rendering/style/ContentData.cpp2
-rw-r--r--WebCore/rendering/style/CounterContent.h2
-rw-r--r--WebCore/rendering/style/CounterDirectives.h2
-rw-r--r--WebCore/rendering/style/KeyframeList.h2
-rw-r--r--WebCore/rendering/style/StyleRareInheritedData.h2
55 files changed, 542 insertions, 285 deletions
diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h
index fcbf23a..7d828f3 100644
--- a/WebCore/rendering/InlineTextBox.h
+++ b/WebCore/rendering/InlineTextBox.h
@@ -67,6 +67,7 @@ public:
bool hasHyphen() const { return m_hasEllipsisBoxOrHyphen; }
void setHasHyphen(bool hasHyphen) { m_hasEllipsisBoxOrHyphen = hasHyphen; }
+ static inline bool compareByStart(const InlineTextBox* first, const InlineTextBox* second) { return first->start() < second->start(); }
private:
virtual int selectionTop();
diff --git a/WebCore/rendering/RenderApplet.h b/WebCore/rendering/RenderApplet.h
index 343421e..62f46cd 100644
--- a/WebCore/rendering/RenderApplet.h
+++ b/WebCore/rendering/RenderApplet.h
@@ -23,7 +23,7 @@
#define RenderApplet_h
#include "RenderWidget.h"
-#include "StringHash.h"
+#include <wtf/text/StringHash.h>
namespace WebCore {
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index c982d26..574d389 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -1021,8 +1021,8 @@ void RenderBlock::removeChild(RenderObject* oldChild)
// If this was our last child be sure to clear out our line boxes.
if (childrenInline())
lineBoxes()->deleteLineBoxes(renderArena());
- // If we're now an empty anonymous block then go ahead and delete ourselves.
- else if (isAnonymousBlock() && parent() && parent()->isRenderBlock() && !continuation())
+ // If we're now an empty anonymous columns or column span block, then go ahead and delete ourselves.
+ else if ((isAnonymousColumnsBlock() || isAnonymousColumnSpanBlock()) && parent() && parent()->isRenderBlock() && !continuation())
destroy();
}
}
@@ -2120,7 +2120,7 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
PaintInfo info(paintInfo);
info.phase = newPhase;
info.updatePaintingRootForChildren(this);
- bool checkPageBreaks = document()->printing() && !document()->settings()->paginateDuringLayoutEnabled();
+ bool checkPageBreaks = document()->paginated() && !document()->settings()->paginateDuringLayoutEnabled();
bool checkColumnBreaks = !checkPageBreaks && !view()->printRect().isEmpty() && !document()->settings()->paginateDuringLayoutEnabled();
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
@@ -4109,7 +4109,7 @@ void RenderBlock::calcColumnWidth()
int desiredColumnWidth = contentWidth();
// For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
- if (document()->printing() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
+ if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
return;
}
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index e11c7ad..8a3ea8e 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -1476,6 +1476,12 @@ bool RenderBox::sizesToIntrinsicWidth(WidthType widthType) const
&& (parent()->style()->boxOrient() == HORIZONTAL || parent()->style()->boxAlign() != BSTRETCH))
return true;
+ // Button, input, select, textarea, legend and datagrid treat
+ // width value of 'auto' as 'intrinsic' unless it's in a
+ // stretching vertical flexbox.
+ if (width.type() == Auto && !(parent()->isFlexibleBox() && parent()->style()->boxOrient() == VERTICAL && parent()->style()->boxAlign() == BSTRETCH) && node() && (node()->hasTagName(inputTag) || node()->hasTagName(selectTag) || node()->hasTagName(buttonTag) || node()->hasTagName(textareaTag) || node()->hasTagName(legendTag) || node()->hasTagName(datagridTag)))
+ return true;
+
return false;
}
@@ -1579,9 +1585,9 @@ void RenderBox::calcHeight()
// is specified. When we're printing, we also need this quirk if the body or root has a percentage
// height since we don't set a height in RenderView when we're printing. So without this quirk, the
// height has nothing to be a percentage of, and it ends up being 0. That is bad.
- bool printingNeedsBaseHeight = document()->printing() && h.isPercent()
+ bool paginatedContentNeedsBaseHeight = document()->paginated() && h.isPercent()
&& (isRoot() || (isBody() && document()->documentElement()->renderer()->style()->height().isPercent()));
- if (stretchesToViewHeight() || printingNeedsBaseHeight) {
+ if (stretchesToViewHeight() || paginatedContentNeedsBaseHeight) {
int margins = collapsedMarginTop() + collapsedMarginBottom();
int visHeight = document()->printing() ? view()->frameView()->pageHeight() : view()->viewHeight();
if (isRoot())
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index 9117ed8..78618d1 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -531,7 +531,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
// The mask has been created. Now we just need to clip to it.
context->save();
- context->clipToImageBuffer(maskRect, maskImage.get());
+ context->clipToImageBuffer(maskImage.get(), maskRect);
}
StyleImage* bg = bgLayer->image();
diff --git a/WebCore/rendering/RenderEmbeddedObject.cpp b/WebCore/rendering/RenderEmbeddedObject.cpp
index e72825e..55b230b 100644
--- a/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -231,8 +231,8 @@ void RenderEmbeddedObject::updateWidget(bool onlyCreateNonNetscapePlugins)
url = p->value();
if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
serviceType = p->value();
- int pos = serviceType.find(";");
- if (pos != -1)
+ size_t pos = serviceType.find(";");
+ if (pos != notFound)
serviceType = serviceType.left(pos);
}
if (!embed && !name.isEmpty()) {
diff --git a/WebCore/rendering/RenderInputSpeech.cpp b/WebCore/rendering/RenderInputSpeech.cpp
index df17944..5472025 100644
--- a/WebCore/rendering/RenderInputSpeech.cpp
+++ b/WebCore/rendering/RenderInputSpeech.cpp
@@ -36,6 +36,7 @@
#include "GraphicsContext.h"
#include "HTMLNames.h"
#include "RenderBox.h"
+#include "TextControlInnerElements.h"
namespace WebCore {
@@ -79,7 +80,16 @@ bool RenderInputSpeech::paintInputFieldSpeechButton(RenderObject* object, const
buttonRect.move(rect.x(), rect.y());
DEFINE_STATIC_LOCAL(RefPtr<Image>, imageStateNormal, (Image::loadPlatformResource("inputSpeech")));
- paintInfo.context->drawImage(imageStateNormal.get(), object->style()->colorSpace(), buttonRect);
+ DEFINE_STATIC_LOCAL(RefPtr<Image>, imageStateRecording, (Image::loadPlatformResource("inputSpeechRecording")));
+ DEFINE_STATIC_LOCAL(RefPtr<Image>, imageStateWaiting, (Image::loadPlatformResource("inputSpeechWaiting")));
+
+ InputFieldSpeechButtonElement* speechButton = reinterpret_cast<InputFieldSpeechButtonElement*>(object->node());
+ Image* image = imageStateNormal.get();
+ if (speechButton->state() == InputFieldSpeechButtonElement::Recording)
+ image = imageStateRecording.get();
+ else if (speechButton->state() == InputFieldSpeechButtonElement::Recognizing)
+ image = imageStateWaiting.get();
+ paintInfo.context->drawImage(image, object->style()->colorSpace(), buttonRect);
return false;
}
diff --git a/WebCore/rendering/RenderRubyRun.cpp b/WebCore/rendering/RenderRubyRun.cpp
index d6b724b..d48646b 100644
--- a/WebCore/rendering/RenderRubyRun.cpp
+++ b/WebCore/rendering/RenderRubyRun.cpp
@@ -143,14 +143,15 @@ void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
RenderBlock::removeChild(beforeChild);
newRun->addChild(beforeChild);
} else {
- ASSERT(hasRubyBase()); // Otherwise beforeChild would be borked.
- // Insertion before a ruby base object.
- // In this case we need insert a new run before the current one and split the base.
- RenderObject* ruby = parent();
- RenderRubyRun* newRun = staticCreateRubyRun(ruby);
- ruby->addChild(newRun, this);
- newRun->addChild(child);
- rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild);
+ if (hasRubyBase()) {
+ // Insertion before a ruby base object.
+ // In this case we need insert a new run before the current one and split the base.
+ RenderObject* ruby = parent();
+ RenderRubyRun* newRun = staticCreateRubyRun(ruby);
+ ruby->addChild(newRun, this);
+ newRun->addChild(child);
+ rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild);
+ }
}
} else {
// child is not a text -> insert it into the base
@@ -171,13 +172,14 @@ void RenderRubyRun::removeChild(RenderObject* child)
if (base && rightNeighbour && rightNeighbour->isRubyRun()) {
// Ruby run without a base can happen only at the first run.
RenderRubyRun* rightRun = static_cast<RenderRubyRun*>(rightNeighbour);
- ASSERT(rightRun->hasRubyBase());
- RenderRubyBase* rightBase = rightRun->rubyBaseSafe();
- // Collect all children in a single base, then swap the bases.
- rightBase->moveChildren(base);
- moveChildTo(rightRun, base);
- rightRun->moveChildTo(this, rightBase);
- // The now empty ruby base will be removed below.
+ if (rightRun->hasRubyBase()) {
+ RenderRubyBase* rightBase = rightRun->rubyBaseSafe();
+ // Collect all children in a single base, then swap the bases.
+ rightBase->moveChildren(base);
+ moveChildTo(rightRun, base);
+ rightRun->moveChildTo(this, rightBase);
+ // The now empty ruby base will be removed below.
+ }
}
}
diff --git a/WebCore/rendering/RenderSVGAllInOne.cpp b/WebCore/rendering/RenderSVGAllInOne.cpp
index fa5709e..2d44ca2 100644
--- a/WebCore/rendering/RenderSVGAllInOne.cpp
+++ b/WebCore/rendering/RenderSVGAllInOne.cpp
@@ -53,6 +53,7 @@
#include "RenderSVGViewportContainer.cpp"
#include "SVGCharacterData.cpp"
#include "SVGCharacterLayoutInfo.cpp"
+#include "SVGImageBufferTools.cpp"
#include "SVGInlineFlowBox.cpp"
#include "SVGInlineTextBox.cpp"
#include "SVGMarkerLayoutInfo.cpp"
diff --git a/WebCore/rendering/RenderSVGGradientStop.cpp b/WebCore/rendering/RenderSVGGradientStop.cpp
index 3494aa7..ebf7385 100644
--- a/WebCore/rendering/RenderSVGGradientStop.cpp
+++ b/WebCore/rendering/RenderSVGGradientStop.cpp
@@ -47,6 +47,8 @@ RenderSVGGradientStop::~RenderSVGGradientStop()
void RenderSVGGradientStop::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderObject::styleDidChange(diff, oldStyle);
+ if (diff == StyleDifferenceEqual)
+ return;
// <stop> elements should only be allowed to make renderers under gradient elements
// but I can imagine a few cases we might not be catching, so let's not crash if our parent isn't a gradient.
@@ -60,7 +62,7 @@ void RenderSVGGradientStop::styleDidChange(StyleDifference diff, const RenderSty
ASSERT(renderer->isSVGResourceContainer());
RenderSVGResourceContainer* container = renderer->toRenderSVGResourceContainer();
- container->invalidateClients();
+ container->removeAllClientsFromCache();
}
void RenderSVGGradientStop::layout()
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index 993278c..893a4ea 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -177,7 +177,7 @@ void RenderSVGImage::imageChanged(WrappedImagePtr image, const IntRect* rect)
// The image resource defaults to nullImage until the resource arrives.
// This empty image may be cached by SVG resources which must be invalidated.
if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this))
- resources->invalidateClient(this);
+ resources->removeClientFromCache(this);
// Eventually notify parent resources, that we've changed.
RenderSVGResource::markForLayoutAndParentResourceInvalidation(this, false);
diff --git a/WebCore/rendering/RenderSVGImage.h b/WebCore/rendering/RenderSVGImage.h
index 6ee0179..38e3a13 100644
--- a/WebCore/rendering/RenderSVGImage.h
+++ b/WebCore/rendering/RenderSVGImage.h
@@ -81,6 +81,21 @@ private:
mutable FloatRect m_cachedLocalRepaintRect;
};
+inline RenderSVGImage* toRenderSVGImage(RenderObject* object)
+{
+ ASSERT(!object || object->isSVGImage());
+ return static_cast<RenderSVGImage*>(object);
+}
+
+inline const RenderSVGImage* toRenderSVGImage(const RenderObject* object)
+{
+ ASSERT(!object || object->isSVGImage());
+ return static_cast<const RenderSVGImage*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderSVGImage(const RenderSVGImage*);
+
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/RenderSVGResource.cpp b/WebCore/rendering/RenderSVGResource.cpp
index 9c89d3c..0c943e5 100644
--- a/WebCore/rendering/RenderSVGResource.cpp
+++ b/WebCore/rendering/RenderSVGResource.cpp
@@ -171,7 +171,7 @@ void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject*
RenderObject* current = object->parent();
while (current) {
if (current->isSVGResourceContainer()) {
- current->toRenderSVGResourceContainer()->invalidateClients();
+ current->toRenderSVGResourceContainer()->removeAllClientsFromCache();
break;
}
diff --git a/WebCore/rendering/RenderSVGResource.h b/WebCore/rendering/RenderSVGResource.h
index e2d8216..a70ce52 100644
--- a/WebCore/rendering/RenderSVGResource.h
+++ b/WebCore/rendering/RenderSVGResource.h
@@ -57,8 +57,8 @@ public:
RenderSVGResource() { }
virtual ~RenderSVGResource() { }
- virtual void invalidateClients() = 0;
- virtual void invalidateClient(RenderObject*) = 0;
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true) = 0;
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) = 0;
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) = 0;
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short) { }
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
index a201d1f..626a880 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.cpp
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -64,7 +64,7 @@ RenderSVGResourceClipper::~RenderSVGResourceClipper()
m_clipper.clear();
}
-void RenderSVGResourceClipper::invalidateClients()
+void RenderSVGResourceClipper::removeAllClientsFromCache(bool markForInvalidation)
{
if (m_invalidationBlocked)
return;
@@ -75,20 +75,19 @@ void RenderSVGResourceClipper::invalidateClients()
m_clipper.clear();
}
- markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
+ markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceClipper::invalidateClient(RenderObject* client)
+void RenderSVGResourceClipper::removeClientFromCache(RenderObject* client, bool markForInvalidation)
{
ASSERT(client);
if (m_invalidationBlocked)
return;
- ASSERT(client->selfNeedsLayout());
if (m_clipper.contains(client))
delete m_clipper.take(client);
- markClientForInvalidation(client, BoundariesInvalidation);
+ markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}
bool RenderSVGResourceClipper::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
@@ -174,7 +173,7 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* object, cons
if (!clipperData->clipMaskImage)
return false;
- context->clipToImageBuffer(repaintRect, clipperData->clipMaskImage.get());
+ context->clipToImageBuffer(clipperData->clipMaskImage.get(), repaintRect);
return true;
}
diff --git a/WebCore/rendering/RenderSVGResourceClipper.h b/WebCore/rendering/RenderSVGResourceClipper.h
index d334c7d..0f68c67 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.h
+++ b/WebCore/rendering/RenderSVGResourceClipper.h
@@ -47,8 +47,8 @@ public:
virtual const char* renderName() const { return "RenderSVGResourceClipper"; }
- virtual void invalidateClients();
- virtual void invalidateClient(RenderObject*);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual FloatRect resourceBoundingBox(RenderObject*);
diff --git a/WebCore/rendering/RenderSVGResourceContainer.cpp b/WebCore/rendering/RenderSVGResourceContainer.cpp
index 7e43300..5652dcc 100644
--- a/WebCore/rendering/RenderSVGResourceContainer.cpp
+++ b/WebCore/rendering/RenderSVGResourceContainer.cpp
@@ -52,7 +52,7 @@ void RenderSVGResourceContainer::layout()
{
// Invalidate all resources if our layout changed.
if (m_everHadLayout && selfNeedsLayout())
- invalidateClients();
+ removeAllClientsFromCache();
RenderSVGHiddenContainer::layout();
}
@@ -76,7 +76,7 @@ void RenderSVGResourceContainer::styleDidChange(StyleDifference diff, const Rend
void RenderSVGResourceContainer::idChanged()
{
// Invalidate all our current clients.
- invalidateClients();
+ removeAllClientsFromCache();
// Remove old id, that is guaranteed to be present in cache.
SVGDocumentExtensions* extensions = svgExtensionsFromNode(node());
@@ -92,17 +92,32 @@ void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode
return;
bool needsLayout = mode == LayoutAndBoundariesInvalidation;
+ bool markForInvalidation = mode != ParentOnlyInvalidation;
HashSet<RenderObject*>::iterator end = m_clients.end();
for (HashSet<RenderObject*>::iterator it = m_clients.begin(); it != end; ++it) {
RenderObject* client = *it;
if (client->isSVGResourceContainer()) {
- client->toRenderSVGResourceContainer()->invalidateClients();
+ client->toRenderSVGResourceContainer()->removeAllClientsFromCache(markForInvalidation);
continue;
}
- markClientForInvalidation(client, mode);
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(client, needsLayout);
+ if (markForInvalidation)
+ markClientForInvalidation(client, mode);
+
+ if (needsLayout)
+ client->setNeedsLayout(true);
+
+ // Invalidate resources in ancestor chain, if needed.
+ RenderObject* current = client->parent();
+ while (current) {
+ if (current->isSVGResourceContainer()) {
+ current->toRenderSVGResourceContainer()->removeAllClientsFromCache(markForInvalidation);
+ break;
+ }
+
+ current = current->parent();
+ }
}
}
@@ -120,6 +135,8 @@ void RenderSVGResourceContainer::markClientForInvalidation(RenderObject* client,
if (client->view())
client->repaint();
break;
+ case ParentOnlyInvalidation:
+ break;
}
}
diff --git a/WebCore/rendering/RenderSVGResourceContainer.h b/WebCore/rendering/RenderSVGResourceContainer.h
index 4271a5f..08e18d4 100644
--- a/WebCore/rendering/RenderSVGResourceContainer.h
+++ b/WebCore/rendering/RenderSVGResourceContainer.h
@@ -49,7 +49,8 @@ protected:
enum InvalidationMode {
LayoutAndBoundariesInvalidation,
BoundariesInvalidation,
- RepaintInvalidation
+ RepaintInvalidation,
+ ParentOnlyInvalidation
};
// Used from the invalidateClient/invalidateClients methods from classes, inheriting from us.
diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp
index bc5feaf..09e83f4 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.cpp
+++ b/WebCore/rendering/RenderSVGResourceFilter.cpp
@@ -67,25 +67,24 @@ RenderSVGResourceFilter::~RenderSVGResourceFilter()
m_filter.clear();
}
-void RenderSVGResourceFilter::invalidateClients()
+void RenderSVGResourceFilter::removeAllClientsFromCache(bool markForInvalidation)
{
if (!m_filter.isEmpty()) {
deleteAllValues(m_filter);
m_filter.clear();
}
- markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
+ markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceFilter::invalidateClient(RenderObject* client)
+void RenderSVGResourceFilter::removeClientFromCache(RenderObject* client, bool markForInvalidation)
{
ASSERT(client);
- ASSERT(client->selfNeedsLayout());
if (m_filter.contains(client))
delete m_filter.take(client);
- markClientForInvalidation(client, BoundariesInvalidation);
+ markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}
PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives()
@@ -243,7 +242,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
FilterData* filterData = m_filter.get(object);
if (!filterData->builded) {
if (!filterData->savedContext) {
- invalidateClient(object);
+ removeClientFromCache(object);
return;
}
@@ -271,7 +270,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
#if !PLATFORM(CG)
resultImage->transformColorSpace(LinearRGB, DeviceRGB);
#endif
- context->drawImage(resultImage->image(), object->style()->colorSpace(), lastEffect->subRegion());
+ context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->subRegion());
}
}
diff --git a/WebCore/rendering/RenderSVGResourceFilter.h b/WebCore/rendering/RenderSVGResourceFilter.h
index 7b5ab09..314c94d 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.h
+++ b/WebCore/rendering/RenderSVGResourceFilter.h
@@ -64,8 +64,8 @@ public:
virtual const char* renderName() const { return "RenderSVGResourceFilter"; }
- virtual void invalidateClients();
- virtual void invalidateClient(RenderObject*);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
diff --git a/WebCore/rendering/RenderSVGResourceGradient.cpp b/WebCore/rendering/RenderSVGResourceGradient.cpp
index 73b2ab6..d29192a 100644
--- a/WebCore/rendering/RenderSVGResourceGradient.cpp
+++ b/WebCore/rendering/RenderSVGResourceGradient.cpp
@@ -28,6 +28,7 @@
#include "GradientAttributes.h"
#include "GraphicsContext.h"
+#include "SVGImageBufferTools.h"
#include "SVGRenderSupport.h"
#include <wtf/UnusedParam.h>
@@ -50,81 +51,64 @@ RenderSVGResourceGradient::~RenderSVGResourceGradient()
m_gradient.clear();
}
-void RenderSVGResourceGradient::invalidateClients()
+void RenderSVGResourceGradient::removeAllClientsFromCache(bool markForInvalidation)
{
if (!m_gradient.isEmpty()) {
deleteAllValues(m_gradient);
m_gradient.clear();
}
- markAllClientsForInvalidation(RepaintInvalidation);
+ markAllClientsForInvalidation(markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceGradient::invalidateClient(RenderObject* client)
+void RenderSVGResourceGradient::removeClientFromCache(RenderObject* client, bool markForInvalidation)
{
ASSERT(client);
- ASSERT(client->selfNeedsLayout());
if (m_gradient.contains(client))
delete m_gradient.take(client);
- markClientForInvalidation(client, RepaintInvalidation);
+ markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
}
#if PLATFORM(CG)
-static inline AffineTransform absoluteTransformFromContext(GraphicsContext* context)
-{
- // Extract current transformation matrix used in the original context. Note that this coordinate
- // system is flipped compared to SVGs internal coordinate system, done in WebKit level. Fix
- // this transformation by flipping the y component.
- return context->getCTM() * AffineTransform().flipY();
-}
-
static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& context,
GraphicsContext*& savedContext,
OwnPtr<ImageBuffer>& imageBuffer,
const RenderObject* object)
{
const RenderObject* textRootBlock = SVGRenderSupport::findTextRootObject(object);
+ ASSERT(textRootBlock);
- AffineTransform transform(absoluteTransformFromContext(context));
- FloatRect maskAbsoluteBoundingBox = transform.mapRect(textRootBlock->repaintRectInLocalCoordinates());
+ AffineTransform absoluteTransform(SVGImageBufferTools::absoluteTransformFromContext(context));
+ FloatRect absoluteTargetRect = absoluteTransform.mapRect(textRootBlock->repaintRectInLocalCoordinates());
- IntRect maskImageRect = enclosingIntRect(maskAbsoluteBoundingBox);
- if (maskImageRect.isEmpty())
+ OwnPtr<ImageBuffer> maskImage;
+ if (!SVGImageBufferTools::createImageBuffer(absoluteTransform, absoluteTargetRect, maskImage, DeviceRGB))
return false;
- // Allocate an image buffer as big as the absolute unclipped size of the object
- OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskImageRect.size());
- if (!maskImage)
- return false;
-
- GraphicsContext* maskImageContext = maskImage->context();
-
- // Transform the mask image coordinate system to absolute screen coordinates
- maskImageContext->translate(-maskAbsoluteBoundingBox.x(), -maskAbsoluteBoundingBox.y());
- maskImageContext->concatCTM(transform);
-
- imageBuffer = maskImage.release();
+ ASSERT(maskImage);
savedContext = context;
- context = maskImageContext;
-
+ context = maskImage->context();
+ imageBuffer = maskImage.release();
return true;
}
static inline AffineTransform clipToTextMask(GraphicsContext* context,
OwnPtr<ImageBuffer>& imageBuffer,
+ FloatRect& repaintRect,
const RenderObject* object,
GradientData* gradientData)
{
const RenderObject* textRootBlock = SVGRenderSupport::findTextRootObject(object);
+ ASSERT(textRootBlock);
- // The mask image has been created in the device coordinate space, as the image should not be scaled.
- // So the actual masking process has to be done in the device coordinate space as well.
- AffineTransform transform(absoluteTransformFromContext(context));
- context->concatCTM(transform.inverse());
- context->clipToImageBuffer(transform.mapRect(textRootBlock->repaintRectInLocalCoordinates()), imageBuffer.get());
- context->concatCTM(transform);
+ repaintRect = textRootBlock->repaintRectInLocalCoordinates();
+
+ AffineTransform absoluteTransform(SVGImageBufferTools::absoluteTransformFromContext(context));
+ FloatRect absoluteTargetRect = absoluteTransform.mapRect(repaintRect);
+
+ SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, absoluteTargetRect, imageBuffer.get());
AffineTransform matrix;
if (gradientData->boundingBoxMode) {
@@ -146,7 +130,7 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
// Be sure to synchronize all SVG properties on the gradientElement _before_ processing any further.
// Otherwhise the call to collectGradientAttributes() in createTileImage(), may cause the SVG DOM property
- // synchronization to kick in, which causes invalidateClients() to be called, which in turn deletes our
+ // synchronization to kick in, which causes removeAllClientsFromCache() to be called, which in turn deletes our
// GradientData object! Leaving out the line below will cause svg/dynamic-updates/SVG*GradientElement-svgdom* to crash.
SVGGradientElement* gradientElement = static_cast<SVGGradientElement*>(node());
if (!gradientElement)
@@ -232,12 +216,11 @@ void RenderSVGResourceGradient::postApplyResource(RenderObject* object, Graphics
context = m_savedContext;
m_savedContext = 0;
- gradientData->gradient->setGradientSpaceTransform(clipToTextMask(context, m_imageBuffer, object, gradientData));
+ FloatRect repaintRect;
+ gradientData->gradient->setGradientSpaceTransform(clipToTextMask(context, m_imageBuffer, repaintRect, object, gradientData));
context->setFillGradient(gradientData->gradient);
- const RenderObject* textRootBlock = SVGRenderSupport::findTextRootObject(object);
- context->fillRect(textRootBlock->repaintRectInLocalCoordinates());
-
+ context->fillRect(repaintRect);
m_imageBuffer.clear();
}
#else
diff --git a/WebCore/rendering/RenderSVGResourceGradient.h b/WebCore/rendering/RenderSVGResourceGradient.h
index b01af6d..4de4272 100644
--- a/WebCore/rendering/RenderSVGResourceGradient.h
+++ b/WebCore/rendering/RenderSVGResourceGradient.h
@@ -50,8 +50,8 @@ public:
RenderSVGResourceGradient(SVGGradientElement*);
virtual ~RenderSVGResourceGradient();
- virtual void invalidateClients();
- virtual void invalidateClient(RenderObject*);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
diff --git a/WebCore/rendering/RenderSVGResourceMarker.cpp b/WebCore/rendering/RenderSVGResourceMarker.cpp
index fa00fa3..1d5663b 100644
--- a/WebCore/rendering/RenderSVGResourceMarker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMarker.cpp
@@ -50,7 +50,7 @@ void RenderSVGResourceMarker::layout()
{
// Invalidate all resources if our layout changed.
if (m_everHadLayout && selfNeedsLayout())
- invalidateClients();
+ removeAllClientsFromCache();
// RenderSVGHiddenContainer overwrites layout(). We need the
// layouting of RenderSVGContainer for calculating local
@@ -58,16 +58,15 @@ void RenderSVGResourceMarker::layout()
RenderSVGContainer::layout();
}
-void RenderSVGResourceMarker::invalidateClients()
+void RenderSVGResourceMarker::removeAllClientsFromCache(bool markForInvalidation)
{
- markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
+ markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceMarker::invalidateClient(RenderObject* client)
+void RenderSVGResourceMarker::removeClientFromCache(RenderObject* client, bool markForInvalidation)
{
ASSERT(client);
- ASSERT(client->selfNeedsLayout());
- markClientForInvalidation(client, BoundariesInvalidation);
+ markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}
void RenderSVGResourceMarker::applyViewportClip(PaintInfo& paintInfo)
diff --git a/WebCore/rendering/RenderSVGResourceMarker.h b/WebCore/rendering/RenderSVGResourceMarker.h
index 8509aca..e41096e 100644
--- a/WebCore/rendering/RenderSVGResourceMarker.h
+++ b/WebCore/rendering/RenderSVGResourceMarker.h
@@ -41,8 +41,8 @@ public:
virtual const char* renderName() const { return "RenderSVGResourceMarker"; }
- virtual void invalidateClients();
- virtual void invalidateClient(RenderObject*);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
void draw(PaintInfo&, const AffineTransform&);
diff --git a/WebCore/rendering/RenderSVGResourceMasker.cpp b/WebCore/rendering/RenderSVGResourceMasker.cpp
index 2c36c96..9713dd6 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -35,6 +35,7 @@
#include "IntRect.h"
#include "RenderSVGResource.h"
#include "SVGElement.h"
+#include "SVGImageBufferTools.h"
#include "SVGMaskElement.h"
#include "SVGStyledElement.h"
#include "SVGUnitTypes.h"
@@ -59,26 +60,25 @@ RenderSVGResourceMasker::~RenderSVGResourceMasker()
m_masker.clear();
}
-void RenderSVGResourceMasker::invalidateClients()
+void RenderSVGResourceMasker::removeAllClientsFromCache(bool markForInvalidation)
{
- m_maskBoundaries = FloatRect();
+ m_maskContentBoundaries = FloatRect();
if (!m_masker.isEmpty()) {
deleteAllValues(m_masker);
m_masker.clear();
}
- markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
+ markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceMasker::invalidateClient(RenderObject* client)
+void RenderSVGResourceMasker::removeClientFromCache(RenderObject* client, bool markForInvalidation)
{
ASSERT(client);
- ASSERT(client->selfNeedsLayout());
if (m_masker.contains(client))
delete m_masker.take(client);
- markClientForInvalidation(client, BoundariesInvalidation);
+ markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}
bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
@@ -95,73 +95,47 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
m_masker.set(object, new MaskerData);
MaskerData* maskerData = m_masker.get(object);
- if (!maskerData->maskImage && !maskerData->emptyMask) {
+
+ AffineTransform absoluteTransform(SVGImageBufferTools::absoluteTransformFromContext(context));
+ FloatRect maskRect = absoluteTransform.mapRect(object->repaintRectInLocalCoordinates());
+
+ if (!maskerData->maskImage && !maskRect.isEmpty()) {
SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
if (!maskElement)
return false;
- createMaskImage(maskerData, maskElement, object);
+
+ if (!SVGImageBufferTools::createImageBuffer(absoluteTransform, maskRect, maskerData->maskImage, LinearRGB))
+ return false;
+
+ ASSERT(maskerData->maskImage);
+ drawContentIntoMaskImage(maskRect, maskerData, maskElement, object);
}
if (!maskerData->maskImage)
return false;
- context->clipToImageBuffer(maskerData->maskRect, maskerData->maskImage.get());
+ SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, maskRect, maskerData->maskImage.get());
return true;
}
-void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
+void RenderSVGResourceMasker::drawContentIntoMaskImage(const FloatRect& maskRect, MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
{
- FloatRect objectBoundingBox = object->objectBoundingBox();
-
- // Mask rect clipped with clippingBoundingBox and filterBoundingBox as long as they are present.
- maskerData->maskRect = object->repaintRectInLocalCoordinates();
- if (maskerData->maskRect.isEmpty()) {
- maskerData->emptyMask = true;
- return;
- }
-
- if (m_maskBoundaries.isEmpty())
- calculateMaskContentRepaintRect();
+ IntRect maskImageRect = enclosingIntRect(maskRect);
+ maskImageRect.setLocation(IntPoint());
- FloatRect repaintRect = m_maskBoundaries;
- AffineTransform contextTransform;
- // We need to scale repaintRect for objectBoundingBox to get the drawing area.
+ // Eventually adjust the mask image context according to the target objectBoundingBox.
if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- contextTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
- FloatPoint contextAdjustment = repaintRect.location();
- repaintRect = contextTransform.mapRect(repaintRect);
- repaintRect.move(objectBoundingBox.x(), objectBoundingBox.y());
- contextTransform.translate(-contextAdjustment.x(), -contextAdjustment.y());
- }
- repaintRect.intersect(maskerData->maskRect);
- maskerData->maskRect = repaintRect;
- IntRect maskImageRect = enclosingIntRect(maskerData->maskRect);
-
- maskImageRect.setLocation(IntPoint());
+ GraphicsContext* maskImageContext = maskerData->maskImage->context();
+ ASSERT(maskImageContext);
- // Don't create ImageBuffers with image size of 0
- if (maskImageRect.isEmpty()) {
- maskerData->emptyMask = true;
- return;
+ FloatRect objectBoundingBox = object->objectBoundingBox();
+ AffineTransform contextTransform;
+ contextTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ contextTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ maskImageContext->concatCTM(contextTransform);
}
- // FIXME: This changes color space to linearRGB, the default color space
- // for masking operations in SVG. We need a switch for the other color-space
- // attribute values sRGB, inherit and auto.
- maskerData->maskImage = ImageBuffer::create(maskImageRect.size(), LinearRGB);
- if (!maskerData->maskImage)
- return;
-
- GraphicsContext* maskImageContext = maskerData->maskImage->context();
- ASSERT(maskImageContext);
-
- maskImageContext->save();
-
- if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
- maskImageContext->translate(-maskerData->maskRect.x(), -maskerData->maskRect.y());
- maskImageContext->concatCTM(contextTransform);
-
- // draw the content into the ImageBuffer
+ // Draw the content into the ImageBuffer.
for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
RenderObject* renderer = node->renderer();
if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !renderer)
@@ -172,8 +146,6 @@ void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGM
SVGRenderSupport::renderSubtreeToImage(maskerData->maskImage.get(), renderer);
}
- maskImageContext->restore();
-
#if !PLATFORM(CG)
maskerData->maskImage->transformColorSpace(DeviceRGB, LinearRGB);
#endif
@@ -206,31 +178,31 @@ void RenderSVGResourceMasker::calculateMaskContentRepaintRect()
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
- m_maskBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
+ m_maskContentBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
}
}
FloatRect RenderSVGResourceMasker::resourceBoundingBox(RenderObject* object)
{
- // Resource was not layouted yet. Give back clipping rect of the mask.
SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
+ ASSERT(maskElement);
+
FloatRect objectBoundingBox = object->objectBoundingBox();
FloatRect maskBoundaries = maskElement->maskBoundingBox(objectBoundingBox);
+
+ // Resource was not layouted yet. Give back clipping rect of the mask.
if (selfNeedsLayout())
return maskBoundaries;
- if (m_maskBoundaries.isEmpty())
+ if (m_maskContentBoundaries.isEmpty())
calculateMaskContentRepaintRect();
- if (!maskElement)
- return FloatRect();
-
- FloatRect maskRect = m_maskBoundaries;
+ FloatRect maskRect = m_maskContentBoundaries;
if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
AffineTransform transform;
transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
- maskRect = transform.mapRect(maskRect);
+ maskRect = transform.mapRect(maskRect);
}
maskRect.intersect(maskBoundaries);
diff --git a/WebCore/rendering/RenderSVGResourceMasker.h b/WebCore/rendering/RenderSVGResourceMasker.h
index f6301cb..f2d8cb2 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.h
+++ b/WebCore/rendering/RenderSVGResourceMasker.h
@@ -36,14 +36,7 @@
namespace WebCore {
struct MaskerData {
- MaskerData()
- : emptyMask(false)
- {
- }
-
OwnPtr<ImageBuffer> maskImage;
- FloatRect maskRect;
- bool emptyMask;
};
class RenderSVGResourceMasker : public RenderSVGResourceContainer {
@@ -53,9 +46,8 @@ public:
virtual const char* renderName() const { return "RenderSVGResourceMasker"; }
- virtual void invalidateClients();
- virtual void invalidateClient(RenderObject*);
-
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual FloatRect resourceBoundingBox(RenderObject*);
@@ -66,10 +58,10 @@ public:
static RenderSVGResourceType s_resourceType;
private:
- void createMaskImage(MaskerData*, const SVGMaskElement*, RenderObject*);
+ void drawContentIntoMaskImage(const FloatRect& maskRect, MaskerData*, const SVGMaskElement*, RenderObject*);
void calculateMaskContentRepaintRect();
- FloatRect m_maskBoundaries;
+ FloatRect m_maskContentBoundaries;
HashMap<RenderObject*, MaskerData*> m_masker;
};
diff --git a/WebCore/rendering/RenderSVGResourcePattern.cpp b/WebCore/rendering/RenderSVGResourcePattern.cpp
index 902ff02..f4f5cf4 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.cpp
+++ b/WebCore/rendering/RenderSVGResourcePattern.cpp
@@ -47,25 +47,24 @@ RenderSVGResourcePattern::~RenderSVGResourcePattern()
m_pattern.clear();
}
-void RenderSVGResourcePattern::invalidateClients()
+void RenderSVGResourcePattern::removeAllClientsFromCache(bool markForInvalidation)
{
if (!m_pattern.isEmpty()) {
deleteAllValues(m_pattern);
m_pattern.clear();
}
- markAllClientsForInvalidation(RepaintInvalidation);
+ markAllClientsForInvalidation(markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourcePattern::invalidateClient(RenderObject* client)
+void RenderSVGResourcePattern::removeClientFromCache(RenderObject* client, bool markForInvalidation)
{
ASSERT(client);
- ASSERT(client->selfNeedsLayout());
if (m_pattern.contains(client))
delete m_pattern.take(client);
- markClientForInvalidation(client, RepaintInvalidation);
+ markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
}
bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
@@ -77,7 +76,7 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
// Be sure to synchronize all SVG properties on the patternElement _before_ processing any further.
// Otherwhise the call to collectPatternAttributes() in createTileImage(), may cause the SVG DOM property
- // synchronization to kick in, which causes invalidateClients() to be called, which in turn deletes our
+ // synchronization to kick in, which causes removeAllClientsFromCache() to be called, which in turn deletes our
// PatternData object! Leaving out the line below will cause svg/dynamic-updates/SVGPatternElement-svgdom* to crash.
SVGPatternElement* patternElement = static_cast<SVGPatternElement*>(node());
if (!patternElement)
@@ -298,14 +297,15 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(PatternData* p
void RenderSVGResourcePattern::buildPattern(PatternData* patternData, PassOwnPtr<ImageBuffer> tileImage) const
{
- if (!tileImage->image()) {
+ RefPtr<Image> copiedImage = tileImage->copyImage();
+ if (!copiedImage) {
patternData->pattern = 0;
return;
}
-
- IntRect tileRect = tileImage->image()->rect();
+
+ IntRect tileRect = copiedImage->rect();
if (tileRect.width() <= patternData->boundaries.width() && tileRect.height() <= patternData->boundaries.height()) {
- patternData->pattern = Pattern::create(tileImage->image(), true, true);
+ patternData->pattern = Pattern::create(copiedImage, true, true);
return;
}
@@ -331,13 +331,13 @@ void RenderSVGResourcePattern::buildPattern(PatternData* patternData, PassOwnPtr
newTileImageContext->translate(0, patternData->boundaries.height());
for (int j = numX; j > 0; --j) {
newTileImageContext->translate(patternData->boundaries.width(), 0);
- newTileImageContext->drawImage(tileImage->image(), style()->colorSpace(), tileRect, tileRect);
+ newTileImageContext->drawImage(copiedImage.get(), style()->colorSpace(), tileRect, tileRect);
}
newTileImageContext->translate(-patternData->boundaries.width() * numX, 0);
}
newTileImageContext->restore();
- patternData->pattern = Pattern::create(newTileImage->image(), true, true);
+ patternData->pattern = Pattern::create(newTileImage->copyImage(), true, true);
}
}
diff --git a/WebCore/rendering/RenderSVGResourcePattern.h b/WebCore/rendering/RenderSVGResourcePattern.h
index 690b0de..52bf09d 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.h
+++ b/WebCore/rendering/RenderSVGResourcePattern.h
@@ -51,8 +51,8 @@ public:
virtual const char* renderName() const { return "RenderSVGResourcePattern"; }
- virtual void invalidateClients();
- virtual void invalidateClient(RenderObject*);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
diff --git a/WebCore/rendering/RenderSVGResourceSolidColor.h b/WebCore/rendering/RenderSVGResourceSolidColor.h
index ad7fd27..44109db 100644
--- a/WebCore/rendering/RenderSVGResourceSolidColor.h
+++ b/WebCore/rendering/RenderSVGResourceSolidColor.h
@@ -33,8 +33,8 @@ public:
RenderSVGResourceSolidColor();
virtual ~RenderSVGResourceSolidColor();
- virtual void invalidateClients() { }
- virtual void invalidateClient(RenderObject*) { }
+ virtual void removeAllClientsFromCache(bool = true) { }
+ virtual void removeClientFromCache(RenderObject*, bool = true) { }
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index e192e29..8cb54c0 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -25,7 +25,6 @@
#include "config.h"
#include "RenderTableSection.h"
-
#include "CachedImage.h"
#include "Document.h"
#include "HitTestResult.h"
@@ -1116,38 +1115,43 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty)
// If some cell overflows, just paint all of them.
if (!m_hasOverflowingCell) {
- for (; startrow < totalRows; startrow++) {
- if (ty + m_rowPos[startrow + 1] >= y - os)
- break;
- }
- if (startrow == totalRows && ty + m_rowPos[totalRows] + table()->outerBorderBottom() >= y - os)
- startrow--;
+ int relativeY = y - ty;
+ int top = relativeY - os;
+ // binary search to find a row
+ startrow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), top) - m_rowPos.begin();
+
+ // The binary search above gives us the first row with
+ // a y position >= the top of the paint rect. Thus, the previous
+ // may need to be repainted as well.
+ if (startrow == m_rowPos.size() || (startrow > 0 && (m_rowPos[startrow] > top)))
+ --startrow;
+
+ int bottom = relativeY + h + os - 1;
+ endrow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), bottom) - m_rowPos.begin();
+ if ((endrow == m_rowPos.size()) || (endrow > 0 && m_rowPos[endrow - 1] == bottom))
+ --endrow;
- for (; endrow > 0; endrow--) {
- if (ty + m_rowPos[endrow - 1] <= y + h + os)
- break;
- }
if (!endrow && ty + m_rowPos[0] - table()->outerBorderTop() <= y + h + os)
- endrow++;
+ ++endrow;
}
-
unsigned startcol = 0;
unsigned endcol = totalCols;
// FIXME: Implement RTL.
if (!m_hasOverflowingCell && style()->direction() == LTR) {
- for (; startcol < totalCols; startcol++) {
- if (tx + table()->columnPositions()[startcol + 1] >= x - os)
- break;
- }
- if (startcol == totalCols && tx + table()->columnPositions()[totalCols] + table()->outerBorderRight() >= x - os)
- startcol--;
+ int relativeX = x - tx;
+ int left = relativeX - os;
+ Vector<int>& columnPos = table()->columnPositions();
+ startcol = std::lower_bound(columnPos.begin(), columnPos.end(), left) - columnPos.begin();
+ if ((startcol == columnPos.size()) || (startcol > 0 && (columnPos[startcol] > left)))
+ --startcol;
+
+ int right = relativeX + w + os - 1;
+ endcol = std::lower_bound(columnPos.begin(), columnPos.end(), right) - columnPos.begin();
+ if (endcol == columnPos.size() || (endcol > 0 && (columnPos[endcol - 1] == right)))
+ --endcol;
- for (; endcol > 0; endcol--) {
- if (tx + table()->columnPositions()[endcol - 1] <= x + w + os)
- break;
- }
if (!endcol && tx + table()->columnPositions()[0] - table()->outerBorderLeft() <= y + w + os)
- endcol++;
+ ++endcol;
}
#ifdef ANDROID_LAYOUT
@@ -1282,6 +1286,10 @@ void RenderTableSection::splitColumn(int pos, int first)
// Hit Testing
bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction action)
{
+ // If we have no children then we have nothing to do.
+ if (!firstChild())
+ return false;
+
// Table sections cannot ever be hit tested. Effectively they do not exist.
// Just forward to our children always.
tx += x();
@@ -1290,17 +1298,56 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
if (hasOverflowClip() && !overflowClipRect(tx, ty).intersects(result.rectFromPoint(xPos, yPos)))
return false;
- for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
- // FIXME: We have to skip over inline flows, since they can show up inside table rows
- // at the moment (a demoted inline <form> for example). If we ever implement a
- // table-specific hit-test method (which we should do for performance reasons anyway),
- // then we can remove this check.
- if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
+ if (m_hasOverflowingCell) {
+ for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
+ // FIXME: We have to skip over inline flows, since they can show up inside table rows
+ // at the moment (a demoted inline <form> for example). If we ever implement a
+ // table-specific hit-test method (which we should do for performance reasons anyway),
+ // then we can remove this check.
+ if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
+ updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ int relativeY = yPos - ty;
+ // leftrow corresponds to the first row that starts after the y mouse position
+ unsigned leftrow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), relativeY) - m_rowPos.begin();
+ if (leftrow == m_rowPos.size())
+ return false;
+ // Grab the last row that starts before the y mouse position.
+ if (leftrow > 0)
+ --leftrow;
+
+ Vector<int>& columnPos = table()->columnPositions();
+ bool rtl = style()->direction() == RTL;
+ int relativeX = xPos - tx;
+ if (rtl)
+ relativeX = columnPos[columnPos.size() - 1] - relativeX;
+
+ unsigned leftcol = std::lower_bound(columnPos.begin(), columnPos.end(), relativeX) - columnPos.begin();
+ if (leftcol == columnPos.size())
+ return false;
+ if (leftcol > 0)
+ --leftcol;
+
+ CellStruct& current = cellAt(leftrow, leftcol);
+
+ // If the cell is empty, there's nothing to do
+ if (!current.hasCells())
+ return false;
+
+ for (int i = current.cells.size() - 1; i >= 0; --i) {
+ RenderTableCell* cell = current.cells[i];
+ if (static_cast<RenderObject*>(cell)->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
return true;
}
}
return false;
+
}
} // namespace WebCore
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index bd050d8..da152b0 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -37,13 +37,13 @@
#include "RenderBlock.h"
#include "RenderLayer.h"
#include "RenderView.h"
-#include "StringBuffer.h"
#include "Text.h"
#include "TextBreakIterator.h"
#include "TextResourceDecoder.h"
#include "VisiblePosition.h"
#include "break_lines.h"
#include <wtf/AlwaysInline.h>
+#include <wtf/text/StringBuffer.h>
using namespace std;
using namespace WTF;
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index d1c8039..5f8c788 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -29,6 +29,7 @@
#include "EventNames.h"
#include "Frame.h"
#include "HTMLBRElement.h"
+#include "HTMLFormControlElement.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "RenderLayer.h"
@@ -217,12 +218,14 @@ int RenderTextControl::selectionEnd()
void RenderTextControl::setSelectionStart(int start)
{
- setSelectionRange(start, max(start, selectionEnd()));
+ HTMLTextFormControlElement* element = static_cast<HTMLTextFormControlElement*>(node());
+ setSelectionRange(start, max(start, element->selectionEnd()));
}
void RenderTextControl::setSelectionEnd(int end)
{
- setSelectionRange(min(end, selectionStart()), end);
+ HTMLTextFormControlElement* element = static_cast<HTMLTextFormControlElement*>(node());
+ setSelectionRange(min(end, element->selectionStart()), end);
}
void RenderTextControl::select()
diff --git a/WebCore/rendering/RenderTheme.h b/WebCore/rendering/RenderTheme.h
index 1e0b54c..aedb8eb 100644
--- a/WebCore/rendering/RenderTheme.h
+++ b/WebCore/rendering/RenderTheme.h
@@ -29,7 +29,6 @@
#include "ThemeTypes.h"
#endif
#include "RenderObject.h"
-#include "RenderTheme.h"
#include "ScrollTypes.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
diff --git a/WebCore/rendering/RenderThemeChromiumMac.h b/WebCore/rendering/RenderThemeChromiumMac.h
index 2309081..d1875fc 100644
--- a/WebCore/rendering/RenderThemeChromiumMac.h
+++ b/WebCore/rendering/RenderThemeChromiumMac.h
@@ -41,8 +41,11 @@ protected:
virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
virtual String extraMediaControlsStyleSheet();
+ virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual IntPoint volumeSliderOffsetFromMuteButton(Node*, const IntSize&) const;
#endif
diff --git a/WebCore/rendering/RenderThemeChromiumMac.mm b/WebCore/rendering/RenderThemeChromiumMac.mm
index a43da1e..e8ffe6c 100644
--- a/WebCore/rendering/RenderThemeChromiumMac.mm
+++ b/WebCore/rendering/RenderThemeChromiumMac.mm
@@ -134,6 +134,11 @@ String RenderThemeChromiumMac::extraMediaControlsStyleSheet()
return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet));
}
+bool RenderThemeChromiumMac::paintMediaVolumeSliderContainer(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ return true;
+}
+
bool RenderThemeChromiumMac::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
{
return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSlider, object, paintInfo, rect);
@@ -144,6 +149,15 @@ bool RenderThemeChromiumMac::paintMediaVolumeSliderThumb(RenderObject* object, c
return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSliderThumb, object, paintInfo, rect);
}
+bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ return RenderMediaControlsChromium::paintMediaControlsPart(MediaSliderThumb, object, paintInfo, rect);
+}
+
+IntPoint RenderThemeChromiumMac::volumeSliderOffsetFromMuteButton(Node* muteButton, const IntSize& size) const
+{
+ return RenderTheme::volumeSliderOffsetFromMuteButton(muteButton, size);
+}
#endif
} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeMac.mm b/WebCore/rendering/RenderThemeMac.mm
index cc2ff1f..7982834 100644
--- a/WebCore/rendering/RenderThemeMac.mm
+++ b/WebCore/rendering/RenderThemeMac.mm
@@ -963,7 +963,8 @@ bool RenderThemeMac::paintProgressBar(RenderObject* renderObject, const PaintInf
paintInfo.context->translate(2 * rect.x() + rect.width(), 0);
paintInfo.context->scale(FloatSize(-1, 1));
}
- paintInfo.context->drawImage(imageBuffer->image(), DeviceColorSpace, rect.location());
+
+ paintInfo.context->drawImageBuffer(imageBuffer.get(), DeviceColorSpace, rect.location());
paintInfo.context->restore();
return false;
diff --git a/WebCore/rendering/RenderTreeAsText.cpp b/WebCore/rendering/RenderTreeAsText.cpp
index 408015c..e10c2f1 100644
--- a/WebCore/rendering/RenderTreeAsText.cpp
+++ b/WebCore/rendering/RenderTreeAsText.cpp
@@ -442,7 +442,7 @@ void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavi
return;
}
if (o.isSVGImage()) {
- writeSVGImage(ts, *toRenderImage(&o), indent);
+ writeSVGImage(ts, *toRenderSVGImage(&o), indent);
return;
}
#endif
diff --git a/WebCore/rendering/RenderVideo.cpp b/WebCore/rendering/RenderVideo.cpp
index ab969cc..0f444b2 100644
--- a/WebCore/rendering/RenderVideo.cpp
+++ b/WebCore/rendering/RenderVideo.cpp
@@ -134,13 +134,14 @@ void RenderVideo::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
RenderMedia::imageChanged(newImage, rect);
// Cache the image intrinsic size so we can continue to use it to draw the image correctly
- // even after we know the video intrisic size but aren't able to draw video frames yet
- // (we don't want to scale the poster to the video size).
- if (videoElement()->shouldDisplayPosterImage()) {
- if (errorOccurred())
- updateIntrinsicSize();
+ // even if we know the video intrinsic size but aren't able to draw video frames yet
+ // (we don't want to scale the poster to the video size without keeping aspect ratio).
+ if (videoElement()->shouldDisplayPosterImage())
m_cachedImageSize = intrinsicSize();
- }
+
+ // The intrinsic size is now that of the image, but in case we already had the
+ // intrinsic size of the video we call this here to restore the video size.
+ updateIntrinsicSize();
}
IntRect RenderVideo::videoBox() const
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index 449c15c..acb8487 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -186,7 +186,7 @@ void RenderView::paint(PaintInfo& paintInfo, int tx, int ty)
ASSERT(!needsLayout());
// Cache the print rect because the dirty rect could get changed during painting.
- if (printing())
+ if (document()->paginated())
setPrintRect(paintInfo.rect);
else
setPrintRect(IntRect());
diff --git a/WebCore/rendering/SVGImageBufferTools.cpp b/WebCore/rendering/SVGImageBufferTools.cpp
new file mode 100644
index 0000000..5b45ccc
--- /dev/null
+++ b/WebCore/rendering/SVGImageBufferTools.cpp
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) Research In Motion Limited 2010. 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"
+
+#if ENABLE(SVG)
+#include "SVGImageBufferTools.h"
+
+#include "GraphicsContext.h"
+#include "RenderObject.h"
+
+namespace WebCore {
+
+AffineTransform SVGImageBufferTools::absoluteTransformFromContext(GraphicsContext* context)
+{
+ // Extract current transformation matrix used in the original context. Note that this coordinate
+ // system is flipped compared to SVGs internal coordinate system, done in WebKit level. Fix
+ // this transformation by flipping the y component.
+ return context->getCTM() * AffineTransform().flipY();
+}
+
+bool SVGImageBufferTools::createImageBuffer(const AffineTransform& absoluteTransform, const FloatRect& absoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer, ImageColorSpace colorSpace)
+{
+ IntRect imageRect = enclosingIntRect(absoluteTargetRect);
+ if (imageRect.isEmpty())
+ return false;
+
+ // Allocate an image buffer as big as the absolute unclipped size of the object
+ OwnPtr<ImageBuffer> image = ImageBuffer::create(imageRect.size(), colorSpace);
+ if (!image)
+ return false;
+
+ GraphicsContext* imageContext = image->context();
+
+ // Transform the mask image coordinate system to absolute screen coordinates
+ imageContext->translate(-absoluteTargetRect.x(), -absoluteTargetRect.y());
+ imageContext->concatCTM(absoluteTransform);
+
+ imageBuffer = image.release();
+ return true;
+}
+
+void SVGImageBufferTools::clipToImageBuffer(GraphicsContext* context, const AffineTransform& absoluteTransform, const FloatRect& absoluteTargetRect, ImageBuffer* imageBuffer)
+{
+ ASSERT(context);
+ ASSERT(imageBuffer);
+
+ // The mask image has been created in the device coordinate space, as the image should not be scaled.
+ // So the actual masking process has to be done in the device coordinate space as well.
+ context->concatCTM(absoluteTransform.inverse());
+ context->clipToImageBuffer(imageBuffer, absoluteTargetRect);
+ context->concatCTM(absoluteTransform);
+}
+
+}
+
+#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/SVGImageBufferTools.h b/WebCore/rendering/SVGImageBufferTools.h
new file mode 100644
index 0000000..bdbcb1c
--- /dev/null
+++ b/WebCore/rendering/SVGImageBufferTools.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) Research In Motion Limited 2010. 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
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SVGImageBufferTools_h
+#define SVGImageBufferTools_h
+
+#if ENABLE(SVG)
+#include "ImageBuffer.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class AffineTransform;
+class FloatRect;
+class GraphicsContext;
+class RenderObject;
+
+class SVGImageBufferTools : public Noncopyable {
+public:
+ static bool createImageBuffer(const AffineTransform& absoluteTransform, const FloatRect& absoluteTargetRect, OwnPtr<ImageBuffer>&, ImageColorSpace);
+ static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& absoluteTargetRect, ImageBuffer*);
+
+ static AffineTransform absoluteTransformFromContext(GraphicsContext*);
+
+private:
+ SVGImageBufferTools() { }
+ ~SVGImageBufferTools() { }
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index 67e19f2..e265b2b 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -229,9 +229,20 @@ static inline RenderSVGRoot* svgRootTreeObject(RenderObject* start)
return toRenderSVGRoot(start);
}
+static inline void invalidateResourcesOfChildren(RenderObject* start)
+{
+ ASSERT(!start->needsLayout());
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(start))
+ resources->removeClientFromCache(start, false);
+
+ for (RenderObject* child = start->firstChild(); child; child = child->nextSibling())
+ invalidateResourcesOfChildren(child);
+}
+
void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
{
bool layoutSizeChanged = svgRootTreeObject(start)->isLayoutSizeChanged();
+ HashSet<RenderObject*> notlayoutedObjects;
for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
bool needsLayout = selfNeedsLayout;
@@ -252,11 +263,25 @@ void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
if (needsLayout) {
child->setNeedsLayout(true, false);
child->layout();
- } else
- child->layoutIfNeeded();
+ } else {
+ if (child->needsLayout())
+ child->layout();
+ else if (layoutSizeChanged)
+ notlayoutedObjects.add(child);
+ }
ASSERT(!child->needsLayout());
}
+
+ if (!layoutSizeChanged) {
+ ASSERT(notlayoutedObjects.isEmpty());
+ return;
+ }
+
+ // If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path.
+ HashSet<RenderObject*>::iterator end = notlayoutedObjects.end();
+ for (HashSet<RenderObject*>::iterator it = notlayoutedObjects.begin(); it != end; ++it)
+ invalidateResourcesOfChildren(*it);
}
bool SVGRenderSupport::isOverflowHidden(const RenderObject* object)
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index db4c07a..0c9b7e1 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -43,6 +43,7 @@
#include "RenderPath.h"
#include "RenderSVGContainer.h"
#include "RenderSVGGradientStop.h"
+#include "RenderSVGImage.h"
#include "RenderSVGInlineText.h"
#include "RenderSVGResourceClipper.h"
#include "RenderSVGResourceFilter.h"
@@ -708,7 +709,7 @@ void writeSVGInlineText(TextStream& ts, const RenderText& text, int indent)
writeSVGInlineTextBoxes(ts, text, indent);
}
-void writeSVGImage(TextStream& ts, const RenderImage& image, int indent)
+void writeSVGImage(TextStream& ts, const RenderSVGImage& image, int indent)
{
writeStandardPrefix(ts, image, indent);
writePositionAndStyle(ts, image);
diff --git a/WebCore/rendering/SVGRenderTreeAsText.h b/WebCore/rendering/SVGRenderTreeAsText.h
index 0fda958..d4aeaac 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.h
+++ b/WebCore/rendering/SVGRenderTreeAsText.h
@@ -44,6 +44,7 @@ namespace WebCore {
class RenderObject;
class RenderPath;
class RenderSVGGradientStop;
+ class RenderSVGImage;
class RenderSVGRoot;
class RenderText;
class AffineTransform;
@@ -55,7 +56,7 @@ void write(TextStream&, const RenderSVGRoot&, int indent);
void writeSVGGradientStop(TextStream&, const RenderSVGGradientStop&, int indent);
void writeSVGResourceContainer(TextStream&, const RenderObject&, int indent);
void writeSVGContainer(TextStream&, const RenderObject&, int indent);
-void writeSVGImage(TextStream&, const RenderImage&, int indent);
+void writeSVGImage(TextStream&, const RenderSVGImage&, int indent);
void writeSVGInlineText(TextStream&, const RenderText&, int indent);
void writeSVGText(TextStream&, const RenderBlock&, int indent);
void writeResources(TextStream&, const RenderObject&, int indent);
diff --git a/WebCore/rendering/SVGResources.cpp b/WebCore/rendering/SVGResources.cpp
index 290ef41..799301b 100644
--- a/WebCore/rendering/SVGResources.cpp
+++ b/WebCore/rendering/SVGResources.cpp
@@ -279,7 +279,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
return foundResources;
}
-void SVGResources::invalidateClient(RenderObject* object) const
+void SVGResources::removeClientFromCache(RenderObject* object, bool markForInvalidation) const
{
if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData && !m_linkedResource)
return;
@@ -288,35 +288,35 @@ void SVGResources::invalidateClient(RenderObject* object) const
ASSERT(!m_clipperFilterMaskerData);
ASSERT(!m_markerData);
ASSERT(!m_fillStrokeData);
- m_linkedResource->invalidateClient(object);
+ m_linkedResource->removeClientFromCache(object, markForInvalidation);
return;
}
if (m_clipperFilterMaskerData) {
if (m_clipperFilterMaskerData->clipper)
- m_clipperFilterMaskerData->clipper->invalidateClient(object);
+ m_clipperFilterMaskerData->clipper->removeClientFromCache(object, markForInvalidation);
#if ENABLE(FILTERS)
if (m_clipperFilterMaskerData->filter)
- m_clipperFilterMaskerData->filter->invalidateClient(object);
+ m_clipperFilterMaskerData->filter->removeClientFromCache(object, markForInvalidation);
#endif
if (m_clipperFilterMaskerData->masker)
- m_clipperFilterMaskerData->masker->invalidateClient(object);
+ m_clipperFilterMaskerData->masker->removeClientFromCache(object, markForInvalidation);
}
if (m_markerData) {
if (m_markerData->markerStart)
- m_markerData->markerStart->invalidateClient(object);
+ m_markerData->markerStart->removeClientFromCache(object, markForInvalidation);
if (m_markerData->markerMid)
- m_markerData->markerMid->invalidateClient(object);
+ m_markerData->markerMid->removeClientFromCache(object, markForInvalidation);
if (m_markerData->markerEnd)
- m_markerData->markerEnd->invalidateClient(object);
+ m_markerData->markerEnd->removeClientFromCache(object, markForInvalidation);
}
if (m_fillStrokeData) {
if (m_fillStrokeData->fill)
- m_fillStrokeData->fill->invalidateClient(object);
+ m_fillStrokeData->fill->removeClientFromCache(object, markForInvalidation);
if (m_fillStrokeData->stroke)
- m_fillStrokeData->stroke->invalidateClient(object);
+ m_fillStrokeData->stroke->removeClientFromCache(object, markForInvalidation);
}
}
@@ -330,7 +330,7 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
ASSERT(!m_clipperFilterMaskerData);
ASSERT(!m_markerData);
ASSERT(!m_fillStrokeData);
- m_linkedResource->invalidateClients();
+ m_linkedResource->removeAllClientsFromCache();
m_linkedResource = 0;
return;
}
@@ -340,7 +340,7 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
if (!m_clipperFilterMaskerData)
break;
if (m_clipperFilterMaskerData->masker == resource) {
- m_clipperFilterMaskerData->masker->invalidateClients();
+ m_clipperFilterMaskerData->masker->removeAllClientsFromCache();
m_clipperFilterMaskerData->masker = 0;
}
break;
@@ -348,15 +348,15 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
if (!m_markerData)
break;
if (m_markerData->markerStart == resource) {
- m_markerData->markerStart->invalidateClients();
+ m_markerData->markerStart->removeAllClientsFromCache();
m_markerData->markerStart = 0;
}
if (m_markerData->markerMid == resource) {
- m_markerData->markerMid->invalidateClients();
+ m_markerData->markerMid->removeAllClientsFromCache();
m_markerData->markerMid = 0;
}
if (m_markerData->markerEnd == resource) {
- m_markerData->markerEnd->invalidateClients();
+ m_markerData->markerEnd->removeAllClientsFromCache();
m_markerData->markerEnd = 0;
}
break;
@@ -366,11 +366,11 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
if (!m_fillStrokeData)
break;
if (m_fillStrokeData->fill == resource) {
- m_fillStrokeData->fill->invalidateClients();
+ m_fillStrokeData->fill->removeAllClientsFromCache();
m_fillStrokeData->fill = 0;
}
if (m_fillStrokeData->stroke == resource) {
- m_fillStrokeData->stroke->invalidateClients();
+ m_fillStrokeData->stroke->removeAllClientsFromCache();
m_fillStrokeData->stroke = 0;
}
break;
@@ -379,7 +379,7 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
if (!m_clipperFilterMaskerData)
break;
if (m_clipperFilterMaskerData->filter == resource) {
- m_clipperFilterMaskerData->filter->invalidateClients();
+ m_clipperFilterMaskerData->filter->removeAllClientsFromCache();
m_clipperFilterMaskerData->filter = 0;
}
#else
@@ -390,7 +390,7 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
if (!m_clipperFilterMaskerData)
break;
if (m_clipperFilterMaskerData->clipper == resource) {
- m_clipperFilterMaskerData->clipper->invalidateClients();
+ m_clipperFilterMaskerData->clipper->removeAllClientsFromCache();
m_clipperFilterMaskerData->clipper = 0;
}
break;
diff --git a/WebCore/rendering/SVGResources.h b/WebCore/rendering/SVGResources.h
index a07a990..5f6e746 100644
--- a/WebCore/rendering/SVGResources.h
+++ b/WebCore/rendering/SVGResources.h
@@ -64,7 +64,7 @@ public:
void buildSetOfResources(HashSet<RenderSVGResourceContainer*>&);
// Methods operating on all cached resources
- void invalidateClient(RenderObject*) const;
+ void removeClientFromCache(RenderObject*, bool markForInvalidation = true) const;
void resourceDestroyed(RenderSVGResourceContainer*);
#ifndef NDEBUG
diff --git a/WebCore/rendering/SVGResourcesCache.cpp b/WebCore/rendering/SVGResourcesCache.cpp
index b922b44..a4089d6 100644
--- a/WebCore/rendering/SVGResourcesCache.cpp
+++ b/WebCore/rendering/SVGResourcesCache.cpp
@@ -121,7 +121,7 @@ void SVGResourcesCache::clientLayoutChanged(RenderObject* object)
if (!resources)
return;
- resources->invalidateClient(object);
+ resources->removeClientFromCache(object);
}
void SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifference diff, const RenderStyle* newStyle)
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index cf0e864..9852aa6 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -345,9 +345,21 @@ void SpinButtonElement::setHovered(bool flag)
inline InputFieldSpeechButtonElement::InputFieldSpeechButtonElement(Node* shadowParent)
: TextControlInnerElement(shadowParent->document(), shadowParent)
, m_capturing(false)
+ , m_state(Idle)
+ , m_listenerId(document()->page()->speechInput()->registerListener(this))
{
}
+InputFieldSpeechButtonElement::~InputFieldSpeechButtonElement()
+{
+ SpeechInput* speech = speechInput();
+ if (speech) { // Could be null when page is unloading.
+ if (m_state != Idle)
+ speech->cancelRecognition(m_listenerId);
+ speech->unregisterListener(m_listenerId);
+ }
+}
+
PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(Node* shadowParent)
{
return adoptRef(new InputFieldSpeechButtonElement(shadowParent));
@@ -383,7 +395,18 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
}
if (event->type() == eventNames().clickEvent) {
- speechInput()->startRecognition(this);
+ switch (m_state) {
+ case Idle:
+ if (speechInput()->startRecognition(m_listenerId))
+ setState(Recording);
+ break;
+ case Recording:
+ speechInput()->stopRecording(m_listenerId);
+ break;
+ case Recognizing:
+ // Nothing to do here, we will continue to wait for results.
+ break;
+ }
event->setDefaultHandled();
}
@@ -391,23 +414,30 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
HTMLDivElement::defaultEventHandler(event);
}
+void InputFieldSpeechButtonElement::setState(SpeechInputState state)
+{
+ if (m_state != state) {
+ m_state = state;
+ shadowAncestorNode()->renderer()->repaint();
+ }
+}
+
SpeechInput* InputFieldSpeechButtonElement::speechInput()
{
- return document()->page()->speechInput();
+ return document()->page() ? document()->page()->speechInput() : 0;
}
-void InputFieldSpeechButtonElement::didCompleteRecording()
+void InputFieldSpeechButtonElement::didCompleteRecording(int)
{
- // FIXME: Add UI feedback here to indicate that audio recording stopped and recognition is
- // in progress.
+ setState(Recognizing);
}
-void InputFieldSpeechButtonElement::didCompleteRecognition()
+void InputFieldSpeechButtonElement::didCompleteRecognition(int)
{
- // FIXME: Add UI feedback here to indicate that audio recognition has ended.
+ setState(Idle);
}
-void InputFieldSpeechButtonElement::setRecognitionResult(const String& result)
+void InputFieldSpeechButtonElement::setRecognitionResult(int, const String& result)
{
HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
// The call to setValue() below dispatches an event, and an event handler in the page might
diff --git a/WebCore/rendering/TextControlInnerElements.h b/WebCore/rendering/TextControlInnerElements.h
index 2859bd5..3fbc9c8 100644
--- a/WebCore/rendering/TextControlInnerElements.h
+++ b/WebCore/rendering/TextControlInnerElements.h
@@ -119,21 +119,32 @@ class InputFieldSpeechButtonElement
: public TextControlInnerElement,
public SpeechInputListener {
public:
+ enum SpeechInputState {
+ Idle,
+ Recording,
+ Recognizing,
+ };
+
static PassRefPtr<InputFieldSpeechButtonElement> create(Node*);
+ virtual ~InputFieldSpeechButtonElement();
virtual void detach();
virtual void defaultEventHandler(Event*);
+ SpeechInputState state() const { return m_state; }
// SpeechInputListener methods.
- void didCompleteRecording();
- void didCompleteRecognition();
- void setRecognitionResult(const String& result);
+ void didCompleteRecording(int);
+ void didCompleteRecognition(int);
+ void setRecognitionResult(int, const String& result);
private:
InputFieldSpeechButtonElement(Node*);
SpeechInput* speechInput();
+ void setState(SpeechInputState state);
bool m_capturing;
+ SpeechInputState m_state;
+ int m_listenerId;
};
#endif // ENABLE(INPUT_SPEECH)
diff --git a/WebCore/rendering/style/BindingURI.h b/WebCore/rendering/style/BindingURI.h
index 923f1aa..c844b1d 100644
--- a/WebCore/rendering/style/BindingURI.h
+++ b/WebCore/rendering/style/BindingURI.h
@@ -26,7 +26,7 @@
#define BindingURI_h
#if ENABLE(XBL)
-#include "StringImpl.h"
+#include <wtf/text/StringImpl.h>
namespace WebCore {
diff --git a/WebCore/rendering/style/ContentData.cpp b/WebCore/rendering/style/ContentData.cpp
index 410cad4..b0f9e81 100644
--- a/WebCore/rendering/style/ContentData.cpp
+++ b/WebCore/rendering/style/ContentData.cpp
@@ -23,8 +23,8 @@
#include "ContentData.h"
#include "CounterContent.h"
-#include "StringImpl.h"
#include "StyleImage.h"
+#include <wtf/text/StringImpl.h>
namespace WebCore {
diff --git a/WebCore/rendering/style/CounterContent.h b/WebCore/rendering/style/CounterContent.h
index 702d9c2..52757ad 100644
--- a/WebCore/rendering/style/CounterContent.h
+++ b/WebCore/rendering/style/CounterContent.h
@@ -25,8 +25,8 @@
#ifndef CounterContent_h
#define CounterContent_h
-#include "AtomicString.h"
#include "RenderStyleConstants.h"
+#include <wtf/text/AtomicString.h>
namespace WebCore {
diff --git a/WebCore/rendering/style/CounterDirectives.h b/WebCore/rendering/style/CounterDirectives.h
index 9cbdeae..e54028e 100644
--- a/WebCore/rendering/style/CounterDirectives.h
+++ b/WebCore/rendering/style/CounterDirectives.h
@@ -25,9 +25,9 @@
#ifndef CounterDirectives_h
#define CounterDirectives_h
-#include "AtomicStringImpl.h"
#include <wtf/HashMap.h>
#include <wtf/RefPtr.h>
+#include <wtf/text/AtomicStringImpl.h>
namespace WebCore {
diff --git a/WebCore/rendering/style/KeyframeList.h b/WebCore/rendering/style/KeyframeList.h
index b1009d2..bb5f180 100644
--- a/WebCore/rendering/style/KeyframeList.h
+++ b/WebCore/rendering/style/KeyframeList.h
@@ -25,10 +25,10 @@
#ifndef KeyframeList_h
#define KeyframeList_h
-#include "AtomicString.h"
#include <wtf/Vector.h>
#include <wtf/HashSet.h>
#include <wtf/RefPtr.h>
+#include <wtf/text/AtomicString.h>
namespace WebCore {
diff --git a/WebCore/rendering/style/StyleRareInheritedData.h b/WebCore/rendering/style/StyleRareInheritedData.h
index 07541d3..ba914d4 100644
--- a/WebCore/rendering/style/StyleRareInheritedData.h
+++ b/WebCore/rendering/style/StyleRareInheritedData.h
@@ -25,11 +25,11 @@
#ifndef StyleRareInheritedData_h
#define StyleRareInheritedData_h
-#include "AtomicString.h"
#include "Color.h"
#include "Length.h"
#include <wtf/RefCounted.h>
#include <wtf/PassRefPtr.h>
+#include <wtf/text/AtomicString.h>
namespace WebCore {