summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/InlineTextBox.cpp4
-rw-r--r--WebCore/rendering/RenderBlock.cpp36
-rw-r--r--WebCore/rendering/RenderBlock.h1
-rw-r--r--WebCore/rendering/RenderBox.cpp17
-rw-r--r--WebCore/rendering/RenderBox.h2
-rw-r--r--WebCore/rendering/RenderFileUploadControl.cpp18
-rw-r--r--WebCore/rendering/RenderFileUploadControl.h14
-rw-r--r--WebCore/rendering/RenderForeignObject.cpp89
-rw-r--r--WebCore/rendering/RenderForeignObject.h23
-rw-r--r--WebCore/rendering/RenderInline.cpp14
-rw-r--r--WebCore/rendering/RenderInline.h2
-rw-r--r--WebCore/rendering/RenderLayer.cpp4
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp10
-rw-r--r--WebCore/rendering/RenderObject.cpp26
-rw-r--r--WebCore/rendering/RenderObject.h12
-rw-r--r--WebCore/rendering/RenderPath.cpp2
-rw-r--r--WebCore/rendering/RenderRuby.cpp2
-rw-r--r--WebCore/rendering/RenderRubyBase.cpp2
-rw-r--r--WebCore/rendering/RenderRubyRun.cpp2
-rw-r--r--WebCore/rendering/RenderRubyText.cpp2
-rw-r--r--WebCore/rendering/RenderSVGBlock.cpp32
-rw-r--r--WebCore/rendering/RenderSVGBlock.h9
-rw-r--r--WebCore/rendering/RenderSVGImage.cpp9
-rw-r--r--WebCore/rendering/RenderSVGImage.h62
-rw-r--r--WebCore/rendering/RenderSVGInlineText.h4
-rw-r--r--WebCore/rendering/RenderSVGModelObject.cpp10
-rw-r--r--WebCore/rendering/RenderSVGModelObject.h2
-rw-r--r--WebCore/rendering/RenderSVGResource.h84
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.cpp196
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.h79
-rw-r--r--WebCore/rendering/RenderSVGRoot.cpp66
-rw-r--r--WebCore/rendering/RenderSVGRoot.h5
-rw-r--r--WebCore/rendering/RenderSVGText.cpp6
-rw-r--r--WebCore/rendering/RenderSVGText.h2
-rw-r--r--WebCore/rendering/RenderSlider.cpp6
-rw-r--r--WebCore/rendering/RenderTableCell.cpp4
-rw-r--r--WebCore/rendering/RenderTableCell.h2
-rw-r--r--WebCore/rendering/RenderText.cpp17
-rw-r--r--WebCore/rendering/RenderTextControl.cpp76
-rw-r--r--WebCore/rendering/RenderTextControl.h4
-rw-r--r--WebCore/rendering/RenderTextControlMultiLine.cpp11
-rw-r--r--WebCore/rendering/RenderTextControlMultiLine.h1
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp26
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.h1
-rw-r--r--WebCore/rendering/RenderThemeChromiumMac.mm2
-rw-r--r--WebCore/rendering/RenderThemeMac.mm2
-rw-r--r--WebCore/rendering/RenderTreeAsText.cpp4
-rw-r--r--WebCore/rendering/RenderVideo.cpp8
-rw-r--r--WebCore/rendering/RenderVideo.h4
-rw-r--r--WebCore/rendering/SVGCharacterLayoutInfo.h88
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp27
-rw-r--r--WebCore/rendering/SVGRenderSupport.h82
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp70
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.h3
-rw-r--r--WebCore/rendering/SVGRootInlineBox.cpp69
-rw-r--r--WebCore/rendering/style/RenderStyle.cpp5
-rw-r--r--WebCore/rendering/style/RenderStyle.h1
-rw-r--r--WebCore/rendering/style/RenderStyleConstants.h5
58 files changed, 993 insertions, 373 deletions
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index b7e6de2..9f17b0c 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -808,7 +808,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, co
// Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, y), h, sPos, ePos));
- markerRect = root()->block()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
+ markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
// Optionally highlight the text
@@ -837,7 +837,7 @@ void InlineTextBox::computeRectForReplacementMarker(int /*tx*/, int /*ty*/, cons
// Compute and store the rect associated with this marker.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
- markerRect = root()->block()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
+ markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
}
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index eabb054..62e177d 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -1687,6 +1687,16 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
return;
}
+ // Check for page-break-inside: avoid, and it it's set, break and bail.
+ if (isPrinting && !childrenInline() && child->style()->pageBreakInside() == PBAVOID
+ && inRootBlockContext()
+ && ty + child->y() > paintInfo.rect.y()
+ && ty + child->y() < paintInfo.rect.bottom()
+ && ty + child->y() + child->height() > paintInfo.rect.bottom()) {
+ view()->setBestTruncatedAt(ty + child->y(), this, true);
+ return;
+ }
+
if (!child->hasSelfPaintingLayer() && !child->isFloating())
child->paint(info, tx, ty);
@@ -1984,6 +1994,7 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
if (!hasLayer()) {
FloatRect localBounds(gapRectsBounds);
gapRectsBounds = localToContainerQuad(localBounds, layer->renderer()).enclosingBoundingBox();
+ gapRectsBounds.move(layer->scrolledContentOffset());
}
layer->addBlockSelectionGapsBounds(gapRectsBounds);
}
@@ -3897,6 +3908,31 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const
r = result;
}
+void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
+{
+ if (!hasColumns())
+ return;
+
+ // FIXME: This is incorrect for right-to-left columns.
+
+ Vector<IntRect>& columnRects = *this->columnRects();
+
+ int gapWidth = columnGap();
+ int xOffset = 0;
+ int yOffset = 0;
+ size_t columnCount = columnRects.size();
+ for (size_t i = 0; i < columnCount; ++i) {
+ IntRect columnRect = columnRects[i];
+ if (point.y() < columnRect.bottom() + yOffset) {
+ offset.expand(xOffset, -yOffset);
+ return;
+ }
+
+ xOffset += columnRect.width() + gapWidth;
+ yOffset += columnRect.height();
+ }
+}
+
void RenderBlock::calcPrefWidths()
{
ASSERT(prefWidthsDirty());
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index d1d105a..c1f8dde 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -128,6 +128,7 @@ public:
void clearTruncation();
void adjustRectForColumns(IntRect&) const;
+ virtual void adjustForColumns(IntSize&, const IntPoint&) const;
void addContinuationWithOutline(RenderInline*);
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 92c3d99..66a88e2 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -980,7 +980,7 @@ void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool
} else
fixed |= isFixedPos;
- IntSize containerOffset = offsetFromContainer(o);
+ IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -1021,7 +1021,7 @@ void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Transfor
o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
- IntSize containerOffset = offsetFromContainer(o);
+ IntSize containerOffset = offsetFromContainer(o, IntPoint());
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -1032,7 +1032,7 @@ void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Transfor
transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
}
-IntSize RenderBox::offsetFromContainer(RenderObject* o) const
+IntSize RenderBox::offsetFromContainer(RenderObject* o, const IntPoint& point) const
{
ASSERT(o == container());
@@ -1041,14 +1041,9 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o) const
offset += relativePositionOffset();
if (!isInline() || isReplaced()) {
- RenderBlock* cb;
- if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition
- && (cb = toRenderBlock(o))->hasColumns()) {
- IntRect rect(x(), y(), 1, 1);
- cb->adjustRectForColumns(rect);
- offset.expand(rect.x(), rect.y());
- } else
- offset.expand(x(), y());
+ if (style()->position() != AbsolutePosition && style()->position() != FixedPosition)
+ o->adjustForColumns(offset, IntPoint(point.x() + x(), point.y() + y()));
+ offset.expand(x(), y());
}
if (o->hasOverflowClip())
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index 401a46d..2ee368d 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -173,7 +173,7 @@ public:
int overrideHeight() const;
virtual void setOverrideSize(int);
- virtual IntSize offsetFromContainer(RenderObject*) const;
+ virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
int calcBorderBoxWidth(int width) const;
int calcBorderBoxHeight(int height) const;
diff --git a/WebCore/rendering/RenderFileUploadControl.cpp b/WebCore/rendering/RenderFileUploadControl.cpp
index 59cbacf..a31442a 100644
--- a/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/WebCore/rendering/RenderFileUploadControl.cpp
@@ -114,15 +114,27 @@ String RenderFileUploadControl::acceptTypes()
return static_cast<HTMLInputElement*>(node())->accept();
}
+void RenderFileUploadControl::iconForFiles(const Vector<String>& filenames)
+{
+ if (Chrome* chromePointer = chrome())
+ chromePointer->iconForFiles(filenames, m_fileChooser);
+}
+
void RenderFileUploadControl::click()
{
+ if (Chrome* chromePointer = chrome())
+ chromePointer->runOpenPanel(node()->document()->frame(), m_fileChooser);
+}
+
+Chrome* RenderFileUploadControl::chrome() const
+{
Frame* frame = node()->document()->frame();
if (!frame)
- return;
+ return 0;
Page* page = frame->page();
if (!page)
- return;
- page->chrome()->runOpenPanel(frame, m_fileChooser);
+ return 0;
+ return page->chrome();
}
void RenderFileUploadControl::updateFromElement()
diff --git a/WebCore/rendering/RenderFileUploadControl.h b/WebCore/rendering/RenderFileUploadControl.h
index dcdce4d..454041a 100644
--- a/WebCore/rendering/RenderFileUploadControl.h
+++ b/WebCore/rendering/RenderFileUploadControl.h
@@ -26,6 +26,7 @@
namespace WebCore {
+class Chrome;
class HTMLInputElement;
// Each RenderFileUploadControl contains a RenderButton (for opening the file chooser), and
@@ -41,16 +42,11 @@ public:
void click();
- void valueChanged();
-
void receiveDroppedFiles(const Vector<String>&);
String buttonValue();
String fileTextValue() const;
- bool allowsMultipleFiles();
- String acceptTypes();
-
private:
virtual const char* renderName() const { return "RenderFileUploadControl"; }
@@ -60,6 +56,14 @@ private:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ // FileChooserClient methods.
+ void valueChanged();
+ void repaint() { RenderBlock::repaint(); }
+ bool allowsMultipleFiles();
+ String acceptTypes();
+ void iconForFiles(const Vector<String>&);
+
+ Chrome* chrome() const;
int maxFilenameWidth() const;
PassRefPtr<RenderStyle> createButtonStyle(const RenderStyle* parentStyle) const;
diff --git a/WebCore/rendering/RenderForeignObject.cpp b/WebCore/rendering/RenderForeignObject.cpp
index 5bb4439..aa28ff0 100644
--- a/WebCore/rendering/RenderForeignObject.cpp
+++ b/WebCore/rendering/RenderForeignObject.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2009 Google, Inc.
+ * 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
@@ -27,9 +28,9 @@
#include "GraphicsContext.h"
#include "RenderView.h"
#include "SVGForeignObjectElement.h"
-#include "SVGLength.h"
#include "SVGRenderSupport.h"
-#include "SVGTransformList.h"
+#include "SVGSVGElement.h"
+#include "TransformState.h"
namespace WebCore {
@@ -38,22 +39,18 @@ RenderForeignObject::RenderForeignObject(SVGForeignObjectElement* node)
{
}
-FloatPoint RenderForeignObject::translationForAttributes() const
-{
- SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
- return FloatPoint(foreign->x().value(foreign), foreign->y().value(foreign));
-}
-
void RenderForeignObject::paint(PaintInfo& paintInfo, int, int)
{
if (paintInfo.context->paintingDisabled())
return;
- // Copy the paint info so that modifications to the damage rect do not affect callers
- PaintInfo childPaintInfo = paintInfo;
+ PaintInfo childPaintInfo(paintInfo);
childPaintInfo.context->save();
- applyTransformToPaintInfo(childPaintInfo, localToParentTransform());
- childPaintInfo.context->clip(clipRect(0, 0));
+
+ applyTransformToPaintInfo(childPaintInfo, localTransform());
+
+ if (SVGRenderBase::isOverflowHidden(this))
+ childPaintInfo.context->clip(m_viewport);
float opacity = style()->opacity();
if (opacity < 1.0f)
@@ -67,32 +64,33 @@ void RenderForeignObject::paint(PaintInfo& paintInfo, int, int)
childPaintInfo.context->restore();
}
-FloatRect RenderForeignObject::objectBoundingBox() const
+IntRect RenderForeignObject::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
- return borderBoxRect();
+ return SVGRenderBase::clippedOverflowRectForRepaint(this, repaintContainer);
}
-FloatRect RenderForeignObject::repaintRectInLocalCoordinates() const
+void RenderForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
- // HACK: to maintain historical LayoutTest results for now.
- // RenderForeignObject is a RenderBlock (not a RenderSVGModelObject) so this
- // should not affect repaint correctness. But it should really be:
- // return borderBoxRect();
- return FloatRect();
+ SVGRenderBase::computeRectForRepaint(this, repaintContainer, repaintRect, fixed);
}
-void RenderForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
+const AffineTransform& RenderForeignObject::localToParentTransform() const
{
- rect = localToParentTransform().mapRect(rect);
- style()->svgStyle()->inflateForShadow(rect);
- RenderBlock::computeRectForRepaint(repaintContainer, rect, fixed);
+ m_localToParentTransform = localTransform();
+ m_localToParentTransform.translate(m_viewport.x(), m_viewport.y());
+ return m_localToParentTransform;
}
-const AffineTransform& RenderForeignObject::localToParentTransform() const
+void RenderForeignObject::calcWidth()
{
- FloatPoint attributeTranslation(translationForAttributes());
- m_localToParentTransform = localTransform().translateRight(attributeTranslation.x(), attributeTranslation.y());
- return m_localToParentTransform;
+ // FIXME: Investigate in size rounding issues
+ setWidth(static_cast<int>(roundf(m_viewport.width())));
+}
+
+void RenderForeignObject::calcHeight()
+{
+ // FIXME: Investigate in size rounding issues
+ setHeight(static_cast<int>(roundf(m_viewport.height())));
}
void RenderForeignObject::layout()
@@ -101,18 +99,36 @@ void RenderForeignObject::layout()
ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
- m_localTransform = static_cast<SVGForeignObjectElement*>(node())->animatedLocalTransform();
+ SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
+ m_localTransform = foreign->animatedLocalTransform();
+
+ // Cache viewport boundaries
+ FloatPoint viewportLocation(foreign->x().value(foreign), foreign->y().value(foreign));
+ m_viewport = FloatRect(viewportLocation, FloatSize(foreign->width().value(foreign), foreign->height().value(foreign)));
+
+ // Set box origin to the foreignObject x/y translation, so positioned objects in XHTML content get correct
+ // positions. A regular RenderBoxModelObject would pull this information from RenderStyle - in SVG those
+ // properties are ignored for non <svg> elements, so we mimic what happens when specifying them through CSS.
+
+ // FIXME: Investigate in location rounding issues - only affects RenderForeignObject & RenderSVGText
+ setLocation(roundedIntPoint(viewportLocation));
RenderBlock::layout();
- repainter.repaintAfterLayout();
+ repainter.repaintAfterLayout();
setNeedsLayout(false);
}
bool RenderForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
- FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
- return RenderBlock::nodeAtPoint(request, result, static_cast<int>(localPoint.x()), static_cast<int>(localPoint.y()), 0, 0, hitTestAction);
+ FloatPoint localPoint = localTransform().inverse().mapPoint(pointInParent);
+
+ // Early exit if local point is not contained in clipped viewport area
+ if (SVGRenderBase::isOverflowHidden(this) && !m_viewport.contains(localPoint))
+ return false;
+
+ IntPoint roundedLocalPoint = roundedIntPoint(localPoint);
+ return RenderBlock::nodeAtPoint(request, result, roundedLocalPoint.x(), roundedLocalPoint.y(), 0, 0, hitTestAction);
}
bool RenderForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
@@ -121,11 +137,14 @@ bool RenderForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int
return false;
}
-void RenderForeignObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const
+void RenderForeignObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
{
+ // When crawling up the hierachy starting from foreignObject child content, useTransforms may not be set to true.
+ if (!useTransforms)
+ useTransforms = true;
SVGRenderBase::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState);
}
-} // namespace WebCore
+}
-#endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
+#endif
diff --git a/WebCore/rendering/RenderForeignObject.h b/WebCore/rendering/RenderForeignObject.h
index f32069c..bb6b555 100644
--- a/WebCore/rendering/RenderForeignObject.h
+++ b/WebCore/rendering/RenderForeignObject.h
@@ -21,8 +21,8 @@
#ifndef RenderForeignObject_h
#define RenderForeignObject_h
-#if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
+#if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
#include "AffineTransform.h"
#include "FloatPoint.h"
#include "RenderSVGBlock.h"
@@ -39,15 +39,15 @@ public:
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual const AffineTransform& localToParentTransform() const;
-
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
+
virtual bool requiresLayer() const { return false; }
virtual void layout();
- virtual FloatRect objectBoundingBox() const;
- virtual FloatRect strokeBoundingBox() const { return borderBoxRect(); }
- virtual FloatRect repaintRectInLocalCoordinates() const;
+ virtual FloatRect objectBoundingBox() const { return m_viewport; }
+ virtual FloatRect strokeBoundingBox() const { return m_viewport; }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return m_viewport; }
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -56,15 +56,18 @@ public:
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const;
private:
- FloatPoint translationForAttributes() const;
+ virtual void calcWidth();
+ virtual void calcHeight();
+ virtual const AffineTransform& localToParentTransform() const;
virtual AffineTransform localTransform() const { return m_localTransform; }
+ FloatRect m_viewport;
AffineTransform m_localTransform;
mutable AffineTransform m_localToParentTransform;
};
-} // namespace WebCore
+}
-#endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
-#endif // RenderForeignObject_h
+#endif
+#endif
diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp
index 9571751..d254835 100644
--- a/WebCore/rendering/RenderInline.cpp
+++ b/WebCore/rendering/RenderInline.cpp
@@ -710,7 +710,7 @@ void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer,
o->computeRectForRepaint(repaintContainer, rect, fixed);
}
-IntSize RenderInline::offsetFromContainer(RenderObject* container) const
+IntSize RenderInline::offsetFromContainer(RenderObject* container, const IntPoint& point) const
{
ASSERT(container == this->container());
@@ -718,13 +718,7 @@ IntSize RenderInline::offsetFromContainer(RenderObject* container) const
if (isRelPositioned())
offset += relativePositionOffset();
- if (!isInline() || isReplaced()) {
- RenderBlock* cb;
- if (container->isBlockFlow() && (cb = toRenderBlock(container))->hasColumns()) {
- IntRect rect(0, 0, 1, 1);
- cb->adjustRectForColumns(rect);
- }
- }
+ container->adjustForColumns(offset, point);
if (container->hasOverflowClip())
offset -= toRenderBox(container)->layer()->scrolledContentOffset();
@@ -753,7 +747,7 @@ void RenderInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b
if (!o)
return;
- IntSize containerOffset = offsetFromContainer(o);
+ IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -785,7 +779,7 @@ void RenderInline::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Trans
o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
- IntSize containerOffset = offsetFromContainer(o);
+ IntSize containerOffset = offsetFromContainer(o, IntPoint());
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
if (useTransforms && shouldUseTransformFromContainer(o)) {
diff --git a/WebCore/rendering/RenderInline.h b/WebCore/rendering/RenderInline.h
index d35aa85..7fcb516 100644
--- a/WebCore/rendering/RenderInline.h
+++ b/WebCore/rendering/RenderInline.h
@@ -44,7 +44,7 @@ public:
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
- virtual IntSize offsetFromContainer(RenderObject*) const;
+ virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
IntRect linesBoundingBox() const;
IntRect linesVisibleOverflowBoundingBox() const;
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 6dbb413..03a1e75 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -1227,7 +1227,9 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
#if USE(ACCELERATED_COMPOSITING)
if (compositor()->inCompositingMode()) {
- if (RenderLayer* compositingAncestor = ancestorCompositingLayer()) {
+ // Our stacking context is guaranteed to contain all of our descendants that may need
+ // repositioning, so update compositing layers from there.
+ if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
bool isUpdateRoot = true;
compositingAncestor->backing()->updateAfterLayout(RenderLayerBacking::AllDescendants, isUpdateRoot);
}
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 3f60557..f637e3c 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -38,6 +38,7 @@
#include "GraphicsLayer.h"
#include "HTMLCanvasElement.h"
#include "HTMLElement.h"
+#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "InspectorTimelineAgent.h"
#include "KeyframeList.h"
@@ -215,9 +216,14 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
PluginWidget* pluginWidget = static_cast<PluginWidget*>(toRenderEmbeddedObject(renderer())->widget());
m_graphicsLayer->setContentsToMedia(pluginWidget->platformLayer());
}
-
+#if ENABLE(VIDEO)
+ else if (renderer()->isVideo()) {
+ HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(renderer()->node());
+ m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
+ }
+#endif
#if ENABLE(3D_CANVAS)
- if (is3DCanvas(renderer())) {
+ else if (is3DCanvas(renderer())) {
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(canvas->renderingContext());
if (context->graphicsContext3D()->platformGraphicsContext3D())
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 1d1e7c2..e70de96 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -69,6 +69,7 @@
#endif
#if ENABLE(SVG)
+#include "RenderSVGResource.h"
#include "SVGRenderSupport.h"
#endif
@@ -1765,6 +1766,11 @@ void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b
if (!o)
return;
+ IntSize columnOffset;
+ o->adjustForColumns(columnOffset, roundedIntPoint(transformState.mappedPoint()));
+ if (!columnOffset.isZero())
+ transformState.move(columnOffset);
+
if (o->hasOverflowClip())
transformState.move(-toRenderBox(o)->layer()->scrolledContentOffset());
@@ -1821,18 +1827,23 @@ void RenderObject::getTransformFromContainer(const RenderObject* containerObject
FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBoxModelObject* repaintContainer, bool fixed) const
{
- TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint(), &localQuad);
+ // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
+ // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
+ TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), &localQuad);
mapLocalToContainer(repaintContainer, fixed, true, transformState);
transformState.flatten();
return transformState.lastPlanarQuad();
}
-IntSize RenderObject::offsetFromContainer(RenderObject* o) const
+IntSize RenderObject::offsetFromContainer(RenderObject* o, const IntPoint& point) const
{
ASSERT(o == container());
IntSize offset;
+
+ o->adjustForColumns(offset, point);
+
if (o->hasOverflowClip())
offset -= toRenderBox(o)->layer()->scrolledContentOffset();
@@ -1842,6 +1853,7 @@ IntSize RenderObject::offsetFromContainer(RenderObject* o) const
IntSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
{
IntSize offset;
+ IntPoint referencePoint;
const RenderObject* currContainer = this;
do {
RenderObject* nextContainer = currContainer->container();
@@ -1849,7 +1861,9 @@ IntSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
if (!nextContainer)
break;
ASSERT(!currContainer->hasTransform());
- offset += currContainer->offsetFromContainer(nextContainer);
+ IntSize currentOffset = currContainer->offsetFromContainer(nextContainer, referencePoint);
+ offset += currentOffset;
+ referencePoint.move(currentOffset);
currContainer = nextContainer;
} while (currContainer != container);
@@ -2520,6 +2534,12 @@ const SVGRenderBase* RenderObject::toSVGRenderBase() const
return 0;
}
+RenderSVGResource* RenderObject::toRenderSVGResource()
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
FloatRect RenderObject::objectBoundingBox() const
{
ASSERT_NOT_REACHED();
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 6764818..791d4d0 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -54,6 +54,7 @@ class RenderTheme;
class TransformState;
class VisiblePosition;
#if ENABLE(SVG)
+class RenderSVGResource;
class SVGRenderBase;
#endif
@@ -332,8 +333,10 @@ public:
virtual bool isSVGText() const { return false; }
virtual bool isSVGImage() const { return false; }
virtual bool isSVGForeignObject() const { return false; }
+ virtual bool isSVGResource() const { return false; }
virtual const SVGRenderBase* toSVGRenderBase() const;
+ virtual RenderSVGResource* toRenderSVGResource();
// Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects, opacity and stroke-width.
// This is used for all computation of objectBoundingBox relative units and by SVGLocateable::getBBox().
@@ -562,8 +565,9 @@ public:
// Convert a local quad into the coordinate system of container, taking transforms into account.
FloatQuad localToContainerQuad(const FloatQuad&, RenderBoxModelObject* repaintContainer, bool fixed = false) const;
- // Return the offset from the container() renderer (excluding transforms)
- virtual IntSize offsetFromContainer(RenderObject*) const;
+ // Return the offset from the container() renderer (excluding transforms). In multi-column layout,
+ // different offsets apply at different points, so return the offset that applies to the given point.
+ virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
// Return the offset from an object up the container() chain. Asserts that none of the intermediate objects have transforms.
IntSize offsetFromAncestorContainer(RenderObject*) const;
@@ -642,6 +646,10 @@ public:
// that rect in the coordinate space of repaintContainer.
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
+ // If multiple-column layout results in applying an offset to the given point, add the same
+ // offset to the given size.
+ virtual void adjustForColumns(IntSize&, const IntPoint&) const { }
+
virtual unsigned int length() const { return 1; }
bool isFloatingOrPositioned() const { return (isFloating() || isPositioned()); }
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index 7dbde42..bcedd38 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -34,9 +34,7 @@
#include "StrokeStyleApplier.h"
#include "SVGPaintServer.h"
#include "SVGRenderSupport.h"
-#include "SVGResourceFilter.h"
#include "SVGResourceMarker.h"
-#include "SVGResourceMasker.h"
#include "SVGStyledTransformableElement.h"
#include "SVGTransformList.h"
#include "SVGURIReference.h"
diff --git a/WebCore/rendering/RenderRuby.cpp b/WebCore/rendering/RenderRuby.cpp
index f13e2b4..4ab9d73 100644
--- a/WebCore/rendering/RenderRuby.cpp
+++ b/WebCore/rendering/RenderRuby.cpp
@@ -194,4 +194,4 @@ void RenderRubyAsBlock::removeChild(RenderObject* child)
} // namespace WebCore
-#endif
+#endif // ENABLE(RUBY)
diff --git a/WebCore/rendering/RenderRubyBase.cpp b/WebCore/rendering/RenderRubyBase.cpp
index 65f9bc0..9b2dc9e 100644
--- a/WebCore/rendering/RenderRubyBase.cpp
+++ b/WebCore/rendering/RenderRubyBase.cpp
@@ -187,4 +187,4 @@ void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fr
} // namespace WebCore
-#endif
+#endif // ENABLE(RUBY)
diff --git a/WebCore/rendering/RenderRubyRun.cpp b/WebCore/rendering/RenderRubyRun.cpp
index 61be455..d91c625 100644
--- a/WebCore/rendering/RenderRubyRun.cpp
+++ b/WebCore/rendering/RenderRubyRun.cpp
@@ -225,4 +225,4 @@ RenderRubyRun* RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby
} // namespace WebCore
-#endif
+#endif // ENABLE(RUBY)
diff --git a/WebCore/rendering/RenderRubyText.cpp b/WebCore/rendering/RenderRubyText.cpp
index 1cf2b9e..12e8fea 100644
--- a/WebCore/rendering/RenderRubyText.cpp
+++ b/WebCore/rendering/RenderRubyText.cpp
@@ -51,4 +51,4 @@ bool RenderRubyText::isChildAllowed(RenderObject* child, RenderStyle*) const
} // namespace WebCore
-#endif
+#endif // ENABLE(RUBY)
diff --git a/WebCore/rendering/RenderSVGBlock.cpp b/WebCore/rendering/RenderSVGBlock.cpp
index f065c44..99725d6 100644
--- a/WebCore/rendering/RenderSVGBlock.cpp
+++ b/WebCore/rendering/RenderSVGBlock.cpp
@@ -1,8 +1,7 @@
/*
- * This file is part of the WebKit project.
- *
* Copyright (C) 2006 Apple Computer, Inc.
- * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * 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
@@ -40,9 +39,7 @@ void RenderSVGBlock::setStyle(PassRefPtr<RenderStyle> style)
RefPtr<RenderStyle> useStyle = style;
// SVG text layout code expects us to be a block-level style element.
- if (useStyle->display() == NONE)
- setChildrenInline(false);
- else if (useStyle->isDisplayInlineType()) {
+ if (useStyle->isDisplayInlineType()) {
RefPtr<RenderStyle> newStyle = RenderStyle::create();
newStyle->inheritFrom(useStyle.get());
newStyle->setDisplay(BLOCK);
@@ -50,14 +47,27 @@ void RenderSVGBlock::setStyle(PassRefPtr<RenderStyle> style)
}
RenderBlock::setStyle(useStyle.release());
- setReplaced(false);
+}
+
+void RenderSVGBlock::updateBoxModelInfoFromStyle()
+{
+ RenderBlock::updateBoxModelInfoFromStyle();
- //FIXME: Once overflow rules are supported by SVG we should
- //probably map the CSS overflow rules rather than just ignoring
- //them
+ // RenderSVGlock, used by Render(SVGText|ForeignObject), is not allowed to call setHasOverflowClip(true).
+ // RenderBlock assumes a layer to be present when the overflow clip functionality is requested. Both
+ // Render(SVGText|ForeignObject) return 'false' on 'requiresLayer'. Fine for RenderSVGText.
+ //
+ // If we want to support overflow rules for <foreignObject> we can choose between two solutions:
+ // a) make RenderForeignObject require layers and SVG layer aware
+ // b) reactor overflow logic out of RenderLayer (as suggested by dhyatt), which is a large task
+ //
+ // Until this is resolved, disable overflow support. Opera/FF don't support it as well at the moment (Feb 2010).
+ //
+ // Note: This does NOT affect overflow handling on outer/inner <svg> elements - this is handled
+ // manually by RenderSVGRoot - which owns the documents enclosing root layer and thus works fine.
setHasOverflowClip(false);
}
}
-#endif // ENABLE(SVG)
+#endif
diff --git a/WebCore/rendering/RenderSVGBlock.h b/WebCore/rendering/RenderSVGBlock.h
index 0b0d107..19cac62 100644
--- a/WebCore/rendering/RenderSVGBlock.h
+++ b/WebCore/rendering/RenderSVGBlock.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the WebKit project.
- *
* Copyright (C) 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -22,8 +20,8 @@
#ifndef RenderSVGBlock_h
#define RenderSVGBlock_h
-#if ENABLE(SVG)
+#if ENABLE(SVG)
#include "RenderBlock.h"
#include "SVGRenderSupport.h"
@@ -39,8 +37,9 @@ public:
private:
virtual void setStyle(PassRefPtr<RenderStyle>);
+ virtual void updateBoxModelInfoFromStyle();
};
}
-#endif // ENABLE(SVG)
-#endif // !RenderSVGBlock_h
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index 96eeaf9..6fb9501 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -37,9 +37,6 @@
#include "SVGLength.h"
#include "SVGPreserveAspectRatio.h"
#include "SVGRenderSupport.h"
-#include "SVGResourceClipper.h"
-#include "SVGResourceFilter.h"
-#include "SVGResourceMasker.h"
namespace WebCore {
@@ -103,6 +100,12 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
paintInfo.context->restore();
}
+void RenderSVGImage::destroy()
+{
+ SVGRenderBase::deregisterFromResources(this);
+ RenderImage::destroy();
+}
+
bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
// We only draw in the forground phase, so we only hit-test then.
diff --git a/WebCore/rendering/RenderSVGImage.h b/WebCore/rendering/RenderSVGImage.h
index 8ed9146..f48b9dd 100644
--- a/WebCore/rendering/RenderSVGImage.h
+++ b/WebCore/rendering/RenderSVGImage.h
@@ -32,48 +32,50 @@
namespace WebCore {
- class SVGImageElement;
+class SVGImageElement;
- class RenderSVGImage : public RenderImage, protected SVGRenderBase {
- public:
- RenderSVGImage(SVGImageElement*);
+class RenderSVGImage : public RenderImage, protected SVGRenderBase {
+public:
+ RenderSVGImage(SVGImageElement*);
- private:
- virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
- virtual const char* renderName() const { return "RenderSVGImage"; }
- virtual bool isSVGImage() const { return true; }
+private:
+ virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
+ virtual const char* renderName() const { return "RenderSVGImage"; }
+ virtual bool isSVGImage() const { return true; }
- virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
- virtual FloatRect objectBoundingBox() const;
- virtual FloatRect strokeBoundingBox() const { return m_localBounds; }
- virtual FloatRect repaintRectInLocalCoordinates() const;
+ virtual FloatRect objectBoundingBox() const;
+ virtual FloatRect strokeBoundingBox() const { return m_localBounds; }
+ virtual FloatRect repaintRectInLocalCoordinates() const;
- virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
- virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
+ virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
- virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
+ virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
- virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
- virtual void absoluteQuads(Vector<FloatQuad>&);
- virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
+ virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
+ virtual void absoluteQuads(Vector<FloatQuad>&);
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
-
- virtual void layout();
- virtual void paint(PaintInfo&, int parentX, int parentY);
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+
+ virtual void layout();
+ virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual bool requiresLayer() const { return false; }
+ virtual void destroy();
- virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
+ virtual bool requiresLayer() const { return false; }
- virtual AffineTransform localTransform() const { return m_localTransform; }
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
- AffineTransform m_localTransform;
- FloatRect m_localBounds;
- mutable FloatRect m_cachedLocalRepaintRect;
- };
+ virtual AffineTransform localTransform() const { return m_localTransform; }
+
+ AffineTransform m_localTransform;
+ FloatRect m_localBounds;
+ mutable FloatRect m_cachedLocalRepaintRect;
+};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderSVGInlineText.h b/WebCore/rendering/RenderSVGInlineText.h
index e9c5d6e..b475067 100644
--- a/WebCore/rendering/RenderSVGInlineText.h
+++ b/WebCore/rendering/RenderSVGInlineText.h
@@ -39,6 +39,10 @@ private:
virtual void styleDidChange(StyleDifference, const RenderStyle*);
+ // FIXME: We need objectBoundingBox for DRT results and filters at the moment.
+ // This should be fixed to give back the objectBoundingBox of the text root.
+ virtual FloatRect objectBoundingBox() const { return FloatRect(); }
+
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
diff --git a/WebCore/rendering/RenderSVGModelObject.cpp b/WebCore/rendering/RenderSVGModelObject.cpp
index 3fab5a6..c163dc6 100644
--- a/WebCore/rendering/RenderSVGModelObject.cpp
+++ b/WebCore/rendering/RenderSVGModelObject.cpp
@@ -38,10 +38,6 @@
#include "RenderView.h"
#include "SVGStyledElement.h"
-#if ENABLE(FILTERS)
-#include "SVGResourceFilter.h"
-#endif
-
namespace WebCore {
RenderSVGModelObject::RenderSVGModelObject(SVGStyledElement* node)
@@ -86,6 +82,12 @@ void RenderSVGModelObject::absoluteQuads(Vector<FloatQuad>& quads)
quads.append(absoluteClippedOverflowRect());
}
+void RenderSVGModelObject::destroy()
+{
+ deregisterFromResources(this);
+ RenderObject::destroy();
+}
+
bool RenderSVGModelObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
{
ASSERT_NOT_REACHED();
diff --git a/WebCore/rendering/RenderSVGModelObject.h b/WebCore/rendering/RenderSVGModelObject.h
index 4c50734..c04c590 100644
--- a/WebCore/rendering/RenderSVGModelObject.h
+++ b/WebCore/rendering/RenderSVGModelObject.h
@@ -60,6 +60,8 @@ public:
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
+ virtual void destroy();
+
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
private:
diff --git a/WebCore/rendering/RenderSVGResource.h b/WebCore/rendering/RenderSVGResource.h
new file mode 100644
index 0000000..38c6c09
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResource.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-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.
+ *
+ */
+
+#ifndef RenderSVGResource_h
+#define RenderSVGResource_h
+
+#if ENABLE(SVG)
+#include "FloatRect.h"
+#include "RenderSVGHiddenContainer.h"
+
+namespace WebCore {
+
+enum RenderSVGResourceType {
+ MaskerResourceType
+};
+
+class RenderSVGResource : public RenderSVGHiddenContainer {
+public:
+ RenderSVGResource(SVGStyledElement* node) : RenderSVGHiddenContainer(node) { }
+
+ template<class Renderer>
+ Renderer* cast()
+ {
+ if (Renderer::s_resourceType == resourceType())
+ return static_cast<Renderer*>(this);
+
+ return 0;
+ }
+
+ virtual RenderSVGResource* toRenderSVGResource() { return this; }
+ virtual bool isSVGResource() const { return true; }
+ virtual bool drawsContents() { return false; }
+
+ virtual void invalidateClients() = 0;
+ virtual void invalidateClient(RenderObject*) = 0;
+
+ virtual bool applyResource(RenderObject*, GraphicsContext*) = 0;
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const = 0;
+
+ virtual RenderSVGResourceType resourceType() const = 0;
+};
+
+template<typename Renderer>
+Renderer* getRenderSVGResourceById(Document* document, const AtomicString& id)
+{
+ if (id.isEmpty())
+ return 0;
+
+ Element* element = document->getElementById(id);
+ if (!element || !element->isSVGElement())
+ return 0;
+
+ RenderObject* renderer = element->renderer();
+ if (!renderer)
+ return 0;
+
+ RenderSVGResource* renderResource = renderer->toRenderSVGResource();
+ if (!renderResource)
+ return 0;
+
+ return renderResource->cast<Renderer>();
+}
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceMasker.cpp b/WebCore/rendering/RenderSVGResourceMasker.cpp
new file mode 100644
index 0000000..2923c6e
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-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"
+#include "RenderSVGResourceMasker.h"
+
+#include "AffineTransform.h"
+#include "CanvasPixelArray.h"
+#include "Element.h"
+#include "FloatPoint.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "IntRect.h"
+#include "SVGElement.h"
+#include "SVGMaskElement.h"
+#include "SVGStyledElement.h"
+#include "SVGUnitTypes.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourceMasker::s_resourceType = MaskerResourceType;
+
+RenderSVGResourceMasker::RenderSVGResourceMasker(SVGStyledElement* node)
+ : RenderSVGResource(node)
+{
+}
+
+RenderSVGResourceMasker::~RenderSVGResourceMasker()
+{
+ deleteAllValues(m_masker);
+ m_masker.clear();
+}
+
+void RenderSVGResourceMasker::invalidateClients()
+{
+ HashMap<RenderObject*, MaskerData*>::const_iterator end = m_masker.end();
+ for (HashMap<RenderObject*, MaskerData*>::const_iterator it = m_masker.begin(); it != end; ++it)
+ it->first->setNeedsLayout(true);
+ deleteAllValues(m_masker);
+ m_masker.clear();
+}
+
+void RenderSVGResourceMasker::invalidateClient(RenderObject* object)
+{
+ ASSERT(object);
+
+ // FIXME: The HashMap should always contain the object on calling invalidateClient. A race condition
+ // during the parsing can causes a call of invalidateClient right before the call of applyResource.
+ // We return earlier for the moment. This bug should be fixed in:
+ // https://bugs.webkit.org/show_bug.cgi?id=35181
+ if (!m_masker.contains(object))
+ return;
+
+ delete m_masker.take(object);
+}
+
+bool RenderSVGResourceMasker::applyResource(RenderObject* object, GraphicsContext* context)
+{
+ ASSERT(object);
+ ASSERT(context);
+
+ if (!m_masker.contains(object))
+ m_masker.set(object, new MaskerData);
+
+ MaskerData* maskerData = m_masker.get(object);
+ if (!maskerData->maskImage && !maskerData->emptyMask) {
+ SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
+ if (!maskElement)
+ return false;
+
+ createMaskImage(maskerData, maskElement, object);
+ }
+
+ if (!maskerData->maskImage)
+ return false;
+
+ context->clipToImageBuffer(maskerData->maskRect, maskerData->maskImage.get());
+ return true;
+}
+
+FloatRect RenderSVGResourceMasker::resourceBoundingBox(const FloatRect& objectBoundingBox) const
+{
+ if (SVGMaskElement* element = static_cast<SVGMaskElement*>(node()))
+ return element->maskBoundingBox(objectBoundingBox);
+
+ return FloatRect();
+}
+
+void RenderSVGResourceMasker::createMaskImage(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;
+ }
+
+ // Calculate the smallest rect for the mask ImageBuffer.
+ FloatRect repaintRect;
+ Vector<RenderObject*> rendererList;
+ for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
+ RenderObject* renderer = node->renderer();
+ if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !renderer)
+ continue;
+
+ rendererList.append(renderer);
+ repaintRect.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
+ }
+
+ AffineTransform contextTransform;
+ // We need to scale repaintRect for objectBoundingBox to get the drawing area.
+ 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());
+
+ // Don't create ImageBuffers with image size of 0
+ if (!maskImageRect.width() || !maskImageRect.height()) {
+ maskerData->emptyMask = true;
+ return;
+ }
+
+ // 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
+ Vector<RenderObject*>::iterator end = rendererList.end();
+ for (Vector<RenderObject*>::iterator it = rendererList.begin(); it != end; it++)
+ renderSubtreeToImage(maskerData->maskImage.get(), *it);
+
+ maskImageContext->restore();
+
+ // create the luminance mask
+ RefPtr<ImageData> imageData(maskerData->maskImage->getUnmultipliedImageData(maskImageRect));
+ CanvasPixelArray* srcPixelArray(imageData->data());
+
+ for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset += 4) {
+ unsigned char a = srcPixelArray->get(pixelOffset + 3);
+ if (!a)
+ continue;
+ unsigned char r = srcPixelArray->get(pixelOffset);
+ unsigned char g = srcPixelArray->get(pixelOffset + 1);
+ unsigned char b = srcPixelArray->get(pixelOffset + 2);
+
+ double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0);
+ srcPixelArray->set(pixelOffset + 3, luma);
+ }
+
+ maskerData->maskImage->putUnmultipliedImageData(imageData.get(), maskImageRect, IntPoint());
+}
+
+}
diff --git a/WebCore/rendering/RenderSVGResourceMasker.h b/WebCore/rendering/RenderSVGResourceMasker.h
new file mode 100644
index 0000000..6c73c84
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceMasker.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-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.
+ *
+ */
+
+#ifndef RenderSVGResourceMasker_h
+#define RenderSVGResourceMasker_h
+
+#if ENABLE(SVG)
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "IntSize.h"
+#include "RenderSVGResource.h"
+#include "SVGMaskElement.h"
+#include "SVGUnitTypes.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+struct MaskerData {
+ MaskerData(FloatRect rect = FloatRect(), bool emptyObject = false)
+ : maskRect(rect)
+ , emptyMask(emptyObject)
+ {
+ }
+
+ OwnPtr<ImageBuffer> maskImage;
+ FloatRect maskRect;
+ bool emptyMask;
+};
+
+class RenderSVGResourceMasker : public RenderSVGResource {
+
+public:
+ RenderSVGResourceMasker(SVGStyledElement*);
+ virtual ~RenderSVGResourceMasker();
+
+ virtual const char* renderName() const { return "RenderSVGResourceMasker"; }
+
+ virtual void invalidateClients();
+ virtual void invalidateClient(RenderObject*);
+
+ virtual bool applyResource(RenderObject*, GraphicsContext*);
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const;
+
+ SVGUnitTypes::SVGUnitType maskUnits() const { return toUnitType(static_cast<SVGMaskElement*>(node())->maskUnits()); }
+ SVGUnitTypes::SVGUnitType maskContentUnits() const { return toUnitType(static_cast<SVGMaskElement*>(node())->maskContentUnits()); }
+
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
+
+private:
+ void createMaskImage(MaskerData*, const SVGMaskElement*, RenderObject*);
+
+ HashMap<RenderObject*, MaskerData*> m_masker;
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index 74172fc..51bf3e7 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -77,6 +77,28 @@ void RenderSVGRoot::calcPrefWidths()
setPrefWidthsDirty(false);
}
+int RenderSVGRoot::calcReplacedWidth(bool includeMaxWidth) const
+{
+ int replacedWidth = RenderBox::calcReplacedWidth(includeMaxWidth);
+ if (!style()->width().isPercent())
+ return replacedWidth;
+
+ // FIXME: Investigate in size rounding issues
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ return static_cast<int>(roundf(replacedWidth * svg->currentScale()));
+}
+
+int RenderSVGRoot::calcReplacedHeight() const
+{
+ int replacedHeight = RenderBox::calcReplacedHeight();
+ if (!style()->height().isPercent())
+ return replacedHeight;
+
+ // FIXME: Investigate in size rounding issues
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ return static_cast<int>(roundf(replacedHeight * svg->currentScale()));
+}
+
void RenderSVGRoot::layout()
{
ASSERT(needsLayout());
@@ -84,22 +106,19 @@ void RenderSVGRoot::layout()
// Arbitrary affine transforms are incompatible with LayoutState.
view()->disableLayoutState();
- LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
+ bool needsLayout = selfNeedsLayout();
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && needsLayout);
- int oldWidth = width();
+ IntSize oldSize(width(), height());
calcWidth();
-
- int oldHeight = height();
calcHeight();
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
- setWidth(static_cast<int>(width() * svg->currentScale()));
- setHeight(static_cast<int>(height() * svg->currentScale()));
calcViewport();
// RenderSVGRoot needs to take special care to propagate window size changes to the children,
// if the outermost <svg> is using relative x/y/width/height values. Hence the additonal parameters.
- layoutChildren(this, selfNeedsLayout() || (svg->hasRelativeValues() && (width() != oldWidth || height() != oldHeight)));
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ layoutChildren(this, needsLayout || (svg->hasRelativeValues() && oldSize != size()));
repainter.repaintAfterLayout();
view()->enableLayoutState();
@@ -123,7 +142,7 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
return;
IntPoint parentOriginInContainer(parentX, parentY);
- IntPoint borderBoxOriginInContainer = parentOriginInContainer + IntSize(x(), y());
+ IntPoint borderBoxOriginInContainer = parentOriginInContainer + parentOriginToBorderBox();
if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
paintBoxDecorations(paintInfo, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y());
@@ -166,6 +185,12 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
paintOutline(paintInfo.context, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y(), width(), height(), style());
}
+void RenderSVGRoot::destroy()
+{
+ deregisterFromResources(this);
+ RenderBox::destroy();
+}
+
void RenderSVGRoot::calcViewport()
{
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
@@ -177,15 +202,16 @@ void RenderSVGRoot::calcViewport()
// In the normal case of <svg> being stand-alone or in a CSSBoxModel object we use
// RenderBox::width()/height() (which pulls data from RenderStyle)
m_viewportSize = FloatSize(width(), height());
- } else {
- // In the SVGImage case grab the SVGLength values off of SVGSVGElement and use
- // the special relativeWidthValue accessors which respect the specified containerSize
- SVGLength width = svg->width();
- SVGLength height = svg->height();
- float viewportWidth = (width.unitType() == LengthTypePercentage) ? svg->relativeWidthValue() : width.value(svg);
- float viewportHeight = (height.unitType() == LengthTypePercentage) ? svg->relativeHeightValue() : height.value(svg);
- m_viewportSize = FloatSize(viewportWidth, viewportHeight);
+ return;
}
+
+ // In the SVGImage case grab the SVGLength values off of SVGSVGElement and use
+ // the special relativeWidthValue accessors which respect the specified containerSize
+ // FIXME: Check how SVGImage + zooming is supposed to be handled?
+ SVGLength width = svg->width();
+ SVGLength height = svg->height();
+ m_viewportSize = FloatSize(width.unitType() == LengthTypePercentage ? svg->relativeWidthValue() : width.value(svg),
+ height.unitType() == LengthTypePercentage ? svg->relativeHeightValue() : height.value(svg));
}
// RenderBox methods will expect coordinates w/o any transforms in coordinates
@@ -195,9 +221,9 @@ AffineTransform RenderSVGRoot::localToBorderBoxTransform() const
IntSize borderAndPadding = borderOriginToContentBox();
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
float scale = svg->currentScale();
- AffineTransform ctm(scale, 0, 0, scale, borderAndPadding.width(), borderAndPadding.height());
- ctm.translate(svg->currentTranslate().x(), svg->currentTranslate().y());
- return svg->viewBoxToViewTransform(width(), height()) * ctm;
+ FloatPoint translate = svg->currentTranslate();
+ AffineTransform ctm(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y());
+ return svg->viewBoxToViewTransform(width() / scale, height() / scale) * ctm;
}
IntSize RenderSVGRoot::parentOriginToBorderBox() const
diff --git a/WebCore/rendering/RenderSVGRoot.h b/WebCore/rendering/RenderSVGRoot.h
index 8ad5e40..53c1298 100644
--- a/WebCore/rendering/RenderSVGRoot.h
+++ b/WebCore/rendering/RenderSVGRoot.h
@@ -50,10 +50,13 @@ private:
virtual int lineHeight(bool b, bool isRootLineBox = false) const;
virtual int baselinePosition(bool b, bool isRootLineBox = false) const;
virtual void calcPrefWidths();
-
+ virtual int calcReplacedWidth(bool includeMaxWidth = true) const;
+ virtual int calcReplacedHeight() const;
virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
+ virtual void destroy();
+
virtual const AffineTransform& localToParentTransform() const;
bool fillContains(const FloatPoint&) const;
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp
index e332c85..b8b9553 100644
--- a/WebCore/rendering/RenderSVGText.cpp
+++ b/WebCore/rendering/RenderSVGText.cpp
@@ -108,6 +108,12 @@ bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResul
return false;
}
+void RenderSVGText::destroy()
+{
+ deregisterFromResources(this);
+ RenderSVGBlock::destroy();
+}
+
bool RenderSVGText::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
{
ASSERT_NOT_REACHED();
diff --git a/WebCore/rendering/RenderSVGText.h b/WebCore/rendering/RenderSVGText.h
index 9ae96a0..ab4b09b 100644
--- a/WebCore/rendering/RenderSVGText.h
+++ b/WebCore/rendering/RenderSVGText.h
@@ -53,6 +53,8 @@ private:
virtual bool requiresLayer() const { return false; }
virtual void layout();
+ virtual void destroy();
+
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index 7398a2f..344f4ab 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -107,7 +107,7 @@ double SliderRange::clampValue(double value)
double SliderRange::valueFromElement(HTMLInputElement* element, bool* wasClamped)
{
double oldValue;
- bool parseSuccess = HTMLInputElement::formStringToDouble(element->value(), &oldValue);
+ bool parseSuccess = HTMLInputElement::parseToDoubleForNumberType(element->value(), &oldValue);
if (!parseSuccess)
oldValue = (minimum + maximum) / 2;
double newValue = clampValue(oldValue);
@@ -383,7 +383,7 @@ void RenderSlider::updateFromElement()
bool clamped;
double value = range.valueFromElement(element, &clamped);
if (clamped)
- element->setValueFromRenderer(HTMLInputElement::formStringFromDouble(value));
+ element->setValueFromRenderer(HTMLInputElement::serializeForNumberType(value));
// Layout will take care of the thumb's size and position.
if (!m_thumb) {
@@ -439,7 +439,7 @@ void RenderSlider::setValueForPosition(int position)
if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart)
fraction = 1 - fraction;
double value = range.clampValue(range.valueFromProportion(fraction));
- element->setValueFromRenderer(HTMLInputElement::formStringFromDouble(value));
+ element->setValueFromRenderer(HTMLInputElement::serializeForNumberType(value));
// Also update the position if appropriate.
if (position != currentPosition()) {
diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp
index d97ae6e..de71796 100644
--- a/WebCore/rendering/RenderTableCell.cpp
+++ b/WebCore/rendering/RenderTableCell.cpp
@@ -168,11 +168,11 @@ void RenderTableCell::setOverrideSize(int size)
RenderBlock::setOverrideSize(size);
}
-IntSize RenderTableCell::offsetFromContainer(RenderObject* o) const
+IntSize RenderTableCell::offsetFromContainer(RenderObject* o, const IntPoint& point) const
{
ASSERT(o == container());
- IntSize offset = RenderBlock::offsetFromContainer(o);
+ IntSize offset = RenderBlock::offsetFromContainer(o, point);
if (parent())
offset.expand(-parentBox()->x(), -parentBox()->y());
diff --git a/WebCore/rendering/RenderTableCell.h b/WebCore/rendering/RenderTableCell.h
index 0f8580d..a5a1edd 100644
--- a/WebCore/rendering/RenderTableCell.h
+++ b/WebCore/rendering/RenderTableCell.h
@@ -126,7 +126,7 @@ private:
virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
virtual void paintMask(PaintInfo&, int tx, int ty);
- virtual IntSize offsetFromContainer(RenderObject*) const;
+ virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index 2e696a9..4653273 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -230,27 +230,32 @@ void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, u
start = min(start, static_cast<unsigned>(INT_MAX));
end = min(end, static_cast<unsigned>(INT_MAX));
- FloatPoint absPos = localToAbsolute(FloatPoint());
-
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
// Note: box->end() returns the index of the last character, not the index past it
if (start <= box->start() && box->end() < end) {
- IntRect r = IntRect(absPos.x() + box->x(), absPos.y() + box->y(), box->width(), box->height());
+ IntRect r = IntRect(box->x(), box->y(), box->width(), box->height());
if (useSelectionHeight) {
- IntRect selectionRect = box->selectionRect(absPos.x(), absPos.y(), start, end);
+ IntRect selectionRect = box->selectionRect(0, 0, start, end);
r.setHeight(selectionRect.height());
r.setY(selectionRect.y());
}
+ FloatPoint origin = localToAbsolute(r.location());
+ r.setX(origin.x());
+ r.setY(origin.y());
rects.append(r);
} else {
unsigned realEnd = min(box->end() + 1, end);
- IntRect r = box->selectionRect(absPos.x(), absPos.y(), start, realEnd);
+ IntRect r = box->selectionRect(0, 0, start, realEnd);
if (!r.isEmpty()) {
if (!useSelectionHeight) {
// change the height and y position because selectionRect uses selection-specific values
r.setHeight(box->height());
- r.setY(absPos.y() + box->y());
+ r.setY(box->y());
}
+ FloatPoint origin = localToAbsolute(r.location());
+ localToAbsolute(origin);
+ r.setX(origin.x());
+ r.setY(origin.y());
rects.append(r);
}
}
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index c0ba070..d18940b 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -459,6 +459,78 @@ IntRect RenderTextControl::controlClipRect(int tx, int ty) const
return clipRect;
}
+static const char* fontFamiliesWithInvalidCharWidth[] = {
+ "American Typewriter",
+ "Arial Hebrew",
+ "Chalkboard",
+ "Cochin",
+ "Corsiva Hebrew",
+ "Courier",
+ "Euphemia UCAS",
+ "Geneva",
+ "Gill Sans",
+ "Hei",
+ "Helvetica",
+ "Hoefler Text",
+ "InaiMathi",
+ "Kai",
+ "Lucida Grande",
+ "Marker Felt",
+ "Monaco",
+ "Mshtakan",
+ "New Peninim MT",
+ "Osaka",
+ "Raanana",
+ "STHeiti",
+ "Symbol",
+ "Times",
+ "Apple Braille",
+ "Apple LiGothic",
+ "Apple LiSung",
+ "Apple Symbols",
+ "AppleGothic",
+ "AppleMyungjo",
+ "#GungSeo",
+ "#HeadLineA",
+ "#PCMyungjo",
+ "#PilGi",
+};
+
+// For font families where any of the fonts don't have a valid entry in the OS/2 table
+// for avgCharWidth, fallback to the legacy webkit behavior of getting the avgCharWidth
+// from the width of a '0'. This only seems to apply to a fixed number of Mac fonts,
+// but, in order to get similar rendering across platforms, we do this check for
+// all platforms.
+bool RenderTextControl::hasValidAvgCharWidth(AtomicString family)
+{
+ static HashSet<AtomicString>* fontFamiliesWithInvalidCharWidthMap = 0;
+
+ if (!fontFamiliesWithInvalidCharWidthMap) {
+ fontFamiliesWithInvalidCharWidthMap = new HashSet<AtomicString>;
+
+ for (unsigned i = 0; i < sizeof(fontFamiliesWithInvalidCharWidth) / sizeof(fontFamiliesWithInvalidCharWidth[0]); i++)
+ fontFamiliesWithInvalidCharWidthMap->add(AtomicString(fontFamiliesWithInvalidCharWidth[i]));
+ }
+
+ return !fontFamiliesWithInvalidCharWidthMap->contains(family);
+}
+
+float RenderTextControl::getAvgCharWidth(AtomicString family)
+{
+ if (hasValidAvgCharWidth(family))
+ return roundf(style()->font().primaryFont()->avgCharWidth());
+
+ const UChar ch = '0';
+ return style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, false, false, false));
+}
+
+float RenderTextControl::scaleEmToUnits(int x) const
+{
+ // This matches the unitsPerEm value for MS Shell Dlg and Courier New from the "head" font table.
+ float unitsPerEm = 2048.0f;
+ return roundf(style()->font().size() * x / unitsPerEm);
+}
+
void RenderTextControl::calcPrefWidths()
{
ASSERT(prefWidthsDirty());
@@ -470,8 +542,8 @@ void RenderTextControl::calcPrefWidths()
m_minPrefWidth = m_maxPrefWidth = calcContentBoxWidth(style()->width().value());
else {
// Use average character width. Matches IE.
- float charWidth = style()->font().primaryFont()->avgCharWidth();
- m_maxPrefWidth = preferredContentWidth(charWidth) + m_innerText->renderBox()->paddingLeft() + m_innerText->renderBox()->paddingRight();
+ AtomicString family = style()->font().family().family();
+ m_maxPrefWidth = preferredContentWidth(getAvgCharWidth(family)) + m_innerText->renderBox()->paddingLeft() + m_innerText->renderBox()->paddingRight();
}
if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
diff --git a/WebCore/rendering/RenderTextControl.h b/WebCore/rendering/RenderTextControl.h
index d1f3749..2fc8edc 100644
--- a/WebCore/rendering/RenderTextControl.h
+++ b/WebCore/rendering/RenderTextControl.h
@@ -74,6 +74,10 @@ protected:
int textBlockWidth() const;
int textBlockHeight() const;
+ float scaleEmToUnits(int x) const;
+
+ static bool hasValidAvgCharWidth(AtomicString family);
+ virtual float getAvgCharWidth(AtomicString family);
virtual int preferredContentWidth(float charWidth) const = 0;
virtual void adjustControlHeightBasedOnLineHeight(int lineHeight) = 0;
virtual void cacheSelection(int start, int end) = 0;
diff --git a/WebCore/rendering/RenderTextControlMultiLine.cpp b/WebCore/rendering/RenderTextControlMultiLine.cpp
index 0b4c7a7..9fbde3a 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -80,6 +80,17 @@ void RenderTextControlMultiLine::forwardEvent(Event* event)
RenderTextControl::forwardEvent(event);
}
+float RenderTextControlMultiLine::getAvgCharWidth(AtomicString family)
+{
+ // Since Lucida Grande is the default font, we want this to match the width
+ // of Courier New, the default font for textareas in IE, Firefox and Safari Win.
+ // 1229 is the avgCharWidth value in the OS/2 table for Courier New.
+ if (family == AtomicString("Lucida Grande"))
+ return scaleEmToUnits(1229);
+
+ return RenderTextControl::getAvgCharWidth(family);
+}
+
int RenderTextControlMultiLine::preferredContentWidth(float charWidth) const
{
int factor = static_cast<HTMLTextAreaElement*>(node())->cols();
diff --git a/WebCore/rendering/RenderTextControlMultiLine.h b/WebCore/rendering/RenderTextControlMultiLine.h
index 3371a8f..fbca308 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.h
+++ b/WebCore/rendering/RenderTextControlMultiLine.h
@@ -40,6 +40,7 @@ private:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
+ virtual float getAvgCharWidth(AtomicString family);
virtual int preferredContentWidth(float charWidth) const;
virtual void adjustControlHeightBasedOnLineHeight(int lineHeight);
virtual int baselinePosition(bool firstLine, bool isRootLineBox) const;
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index b68f004..4edd203 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -385,7 +385,19 @@ int RenderTextControlSingleLine::textBlockWidth() const
return width;
}
+
+float RenderTextControlSingleLine::getAvgCharWidth(AtomicString family)
+{
+ // Since Lucida Grande is the default font, we want this to match the width
+ // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
+ // IE for some encodings (in IE, the default font is encoding specific).
+ // 901 is the avgCharWidth value in the OS/2 table for MS Shell Dlg.
+ if (family == AtomicString("Lucida Grande"))
+ return scaleEmToUnits(901);
+ return RenderTextControl::getAvgCharWidth(family);
+}
+
int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
{
int factor = inputElement()->size();
@@ -394,8 +406,20 @@ int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
int result = static_cast<int>(ceilf(charWidth * factor));
+ float maxCharWidth = 0.f;
+ AtomicString family = style()->font().family().family();
+ // Since Lucida Grande is the default font, we want this to match the width
+ // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
+ // IE for some encodings (in IE, the default font is encoding specific).
+ // 4027 is the (xMax - xMin) value in the "head" font table for MS Shell Dlg.
+ if (family == AtomicString("Lucida Grande"))
+ maxCharWidth = scaleEmToUnits(4027);
+ else if (hasValidAvgCharWidth(family))
+ maxCharWidth = roundf(style()->font().primaryFont()->maxCharWidth());
+
// For text inputs, IE adds some extra width.
- result += style()->font().primaryFont()->maxCharWidth() - charWidth;
+ if (maxCharWidth > 0.f)
+ result += maxCharWidth - charWidth;
if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0)
result += resultsRenderer->borderLeft() + resultsRenderer->borderRight() +
diff --git a/WebCore/rendering/RenderTextControlSingleLine.h b/WebCore/rendering/RenderTextControlSingleLine.h
index e30ff0d..aa1f1e3 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/WebCore/rendering/RenderTextControlSingleLine.h
@@ -75,6 +75,7 @@ private:
virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0);
int textBlockWidth() const;
+ virtual float getAvgCharWidth(AtomicString family);
virtual int preferredContentWidth(float charWidth) const;
virtual void adjustControlHeightBasedOnLineHeight(int lineHeight);
diff --git a/WebCore/rendering/RenderThemeChromiumMac.mm b/WebCore/rendering/RenderThemeChromiumMac.mm
index e274b05..03aab1c 100644
--- a/WebCore/rendering/RenderThemeChromiumMac.mm
+++ b/WebCore/rendering/RenderThemeChromiumMac.mm
@@ -572,7 +572,7 @@ FloatRect RenderThemeChromiumMac::convertToPaintingRect(const RenderObject* inpu
const RenderObject* renderer = partRenderer;
while (renderer && renderer != inputRenderer) {
RenderObject* containingRenderer = renderer->container();
- offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer);
+ offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer, IntPoint());
renderer = containingRenderer;
}
// If the input renderer was not a container, something went wrong
diff --git a/WebCore/rendering/RenderThemeMac.mm b/WebCore/rendering/RenderThemeMac.mm
index ddb538b..b6ce93d 100644
--- a/WebCore/rendering/RenderThemeMac.mm
+++ b/WebCore/rendering/RenderThemeMac.mm
@@ -520,7 +520,7 @@ FloatRect RenderThemeMac::convertToPaintingRect(const RenderObject* inputRendere
const RenderObject* renderer = partRenderer;
while (renderer && renderer != inputRenderer) {
RenderObject* containingRenderer = renderer->container();
- offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer);
+ offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer, IntPoint());
renderer = containingRenderer;
}
// If the input renderer was not a container, something went wrong
diff --git a/WebCore/rendering/RenderTreeAsText.cpp b/WebCore/rendering/RenderTreeAsText.cpp
index ca4d9d1..164a656 100644
--- a/WebCore/rendering/RenderTreeAsText.cpp
+++ b/WebCore/rendering/RenderTreeAsText.cpp
@@ -395,6 +395,10 @@ void write(TextStream& ts, const RenderObject& o, int indent)
write(ts, *toRenderPath(&o), indent);
return;
}
+ if (o.isSVGResource()) {
+ writeSVGResource(ts, o, indent);
+ return;
+ }
if (o.isSVGContainer()) {
writeSVGContainer(ts, o, indent);
return;
diff --git a/WebCore/rendering/RenderVideo.cpp b/WebCore/rendering/RenderVideo.cpp
index 813f2ef..13d6f60 100644
--- a/WebCore/rendering/RenderVideo.cpp
+++ b/WebCore/rendering/RenderVideo.cpp
@@ -275,14 +275,6 @@ void RenderVideo::acceleratedRenderingStateChanged()
if (p)
p->acceleratedRenderingStateChanged();
}
-
-GraphicsLayer* RenderVideo::videoGraphicsLayer() const
-{
- if (hasLayer() && layer()->isComposited())
- return layer()->backing()->graphicsLayer();
-
- return 0;
-}
#endif // USE(ACCELERATED_COMPOSITING)
} // namespace WebCore
diff --git a/WebCore/rendering/RenderVideo.h b/WebCore/rendering/RenderVideo.h
index 3ca5328..16c846d 100644
--- a/WebCore/rendering/RenderVideo.h
+++ b/WebCore/rendering/RenderVideo.h
@@ -34,9 +34,6 @@ namespace WebCore {
class HTMLMediaElement;
class HTMLVideoElement;
-#if USE(ACCELERATED_COMPOSITING)
-class GraphicsLayer;
-#endif
class RenderVideo : public RenderMedia {
public:
@@ -49,7 +46,6 @@ public:
#if USE(ACCELERATED_COMPOSITING)
bool supportsAcceleratedRendering() const;
void acceleratedRenderingStateChanged();
- GraphicsLayer* videoGraphicsLayer() const;
#endif
private:
diff --git a/WebCore/rendering/SVGCharacterLayoutInfo.h b/WebCore/rendering/SVGCharacterLayoutInfo.h
index f80c79c..f0d1fa4 100644
--- a/WebCore/rendering/SVGCharacterLayoutInfo.h
+++ b/WebCore/rendering/SVGCharacterLayoutInfo.h
@@ -297,13 +297,6 @@ struct SVGTextChunkWalkerBase {
// Followings methods are only used for painting text chunks
virtual void start(InlineBox*) = 0;
virtual void end(InlineBox*) = 0;
-
- virtual bool setupBackground(InlineBox*) = 0;
- virtual bool setupFill(InlineBox*) = 0;
- virtual bool setupFillSelection(InlineBox*) = 0;
- virtual bool setupStroke(InlineBox*) = 0;
- virtual bool setupStrokeSelection(InlineBox*) = 0;
- virtual bool setupForeground(InlineBox*) = 0;
};
template<typename CallbackClass>
@@ -319,31 +312,14 @@ public:
typedef void (CallbackClass::*SVGTextChunkStartCallback)(InlineBox* box);
typedef void (CallbackClass::*SVGTextChunkEndCallback)(InlineBox* box);
- typedef bool (CallbackClass::*SVGTextChunkSetupBackgroundCallback)(InlineBox* box);
- typedef bool (CallbackClass::*SVGTextChunkSetupFillCallback)(InlineBox* box);
- typedef bool (CallbackClass::*SVGTextChunkSetupStrokeCallback)(InlineBox* box);
- typedef bool (CallbackClass::*SVGTextChunkSetupForegroundCallback)(InlineBox* box);
-
- SVGTextChunkWalker(CallbackClass* object,
+ SVGTextChunkWalker(CallbackClass* object,
SVGTextChunkWalkerCallback walker,
SVGTextChunkStartCallback start = 0,
- SVGTextChunkEndCallback end = 0,
- SVGTextChunkSetupBackgroundCallback background = 0,
- SVGTextChunkSetupFillCallback fill = 0,
- SVGTextChunkSetupFillCallback fillSelection = 0,
- SVGTextChunkSetupStrokeCallback stroke = 0,
- SVGTextChunkSetupStrokeCallback strokeSelection = 0,
- SVGTextChunkSetupForegroundCallback foreground = 0)
+ SVGTextChunkEndCallback end = 0)
: m_object(object)
, m_walkerCallback(walker)
, m_startCallback(start)
, m_endCallback(end)
- , m_setupBackgroundCallback(background)
- , m_setupFillCallback(fill)
- , m_setupFillSelectionCallback(fillSelection)
- , m_setupStrokeCallback(stroke)
- , m_setupStrokeSelectionCallback(strokeSelection)
- , m_setupForegroundCallback(foreground)
{
ASSERT(object);
ASSERT(walker);
@@ -372,71 +348,11 @@ public:
ASSERT_NOT_REACHED();
}
- virtual bool setupBackground(InlineBox* box)
- {
- if (m_setupBackgroundCallback)
- return (*m_object.*m_setupBackgroundCallback)(box);
-
- ASSERT_NOT_REACHED();
- return false;
- }
-
- virtual bool setupFill(InlineBox* box)
- {
- if (m_setupFillCallback)
- return (*m_object.*m_setupFillCallback)(box);
-
- ASSERT_NOT_REACHED();
- return false;
- }
-
- virtual bool setupFillSelection(InlineBox* box)
- {
- if (m_setupFillSelectionCallback)
- return (*m_object.*m_setupFillSelectionCallback)(box);
-
- ASSERT_NOT_REACHED();
- return false;
- }
-
- virtual bool setupStroke(InlineBox* box)
- {
- if (m_setupStrokeCallback)
- return (*m_object.*m_setupStrokeCallback)(box);
-
- ASSERT_NOT_REACHED();
- return false;
- }
-
- virtual bool setupStrokeSelection(InlineBox* box)
- {
- if (m_setupStrokeSelectionCallback)
- return (*m_object.*m_setupStrokeSelectionCallback)(box);
-
- ASSERT_NOT_REACHED();
- return false;
- }
-
- virtual bool setupForeground(InlineBox* box)
- {
- if (m_setupForegroundCallback)
- return (*m_object.*m_setupForegroundCallback)(box);
-
- ASSERT_NOT_REACHED();
- return false;
- }
-
private:
CallbackClass* m_object;
SVGTextChunkWalkerCallback m_walkerCallback;
SVGTextChunkStartCallback m_startCallback;
SVGTextChunkEndCallback m_endCallback;
- SVGTextChunkSetupBackgroundCallback m_setupBackgroundCallback;
- SVGTextChunkSetupFillCallback m_setupFillCallback;
- SVGTextChunkSetupFillCallback m_setupFillSelectionCallback;
- SVGTextChunkSetupStrokeCallback m_setupStrokeCallback;
- SVGTextChunkSetupStrokeCallback m_setupStrokeSelectionCallback;
- SVGTextChunkSetupForegroundCallback m_setupForegroundCallback;
};
struct SVGTextChunkLayoutInfo {
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index 079a36e..dc1b3c1 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -28,13 +28,15 @@
#include "SVGRenderSupport.h"
#include "AffineTransform.h"
+#include "Document.h"
#include "ImageBuffer.h"
#include "RenderObject.h"
#include "RenderSVGContainer.h"
+#include "RenderSVGResource.h"
+#include "RenderSVGResourceMasker.h"
#include "RenderView.h"
#include "SVGResourceClipper.h"
#include "SVGResourceFilter.h"
-#include "SVGResourceMasker.h"
#include "SVGStyledElement.h"
#include "SVGURIReference.h"
#include "TransformState.h"
@@ -127,17 +129,14 @@ bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
filter = newFilter;
#endif
- SVGResourceClipper* clipper = getClipperById(document, clipperId, object);
- SVGResourceMasker* masker = getMaskerById(document, maskerId, object);
-
- if (masker) {
- masker->addClient(styledElement);
- if (!masker->applyMask(paintInfo.context, object))
+ // apply Masker
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, maskerId)) {
+ if (!masker->applyResource(object, paintInfo.context))
return false;
} else if (!maskerId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
- if (clipper) {
+ if (SVGResourceClipper* clipper = getClipperById(document, clipperId, object)) {
clipper->addClient(styledElement);
clipper->applyClip(paintInfo.context, object->objectBoundingBox());
} else if (!clipperId.isEmpty())
@@ -297,13 +296,19 @@ FloatRect SVGRenderBase::clipperBoundingBoxForRenderer(const RenderObject* objec
FloatRect SVGRenderBase::maskerBoundingBoxForRenderer(const RenderObject* object) const
{
- SVGResourceMasker* masker = getMaskerById(object->document(), object->style()->svgStyle()->maskElement(), object);
- if (masker)
- return masker->maskerBoundingBox(object->objectBoundingBox());
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskElement()))
+ return masker->resourceBoundingBox(object->objectBoundingBox());
return FloatRect();
}
+void SVGRenderBase::deregisterFromResources(RenderObject* object)
+{
+ // We only have a renderer for masker at the moment.
+ if (RenderSVGResourceMasker* resource = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskElement()))
+ resource->invalidateClient(object);
+}
+
void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const AffineTransform& localToAncestorTransform)
{
if (localToAncestorTransform.isIdentity())
diff --git a/WebCore/rendering/SVGRenderSupport.h b/WebCore/rendering/SVGRenderSupport.h
index cf75365..427ff1f 100644
--- a/WebCore/rendering/SVGRenderSupport.h
+++ b/WebCore/rendering/SVGRenderSupport.h
@@ -26,61 +26,65 @@
#if ENABLE(SVG)
#include "RenderObject.h"
+#include "SVGElement.h"
+#include "SVGStyledElement.h"
namespace WebCore {
- class SVGResourceFilter;
- class ImageBuffer;
+class SVGResourceFilter;
+class ImageBuffer;
- // SVGRendererBase is an abstract base class which all SVG renderers inherit
- // from in order to share SVG renderer code.
- // FIXME: This code can all move into RenderSVGModelObject once
- // all SVG renderers inherit from RenderSVGModelObject.
- class SVGRenderBase {
- public:
- virtual ~SVGRenderBase();
+// SVGRendererBase is an abstract base class which all SVG renderers inherit
+// from in order to share SVG renderer code.
+// FIXME: This code can all move into RenderSVGModelObject once
+// all SVG renderers inherit from RenderSVGModelObject.
+class SVGRenderBase {
+public:
+ virtual ~SVGRenderBase();
- virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
+ virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
- // 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, SVGResourceFilter*&, SVGResourceFilter* rootFilter = 0);
- static void finishRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, SVGResourceFilter*&, GraphicsContext* savedContext);
+ // 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, SVGResourceFilter*&, SVGResourceFilter* rootFilter = 0);
+ static void finishRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, SVGResourceFilter*&, GraphicsContext* savedContext);
- // Layout all children of the passed render object
- static void layoutChildren(RenderObject*, bool selfNeedsLayout);
+ // Layout all children of the passed render object
+ static void layoutChildren(RenderObject*, bool selfNeedsLayout);
- // Helper function determining wheter overflow is hidden
- static bool isOverflowHidden(const RenderObject*);
+ // Helper function determining wheter overflow is hidden
+ static bool isOverflowHidden(const RenderObject*);
- virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
- virtual FloatRect markerBoundingBox() const { return FloatRect(); }
+ virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
+ virtual FloatRect markerBoundingBox() 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;
+ // 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;
- protected:
- static IntRect clippedOverflowRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer);
- static void computeRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer, IntRect&, bool fixed);
+protected:
+ static IntRect clippedOverflowRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer);
+ static void computeRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer, IntRect&, bool fixed);
- static void mapLocalToContainer(const RenderObject*, RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&);
+ static void mapLocalToContainer(const RenderObject*, RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&);
- // Used to share the "walk all the children" logic between objectBoundingBox
- // and repaintRectInLocalCoordinates in RenderSVGRoot and RenderSVGContainer
- static FloatRect computeContainerBoundingBox(const RenderObject* container, bool includeAllPaintedContent);
- };
+ // Used to share the "walk all the children" logic between objectBoundingBox
+ // and repaintRectInLocalCoordinates in RenderSVGRoot and RenderSVGContainer
+ static FloatRect computeContainerBoundingBox(const RenderObject* container, bool includeAllPaintedContent);
- // FIXME: This should move to RenderObject or PaintInfo
- // Used for transforming the GraphicsContext and damage rect before passing PaintInfo to child renderers.
- void applyTransformToPaintInfo(RenderObject::PaintInfo&, const AffineTransform& localToChildTransform);
+ static void deregisterFromResources(RenderObject*);
+};
- // This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.
- void renderSubtreeToImage(ImageBuffer*, RenderObject*);
+// FIXME: This should move to RenderObject or PaintInfo
+// Used for transforming the GraphicsContext and damage rect before passing PaintInfo to child renderers.
+void applyTransformToPaintInfo(RenderObject::PaintInfo&, const AffineTransform& localToChildTransform);
- void clampImageBufferSizeToViewport(FrameView*, IntSize& imageBufferSize);
+// This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.
+void renderSubtreeToImage(ImageBuffer*, RenderObject*);
+
+void clampImageBufferSizeToViewport(FrameView*, IntSize& imageBufferSize);
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index aff718f..f892144 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -38,6 +38,7 @@
#include "RenderPath.h"
#include "RenderSVGContainer.h"
#include "RenderSVGInlineText.h"
+#include "RenderSVGResourceMasker.h"
#include "RenderSVGRoot.h"
#include "RenderSVGText.h"
#include "RenderTreeAsText.h"
@@ -195,6 +196,23 @@ TextStream& operator<<(TextStream& ts, const AffineTransform& transform)
return ts;
}
+static TextStream& operator<<(TextStream& ts, const SVGUnitTypes::SVGUnitType& unitType)
+{
+ switch (unitType) {
+ case SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN:
+ ts << "unknown";
+ break;
+ case SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE:
+ ts << "userSpaceOnUse";
+ break;
+ case SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX:
+ ts << "objectBoundingBox";
+ break;
+ }
+
+ return ts;
+}
+
TextStream& operator<<(TextStream& ts, const Color& c)
{
return ts << c.name();
@@ -464,11 +482,33 @@ static void writeChildren(TextStream& ts, const RenderObject& object, int indent
write(ts, *child, indent + 1);
}
+void writeSVGResource(TextStream& ts, const RenderObject& object, int indent)
+{
+ writeStandardPrefix(ts, object, indent);
+
+ Element* element = static_cast<Element*>(object.node());
+ const AtomicString& id = element->getIDAttribute();
+ writeNameAndQuotedValue(ts, "id", id);
+
+ RenderSVGResource* resource = const_cast<RenderObject&>(object).toRenderSVGResource();
+ if (resource->resourceType() == MaskerResourceType) {
+ RenderSVGResourceMasker* masker = static_cast<RenderSVGResourceMasker*>(resource);
+ ASSERT(masker);
+ writeNameValuePair(ts, "maskUnits", masker->maskUnits());
+ writeNameValuePair(ts, "maskContentUnits", masker->maskContentUnits());
+ }
+
+ // FIXME: Handle other RenderSVGResource* classes here, after converting them from SVGResource*.
+ ts << "\n";
+ writeChildren(ts, object, indent);
+}
+
void writeSVGContainer(TextStream& ts, const RenderObject& container, int indent)
{
writeStandardPrefix(ts, container, indent);
writePositionAndStyle(ts, container);
ts << "\n";
+ writeResources(ts, container, indent);
writeChildren(ts, container, indent);
}
@@ -484,6 +524,7 @@ void writeSVGText(TextStream& ts, const RenderBlock& text, int indent)
writeStandardPrefix(ts, text, indent);
writeRenderSVGTextBox(ts, text);
ts << "\n";
+ writeResources(ts, text, indent);
writeChildren(ts, text, indent);
}
@@ -493,20 +534,41 @@ void writeSVGInlineText(TextStream& ts, const RenderText& text, int indent)
// Why not just linesBoundingBox()?
ts << " " << FloatRect(text.firstRunOrigin(), text.linesBoundingBox().size()) << "\n";
+ writeResources(ts, text, indent);
writeSVGInlineTextBoxes(ts, text, indent);
}
+void writeSVGImage(TextStream& ts, const RenderImage& image, int indent)
+{
+ writeStandardPrefix(ts, image, indent);
+ writePositionAndStyle(ts, image);
+ ts << "\n";
+ writeResources(ts, image, indent);
+}
+
void write(TextStream& ts, const RenderPath& path, int indent)
{
writeStandardPrefix(ts, path, indent);
ts << path << "\n";
+ writeResources(ts, path, indent);
}
-void writeSVGImage(TextStream& ts, const RenderImage& image, int indent)
+void writeResources(TextStream& ts, const RenderObject& object, int indent)
{
- writeStandardPrefix(ts, image, indent);
- writePositionAndStyle(ts, image);
- ts << "\n";
+ const RenderStyle* style = object.style();
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+
+ if (!svgStyle->maskElement().isEmpty()) {
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskElement())) {
+ writeIndent(ts, indent);
+ ts << " ";
+ writeNameAndQuotedValue(ts, "masker", svgStyle->maskElement());
+ ts << " ";
+ writeStandardPrefix(ts, *masker, 0);
+ ts << " " << masker->resourceBoundingBox(object.objectBoundingBox()) << "\n";
+ }
+ }
+ // FIXME: Handle other RenderSVGResource* classes here, after converting them from SVGResource*.
}
void writeRenderResources(TextStream& ts, Node* parent)
diff --git a/WebCore/rendering/SVGRenderTreeAsText.h b/WebCore/rendering/SVGRenderTreeAsText.h
index 13fc475..905652b 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.h
+++ b/WebCore/rendering/SVGRenderTreeAsText.h
@@ -46,14 +46,17 @@ namespace WebCore {
class RenderSVGRoot;
class RenderText;
class AffineTransform;
+ class SVGUnitTypes;
// functions used by the main RenderTreeAsText code
void write(TextStream&, const RenderPath&, int indent);
void write(TextStream&, const RenderSVGRoot&, int indent);
+void writeSVGResource(TextStream&, const RenderObject&, int indent);
void writeSVGContainer(TextStream&, const RenderObject&, int indent);
void writeSVGImage(TextStream&, const RenderImage&, int indent);
void writeSVGInlineText(TextStream&, const RenderText&, int indent);
void writeSVGText(TextStream&, const RenderBlock&, int indent);
+void writeResources(TextStream&, const RenderObject&, int indent);
void writeRenderResources(TextStream&, Node* parent);
diff --git a/WebCore/rendering/SVGRootInlineBox.cpp b/WebCore/rendering/SVGRootInlineBox.cpp
index d0dd4a8..03b9db4 100644
--- a/WebCore/rendering/SVGRootInlineBox.cpp
+++ b/WebCore/rendering/SVGRootInlineBox.cpp
@@ -363,10 +363,10 @@ struct SVGRootInlineBoxPaintWalker {
ASSERT(!m_chunkStarted);
}
- bool mayHaveSelection(InlineBox* box) const
+ bool mayHaveSelection(SVGInlineTextBox* box) const
{
int selectionStart = 0, selectionEnd = 0;
- box->renderer()->selectionStartEnd(selectionStart, selectionEnd);
+ box->selectionStartEnd(selectionStart, selectionEnd);
return selectionStart < selectionEnd;
}
@@ -436,13 +436,13 @@ struct SVGRootInlineBoxPaintWalker {
m_paintInfo.rect = m_savedInfo.rect;
}
- bool chunkSetupBackgroundCallback(InlineBox* /*box*/)
+ bool setupBackground(SVGInlineTextBox* /*box*/)
{
m_textPaintInfo.subphase = SVGTextPaintSubphaseBackground;
return true;
}
- bool chunkSetupFillCallback(InlineBox* box)
+ bool setupFill(SVGInlineTextBox* box)
{
InlineFlowBox* flowBox = box->parent();
@@ -464,7 +464,7 @@ struct SVGRootInlineBoxPaintWalker {
return false;
}
- bool chunkSetupFillSelectionCallback(InlineBox* box)
+ bool setupFillSelection(SVGInlineTextBox* box)
{
InlineFlowBox* flowBox = box->parent();
@@ -492,7 +492,7 @@ struct SVGRootInlineBoxPaintWalker {
return false;
}
- bool chunkSetupStrokeCallback(InlineBox* box)
+ bool setupStroke(SVGInlineTextBox* box)
{
InlineFlowBox* flowBox = box->parent();
@@ -516,7 +516,7 @@ struct SVGRootInlineBoxPaintWalker {
return false;
}
- bool chunkSetupStrokeSelectionCallback(InlineBox* box)
+ bool setupStrokeSelection(SVGInlineTextBox* box)
{
InlineFlowBox* flowBox = box->parent();
@@ -545,7 +545,7 @@ struct SVGRootInlineBoxPaintWalker {
return false;
}
- bool chunkSetupForegroundCallback(InlineBox* /*box*/)
+ bool setupForeground(SVGInlineTextBox* /*box*/)
{
teardownFillPaintServer();
teardownStrokePaintServer();
@@ -576,6 +576,28 @@ struct SVGRootInlineBoxPaintWalker {
void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
+ if (setupBackground(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupFill(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupFillSelection(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupStroke(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupStrokeSelection(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupForeground(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+ }
+
+ void paintChunk(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
+ const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
+ {
RenderText* text = textBox->textRenderer();
ASSERT(text);
@@ -679,13 +701,7 @@ void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
SVGTextChunkWalker<SVGRootInlineBoxPaintWalker> walker(&walkerCallback,
&SVGRootInlineBoxPaintWalker::chunkPortionCallback,
&SVGRootInlineBoxPaintWalker::chunkStartCallback,
- &SVGRootInlineBoxPaintWalker::chunkEndCallback,
- &SVGRootInlineBoxPaintWalker::chunkSetupBackgroundCallback,
- &SVGRootInlineBoxPaintWalker::chunkSetupFillCallback,
- &SVGRootInlineBoxPaintWalker::chunkSetupFillSelectionCallback,
- &SVGRootInlineBoxPaintWalker::chunkSetupStrokeCallback,
- &SVGRootInlineBoxPaintWalker::chunkSetupStrokeSelectionCallback,
- &SVGRootInlineBoxPaintWalker::chunkSetupForegroundCallback);
+ &SVGRootInlineBoxPaintWalker::chunkEndCallback);
walkTextChunks(&walker);
}
@@ -1777,28 +1793,7 @@ void SVGRootInlineBox::walkTextChunks(SVGTextChunkWalkerBase* walker, const SVGI
ASSERT(itCharEnd <= curChunk.end);
// Process this chunk portion
- if (textBox)
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
- else {
- if (walker->setupBackground(range.box))
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
-
- if (walker->setupFill(range.box))
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
-
- if (walker->setupFillSelection(range.box))
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
-
- if (walker->setupStroke(range.box))
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
-
- if (walker->setupStrokeSelection(range.box))
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
-
- if (walker->setupForeground(range.box))
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
-
- }
+ (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
chunkOffset += length;
diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp
index 0952557..712344f 100644
--- a/WebCore/rendering/style/RenderStyle.cpp
+++ b/WebCore/rendering/style/RenderStyle.cpp
@@ -192,6 +192,11 @@ static inline int pseudoBit(PseudoId pseudo)
return 1 << (pseudo - 1);
}
+bool RenderStyle::hasAnyPublicPseudoStyles() const
+{
+ return PUBLIC_PSEUDOID_MASK & noninherited_flags._pseudoBits;
+}
+
bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const
{
ASSERT(pseudo > NOPSEUDO);
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index 696a2b7..c7db254 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -350,6 +350,7 @@ public:
bool isStyleAvailable() const;
+ bool hasAnyPublicPseudoStyles() const;
bool hasPseudoStyle(PseudoId pseudo) const;
void setHasPseudoStyle(PseudoId pseudo);
diff --git a/WebCore/rendering/style/RenderStyleConstants.h b/WebCore/rendering/style/RenderStyleConstants.h
index 01862f6..4abbc1c 100644
--- a/WebCore/rendering/style/RenderStyleConstants.h
+++ b/WebCore/rendering/style/RenderStyleConstants.h
@@ -66,6 +66,7 @@ enum StyleDifferenceContextSensitiveProperty {
// Static pseudo styles. Dynamic ones are produced on the fly.
enum PseudoId {
+ // The order must be NOP ID, public IDs, and then internal IDs.
NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR, FILE_UPLOAD_BUTTON, INPUT_PLACEHOLDER,
SLIDER_THUMB, SEARCH_CANCEL_BUTTON, SEARCH_DECORATION, SEARCH_RESULTS_DECORATION, SEARCH_RESULTS_BUTTON, MEDIA_CONTROLS_PANEL,
MEDIA_CONTROLS_PLAY_BUTTON, MEDIA_CONTROLS_MUTE_BUTTON, MEDIA_CONTROLS_TIMELINE, MEDIA_CONTROLS_TIMELINE_CONTAINER,
@@ -75,7 +76,9 @@ enum PseudoId {
MEDIA_CONTROLS_STATUS_DISPLAY, SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
INPUT_LIST_BUTTON, INNER_SPIN_BUTTON, OUTER_SPIN_BUTTON,
- FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON
+ FIRST_PUBLIC_PSEUDOID = FIRST_LINE,
+ FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON,
+ PUBLIC_PSEUDOID_MASK = ((1 << FIRST_INTERNAL_PSEUDOID) - 1) & ~((1 << FIRST_PUBLIC_PSEUDOID) - 1)
};
// These have been defined in the order of their precedence for border-collapsing. Do