summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/AutoTableLayout.cpp2
-rw-r--r--WebCore/rendering/FixedTableLayout.cpp2
-rw-r--r--WebCore/rendering/InlineFlowBox.cpp10
-rw-r--r--WebCore/rendering/InlineTextBox.cpp24
-rw-r--r--WebCore/rendering/MediaControlElements.cpp16
-rw-r--r--WebCore/rendering/RenderBlock.cpp31
-rw-r--r--WebCore/rendering/RenderBlockLineLayout.cpp4
-rw-r--r--WebCore/rendering/RenderBox.cpp8
-rw-r--r--WebCore/rendering/RenderBox.h4
-rw-r--r--WebCore/rendering/RenderBoxModelObject.cpp23
-rw-r--r--WebCore/rendering/RenderEmbeddedObject.cpp331
-rw-r--r--WebCore/rendering/RenderEmbeddedObject.h4
-rw-r--r--WebCore/rendering/RenderForeignObject.cpp10
-rw-r--r--WebCore/rendering/RenderImage.cpp100
-rw-r--r--WebCore/rendering/RenderImage.h39
-rw-r--r--WebCore/rendering/RenderImageGeneratedContent.cpp53
-rw-r--r--WebCore/rendering/RenderImageGeneratedContent.h64
-rw-r--r--WebCore/rendering/RenderImageResource.cpp106
-rw-r--r--WebCore/rendering/RenderImageResource.h79
-rw-r--r--WebCore/rendering/RenderImageResourceStyleImage.cpp63
-rw-r--r--WebCore/rendering/RenderImageResourceStyleImage.h68
-rw-r--r--WebCore/rendering/RenderLayer.cpp10
-rw-r--r--WebCore/rendering/RenderLayer.h2
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp12
-rw-r--r--WebCore/rendering/RenderLayerCompositor.h1
-rw-r--r--WebCore/rendering/RenderListBox.h2
-rw-r--r--WebCore/rendering/RenderListItem.cpp3
-rw-r--r--WebCore/rendering/RenderListMarker.cpp61
-rw-r--r--WebCore/rendering/RenderMedia.cpp2
-rw-r--r--WebCore/rendering/RenderObject.cpp45
-rw-r--r--WebCore/rendering/RenderObject.h11
-rw-r--r--WebCore/rendering/RenderObjectChildList.cpp14
-rw-r--r--WebCore/rendering/RenderPath.cpp23
-rw-r--r--WebCore/rendering/RenderPath.h3
-rw-r--r--WebCore/rendering/RenderRuby.cpp13
-rw-r--r--WebCore/rendering/RenderSVGBlock.cpp7
-rw-r--r--WebCore/rendering/RenderSVGBlock.h1
-rw-r--r--WebCore/rendering/RenderSVGContainer.cpp38
-rw-r--r--WebCore/rendering/RenderSVGContainer.h14
-rw-r--r--WebCore/rendering/RenderSVGGradientStop.h1
-rw-r--r--WebCore/rendering/RenderSVGHiddenContainer.cpp15
-rw-r--r--WebCore/rendering/RenderSVGHiddenContainer.h5
-rw-r--r--WebCore/rendering/RenderSVGImage.cpp128
-rw-r--r--WebCore/rendering/RenderSVGImage.h25
-rw-r--r--WebCore/rendering/RenderSVGInline.cpp7
-rw-r--r--WebCore/rendering/RenderSVGInline.h1
-rw-r--r--WebCore/rendering/RenderSVGModelObject.cpp7
-rw-r--r--WebCore/rendering/RenderSVGModelObject.h3
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.cpp11
-rw-r--r--WebCore/rendering/RenderSVGRoot.cpp49
-rw-r--r--WebCore/rendering/RenderSVGRoot.h14
-rw-r--r--WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp2
-rw-r--r--WebCore/rendering/RenderSVGText.cpp14
-rw-r--r--WebCore/rendering/RenderSVGTransformableContainer.cpp7
-rw-r--r--WebCore/rendering/RenderSVGTransformableContainer.h2
-rw-r--r--WebCore/rendering/RenderSVGViewportContainer.cpp5
-rw-r--r--WebCore/rendering/RenderScrollbar.cpp9
-rw-r--r--WebCore/rendering/RenderTable.cpp2
-rw-r--r--WebCore/rendering/RenderTableSection.cpp2
-rw-r--r--WebCore/rendering/RenderTextControl.cpp16
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.h2
-rw-r--r--WebCore/rendering/RenderTheme.cpp2
-rw-r--r--WebCore/rendering/RenderVideo.cpp2
-rw-r--r--WebCore/rendering/RootInlineBox.cpp14
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp79
-rw-r--r--WebCore/rendering/SVGRenderSupport.h11
-rw-r--r--WebCore/rendering/SVGResources.h2
-rw-r--r--WebCore/rendering/SVGResourcesCache.cpp4
-rw-r--r--WebCore/rendering/SVGShadowTreeElements.cpp13
-rw-r--r--WebCore/rendering/SVGShadowTreeElements.h23
-rw-r--r--WebCore/rendering/style/BorderData.h32
-rw-r--r--WebCore/rendering/style/ContentData.cpp65
-rw-r--r--WebCore/rendering/style/ContentData.h46
-rw-r--r--WebCore/rendering/style/CursorData.h11
-rw-r--r--WebCore/rendering/style/CursorList.h1
-rw-r--r--WebCore/rendering/style/KeyframeList.cpp47
-rw-r--r--WebCore/rendering/style/KeyframeList.h27
-rw-r--r--WebCore/rendering/style/RenderStyle.cpp117
-rw-r--r--WebCore/rendering/style/RenderStyle.h49
-rw-r--r--WebCore/rendering/style/RenderStyleConstants.h3
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.cpp50
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.h4
-rw-r--r--WebCore/rendering/style/ShadowData.cpp46
-rw-r--r--WebCore/rendering/style/ShadowData.h6
-rw-r--r--WebCore/rendering/style/StyleCachedImage.cpp2
-rw-r--r--WebCore/rendering/style/StyleCachedImage.h2
-rw-r--r--WebCore/rendering/style/StyleGeneratedImage.cpp2
-rw-r--r--WebCore/rendering/style/StyleGeneratedImage.h2
-rw-r--r--WebCore/rendering/style/StyleImage.h9
-rw-r--r--WebCore/rendering/style/StylePendingImage.h71
90 files changed, 1388 insertions, 984 deletions
diff --git a/WebCore/rendering/AutoTableLayout.cpp b/WebCore/rendering/AutoTableLayout.cpp
index ea8b416..d9233a2 100644
--- a/WebCore/rendering/AutoTableLayout.cpp
+++ b/WebCore/rendering/AutoTableLayout.cpp
@@ -140,7 +140,7 @@ void AutoTableLayout::recalcColumn(int effCol)
// Nav/IE weirdness
if (l.width.isFixed()) {
- if (m_table->style()->htmlHacks() && l.maxWidth > l.width.value() && fixedContributor != maxContributor) {
+ if (m_table->document()->inQuirksMode() && l.maxWidth > l.width.value() && fixedContributor != maxContributor) {
l.width = Length();
fixedContributor = 0;
}
diff --git a/WebCore/rendering/FixedTableLayout.cpp b/WebCore/rendering/FixedTableLayout.cpp
index 4d6b88c..b5ff971 100644
--- a/WebCore/rendering/FixedTableLayout.cpp
+++ b/WebCore/rendering/FixedTableLayout.cpp
@@ -223,7 +223,7 @@ void FixedTableLayout::calcPrefWidths(int& minWidth, int& maxWidth)
// In this example, the two inner tables should be as large as the outer table.
// We can achieve this effect by making the maxwidth of fixed tables with percentage
// widths be infinite.
- if (m_table->style()->htmlHacks() && m_table->style()->width().isPercent()
+ if (m_table->document()->inQuirksMode() && m_table->style()->width().isPercent()
&& maxWidth < TABLE_MAX_WIDTH)
maxWidth = TABLE_MAX_WIDTH;
}
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index dfe7561..a71b796 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -761,8 +761,8 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
int h = height();
// Constrain our background/border painting to the line top and bottom if necessary.
- bool strictMode = renderer()->document()->inStrictMode();
- if (!hasTextChildren() && !strictMode) {
+ bool noQuirksMode = renderer()->document()->inNoQuirksMode();
+ if (!hasTextChildren() && !noQuirksMode) {
RootInlineBox* rootBox = root();
int bottom = min(rootBox->lineBottom(), y + h);
y = max(rootBox->lineTop(), y);
@@ -837,8 +837,8 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, int tx, int ty)
int h = height();
// Constrain our background/border painting to the line top and bottom if necessary.
- bool strictMode = renderer()->document()->inStrictMode();
- if (!hasTextChildren() && !strictMode) {
+ bool noQuirksMode = renderer()->document()->inNoQuirksMode();
+ if (!hasTextChildren() && !noQuirksMode) {
RootInlineBox* rootBox = root();
int bottom = min(rootBox->lineBottom(), y + h);
y = max(rootBox->lineTop(), y);
@@ -922,7 +922,7 @@ void InlineFlowBox::paintTextDecorations(PaintInfo& paintInfo, int tx, int ty, b
{
// Paint text decorations like underlines/overlines. We only do this if we aren't in quirks mode (i.e., in
// almost-strict mode or strict mode).
- if (renderer()->style()->htmlHacks() || !paintInfo.shouldPaintWithinRoot(renderer()) ||
+ if (renderer()->document()->inQuirksMode() || !paintInfo.shouldPaintWithinRoot(renderer()) ||
renderer()->style()->visibility() != VISIBLE)
return;
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index cb4fdb8..c74fe1e 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -547,7 +547,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
}
// Paint decorations
- if (d != TDNONE && paintInfo.phase != PaintPhaseSelection && styleToUse->htmlHacks()) {
+ if (d != TDNONE && paintInfo.phase != PaintPhaseSelection && renderer()->document()->inQuirksMode()) {
context->setStrokeColor(styleToUse->visitedDependentColor(CSSPropertyColor), styleToUse->colorSpace());
paintDecoration(context, tx, ty, d, textShadow);
}
@@ -768,6 +768,21 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
context->clearShadow();
}
+static GraphicsContext::TextCheckingLineStyle textCheckingLineStyleForMarkerType(DocumentMarker::MarkerType markerType)
+{
+ switch (markerType) {
+ case DocumentMarker::Spelling:
+ return GraphicsContext::TextCheckingSpellingLineStyle;
+ case DocumentMarker::Grammar:
+ return GraphicsContext::TextCheckingGrammarLineStyle;
+ case DocumentMarker::Replacement:
+ return GraphicsContext::TextCheckingReplacementLineStyle;
+ default:
+ ASSERT_NOT_REACHED();
+ return GraphicsContext::TextCheckingSpellingLineStyle;
+ }
+}
+
void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
{
// Never print spelling/grammar markers (5327887)
@@ -831,7 +846,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
// In larger fonts, though, place the underline up near the baseline to prevent a big gap.
underlineOffset = baseline + 2;
}
- pt->drawLineForMisspellingOrBadGrammar(IntPoint(tx + m_x + start, ty + m_y + underlineOffset), width, grammar);
+ pt->drawLineForTextChecking(IntPoint(tx + m_x + start, ty + m_y + underlineOffset), width, textCheckingLineStyleForMarkerType(marker.type));
}
void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font)
@@ -898,10 +913,10 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, Re
case DocumentMarker::Grammar:
case DocumentMarker::Spelling:
case DocumentMarker::Replacement:
+ case DocumentMarker::RejectedCorrection:
if (background)
continue;
break;
-
case DocumentMarker::TextMatch:
if (!background)
continue;
@@ -933,6 +948,9 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, Re
break;
case DocumentMarker::Replacement:
computeRectForReplacementMarker(tx, ty, marker, style, font);
+ paintSpellingOrGrammarMarker(pt, tx, ty, marker, style, font, false);
+ break;
+ case DocumentMarker::RejectedCorrection:
break;
default:
ASSERT_NOT_REACHED();
diff --git a/WebCore/rendering/MediaControlElements.cpp b/WebCore/rendering/MediaControlElements.cpp
index 3fb712f..aaeb3e2 100644
--- a/WebCore/rendering/MediaControlElements.cpp
+++ b/WebCore/rendering/MediaControlElements.cpp
@@ -42,6 +42,7 @@
#include "RenderMedia.h"
#include "RenderSlider.h"
#include "RenderTheme.h"
+#include "Settings.h"
namespace WebCore {
@@ -780,7 +781,20 @@ PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElem
void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == eventNames().clickEvent) {
- mediaElement()->enterFullscreen();
+#if ENABLE(FULLSCREEN_API)
+ // Only use the new full screen API if the fullScreenEnabled setting has
+ // been explicitly enabled. Otherwise, use the old fullscreen API. This
+ // allows apps which embed a WebView to retain the existing full screen
+ // video implementation without requiring them to implement their own full
+ // screen behavior.
+ if (document()->settings() && document()->settings()->fullScreenEnabled()) {
+ if (document()->webkitFullScreen() && document()->webkitCurrentFullScreenElement() == mediaElement())
+ document()->webkitCancelFullScreen();
+ else
+ mediaElement()->webkitRequestFullScreen(0);
+ } else
+#endif
+ mediaElement()->enterFullscreen();
event->setDefaultHandled();
}
HTMLInputElement::defaultEventHandler(event);
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 28d7914..d66336d 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -1042,7 +1042,7 @@ bool RenderBlock::isSelfCollapsingBlock() const
return false;
bool hasAutoHeight = style()->height().isAuto();
- if (style()->height().isPercent() && !style()->htmlHacks()) {
+ if (style()->height().isPercent() && !document()->inQuirksMode()) {
hasAutoHeight = true;
for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
if (cb->style()->height().isFixed() || cb->isTableCell())
@@ -1478,7 +1478,7 @@ int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
// This child is collapsing with the top of the
// block. If it has larger margin values, then we need to update
// our own maximal values.
- if (!style()->htmlHacks() || !marginInfo.quirkContainer() || !topQuirk)
+ if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
setMaxTopMargins(max(posTop, maxTopPosMargin()), max(negTop, maxTopNegMargin()));
// The minute any of the margins involved isn't a quirk, don't
@@ -1530,7 +1530,7 @@ int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
}
else if (!marginInfo.atTopOfBlock() ||
(!marginInfo.canCollapseTopWithChildren()
- && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.topQuirk()))) {
+ && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.topQuirk()))) {
// We're collapsing with a previous sibling's margins and not
// with the top of the block.
setHeight(height() + max(marginInfo.posMargin(), posTop) - max(marginInfo.negMargin(), negTop));
@@ -1683,7 +1683,7 @@ void RenderBlock::handleBottomOfBlock(int top, int bottom, MarginInfo& marginInf
// If we can't collapse with children then go ahead and add in the bottom margin.
if (!marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()
- && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.bottomQuirk()))
+ && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.bottomQuirk()))
setHeight(height() + marginInfo.margin());
// Now add in our bottom border/padding.
@@ -2120,8 +2120,12 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
PaintInfo info(paintInfo);
info.phase = newPhase;
info.updatePaintingRootForChildren(this);
+
+ RenderView* renderView = view();
+ bool usePrintRect = !renderView->printRect().isEmpty() && !document()->settings()->paginateDuringLayoutEnabled();
+
bool checkPageBreaks = document()->paginated() && !document()->settings()->paginateDuringLayoutEnabled();
- bool checkColumnBreaks = !checkPageBreaks && !view()->printRect().isEmpty() && !document()->settings()->paginateDuringLayoutEnabled();
+ bool checkColumnBreaks = !checkPageBreaks && usePrintRect;
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
// Check for page-break-before: always, and if it's set, break and bail.
@@ -2133,6 +2137,17 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
return;
}
+ if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) {
+ // Paginate block-level replaced elements.
+ if (ty + child->y() + child->height() > renderView->printRect().bottom()) {
+ if (ty + child->y() < renderView->truncatedAt())
+ renderView->setBestTruncatedAt(ty + child->y(), child);
+ // If we were able to truncate, don't paint.
+ if (ty + child->y() >= renderView->truncatedAt())
+ break;
+ }
+ }
+
if (!child->hasSelfPaintingLayer() && !child->isFloating())
child->paint(info, tx, ty);
@@ -3529,7 +3544,7 @@ void RenderBlock::clearFloats()
int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bool makeChildPaintOtherFloats)
{
// Prevent floats from being added to the canvas by the root element, e.g., <html>.
- if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot())
+ if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns())
return 0;
int lowestFloatBottom = 0;
@@ -4593,7 +4608,7 @@ void RenderBlock::calcInlinePrefWidths()
// Firefox and Opera will allow a table cell to grow to fit an image inside it under
// very specific cirucumstances (in order to match common WinIE renderings).
// Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
- bool allowImagesToBreak = !style()->htmlHacks() || !isTableCell() || !style()->width().isIntrinsicOrAuto();
+ bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->width().isIntrinsicOrAuto();
bool autoWrap, oldAutoWrap;
autoWrap = oldAutoWrap = style()->autoWrap();
@@ -4922,7 +4937,7 @@ void RenderBlock::calcBlockPrefWidths()
// of 100px because of the table.
// We can achieve this effect by making the maxwidth of blocks that contain tables
// with percentage widths be infinite (as long as they are not inside a table cell).
- if (style()->htmlHacks() && child->style()->width().isPercent() &&
+ if (document()->inQuirksMode() && child->style()->width().isPercent() &&
!isTableCell() && child->isTable() && m_maxPrefWidth < BLOCK_MAX_WIDTH) {
RenderBlock* cb = containingBlock();
while (!cb->isRenderView() && !cb->isTableCell())
diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp
index 7cb1597..d703fb2 100644
--- a/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -194,7 +194,7 @@ static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRo
// We only treat a box as text for a <br> if we are on a line by ourself or in strict mode
// (Note the use of strict mode. In "almost strict" mode, we don't treat the box for <br> as text.)
if (obj->isBR())
- textBox->setIsText(isOnlyRun || obj->document()->inStrictMode());
+ textBox->setIsText(isOnlyRun || obj->document()->inNoQuirksMode());
return textBox;
}
@@ -1518,7 +1518,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
// Firefox and Opera will allow a table cell to grow to fit an image inside it under
// very specific circumstances (in order to match common WinIE renderings).
// Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
- bool allowImagesToBreak = !style()->htmlHacks() || !isTableCell() || !style()->width().isIntrinsicOrAuto();
+ bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->width().isIntrinsicOrAuto();
EWhiteSpace currWS = style()->whiteSpace();
EWhiteSpace lastWS = currWS;
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index d614081..e107c4f 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -1619,7 +1619,7 @@ int RenderBox::calcPercentageHeight(const Length& height)
int result = -1;
bool skippedAutoHeightContainingBlock = false;
RenderBlock* cb = containingBlock();
- if (style()->htmlHacks()) {
+ if (document()->inQuirksMode()) {
// In quirks mode, blocks with auto height are skipped, and we keep looking for an enclosing
// block that may have a specified height and then use it. In strict mode, this violates the
// specification, which states that percentage heights just revert to auto if the containing
@@ -1668,7 +1668,7 @@ int RenderBox::calcPercentageHeight(const Length& height)
result = cb->calcPercentageHeight(cb->style()->height());
if (result != -1)
result = cb->calcContentBoxHeight(result);
- } else if (cb->isRenderView() || (cb->isBody() && style()->htmlHacks()) || isPositionedWithSpecifiedHeight) {
+ } else if (cb->isRenderView() || (cb->isBody() && document()->inQuirksMode()) || isPositionedWithSpecifiedHeight) {
// Don't allow this to affect the block' height() member variable, since this
// can get called while the block is still laying out its kids.
int oldHeight = cb->height();
@@ -1901,7 +1901,7 @@ void RenderBox::calcAbsoluteHorizontal()
// To match WinIE, in quirks mode use the parent's 'direction' property
// instead of the the container block's.
- TextDirection containerDirection = (style()->htmlHacks()) ? parent()->style()->direction() : containerBlock->style()->direction();
+ TextDirection containerDirection = (document()->inQuirksMode()) ? parent()->style()->direction() : containerBlock->style()->direction();
const int bordersPlusPadding = borderAndPaddingWidth();
const Length marginLeft = style()->marginLeft();
@@ -2437,7 +2437,7 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
// To match WinIE, in quirks mode use the parent's 'direction' property
// instead of the the container block's.
- TextDirection containerDirection = (style()->htmlHacks()) ? parent()->style()->direction() : containerBlock->style()->direction();
+ TextDirection containerDirection = (document()->inQuirksMode()) ? parent()->style()->direction() : containerBlock->style()->direction();
// Variables to solve.
Length left = style()->left();
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index e02f77a..8f1e9c3 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -217,7 +217,7 @@ public:
bool stretchesToViewHeight() const
{
- return style()->htmlHacks() && style()->height().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody());
+ return document()->inQuirksMode() && style()->height().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody());
}
virtual IntSize intrinsicSize() const { return IntSize(); }
@@ -246,7 +246,7 @@ public:
virtual int verticalScrollbarWidth() const;
int horizontalScrollbarHeight() const;
- virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0);
+ virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1, Node** stopNode = 0);
bool canBeScrolledAndHasScrollableArea() const;
virtual bool canBeProgramaticallyScrolled(bool) const;
virtual void autoscroll();
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index 78618d1..0fbc9f2 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -337,10 +337,25 @@ int RenderBoxModelObject::relativePositionOffsetX() const
int RenderBoxModelObject::relativePositionOffsetY() const
{
- if (!style()->top().isAuto())
- return style()->top().calcValue(containingBlock()->availableHeight());
- else if (!style()->bottom().isAuto())
- return -style()->bottom().calcValue(containingBlock()->availableHeight());
+ RenderBlock* containingBlock = this->containingBlock();
+
+ // If the containing block of a relatively positioned element does not
+ // specify a height, a percentage top or bottom offset should be resolved as
+ // auto. An exception to this is if the containing block has the WinIE quirk
+ // where <html> and <body> assume the size of the viewport. In this case,
+ // calculate the percent offset based on this height.
+ // See <https://bugs.webkit.org/show_bug.cgi?id=26396>.
+ if (!style()->top().isAuto()
+ && (!containingBlock->style()->height().isAuto()
+ || !style()->top().isPercent()
+ || containingBlock->stretchesToViewHeight()))
+ return style()->top().calcValue(containingBlock->availableHeight());
+
+ if (!style()->bottom().isAuto()
+ && (!containingBlock->style()->height().isAuto()
+ || !style()->bottom().isPercent()
+ || containingBlock->stretchesToViewHeight()))
+ return -style()->bottom().calcValue(containingBlock->availableHeight());
return 0;
}
diff --git a/WebCore/rendering/RenderEmbeddedObject.cpp b/WebCore/rendering/RenderEmbeddedObject.cpp
index 55b230b..b1b253a 100644
--- a/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -102,6 +102,7 @@ bool RenderEmbeddedObject::allowsAcceleratedCompositing() const
}
#endif
+// FIXME: This belongs in HTMLPluginElement.cpp to be shared by HTMLObjectElement and HTMLEmbedElement.
static bool isURLAllowed(Document* doc, const String& url)
{
if (doc->frame()->page()->frameCount() >= Page::maxNumberOfFrames)
@@ -123,6 +124,7 @@ static bool isURLAllowed(Document* doc, const String& url)
typedef HashMap<String, String, CaseFoldingHash> ClassIdToTypeMap;
+// FIXME: This belongs in HTMLObjectElement.cpp
static ClassIdToTypeMap* createClassIdToTypeMap()
{
ClassIdToTypeMap* map = new ClassIdToTypeMap;
@@ -135,6 +137,7 @@ static ClassIdToTypeMap* createClassIdToTypeMap()
return map;
}
+// FIXME: This belongs in HTMLObjectElement.cpp
static String serviceTypeForClassId(const String& classId)
{
// Return early if classId is empty (since we won't do anything below).
@@ -146,6 +149,7 @@ static String serviceTypeForClassId(const String& classId)
return map->get(classId);
}
+// FIXME: This belongs in HTMLObjectElement.cpp
static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues)
{
// Some plugins don't understand the "data" attribute of the OBJECT tag (i.e. Real and WMP
@@ -164,190 +168,205 @@ static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramV
}
}
-void RenderEmbeddedObject::updateWidget(bool onlyCreateNonNetscapePlugins)
+// FIXME: This belongs in some loader header?
+static bool isNetscapePlugin(Frame* frame, const String& url, const String& serviceType)
{
- if (!m_replacementText.isNull() || !node()) // Check the node in case destroy() has been called.
- return;
-
- String url;
- String serviceType;
- Vector<String> paramNames;
- Vector<String> paramValues;
- Frame* frame = frameView()->frame();
-
- // The calls to SubframeLoader::requestObject within this function can result in a plug-in being initialized.
- // This can run cause arbitrary JavaScript to run and may result in this RenderObject being detached from
- // the render tree and destroyed, causing a crash like <rdar://problem/6954546>. By extending our lifetime
- // artifically to ensure that we remain alive for the duration of plug-in initialization.
- RenderWidgetProtector protector(this);
+ KURL completedURL;
+ if (!url.isEmpty())
+ completedURL = frame->loader()->completeURL(url);
- if (node()->hasTagName(objectTag)) {
- HTMLObjectElement* objectElement = static_cast<HTMLObjectElement*>(node());
+ if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
+ return true;
+ return false;
+}
- objectElement->setNeedWidgetUpdate(false);
- if (!objectElement->isFinishedParsingChildren())
- return;
+// FIXME: This belongs on HTMLObjectElement.
+static bool hasFallbackContent(HTMLObjectElement* objectElement)
+{
+ for (Node* child = objectElement->firstChild(); child; child = child->nextSibling()) {
+ if ((!child->isTextNode() && !child->hasTagName(paramTag)) // Discount <param>
+ || (child->isTextNode() && !static_cast<Text*>(child)->containsOnlyWhitespace()))
+ return true;
+ }
+ return false;
+}
- // Check for a child EMBED tag.
- HTMLEmbedElement* embed = 0;
- for (Node* child = objectElement->firstChild(); child; ) {
- if (child->hasTagName(embedTag)) {
- embed = static_cast<HTMLEmbedElement*>(child);
- break;
+// FIXME: This belongs on HTMLObjectElement.
+static void parametersFromObject(HTMLObjectElement* objectElement, Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType)
+{
+ HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
+
+ // Scan the PARAM children and store their name/value pairs.
+ // Get the URL and type from the params if we don't already have them.
+ Node* child = objectElement->firstChild();
+ while (child) {
+ if (child->hasTagName(paramTag)) {
+ HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
+ String name = p->name();
+ if (url.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
+ url = deprecatedParseURL(p->value());
+ // FIXME: serviceType calculation does not belong in this function.
+ if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
+ serviceType = p->value();
+ size_t pos = serviceType.find(";");
+ if (pos != notFound)
+ serviceType = serviceType.left(pos);
}
-
- if (child->hasTagName(objectTag))
- child = child->nextSibling(); // Don't descend into nested OBJECT tags
- else
- child = child->traverseNextNode(objectElement); // Otherwise descend (EMBEDs may be inside COMMENT tags)
- }
-
- // Use the attributes from the EMBED tag instead of the OBJECT tag including WIDTH and HEIGHT.
- HTMLElement* embedOrObject;
- if (embed) {
- embedOrObject = embed;
- url = embed->url();
- serviceType = embed->serviceType();
- } else
- embedOrObject = objectElement;
-
- // If there was no URL or type defined in EMBED, try the OBJECT tag.
- if (url.isEmpty())
- url = objectElement->url();
- if (serviceType.isEmpty())
- serviceType = objectElement->serviceType();
-
- HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
-
- // Scan the PARAM children.
- // Get the URL and type from the params if we don't already have them.
- // Get the attributes from the params if there is no EMBED tag.
- Node* child = objectElement->firstChild();
- while (child && (url.isEmpty() || serviceType.isEmpty() || !embed)) {
- if (child->hasTagName(paramTag)) {
- HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
- String name = p->name();
- if (url.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
- url = p->value();
- if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
- serviceType = p->value();
- size_t pos = serviceType.find(";");
- if (pos != notFound)
- serviceType = serviceType.left(pos);
- }
- if (!embed && !name.isEmpty()) {
- uniqueParamNames.add(name.impl());
- paramNames.append(p->name());
- paramValues.append(p->value());
- }
+ if (!name.isEmpty()) {
+ uniqueParamNames.add(name.impl());
+ paramNames.append(p->name());
+ paramValues.append(p->value());
}
- child = child->nextSibling();
}
+ child = child->nextSibling();
+ }
- // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
- // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
- // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
- // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
- // else our Java plugin will misinterpret it. [4004531]
- String codebase;
- if (!embed && MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
- codebase = "codebase";
- uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
- }
-
- // Turn the attributes of either the EMBED tag or OBJECT tag into arrays, but don't override PARAM values.
- NamedNodeMap* attributes = embedOrObject->attributes();
- if (attributes) {
- for (unsigned i = 0; i < attributes->length(); ++i) {
- Attribute* it = attributes->attributeItem(i);
- const AtomicString& name = it->name().localName();
- if (embed || !uniqueParamNames.contains(name.impl())) {
- paramNames.append(name.string());
- paramValues.append(it->value().string());
- }
+ // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
+ // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
+ // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
+ // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
+ // else our Java plugin will misinterpret it. [4004531]
+ String codebase;
+ if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
+ codebase = "codebase";
+ uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
+ }
+
+ // Turn the attributes of the <object> element into arrays, but don't override <param> values.
+ NamedNodeMap* attributes = objectElement->attributes();
+ if (attributes) {
+ for (unsigned i = 0; i < attributes->length(); ++i) {
+ Attribute* it = attributes->attributeItem(i);
+ const AtomicString& name = it->name().localName();
+ if (!uniqueParamNames.contains(name.impl())) {
+ paramNames.append(name.string());
+ paramValues.append(it->value().string());
}
}
+ }
- mapDataParamToSrc(&paramNames, &paramValues);
+ mapDataParamToSrc(&paramNames, &paramValues);
- // If we still don't have a type, try to map from a specific CLASSID to a type.
- if (serviceType.isEmpty())
- serviceType = serviceTypeForClassId(objectElement->classId());
+ // If we still don't have a type, try to map from a specific CLASSID to a type.
+ if (serviceType.isEmpty())
+ serviceType = serviceTypeForClassId(objectElement->classId());
+}
- if (!isURLAllowed(document(), url))
- return;
+// FIXME: This belongs on HTMLObjectElement, HTMLPluginElement or HTMLFrameOwnerElement.
+static void updateWidgetForObjectElement(HTMLObjectElement* objectElement, bool onlyCreateNonNetscapePlugins)
+{
+ objectElement->setNeedsWidgetUpdate(false);
+ if (!objectElement->isFinishedParsingChildren())
+ return;
- // Find out if we support fallback content.
- m_hasFallbackContent = false;
- for (Node* child = objectElement->firstChild(); child && !m_hasFallbackContent; child = child->nextSibling()) {
- if ((!child->isTextNode() && !child->hasTagName(embedTag) && !child->hasTagName(paramTag)) // Discount <embed> and <param>
- || (child->isTextNode() && !static_cast<Text*>(child)->containsOnlyWhitespace()))
- m_hasFallbackContent = true;
- }
+ Frame* frame = objectElement->document()->frame();
+ String url = objectElement->url();
+ String serviceType = objectElement->serviceType();
- if (onlyCreateNonNetscapePlugins) {
- KURL completedURL;
- if (!url.isEmpty())
- completedURL = frame->loader()->completeURL(url);
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ parametersFromObject(objectElement, paramNames, paramValues, url, serviceType);
- if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
- return;
- }
+ if (!isURLAllowed(objectElement->document(), url))
+ return;
- bool beforeLoadAllowedLoad = objectElement->dispatchBeforeLoadEvent(url);
-
- // beforeload events can modify the DOM, potentially causing
- // RenderWidget::destroy() to be called. Ensure we haven't been
- // destroyed before continuing.
- if (!node())
- return;
-
- bool success = beforeLoadAllowedLoad && frame->loader()->subframeLoader()->requestObject(this, url, objectElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
-
- if (!success && m_hasFallbackContent)
- objectElement->renderFallbackContent();
+ bool fallbackContent = hasFallbackContent(objectElement);
+ objectElement->renderEmbeddedObject()->setHasFallbackContent(fallbackContent);
- } else if (node()->hasTagName(embedTag)) {
- HTMLEmbedElement* embedElement = static_cast<HTMLEmbedElement*>(node());
- embedElement->setNeedWidgetUpdate(false);
- url = embedElement->url();
- serviceType = embedElement->serviceType();
+ if (onlyCreateNonNetscapePlugins && isNetscapePlugin(frame, url, serviceType))
+ return;
- if (url.isEmpty() && serviceType.isEmpty())
- return;
- if (!isURLAllowed(document(), url))
- return;
+ bool beforeLoadAllowedLoad = objectElement->dispatchBeforeLoadEvent(url);
- // add all attributes set on the embed object
- NamedNodeMap* attributes = embedElement->attributes();
- if (attributes) {
- for (unsigned i = 0; i < attributes->length(); ++i) {
- Attribute* it = attributes->attributeItem(i);
- paramNames.append(it->name().localName().string());
- paramValues.append(it->value().string());
- }
- }
+ // beforeload events can modify the DOM, potentially causing
+ // RenderWidget::destroy() to be called. Ensure we haven't been
+ // destroyed before continuing.
+ // FIXME: Should this render fallback content?
+ if (!objectElement->renderer())
+ return;
+
+ bool success = beforeLoadAllowedLoad && frame->loader()->subframeLoader()->requestObject(objectElement, url, objectElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
- if (onlyCreateNonNetscapePlugins) {
- KURL completedURL;
- if (!url.isEmpty())
- completedURL = frame->loader()->completeURL(url);
+ if (!success && fallbackContent)
+ objectElement->renderFallbackContent();
+}
- if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
- return;
+// FIXME: This belongs on HTMLEmbedElement.
+static void parametersFromEmbed(HTMLEmbedElement* embedElement, Vector<String>& paramNames, Vector<String>& paramValues)
+{
+ NamedNodeMap* attributes = embedElement->attributes();
+ if (attributes) {
+ for (unsigned i = 0; i < attributes->length(); ++i) {
+ Attribute* it = attributes->attributeItem(i);
+ paramNames.append(it->name().localName().string());
+ paramValues.append(it->value().string());
}
+ }
+}
+
+// FIXME: This belongs on HTMLEmbedElement, HTMLPluginElement or HTMLFrameOwnerElement.
+static void updateWidgetForEmbedElement(HTMLEmbedElement* embedElement, bool onlyCreateNonNetscapePlugins)
+{
+ Frame* frame = embedElement->document()->frame();
+ String url = embedElement->url();
+ String serviceType = embedElement->serviceType();
- if (embedElement->dispatchBeforeLoadEvent(url))
- frame->loader()->subframeLoader()->requestObject(this, url, embedElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
+ embedElement->setNeedsWidgetUpdate(false);
+
+ if (url.isEmpty() && serviceType.isEmpty())
+ return;
+ if (!isURLAllowed(embedElement->document(), url))
+ return;
+
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ parametersFromEmbed(embedElement, paramNames, paramValues);
+
+ if (onlyCreateNonNetscapePlugins && isNetscapePlugin(frame, url, serviceType))
+ return;
+
+ if (embedElement->dispatchBeforeLoadEvent(url)) {
+ // FIXME: beforeLoad could have detached the renderer! Just like in the <object> case above.
+ frame->loader()->subframeLoader()->requestObject(embedElement, url, embedElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
+ }
+}
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+// FIXME: This belongs on HTMLMediaElement.
+static void updateWidgetForMediaElement(HTMLMediaElement* mediaElement, bool ignored)
+{
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ KURL kurl;
+
+ mediaElement->getPluginProxyParams(kurl, paramNames, paramValues);
+ mediaElement->setNeedWidgetUpdate(false);
+ frame->loader()->subframeLoader()->loadMediaPlayerProxyPlugin(mediaElement, kurl, paramNames, paramValues);
+}
+#endif
+
+void RenderEmbeddedObject::updateWidget(bool onlyCreateNonNetscapePlugins)
+{
+ if (!m_replacementText.isNull() || !node()) // Check the node in case destroy() has been called.
+ return;
+
+ // The calls to SubframeLoader::requestObject within this function can result in a plug-in being initialized.
+ // This can run cause arbitrary JavaScript to run and may result in this RenderObject being detached from
+ // the render tree and destroyed, causing a crash like <rdar://problem/6954546>. By extending our lifetime
+ // artifically to ensure that we remain alive for the duration of plug-in initialization.
+ RenderWidgetProtector protector(this);
+
+ if (node()->hasTagName(objectTag)) {
+ HTMLObjectElement* objectElement = static_cast<HTMLObjectElement*>(node());
+ updateWidgetForObjectElement(objectElement, onlyCreateNonNetscapePlugins);
+ } else if (node()->hasTagName(embedTag)) {
+ HTMLEmbedElement* embedElement = static_cast<HTMLEmbedElement*>(node());
+ updateWidgetForEmbedElement(embedElement, onlyCreateNonNetscapePlugins);
}
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
else if (node()->hasTagName(videoTag) || node()->hasTagName(audioTag)) {
HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node());
- KURL kurl;
-
- mediaElement->getPluginProxyParams(kurl, paramNames, paramValues);
- mediaElement->setNeedWidgetUpdate(false);
- frame->loader()->subframeLoader()->loadMediaPlayerProxyPlugin(node(), kurl, paramNames, paramValues);
+ updateWidgetForMediaElement(mediaElement, onlyCreateNonNetscapePlugins);
}
#endif
}
diff --git a/WebCore/rendering/RenderEmbeddedObject.h b/WebCore/rendering/RenderEmbeddedObject.h
index 0944094..6376f93 100644
--- a/WebCore/rendering/RenderEmbeddedObject.h
+++ b/WebCore/rendering/RenderEmbeddedObject.h
@@ -41,7 +41,9 @@ public:
void setShowsCrashedPluginIndicator();
bool showsMissingPluginIndicator() const { return m_showsMissingPluginIndicator; }
+ // FIXME: This belongs on HTMLObjectElement.
bool hasFallbackContent() const { return m_hasFallbackContent; }
+ void setHasFallbackContent(bool hasFallbackContent) { m_hasFallbackContent = hasFallbackContent; }
void handleMissingPluginIndicatorEvent(Event*);
@@ -68,7 +70,7 @@ private:
bool getReplacementTextGeometry(int tx, int ty, FloatRect& contentRect, Path&, FloatRect& replacementTextRect, Font&, TextRun&, float& textWidth);
String m_replacementText;
- bool m_hasFallbackContent;
+ bool m_hasFallbackContent; // FIXME: This belongs on HTMLObjectElement.
bool m_showsMissingPluginIndicator;
bool m_missingPluginIndicatorIsPressed;
bool m_mouseDownWasInMissingPluginIndicator;
diff --git a/WebCore/rendering/RenderForeignObject.cpp b/WebCore/rendering/RenderForeignObject.cpp
index 50c1a42..bfcb940 100644
--- a/WebCore/rendering/RenderForeignObject.cpp
+++ b/WebCore/rendering/RenderForeignObject.cpp
@@ -102,14 +102,20 @@ void RenderForeignObject::layout()
LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
+ bool updateCachedBoundariesInParents = false;
if (m_needsTransformUpdate) {
m_localTransform = foreign->animatedLocalTransform();
m_needsTransformUpdate = false;
+ updateCachedBoundariesInParents = true;
}
+ FloatRect oldViewport = m_viewport;
+
// 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)));
+ if (!updateCachedBoundariesInParents)
+ updateCachedBoundariesInParents = oldViewport != m_viewport;
// 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
@@ -122,6 +128,10 @@ void RenderForeignObject::layout()
RenderBlock::layout();
ASSERT(!needsLayout());
+ // If our bounds changed, notify the parents.
+ if (updateCachedBoundariesInParents)
+ RenderSVGBlock::setNeedsBoundariesUpdate();
+
// Invalidate all resources of this client if our layout changed.
if (layoutChanged)
SVGResourcesCache::clientLayoutChanged(this);
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index f34b691..316b1cf 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -61,7 +61,6 @@ using namespace HTMLNames;
RenderImage::RenderImage(Node* node)
: RenderReplaced(node, IntSize(0, 0))
- , m_cachedImage(0)
{
updateAltText();
@@ -70,22 +69,15 @@ RenderImage::RenderImage(Node* node)
RenderImage::~RenderImage()
{
- if (m_cachedImage)
- m_cachedImage->removeClient(this);
+ ASSERT(m_imageResource);
+ m_imageResource->shutdown();
}
-void RenderImage::setCachedImage(CachedImage* newImage)
+void RenderImage::setImageResource(PassOwnPtr<RenderImageResource> imageResource)
{
- if (m_cachedImage == newImage)
- return;
- if (m_cachedImage)
- m_cachedImage->removeClient(this);
- m_cachedImage = newImage;
- if (m_cachedImage) {
- m_cachedImage->addClient(this);
- if (m_cachedImage->errorOccurred())
- imageChanged(m_cachedImage.get());
- }
+ ASSERT(!m_imageResource);
+ m_imageResource = imageResource;
+ m_imageResource->initialize(this);
}
// If we'll be displaying either alt text or an image, add some padding.
@@ -139,22 +131,22 @@ void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
if (hasBoxDecorations() || hasMask())
RenderReplaced::imageChanged(newImage, rect);
-
- if (newImage != imagePtr() || !newImage)
+
+ if (newImage != m_imageResource->imagePtr() || !newImage)
return;
bool imageSizeChanged = false;
// Set image dimensions, taking into account the size of the alt text.
- if (errorOccurred())
- imageSizeChanged = setImageSizeForAltText(m_cachedImage.get());
-
+ if (m_imageResource->errorOccurred())
+ imageSizeChanged = setImageSizeForAltText(m_imageResource->cachedImage());
+
bool shouldRepaint = true;
// Image dimensions have been changed, see what needs to be done
- if (imageSize(style()->effectiveZoom()) != intrinsicSize() || imageSizeChanged) {
- if (!errorOccurred())
- setIntrinsicSize(imageSize(style()->effectiveZoom()));
+ if (m_imageResource->imageSize(style()->effectiveZoom()) != intrinsicSize() || imageSizeChanged) {
+ if (!m_imageResource->errorOccurred())
+ setIntrinsicSize(m_imageResource->imageSize(style()->effectiveZoom()));
// In the case of generated image content using :before/:after, we might not be in the
// render tree yet. In that case, we don't need to worry about check for layout, since we'll get a
@@ -184,7 +176,7 @@ void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
if (rect) {
// The image changed rect is in source image coordinates (pre-zooming),
// so map from the bounds of the image to the contentsBox.
- repaintRect = enclosingIntRect(mapRect(*rect, FloatRect(FloatPoint(), imageSize(1.0f)), contentBoxRect()));
+ repaintRect = enclosingIntRect(mapRect(*rect, FloatRect(FloatPoint(), m_imageResource->imageSize(1.0f)), contentBoxRect()));
// Guard against too-large changed rects.
repaintRect.intersect(contentBoxRect());
} else
@@ -207,7 +199,7 @@ void RenderImage::notifyFinished(CachedResource* newImage)
return;
#if USE(ACCELERATED_COMPOSITING)
- if ((newImage == m_cachedImage) && hasLayer()) {
+ if (newImage == m_imageResource->cachedImage() && hasLayer()) {
// tell any potential compositing layers
// that the image is done and they can reference it directly.
layer()->rendererContentChanged();
@@ -216,15 +208,6 @@ void RenderImage::notifyFinished(CachedResource* newImage)
UNUSED_PARAM(newImage);
#endif
}
-
-void RenderImage::resetAnimation()
-{
- if (m_cachedImage) {
- image()->resetAnimation();
- if (!needsLayout())
- repaint();
- }
-}
void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
{
@@ -240,7 +223,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
GraphicsContext* context = paintInfo.context;
- if (!hasImage() || errorOccurred()) {
+ if (!m_imageResource->hasImage() || m_imageResource->errorOccurred()) {
if (paintInfo.phase == PaintPhaseSelection)
return;
@@ -265,17 +248,19 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
int usableWidth = cWidth - 2;
int usableHeight = cHeight - 2;
- if (errorOccurred() && !image()->isNull() && (usableWidth >= image()->width()) && (usableHeight >= image()->height())) {
+ Image* image = m_imageResource->image();
+
+ if (m_imageResource->errorOccurred() && !image->isNull() && usableWidth >= image->width() && usableHeight >= image->height()) {
// Center the error image, accounting for border and padding.
- int centerX = (usableWidth - image()->width()) / 2;
+ int centerX = (usableWidth - image->width()) / 2;
if (centerX < 0)
centerX = 0;
- int centerY = (usableHeight - image()->height()) / 2;
+ int centerY = (usableHeight - image->height()) / 2;
if (centerY < 0)
centerY = 0;
imageX = leftBorder + leftPad + centerX + 1;
imageY = topBorder + topPad + centerY + 1;
- context->drawImage(image(), style()->colorSpace(), IntPoint(tx + imageX, ty + imageY));
+ context->drawImage(image, style()->colorSpace(), IntPoint(tx + imageX, ty + imageY));
errorPictureDrawn = true;
}
@@ -298,8 +283,8 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
context->drawText(style()->font(), textRun, IntPoint(ax, ay + ascent));
}
}
- } else if (hasImage() && cWidth > 0 && cHeight > 0) {
- Image* img = image(cWidth, cHeight);
+ } else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) {
+ Image* img = m_imageResource->image(cWidth, cHeight);
if (!img || img->isNull())
return;
@@ -361,22 +346,22 @@ void RenderImage::paintFocusRings(PaintInfo& paintInfo, const RenderStyle* style
void RenderImage::paintIntoRect(GraphicsContext* context, const IntRect& rect)
{
- if (!hasImage() || errorOccurred() || rect.width() <= 0 || rect.height() <= 0)
+ if (!m_imageResource->hasImage() || m_imageResource->errorOccurred() || rect.width() <= 0 || rect.height() <= 0)
return;
- Image* img = image(rect.width(), rect.height());
+ Image* img = m_imageResource->image(rect.width(), rect.height());
if (!img || img->isNull())
return;
HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, this->image(), rect.size());
- context->drawImage(image(rect.width(), rect.height()), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
+ bool useLowQualityScaling = shouldPaintAtLowQuality(context, m_imageResource->image(), rect.size());
+ context->drawImage(m_imageResource->image(rect.width(), rect.height()), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
}
int RenderImage::minimumReplacedHeight() const
{
- return errorOccurred() ? intrinsicSize().height() : 0;
+ return m_imageResource->errorOccurred() ? intrinsicSize().height() : 0;
}
HTMLMapElement* RenderImage::imageMap() const
@@ -459,18 +444,18 @@ bool RenderImage::isHeightSpecified() const
int RenderImage::calcReplacedWidth(bool includeMaxWidth) const
{
- if (imageHasRelativeWidth())
+ if (m_imageResource->imageHasRelativeWidth())
if (RenderObject* cb = isPositioned() ? container() : containingBlock()) {
if (cb->isBox())
- setImageContainerSize(IntSize(toRenderBox(cb)->availableWidth(), toRenderBox(cb)->availableHeight()));
+ m_imageResource->setImageContainerSize(IntSize(toRenderBox(cb)->availableWidth(), toRenderBox(cb)->availableHeight()));
}
int width;
if (isWidthSpecified())
width = calcReplacedWidthUsing(style()->width());
- else if (usesImageContainerSize())
- width = imageSize(style()->effectiveZoom()).width();
- else if (imageHasRelativeWidth())
+ else if (m_imageResource->usesImageContainerSize())
+ width = m_imageResource->imageSize(style()->effectiveZoom()).width();
+ else if (m_imageResource->imageHasRelativeWidth())
width = 0; // If the image is relatively-sized, set the width to 0 until there is a set container size.
else
width = calcAspectRatioWidth();
@@ -497,9 +482,9 @@ int RenderImage::calcReplacedHeight() const
int height;
if (isHeightSpecified())
height = calcReplacedHeightUsing(style()->height());
- else if (usesImageContainerSize())
- height = imageSize(style()->effectiveZoom()).height();
- else if (imageHasRelativeHeight())
+ else if (m_imageResource->usesImageContainerSize())
+ height = m_imageResource->imageSize(style()->effectiveZoom()).height();
+ else if (m_imageResource->imageHasRelativeHeight())
height = 0; // If the image is relatively-sized, set the height to 0 until there is a set container size.
else
height = calcAspectRatioHeight();
@@ -536,7 +521,7 @@ int RenderImage::calcAspectRatioWidth() const
IntSize size = intrinsicSize();
if (!size.height())
return 0;
- if (!hasImage() || errorOccurred())
+ if (!m_imageResource->hasImage() || m_imageResource->errorOccurred())
return size.width(); // Don't bother scaling.
return RenderReplaced::calcReplacedHeight() * size.width() / size.height();
}
@@ -546,7 +531,7 @@ int RenderImage::calcAspectRatioHeight() const
IntSize size = intrinsicSize();
if (!size.width())
return 0;
- if (!hasImage() || errorOccurred())
+ if (!m_imageResource->hasImage() || m_imageResource->errorOccurred())
return size.height(); // Don't bother scaling.
return RenderReplaced::calcReplacedWidth() * size.height() / size.width();
}
@@ -571,9 +556,4 @@ void RenderImage::calcPrefWidths()
setPrefWidthsDirty(false);
}
-Image* RenderImage::nullImage()
-{
- return Image::nullImage();
-}
-
} // namespace WebCore
diff --git a/WebCore/rendering/RenderImage.h b/WebCore/rendering/RenderImage.h
index b89a652..2b88c32 100644
--- a/WebCore/rendering/RenderImage.h
+++ b/WebCore/rendering/RenderImage.h
@@ -25,6 +25,7 @@
#ifndef RenderImage_h
#define RenderImage_h
+#include "RenderImageResource.h"
#include "RenderReplaced.h"
namespace WebCore {
@@ -36,25 +37,21 @@ public:
RenderImage(Node*);
virtual ~RenderImage();
+ void setImageResource(PassOwnPtr<RenderImageResource>);
+
+ RenderImageResource* imageResource() { return m_imageResource.get(); }
+ const RenderImageResource* imageResource() const { return m_imageResource.get(); }
+ CachedImage* cachedImage() const { return m_imageResource->cachedImage(); }
+
bool setImageSizeForAltText(CachedImage* newImage = 0);
void updateAltText();
- void setCachedImage(CachedImage*);
- CachedImage* cachedImage() const { return m_cachedImage.get(); }
-
HTMLMapElement* imageMap() const;
- void resetAnimation();
-
- virtual bool hasImage() const { return m_cachedImage; }
-
void highQualityRepaintTimerFired(Timer<RenderImage>*);
protected:
- virtual Image* image(int /* width */ = 0, int /* height */ = 0) { return m_cachedImage ? m_cachedImage->image() : nullImage(); }
- virtual bool errorOccurred() const { return m_cachedImage && m_cachedImage->errorOccurred(); }
-
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
virtual void paintIntoRect(GraphicsContext*, const IntRect&);
@@ -64,14 +61,14 @@ protected:
bool isWidthSpecified() const;
bool isHeightSpecified() const;
- virtual void intrinsicSizeChanged() { imageChanged(imagePtr()); }
+ virtual void intrinsicSizeChanged() { imageChanged(m_imageResource->imagePtr()); }
private:
virtual const char* renderName() const { return "RenderImage"; }
virtual bool isImage() const { return true; }
virtual bool isRenderImage() const { return true; }
-
+
virtual void paintReplaced(PaintInfo&, int tx, int ty);
virtual int minimumReplacedHeight() const;
@@ -84,37 +81,25 @@ private:
virtual void calcPrefWidths();
- virtual bool usesImageContainerSize() const { return m_cachedImage ? m_cachedImage->usesImageContainerSize() : false; }
- virtual void setImageContainerSize(const IntSize& size) const { if (m_cachedImage) m_cachedImage->setImageContainerSize(size); }
- virtual bool imageHasRelativeWidth() const { return m_cachedImage ? m_cachedImage->imageHasRelativeWidth() : false; }
- virtual bool imageHasRelativeHeight() const { return m_cachedImage ? m_cachedImage->imageHasRelativeHeight() : false; }
- virtual IntSize imageSize(float multiplier) const { return m_cachedImage ? m_cachedImage->imageSize(multiplier) : IntSize(); }
- virtual WrappedImagePtr imagePtr() const { return m_cachedImage.get(); }
-
int calcAspectRatioWidth() const;
int calcAspectRatioHeight() const;
-protected:
- // The image we are rendering.
- CachedResourceHandle<CachedImage> m_cachedImage;
-
private:
// Text to display as long as the image isn't available.
String m_altText;
+ OwnPtr<RenderImageResource> m_imageResource;
- static Image* nullImage();
-
friend class RenderImageScaleObserver;
};
inline RenderImage* toRenderImage(RenderObject* object)
-{
+{
ASSERT(!object || object->isRenderImage());
return static_cast<RenderImage*>(object);
}
inline const RenderImage* toRenderImage(const RenderObject* object)
-{
+{
ASSERT(!object || object->isRenderImage());
return static_cast<const RenderImage*>(object);
}
diff --git a/WebCore/rendering/RenderImageGeneratedContent.cpp b/WebCore/rendering/RenderImageGeneratedContent.cpp
deleted file mode 100644
index 29d0508..0000000
--- a/WebCore/rendering/RenderImageGeneratedContent.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "RenderImageGeneratedContent.h"
-
-#include "RenderBlock.h"
-#include "RenderStyle.h"
-#include "StyleCachedImage.h"
-
-namespace WebCore {
-
-RenderImageGeneratedContent::RenderImageGeneratedContent(Node* n)
-: RenderImage(n)
-{}
-
-RenderImageGeneratedContent::~RenderImageGeneratedContent()
-{
- m_cachedImage = 0;
- m_styleImage->removeClient(this);
-}
-
-void RenderImageGeneratedContent::setStyleImage(StyleImage* image)
-{
- if (image->isCachedImage())
- m_cachedImage = static_cast<StyleCachedImage*>(image)->cachedImage();
- m_styleImage = image;
- m_styleImage->addClient(this);
-}
-
-}
diff --git a/WebCore/rendering/RenderImageGeneratedContent.h b/WebCore/rendering/RenderImageGeneratedContent.h
deleted file mode 100644
index 9f8330d..0000000
--- a/WebCore/rendering/RenderImageGeneratedContent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RenderImageGeneratedContent_h
-#define RenderImageGeneratedContent_h
-
-#include "RenderImage.h"
-#include "StyleImage.h"
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-class StyleImage;
-
-class RenderImageGeneratedContent : public RenderImage {
-public:
- RenderImageGeneratedContent(Node*);
- virtual ~RenderImageGeneratedContent();
-
- void setStyleImage(StyleImage*);
-
- virtual bool hasImage() const { return true; }
-
-protected:
- virtual Image* image(int w = 0, int h = 0) { return m_styleImage->image(this, IntSize(w, h)); }
- virtual bool errorOccurred() const { return m_styleImage->errorOccurred(); }
- virtual bool usesImageContainerSize() const { return m_styleImage->usesImageContainerSize(); }
- virtual void setImageContainerSize(const IntSize& size) const { m_styleImage->setImageContainerSize(size); }
- virtual bool imageHasRelativeWidth() const { return m_styleImage->imageHasRelativeWidth(); }
- virtual bool imageHasRelativeHeight() const { return m_styleImage->imageHasRelativeHeight(); }
- virtual IntSize imageSize(float multiplier) const { return m_styleImage->imageSize(this, multiplier); }
-
- // |m_styleImage| can be 0 if we get a callback for a background image from RenderObject::setStyle.
- virtual WrappedImagePtr imagePtr() const { return m_styleImage ? m_styleImage->data() : 0; }
-
-private:
- RefPtr<StyleImage> m_styleImage;
-};
-
-} // namespace WebCore
-
-#endif // RenderImageGeneratedContent_h
diff --git a/WebCore/rendering/RenderImageResource.cpp b/WebCore/rendering/RenderImageResource.cpp
new file mode 100644
index 0000000..ea3ed2f
--- /dev/null
+++ b/WebCore/rendering/RenderImageResource.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 1999 Lars Knoll <knoll@kde.org>
+ * Copyright (C) 1999 Antti Koivisto <koivisto@kde.org>
+ * Copyright (C) 2000 Dirk Mueller <mueller@kde.org>
+ * Copyright (C) 2006 Allan Sandfeld Jensen <kde@carewolf.com>
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
+ *
+ * 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 "RenderImageResource.h"
+
+#include "RenderImageResourceStyleImage.h"
+#include "RenderObject.h"
+
+namespace WebCore {
+
+RenderImageResource::RenderImageResource()
+ : m_renderer(0)
+ , m_cachedImage(0)
+{
+}
+
+RenderImageResource::~RenderImageResource()
+{
+}
+
+void RenderImageResource::initialize(RenderObject* renderer)
+{
+ ASSERT(!m_renderer);
+ ASSERT(renderer);
+ m_renderer = renderer;
+}
+
+void RenderImageResource::shutdown()
+{
+ ASSERT(m_renderer);
+
+ if (m_cachedImage)
+ m_cachedImage->removeClient(m_renderer);
+}
+
+void RenderImageResource::setCachedImage(CachedImage* newImage)
+{
+ ASSERT(m_renderer);
+
+ if (m_cachedImage == newImage)
+ return;
+
+ if (m_cachedImage)
+ m_cachedImage->removeClient(m_renderer);
+ m_cachedImage = newImage;
+ if (m_cachedImage) {
+ m_cachedImage->addClient(m_renderer);
+ if (m_cachedImage->errorOccurred())
+ m_renderer->imageChanged(m_cachedImage.get());
+ }
+}
+
+void RenderImageResource::resetAnimation()
+{
+ ASSERT(m_renderer);
+
+ if (!m_cachedImage)
+ return;
+
+ image()->resetAnimation();
+
+ if (!m_renderer->needsLayout())
+ m_renderer->repaint();
+}
+
+void RenderImageResource::setImageContainerSize(const IntSize& size) const
+{
+ ASSERT(m_renderer);
+
+ if (!m_cachedImage)
+ return;
+
+ m_cachedImage->setImageContainerSize(size);
+}
+
+Image* RenderImageResource::nullImage()
+{
+ return Image::nullImage();
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/RenderImageResource.h b/WebCore/rendering/RenderImageResource.h
new file mode 100644
index 0000000..2346712
--- /dev/null
+++ b/WebCore/rendering/RenderImageResource.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 1999 Lars Knoll <knoll@kde.org>
+ * Copyright (C) 1999 Antti Koivisto <koivisto@kde.org>
+ * Copyright (C) 2006 Allan Sandfeld Jensen <kde@carewolf.com>
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
+ *
+ * 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 RenderImageResource_h
+#define RenderImageResource_h
+
+#include "CachedImage.h"
+#include "CachedResourceHandle.h"
+#include "StyleImage.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class RenderObject;
+
+class RenderImageResource : public Noncopyable {
+public:
+ virtual ~RenderImageResource();
+
+ static PassOwnPtr<RenderImageResource> create()
+ {
+ return adoptPtr(new RenderImageResource);
+ }
+
+ virtual void initialize(RenderObject*);
+ virtual void shutdown();
+
+ void setCachedImage(CachedImage*);
+ CachedImage* cachedImage() const { return m_cachedImage.get(); }
+ virtual bool hasImage() const { return m_cachedImage; }
+
+ void resetAnimation();
+
+ virtual Image* image(int /* width */ = 0, int /* height */ = 0) { return m_cachedImage ? m_cachedImage->image() : nullImage(); }
+ virtual bool errorOccurred() const { return m_cachedImage && m_cachedImage->errorOccurred(); }
+
+ virtual void setImageContainerSize(const IntSize& size) const;
+ virtual bool usesImageContainerSize() const { return m_cachedImage ? m_cachedImage->usesImageContainerSize() : false; }
+ virtual bool imageHasRelativeWidth() const { return m_cachedImage ? m_cachedImage->imageHasRelativeWidth() : false; }
+ virtual bool imageHasRelativeHeight() const { return m_cachedImage ? m_cachedImage->imageHasRelativeHeight() : false; }
+
+ virtual IntSize imageSize(float multiplier) const { return m_cachedImage ? m_cachedImage->imageSize(multiplier) : IntSize(); }
+
+ virtual WrappedImagePtr imagePtr() const { return m_cachedImage.get(); }
+
+protected:
+ RenderImageResource();
+ RenderObject* m_renderer;
+ CachedResourceHandle<CachedImage> m_cachedImage;
+
+private:
+ static Image* nullImage();
+};
+
+} // namespace WebCore
+
+#endif // RenderImage_h
diff --git a/WebCore/rendering/RenderImageResourceStyleImage.cpp b/WebCore/rendering/RenderImageResourceStyleImage.cpp
new file mode 100644
index 0000000..7f41984
--- /dev/null
+++ b/WebCore/rendering/RenderImageResourceStyleImage.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 1999 Lars Knoll <knoll@kde.org>
+ * Copyright (C) 1999 Antti Koivisto <koivisto@kde.org>
+ * Copyright (C) 2000 Dirk Mueller <mueller@kde.org>
+ * Copyright (C) 2006 Allan Sandfeld Jensen <kde@carewolf.com>
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
+ *
+ * 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 "RenderImageResourceStyleImage.h"
+
+#include "RenderObject.h"
+#include "StyleCachedImage.h"
+
+namespace WebCore {
+
+RenderImageResourceStyleImage::RenderImageResourceStyleImage(StyleImage* styleImage)
+ : m_styleImage(styleImage)
+{
+ ASSERT(m_styleImage);
+}
+
+RenderImageResourceStyleImage::~RenderImageResourceStyleImage()
+{
+}
+
+void RenderImageResourceStyleImage::initialize(RenderObject* renderer)
+{
+ RenderImageResource::initialize(renderer);
+
+ if (m_styleImage->isCachedImage())
+ m_cachedImage = static_cast<StyleCachedImage*>(m_styleImage.get())->cachedImage();
+
+ m_styleImage->addClient(m_renderer);
+}
+
+void RenderImageResourceStyleImage::shutdown()
+{
+ ASSERT(m_renderer);
+ m_styleImage->removeClient(m_renderer);
+ m_cachedImage = 0;
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/RenderImageResourceStyleImage.h b/WebCore/rendering/RenderImageResourceStyleImage.h
new file mode 100644
index 0000000..d91aaa8
--- /dev/null
+++ b/WebCore/rendering/RenderImageResourceStyleImage.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 1999 Lars Knoll <knoll@kde.org>
+ * Copyright (C) 1999 Antti Koivisto <koivisto@kde.org>
+ * Copyright (C) 2006 Allan Sandfeld Jensen <kde@carewolf.com>
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
+ *
+ * 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 RenderImageResourceStyleImage_h
+#define RenderImageResourceStyleImage_h
+
+#include "RenderImageResource.h"
+#include "StyleImage.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class RenderObject;
+
+class RenderImageResourceStyleImage : public RenderImageResource {
+public:
+ virtual ~RenderImageResourceStyleImage();
+
+ static PassOwnPtr<RenderImageResource> create(StyleImage* styleImage)
+ {
+ return adoptPtr(new RenderImageResourceStyleImage(styleImage));
+ }
+ virtual void initialize(RenderObject*);
+ virtual void shutdown();
+
+ virtual bool hasImage() const { return true; }
+ virtual Image* image(int width = 0, int height = 0) { return m_styleImage->image(m_renderer, IntSize(width, height)); }
+ virtual bool errorOccurred() const { return m_styleImage->errorOccurred(); }
+
+ virtual void setImageContainerSize(const IntSize& size) const { m_styleImage->setImageContainerSize(size); }
+ virtual bool usesImageContainerSize() const { return m_styleImage->usesImageContainerSize(); }
+ virtual bool imageHasRelativeWidth() const { return m_styleImage->imageHasRelativeWidth(); }
+ virtual bool imageHasRelativeHeight() const { return m_styleImage->imageHasRelativeHeight(); }
+
+ virtual IntSize imageSize(float multiplier) const { return m_styleImage->imageSize(m_renderer, multiplier); }
+
+ virtual WrappedImagePtr imagePtr() const { return m_styleImage->data(); }
+
+private:
+ RenderImageResourceStyleImage(StyleImage*);
+ RefPtr<StyleImage> m_styleImage;
+};
+
+} // namespace WebCore
+
+#endif // RenderImageStyleImage_h
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 347fa32..331750c 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -2268,12 +2268,10 @@ bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularit
bool didVerticalScroll = false;
if (m_hBar) {
- if (granularity == ScrollByDocument) {
- // Special-case for the ScrollByDocument granularity. A document scroll can only be up
- // or down and in both cases the horizontal bar goes all the way to the left.
- didHorizontalScroll = m_hBar->scroll(ScrollLeft, ScrollByDocument, multiplier);
- } else
- didHorizontalScroll = m_hBar->scroll(direction, granularity, multiplier);
+ // Special-case for the ScrollByDocument granularity. A document scroll
+ // can only be up or down and in both cases the horizontal bar goes all
+ // the way to the left.
+ didHorizontalScroll = m_hBar->scroll((granularity == ScrollByDocument) ? ScrollLeft : direction, granularity, multiplier);
}
if (m_vBar)
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index 17521ad..3f0ac7c 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -277,7 +277,7 @@ public:
void updateScrollInfoAfterLayout();
- bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f);
+ bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1);
void autoscroll();
void resize(const PlatformMouseEvent&, const IntSize&);
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 23645d5..449466d 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -1163,9 +1163,11 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim
KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
KeyframeValueList opacityVector(AnimatedPropertyOpacity);
- for (Vector<KeyframeValue>::const_iterator it = keyframes.beginKeyframes(); it != keyframes.endKeyframes(); ++it) {
- const RenderStyle* keyframeStyle = it->style();
- float key = it->key();
+ size_t numKeyframes = keyframes.size();
+ for (size_t i = 0; i < numKeyframes; ++i) {
+ const KeyframeValue& currentKeyframe = keyframes[i];
+ const RenderStyle* keyframeStyle = currentKeyframe.style();
+ float key = currentKeyframe.key();
if (!keyframeStyle)
continue;
@@ -1173,10 +1175,10 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim
// get timing function
const TimingFunction* tf = keyframeStyle->hasAnimations() ? &((*keyframeStyle->animations()).animation(0)->timingFunction()) : 0;
- if (hasTransform)
+ if (currentKeyframe.containsProperty(AnimatedPropertyWebkitTransform))
transformVector.insert(new TransformAnimationValue(key, &(keyframeStyle->transform()), tf));
- if (hasOpacity)
+ if (currentKeyframe.containsProperty(AnimatedPropertyOpacity))
opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf));
}
diff --git a/WebCore/rendering/RenderLayerCompositor.h b/WebCore/rendering/RenderLayerCompositor.h
index 917d610..86c061b 100644
--- a/WebCore/rendering/RenderLayerCompositor.h
+++ b/WebCore/rendering/RenderLayerCompositor.h
@@ -155,6 +155,7 @@ public:
// their parent document.
bool shouldPropagateCompositingToEnclosingIFrame() const;
+ // FIXME: This should be a RenderIFrame*
HTMLFrameOwnerElement* enclosingIFrameElement() const;
static RenderLayerCompositor* iframeContentsCompositor(RenderIFrame*);
diff --git a/WebCore/rendering/RenderListBox.h b/WebCore/rendering/RenderListBox.h
index aafb87e..36cb87a 100644
--- a/WebCore/rendering/RenderListBox.h
+++ b/WebCore/rendering/RenderListBox.h
@@ -68,7 +68,7 @@ private:
virtual bool isPointInOverflowControl(HitTestResult&, int x, int y, int tx, int ty);
- virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0);
+ virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1, Node** stopNode = 0);
virtual void calcPrefWidths();
virtual int baselinePosition(bool firstLine, bool isRootLineBox) const;
diff --git a/WebCore/rendering/RenderListItem.cpp b/WebCore/rendering/RenderListItem.cpp
index f861467..2366a34 100644
--- a/WebCore/rendering/RenderListItem.cpp
+++ b/WebCore/rendering/RenderListItem.cpp
@@ -150,6 +150,7 @@ static RenderObject* getParentOfFirstLineBox(RenderBlock* curr, RenderObject* ma
if (!firstChild)
return 0;
+ bool inQuirksMode = curr->document()->inQuirksMode();
for (RenderObject* currChild = firstChild; currChild; currChild = currChild->nextSibling()) {
if (currChild == marker)
continue;
@@ -163,7 +164,7 @@ static RenderObject* getParentOfFirstLineBox(RenderBlock* curr, RenderObject* ma
if (currChild->isTable() || !currChild->isRenderBlock())
break;
- if (curr->isListItem() && currChild->style()->htmlHacks() && currChild->node() &&
+ if (curr->isListItem() && inQuirksMode && currChild->node() &&
(currChild->node()->hasTagName(ulTag)|| currChild->node()->hasTagName(olTag)))
break;
diff --git a/WebCore/rendering/RenderListMarker.cpp b/WebCore/rendering/RenderListMarker.cpp
index 6ff1709..7b33c3d 100644
--- a/WebCore/rendering/RenderListMarker.cpp
+++ b/WebCore/rendering/RenderListMarker.cpp
@@ -79,7 +79,7 @@ static String toRoman(int number, bool upper)
return String(&letters[lettersSize - length], length);
}
-static inline String toAlphabeticOrNumeric(int number, const UChar* sequence, int sequenceSize, SequenceType type)
+static inline String toAlphabeticOrNumeric(int number, const UChar* sequence, unsigned sequenceSize, SequenceType type)
{
ASSERT(sequenceSize >= 2);
@@ -115,12 +115,28 @@ static inline String toAlphabeticOrNumeric(int number, const UChar* sequence, in
return String(&letters[lettersSize - length], length);
}
-static String toAlphabetic(int number, const UChar* alphabet, int alphabetSize)
+static String toSymbolic(int number, const UChar* symbols, unsigned symbolsSize)
+{
+ ASSERT(number > 0);
+ ASSERT(symbolsSize >= 1);
+ unsigned numberShadow = number;
+ --numberShadow;
+
+ // The asterisks list-style-type is the worst case; we show |numberShadow| asterisks.
+ Vector<UChar> letters;
+ letters.append(symbols[numberShadow % symbolsSize]);
+ unsigned numSymbols = numberShadow / symbolsSize;
+ while (numSymbols--)
+ letters.append(symbols[numberShadow % symbolsSize]);
+ return String::adopt(letters);
+}
+
+static String toAlphabetic(int number, const UChar* alphabet, unsigned alphabetSize)
{
return toAlphabeticOrNumeric(number, alphabet, alphabetSize, AlphabeticSequence);
}
-static String toNumeric(int number, const UChar* numerals, int numeralsSize)
+static String toNumeric(int number, const UChar* numerals, unsigned numeralsSize)
{
return toAlphabeticOrNumeric(number, numerals, numeralsSize, NumericSequence);
}
@@ -135,6 +151,11 @@ template <size_t size> static inline String toNumeric(int number, const UChar(&a
return toNumeric(number, alphabet, size);
}
+template <size_t size> static inline String toSymbolic(int number, const UChar(&alphabet)[size])
+{
+ return toSymbolic(number, alphabet, size);
+}
+
static int toHebrewUnder1000(int number, UChar letters[5])
{
// FIXME: CSS3 mentions various refinements not implemented here.
@@ -419,6 +440,7 @@ static EListStyleType effectiveListMarkerType(EListStyleType type, int value)
case Afar:
case Amharic:
case AmharicAbegede:
+ case Asterisks:
case CjkEarthlyBranch:
case CjkHeavenlyStem:
case Ethiopic:
@@ -437,6 +459,7 @@ static EListStyleType effectiveListMarkerType(EListStyleType type, int value)
case EthiopicHalehameTiEr:
case EthiopicHalehameTiEt:
case EthiopicHalehameTig:
+ case Footnotes:
case Hangul:
case HangulConsonant:
case Hiragana:
@@ -475,9 +498,11 @@ static UChar listMarkerSuffix(EListStyleType type, int value)
// Note, the following switch statement has been explicitly
// grouped by list-style-type suffix.
switch (effectiveType) {
- case NoneListStyle:
- case Disc:
+ case Asterisks:
case Circle:
+ case Disc:
+ case Footnotes:
+ case NoneListStyle:
case Square:
ASSERT_NOT_REACHED();
return ' ';
@@ -570,12 +595,24 @@ String listMarkerText(EListStyleType type, int value)
case NoneListStyle:
return "";
+ case Asterisks: {
+ static const UChar asterisksSymbols[1] = {
+ 0x002A
+ };
+ return toSymbolic(value, asterisksSymbols);
+ }
// We use the same characters for text security.
// See RenderText::setInternalString.
case Circle:
return String(&whiteBullet, 1);
case Disc:
return String(&bullet, 1);
+ case Footnotes: {
+ static const UChar footnotesSymbols[4] = {
+ 0x002A, 0x2051, 0x2020, 0x2021
+ };
+ return toSymbolic(value, footnotesSymbols);
+ }
case Square:
// The CSS 2.1 test suite uses U+25EE BLACK MEDIUM SMALL SQUARE
// instead, but I think this looks better.
@@ -1110,6 +1147,10 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
EListStyleType type = style()->listStyleType();
switch (type) {
+ case Asterisks:
+ case Footnotes:
+ context->drawText(style()->font(), TextRun(m_text), marker.location());
+ return;
case Disc:
context->drawEllipse(marker);
return;
@@ -1291,6 +1332,11 @@ void RenderListMarker::calcPrefWidths()
switch (type) {
case NoneListStyle:
break;
+ case Asterisks:
+ case Footnotes:
+ m_text = listMarkerText(type, m_listItem->value());
+ width = font.width(m_text); // no suffix for these types
+ break;
case Circle:
case Disc:
case Square:
@@ -1489,6 +1535,11 @@ IntRect RenderListMarker::getRelativeMarkerRect()
EListStyleType type = style()->listStyleType();
switch (type) {
+ case Asterisks:
+ case Footnotes: {
+ const Font& font = style()->font();
+ return IntRect(x(), y() + font.ascent(), font.width(m_text), font.height());
+ }
case Disc:
case Circle:
case Square: {
diff --git a/WebCore/rendering/RenderMedia.cpp b/WebCore/rendering/RenderMedia.cpp
index d7b4a99..a589a2d 100644
--- a/WebCore/rendering/RenderMedia.cpp
+++ b/WebCore/rendering/RenderMedia.cpp
@@ -57,6 +57,7 @@ RenderMedia::RenderMedia(HTMLMediaElement* video)
, m_opacityAnimationFrom(0)
, m_opacityAnimationTo(1.0f)
{
+ setImageResource(RenderImageResource::create());
}
RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
@@ -69,6 +70,7 @@ RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
, m_opacityAnimationFrom(0)
, m_opacityAnimationTo(1.0f)
{
+ setImageResource(RenderImageResource::create());
setIntrinsicSize(intrinsicSize);
}
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 78da758..9ee97b4 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -41,7 +41,8 @@
#include "RenderArena.h"
#include "RenderCounter.h"
#include "RenderFlexibleBox.h"
-#include "RenderImageGeneratedContent.h"
+#include "RenderImage.h"
+#include "RenderImageResourceStyleImage.h"
#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderListItem.h"
@@ -110,10 +111,12 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
// Otherwise acts as if we didn't support this feature.
const ContentData* contentData = style->contentData();
if (contentData && !contentData->next() && contentData->isImage() && doc != node) {
- RenderImageGeneratedContent* image = new (arena) RenderImageGeneratedContent(node);
+ RenderImage* image = new (arena) RenderImage(node);
image->setStyle(style);
if (StyleImage* styleImage = contentData->image())
- image->setStyleImage(styleImage);
+ image->setImageResource(RenderImageResourceStyleImage::create(styleImage));
+ else
+ image->setImageResource(RenderImageResource::create());
return image;
}
@@ -1425,7 +1428,8 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta
style()->getBoxShadowHorizontalExtent(shadowLeft, shadowRight);
int borderRight = isBox() ? toRenderBox(this)->borderRight() : 0;
- int borderWidth = max(-outlineStyle->outlineOffset(), max(borderRight, max(style()->borderTopRightRadius().width(), style()->borderBottomRightRadius().width()))) + max(ow, shadowRight);
+ int boxWidth = isBox() ? toRenderBox(this)->width() : 0;
+ int borderWidth = max(-outlineStyle->outlineOffset(), max(borderRight, max(style()->borderTopRightRadius().width().calcValue(boxWidth), style()->borderBottomRightRadius().width().calcValue(boxWidth)))) + max(ow, shadowRight);
IntRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - borderWidth,
newOutlineBox.y(),
width + borderWidth,
@@ -1443,7 +1447,8 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta
style()->getBoxShadowVerticalExtent(shadowTop, shadowBottom);
int borderBottom = isBox() ? toRenderBox(this)->borderBottom() : 0;
- int borderHeight = max(-outlineStyle->outlineOffset(), max(borderBottom, max(style()->borderBottomLeftRadius().height(), style()->borderBottomRightRadius().height()))) + max(ow, shadowBottom);
+ int boxHeight = isBox() ? toRenderBox(this)->height() : 0;
+ int borderHeight = max(-outlineStyle->outlineOffset(), max(borderBottom, max(style()->borderBottomLeftRadius().height().calcValue(boxHeight), style()->borderBottomRightRadius().height().calcValue(boxHeight)))) + max(ow, shadowBottom);
IntRect bottomRect(newOutlineBox.x(),
min(newOutlineBox.bottom(), oldOutlineBox.bottom()) - borderHeight,
max(newOutlineBox.width(), oldOutlineBox.width()),
@@ -2556,27 +2561,11 @@ void RenderObject::adjustRectForOutlineAndShadow(IntRect& rect) const
{
int outlineSize = outlineStyleForRepaint()->outlineSize();
if (const ShadowData* boxShadow = style()->boxShadow()) {
- int shadowLeft = 0;
- int shadowRight = 0;
- int shadowTop = 0;
- int shadowBottom = 0;
-
- do {
- if (boxShadow->style() == Normal) {
- shadowLeft = min(boxShadow->x() - boxShadow->blur() - boxShadow->spread() - outlineSize, shadowLeft);
- shadowRight = max(boxShadow->x() + boxShadow->blur() + boxShadow->spread() + outlineSize, shadowRight);
- shadowTop = min(boxShadow->y() - boxShadow->blur() - boxShadow->spread() - outlineSize, shadowTop);
- shadowBottom = max(boxShadow->y() + boxShadow->blur() + boxShadow->spread() + outlineSize, shadowBottom);
- }
-
- boxShadow = boxShadow->next();
- } while (boxShadow);
+ boxShadow->adjustRectForShadow(rect, outlineSize);
+ return;
+ }
- rect.move(shadowLeft, shadowTop);
- rect.setWidth(rect.width() - shadowLeft + shadowRight);
- rect.setHeight(rect.height() - shadowTop + shadowBottom);
- } else
- rect.inflate(outlineSize);
+ rect.inflate(outlineSize);
}
AnimationController* RenderObject::animation() const
@@ -2708,6 +2697,12 @@ RenderSVGResourceContainer* RenderObject::toRenderSVGResourceContainer()
return 0;
}
+void RenderObject::setNeedsBoundariesUpdate()
+{
+ if (RenderObject* renderer = parent())
+ renderer->setNeedsBoundariesUpdate();
+}
+
FloatRect RenderObject::objectBoundingBox() const
{
ASSERT_NOT_REACHED();
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index d2046cf..9fbaf91 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -327,7 +327,7 @@ public:
// Unfortunately we don't have such a class yet, because it's not possible for all renderers
// to inherit from RenderSVGObject -> RenderObject (some need RenderBlock inheritance for instance)
virtual void setNeedsTransformUpdate() { }
- virtual void setNeedsBoundariesUpdate() { }
+ virtual void setNeedsBoundariesUpdate();
// 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().
@@ -383,14 +383,7 @@ public:
bool hasBoxDecorations() const { return m_paintBackground; }
bool mustRepaintBackgroundOrBorder() const;
- bool hasBackground() const
- {
- Color color = style()->visitedDependentColor(CSSPropertyBackgroundColor);
- if (color.isValid() && color.alpha() > 0)
- return true;
- return style()->hasBackgroundImage();
- }
-
+ bool hasBackground() const { return style()->hasBackground(); }
bool needsLayout() const { return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout || m_needsPositionedMovementLayout; }
bool selfNeedsLayout() const { return m_needsLayout; }
bool needsPositionedMovementLayout() const { return m_needsPositionedMovementLayout; }
diff --git a/WebCore/rendering/RenderObjectChildList.cpp b/WebCore/rendering/RenderObjectChildList.cpp
index 68e392c..96ec800 100644
--- a/WebCore/rendering/RenderObjectChildList.cpp
+++ b/WebCore/rendering/RenderObjectChildList.cpp
@@ -30,7 +30,8 @@
#include "AXObjectCache.h"
#include "RenderBlock.h"
#include "RenderCounter.h"
-#include "RenderImageGeneratedContent.h"
+#include "RenderImage.h"
+#include "RenderImageResourceStyleImage.h"
#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderListItem.h"
@@ -97,6 +98,11 @@ RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, Render
if (oldChild->isPositioned() && owner->childrenInline())
owner->dirtyLinesFromChangedChild(oldChild);
+
+#if ENABLE(SVG)
+ // Update cached boundaries in SVG renderers, if a child is removed.
+ owner->setNeedsBoundariesUpdate();
+#endif
}
// If oldChild is the start or end of the selection, then clear the selection to
@@ -430,12 +436,14 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
renderer->setStyle(pseudoElementStyle);
break;
case CONTENT_OBJECT: {
- RenderImageGeneratedContent* image = new (owner->renderArena()) RenderImageGeneratedContent(owner->document()); // anonymous object
+ RenderImage* image = new (owner->renderArena()) RenderImage(owner->document()); // anonymous object
RefPtr<RenderStyle> style = RenderStyle::create();
style->inheritFrom(pseudoElementStyle);
image->setStyle(style.release());
if (StyleImage* styleImage = content->image())
- image->setStyleImage(styleImage);
+ image->setImageResource(RenderImageResourceStyleImage::create(styleImage));
+ else
+ image->setImageResource(RenderImageResource::create());
renderer = image;
break;
}
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index 86a12c8..0f31df1 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -101,28 +101,39 @@ void RenderPath::layout()
LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
+ bool updateCachedBoundariesInParents = false;
+
bool needsPathUpdate = m_needsPathUpdate;
if (needsPathUpdate) {
m_path = element->toPathData();
m_needsPathUpdate = false;
+ updateCachedBoundariesInParents = true;
}
if (m_needsTransformUpdate) {
m_localTransform = element->animatedLocalTransform();
m_needsTransformUpdate = false;
+ updateCachedBoundariesInParents = true;
}
+ if (m_needsBoundariesUpdate)
+ updateCachedBoundariesInParents = true;
+
// Invalidate all resources of this client if our layout changed.
if (m_everHadLayout && selfNeedsLayout())
SVGResourcesCache::clientLayoutChanged(this);
// At this point LayoutRepainter already grabbed the old bounds,
- // recalculate them now so repaintAfterLayout() uses the new bounds
+ // recalculate them now so repaintAfterLayout() uses the new bounds.
if (needsPathUpdate || m_needsBoundariesUpdate) {
updateCachedBoundaries();
m_needsBoundariesUpdate = false;
}
+ // If our bounds changed, notify the parents.
+ if (updateCachedBoundariesInParents)
+ RenderSVGModelObject::setNeedsBoundariesUpdate();
+
repainter.repaintAfterLayout();
setNeedsLayout(false);
}
@@ -172,8 +183,7 @@ void RenderPath::paint(PaintInfo& paintInfo, int, int)
return;
FloatRect boundingBox = repaintRectInLocalCoordinates();
- FloatRect nonLocalBoundingBox = m_localTransform.mapRect(boundingBox);
- if (!nonLocalBoundingBox.intersects(paintInfo.rect))
+ if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
return;
PaintInfo childPaintInfo(paintInfo);
@@ -270,13 +280,6 @@ FloatRect RenderPath::calculateMarkerBoundsIfNeeded()
return m_markerLayoutInfo.calculateBoundaries(markerStart, markerMid, markerEnd, svgStyle->strokeWidth().value(svgElement), m_path);
}
-void RenderPath::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
-{
- if (diff == StyleDifferenceLayout)
- setNeedsBoundariesUpdate();
- RenderSVGModelObject::styleWillChange(diff, newStyle);
-}
-
void RenderPath::updateCachedBoundaries()
{
if (m_path.isEmpty()) {
diff --git a/WebCore/rendering/RenderPath.h b/WebCore/rendering/RenderPath.h
index 1bdac07..1d35a01 100644
--- a/WebCore/rendering/RenderPath.h
+++ b/WebCore/rendering/RenderPath.h
@@ -41,8 +41,8 @@ public:
RenderPath(SVGStyledTransformableElement*);
const Path& path() const { return m_path; }
- void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
void setNeedsPathUpdate() { m_needsPathUpdate = true; }
+ virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
private:
@@ -63,7 +63,6 @@ private:
virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
- virtual void styleWillChange(StyleDifference, const RenderStyle*);
FloatRect calculateMarkerBoundsIfNeeded();
void updateCachedBoundaries();
diff --git a/WebCore/rendering/RenderRuby.cpp b/WebCore/rendering/RenderRuby.cpp
index 4ab9d73..2f543d5 100644
--- a/WebCore/rendering/RenderRuby.cpp
+++ b/WebCore/rendering/RenderRuby.cpp
@@ -75,24 +75,19 @@ bool RenderRubyAsInline::isChildAllowed(RenderObject* child, RenderStyle*) const
void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild)
{
- // Note: ':after' content is handled implicitely below
+ // Note: ':after' content is handled implicitly below
- // if child is a ruby run, just add it normally
if (child->isRubyRun()) {
RenderInline::addChild(child, beforeChild);
return;
}
- if (beforeChild && !isAfterContent(beforeChild)) {
- // insert child into run
- ASSERT(!beforeChild->isRubyRun());
- RenderRubyRun* run = findRubyRunParent(beforeChild);
- ASSERT(run); // beforeChild should always have a run as parent
- if (run) {
+ if (beforeChild && !isAfterContent(beforeChild) && !beforeChild->isRubyRun()) {
+ if (RenderRubyRun* run = findRubyRunParent(beforeChild)) {
run->addChild(child, beforeChild);
return;
}
- ASSERT(false); // beforeChild should always have a run as parent!
+ ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
// Emergency fallback: fall through and just append.
}
diff --git a/WebCore/rendering/RenderSVGBlock.cpp b/WebCore/rendering/RenderSVGBlock.cpp
index d6022b5..b2d727a 100644
--- a/WebCore/rendering/RenderSVGBlock.cpp
+++ b/WebCore/rendering/RenderSVGBlock.cpp
@@ -81,6 +81,13 @@ void RenderSVGBlock::destroy()
RenderBlock::destroy();
}
+void RenderSVGBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+{
+ if (diff == StyleDifferenceLayout)
+ setNeedsBoundariesUpdate();
+ RenderBlock::styleWillChange(diff, newStyle);
+}
+
void RenderSVGBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
diff --git a/WebCore/rendering/RenderSVGBlock.h b/WebCore/rendering/RenderSVGBlock.h
index c4337cc..c1379da 100644
--- a/WebCore/rendering/RenderSVGBlock.h
+++ b/WebCore/rendering/RenderSVGBlock.h
@@ -40,6 +40,7 @@ private:
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
virtual void destroy();
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void updateFromElement();
};
diff --git a/WebCore/rendering/RenderSVGContainer.cpp b/WebCore/rendering/RenderSVGContainer.cpp
index bab07a4..8c99270 100644
--- a/WebCore/rendering/RenderSVGContainer.cpp
+++ b/WebCore/rendering/RenderSVGContainer.cpp
@@ -39,6 +39,7 @@ namespace WebCore {
RenderSVGContainer::RenderSVGContainer(SVGStyledElement* node)
: RenderSVGModelObject(node)
, m_drawsContents(true)
+ , m_needsBoundariesUpdate(true)
{
}
@@ -55,7 +56,7 @@ void RenderSVGContainer::layout()
LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
// Allow RenderSVGTransformableContainer to update its transform.
- calculateLocalTransform();
+ bool updatedTransform = calculateLocalTransform();
SVGRenderSupport::layoutChildren(this, selfNeedsLayout());
@@ -63,6 +64,16 @@ void RenderSVGContainer::layout()
if (m_everHadLayout && selfNeedsLayout())
SVGResourcesCache::clientLayoutChanged(this);
+ // At this point LayoutRepainter already grabbed the old bounds,
+ // recalculate them now so repaintAfterLayout() uses the new bounds.
+ if (m_needsBoundariesUpdate || updatedTransform) {
+ updateCachedBoundaries();
+ m_needsBoundariesUpdate = false;
+
+ // If our bounds changed, notify the parents.
+ RenderSVGModelObject::setNeedsBoundariesUpdate();
+ }
+
repainter.repaintAfterLayout();
setNeedsLayout(false);
}
@@ -86,6 +97,10 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int)
if (!firstChild() && !selfWillPaint())
return;
+ FloatRect repaintRect = repaintRectInLocalCoordinates();
+ if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(repaintRect, localToParentTransform(), paintInfo))
+ return;
+
PaintInfo childPaintInfo(paintInfo);
childPaintInfo.context->save();
@@ -115,7 +130,7 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int)
// FIXME: This means our focus ring won't share our rotation like it should.
// We should instead disable our clip during PaintPhaseOutline
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE) {
- IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRectInLocalCoordinates()));
+ IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRect));
paintOutline(paintInfo.context, paintRectInParent.x(), paintRectInParent.y(), paintRectInParent.width(), paintRectInParent.height());
}
}
@@ -128,21 +143,14 @@ void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, int, int)
rects.append(paintRectInParent);
}
-FloatRect RenderSVGContainer::objectBoundingBox() const
+void RenderSVGContainer::updateCachedBoundaries()
{
- return SVGRenderSupport::computeContainerBoundingBox(this, SVGRenderSupport::ObjectBoundingBox);
-}
+ m_objectBoundingBox = FloatRect();
+ m_strokeBoundingBox = FloatRect();
+ m_repaintBoundingBox = FloatRect();
-FloatRect RenderSVGContainer::strokeBoundingBox() const
-{
- return SVGRenderSupport::computeContainerBoundingBox(this, SVGRenderSupport::StrokeBoundingBox);
-}
-
-FloatRect RenderSVGContainer::repaintRectInLocalCoordinates() const
-{
- FloatRect repaintRect = SVGRenderSupport::computeContainerBoundingBox(this, SVGRenderSupport::RepaintBoundingBox);
- SVGRenderSupport::intersectRepaintRectWithResources(this, repaintRect);
- return repaintRect;
+ SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_strokeBoundingBox, m_repaintBoundingBox);
+ SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
}
bool RenderSVGContainer::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
diff --git a/WebCore/rendering/RenderSVGContainer.h b/WebCore/rendering/RenderSVGContainer.h
index 0a122cd..b0c952f 100644
--- a/WebCore/rendering/RenderSVGContainer.h
+++ b/WebCore/rendering/RenderSVGContainer.h
@@ -43,6 +43,7 @@ public:
bool drawsContents() const { return m_drawsContents; }
virtual void paint(PaintInfo&, int parentX, int parentY);
+ virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
protected:
virtual RenderObjectChildList* virtualChildren() { return children(); }
@@ -55,14 +56,14 @@ protected:
virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
- virtual FloatRect objectBoundingBox() const;
- virtual FloatRect strokeBoundingBox() const;
- virtual FloatRect repaintRectInLocalCoordinates() const;
+ virtual FloatRect objectBoundingBox() const { return m_objectBoundingBox; }
+ virtual FloatRect strokeBoundingBox() const { return m_strokeBoundingBox; }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
// Allow RenderSVGTransformableContainer to hook in at the right time in layout()
- virtual void calculateLocalTransform() { }
+ virtual bool calculateLocalTransform() { return false; }
// Allow RenderSVGViewportContainer to hook in at the right times in layout(), paint() and nodeAtFloatPoint()
virtual void calcViewport() { }
@@ -70,10 +71,15 @@ protected:
virtual bool pointIsInsideViewportClip(const FloatPoint& /*pointInParent*/) { return true; }
bool selfWillPaint();
+ void updateCachedBoundaries();
private:
RenderObjectChildList m_children;
+ FloatRect m_objectBoundingBox;
+ FloatRect m_strokeBoundingBox;
+ FloatRect m_repaintBoundingBox;
bool m_drawsContents : 1;
+ bool m_needsBoundariesUpdate : 1;
};
inline RenderSVGContainer* toRenderSVGContainer(RenderObject* object)
diff --git a/WebCore/rendering/RenderSVGGradientStop.h b/WebCore/rendering/RenderSVGGradientStop.h
index 45da7b4..f06a9a5 100644
--- a/WebCore/rendering/RenderSVGGradientStop.h
+++ b/WebCore/rendering/RenderSVGGradientStop.h
@@ -46,6 +46,7 @@ public:
// https://bugs.webkit.org/show_bug.cgi?id=20400
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject*) { return IntRect(); }
virtual FloatRect objectBoundingBox() const { return FloatRect(); }
+ virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
protected:
diff --git a/WebCore/rendering/RenderSVGHiddenContainer.cpp b/WebCore/rendering/RenderSVGHiddenContainer.cpp
index 0af4236..ee1d214 100644
--- a/WebCore/rendering/RenderSVGHiddenContainer.cpp
+++ b/WebCore/rendering/RenderSVGHiddenContainer.cpp
@@ -47,11 +47,6 @@ void RenderSVGHiddenContainer::paint(PaintInfo&, int, int)
// This subtree does not paint.
}
-IntRect RenderSVGHiddenContainer::clippedOverflowRectForRepaint(RenderBoxModelObject* /*repaintContainer*/)
-{
- return IntRect();
-}
-
void RenderSVGHiddenContainer::absoluteQuads(Vector<FloatQuad>&)
{
// This subtree does not take up space or paint
@@ -62,16 +57,6 @@ bool RenderSVGHiddenContainer::nodeAtFloatPoint(const HitTestRequest&, HitTestRe
return false;
}
-FloatRect RenderSVGHiddenContainer::objectBoundingBox() const
-{
- return FloatRect();
-}
-
-FloatRect RenderSVGHiddenContainer::repaintRectInLocalCoordinates() const
-{
- return FloatRect();
-}
-
}
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/RenderSVGHiddenContainer.h b/WebCore/rendering/RenderSVGHiddenContainer.h
index e0daac1..97800d4 100644
--- a/WebCore/rendering/RenderSVGHiddenContainer.h
+++ b/WebCore/rendering/RenderSVGHiddenContainer.h
@@ -47,12 +47,9 @@ namespace WebCore {
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject*) { return IntRect(); }
virtual void absoluteQuads(Vector<FloatQuad>&);
- virtual FloatRect objectBoundingBox() const;
- virtual FloatRect repaintRectInLocalCoordinates() const;
-
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
};
}
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index 893a4ea..0056fa3 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -5,6 +5,7 @@
Copyright (C) 2007, 2008, 2009 Rob Buis <buis@kde.org>
Copyright (C) 2009, Google, Inc.
Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -32,6 +33,7 @@
#include "FloatQuad.h"
#include "GraphicsContext.h"
#include "PointerEventsHitRules.h"
+#include "RenderImageResource.h"
#include "RenderLayer.h"
#include "RenderSVGResourceContainer.h"
#include "RenderSVGResourceFilter.h"
@@ -44,9 +46,16 @@
namespace WebCore {
RenderSVGImage::RenderSVGImage(SVGImageElement* impl)
- : RenderImage(impl)
+ : RenderSVGModelObject(impl)
, m_needsTransformUpdate(true)
+ , m_imageResource(RenderImageResource::create())
{
+ m_imageResource->initialize(this);
+}
+
+RenderSVGImage::~RenderSVGImage()
+{
+ m_imageResource->shutdown();
}
void RenderSVGImage::layout()
@@ -56,75 +65,72 @@ void RenderSVGImage::layout()
LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
SVGImageElement* image = static_cast<SVGImageElement*>(node());
+ bool updateCachedBoundariesInParents = false;
if (m_needsTransformUpdate) {
m_localTransform = image->animatedLocalTransform();
m_needsTransformUpdate = false;
+ updateCachedBoundariesInParents = true;
}
- // minimum height
- setHeight(errorOccurred() ? intrinsicSize().height() : 0);
-
- calcWidth();
- calcHeight();
-
// FIXME: Optimize caching the repaint rects.
+ FloatRect oldBoundaries = m_localBounds;
m_localBounds = FloatRect(image->x().value(image), image->y().value(image), image->width().value(image), image->height().value(image));
m_cachedLocalRepaintRect = FloatRect();
+ if (!updateCachedBoundariesInParents)
+ updateCachedBoundariesInParents = oldBoundaries != m_localBounds;
+
// Invalidate all resources of this client if our layout changed.
if (m_everHadLayout && selfNeedsLayout())
SVGResourcesCache::clientLayoutChanged(this);
+ // If our bounds changed, notify the parents.
+ if (updateCachedBoundariesInParents)
+ RenderSVGModelObject::setNeedsBoundariesUpdate();
+
repainter.repaintAfterLayout();
setNeedsLayout(false);
}
void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
{
- if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN)
+ if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || !m_imageResource->hasImage())
return;
- paintInfo.context->save();
- paintInfo.context->concatCTM(localToParentTransform());
-
- if (paintInfo.phase == PaintPhaseForeground) {
- PaintInfo savedInfo(paintInfo);
+ FloatRect boundingBox = repaintRectInLocalCoordinates();
+ if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
+ return;
- if (SVGRenderSupport::prepareToRenderSVGContent(this, paintInfo)) {
- FloatRect destRect = m_localBounds;
- FloatRect srcRect(0, 0, image()->width(), image()->height());
+ PaintInfo childPaintInfo(paintInfo);
+ bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
+ if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
+ childPaintInfo.context->save();
+ childPaintInfo.applyTransform(m_localTransform);
- SVGImageElement* imageElt = static_cast<SVGImageElement*>(node());
- if (imageElt->preserveAspectRatio().align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
- imageElt->preserveAspectRatio().transformRect(destRect, srcRect);
+ if (childPaintInfo.phase == PaintPhaseForeground) {
+ PaintInfo savedInfo(childPaintInfo);
- paintInfo.context->drawImage(image(), DeviceColorSpace, destRect, srcRect);
- }
- SVGRenderSupport::finishRenderSVGContent(this, paintInfo, savedInfo.context);
- }
+ if (SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo)) {
+ Image* image = m_imageResource->image();
+ FloatRect destRect = m_localBounds;
+ FloatRect srcRect(0, 0, image->width(), image->height());
- if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
- paintOutline(paintInfo.context, 0, 0, width(), height());
+ SVGImageElement* imageElement = static_cast<SVGImageElement*>(node());
+ if (imageElement->preserveAspectRatio().align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
+ imageElement->preserveAspectRatio().transformRect(destRect, srcRect);
- paintInfo.context->restore();
-}
-
-void RenderSVGImage::destroy()
-{
- SVGResourcesCache::clientDestroyed(this);
- RenderImage::destroy();
-}
+ childPaintInfo.context->drawImage(image, DeviceColorSpace, destRect, srcRect);
+ }
-void RenderSVGImage::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderImage::styleDidChange(diff, oldStyle);
- SVGResourcesCache::clientStyleChanged(this, diff, style());
-}
+ SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, savedInfo.context);
+ }
-void RenderSVGImage::updateFromElement()
-{
- RenderImage::updateFromElement();
- SVGResourcesCache::clientUpdatedFromElement(this, style());
+ if (drawsOutline)
+ paintOutline(childPaintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()),
+ static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height()));
+
+ childPaintInfo.context->restore();
+ }
}
bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
@@ -152,12 +158,6 @@ bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest& request, HitTestResu
return false;
}
-bool RenderSVGImage::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
-{
- ASSERT_NOT_REACHED();
- return false;
-}
-
FloatRect RenderSVGImage::repaintRectInLocalCoordinates() const
{
// If we already have a cached repaint rect, return that
@@ -170,10 +170,8 @@ FloatRect RenderSVGImage::repaintRectInLocalCoordinates() const
return m_cachedLocalRepaintRect;
}
-void RenderSVGImage::imageChanged(WrappedImagePtr image, const IntRect* rect)
+void RenderSVGImage::imageChanged(WrappedImagePtr, const IntRect*)
{
- RenderImage::imageChanged(image, rect);
-
// The image resource defaults to nullImage until the resource arrives.
// This empty image may be cached by SVG resources which must be invalidated.
if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this))
@@ -185,21 +183,6 @@ void RenderSVGImage::imageChanged(WrappedImagePtr image, const IntRect* rect)
repaint();
}
-IntRect RenderSVGImage::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
-{
- return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer);
-}
-
-void RenderSVGImage::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
-{
- SVGRenderSupport::computeRectForRepaint(this, repaintContainer, repaintRect, fixed);
-}
-
-void RenderSVGImage::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const
-{
- SVGRenderSupport::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState);
-}
-
void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, int, int)
{
// this is called from paint() after the localTransform has already been applied
@@ -208,17 +191,6 @@ void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, int, int)
rects.append(contentRect);
}
-void RenderSVGImage::absoluteRects(Vector<IntRect>&, int, int)
-{
- // This code path should never be taken for SVG, as we're assuming useTransforms=true everywhere, absoluteQuads should be used.
- ASSERT_NOT_REACHED();
-}
-
-void RenderSVGImage::absoluteQuads(Vector<FloatQuad>& quads)
-{
- quads.append(localToAbsoluteQuad(strokeBoundingBox()));
-}
-
-}
+} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/RenderSVGImage.h b/WebCore/rendering/RenderSVGImage.h
index 38e3a13..da94568 100644
--- a/WebCore/rendering/RenderSVGImage.h
+++ b/WebCore/rendering/RenderSVGImage.h
@@ -3,6 +3,7 @@
Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
Copyright (C) 2007 Rob Buis <buis@kde.org>
Copyright (C) 2009 Google, Inc.
+ Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -26,20 +27,25 @@
#if ENABLE(SVG)
#include "AffineTransform.h"
#include "FloatRect.h"
-#include "RenderImage.h"
+#include "RenderSVGModelObject.h"
#include "SVGPreserveAspectRatio.h"
#include "SVGRenderSupport.h"
namespace WebCore {
+class RenderImageResource;
class SVGImageElement;
-class RenderSVGImage : public RenderImage {
+class RenderSVGImage : public RenderSVGModelObject {
public:
RenderSVGImage(SVGImageElement*);
+ virtual ~RenderSVGImage();
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ RenderImageResource* imageResource() { return m_imageResource.get(); }
+ const RenderImageResource* imageResource() const { return m_imageResource.get(); }
+
private:
virtual const char* renderName() const { return "RenderSVGImage"; }
virtual bool isSVGImage() const { return true; }
@@ -50,28 +56,16 @@ private:
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 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 imageChanged(WrappedImagePtr, const IntRect* = 0);
-
+
virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual void destroy();
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- virtual void updateFromElement();
-
virtual bool requiresLayer() const { return false; }
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 AffineTransform localTransform() const { return m_localTransform; }
@@ -79,6 +73,7 @@ private:
AffineTransform m_localTransform;
FloatRect m_localBounds;
mutable FloatRect m_cachedLocalRepaintRect;
+ OwnPtr<RenderImageResource> m_imageResource;
};
inline RenderSVGImage* toRenderSVGImage(RenderObject* object)
diff --git a/WebCore/rendering/RenderSVGInline.cpp b/WebCore/rendering/RenderSVGInline.cpp
index 93e6a06..bc6bc12 100644
--- a/WebCore/rendering/RenderSVGInline.cpp
+++ b/WebCore/rendering/RenderSVGInline.cpp
@@ -99,6 +99,13 @@ void RenderSVGInline::destroy()
RenderInline::destroy();
}
+void RenderSVGInline::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+{
+ if (diff == StyleDifferenceLayout)
+ setNeedsBoundariesUpdate();
+ RenderInline::styleWillChange(diff, newStyle);
+}
+
void RenderSVGInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderInline::styleDidChange(diff, oldStyle);
diff --git a/WebCore/rendering/RenderSVGInline.h b/WebCore/rendering/RenderSVGInline.h
index 56d911f..fb38f1b 100644
--- a/WebCore/rendering/RenderSVGInline.h
+++ b/WebCore/rendering/RenderSVGInline.h
@@ -56,6 +56,7 @@ private:
virtual InlineFlowBox* createInlineFlowBox();
virtual void destroy();
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void updateFromElement();
};
diff --git a/WebCore/rendering/RenderSVGModelObject.cpp b/WebCore/rendering/RenderSVGModelObject.cpp
index 5a19749..28760a0 100644
--- a/WebCore/rendering/RenderSVGModelObject.cpp
+++ b/WebCore/rendering/RenderSVGModelObject.cpp
@@ -87,6 +87,13 @@ void RenderSVGModelObject::destroy()
RenderObject::destroy();
}
+void RenderSVGModelObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+{
+ if (diff == StyleDifferenceLayout)
+ setNeedsBoundariesUpdate();
+ RenderObject::styleWillChange(diff, newStyle);
+}
+
void RenderSVGModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderObject::styleDidChange(diff, oldStyle);
diff --git a/WebCore/rendering/RenderSVGModelObject.h b/WebCore/rendering/RenderSVGModelObject.h
index 35c4dc3..9de217c 100644
--- a/WebCore/rendering/RenderSVGModelObject.h
+++ b/WebCore/rendering/RenderSVGModelObject.h
@@ -39,7 +39,7 @@
namespace WebCore {
// Most renderers in the SVG rendering tree will inherit from this class
-// but not all. (e.g. RenderSVGForeignObject, RenderSVGBlock, RenderSVGImage) thus methods
+// but not all. (e.g. RenderSVGForeignObject, RenderSVGBlock) thus methods
// required by SVG renders need to be declared on RenderObject, but shared
// logic can go in this class or in SVGRenderSupport.
@@ -61,6 +61,7 @@ public:
virtual void destroy();
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void updateFromElement();
diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp
index 09e83f4..982375e 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.cpp
+++ b/WebCore/rendering/RenderSVGResourceFilter.cpp
@@ -262,16 +262,17 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
if (!filterData->builded) {
filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release());
lastEffect->apply(filterData->filter.get());
+#if !PLATFORM(CG)
+ ImageBuffer* resultImage = lastEffect->resultImage();
+ if (resultImage)
+ resultImage->transformColorSpace(LinearRGB, DeviceRGB);
+#endif
filterData->builded = true;
}
ImageBuffer* resultImage = lastEffect->resultImage();
- if (resultImage) {
-#if !PLATFORM(CG)
- resultImage->transformColorSpace(LinearRGB, DeviceRGB);
-#endif
+ if (resultImage)
context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->subRegion());
- }
}
filterData->sourceGraphicBuffer.clear();
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index b66a870..3fd439c 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -48,6 +48,7 @@ namespace WebCore {
RenderSVGRoot::RenderSVGRoot(SVGStyledElement* node)
: RenderBox(node)
, m_isLayoutSizeChanged(false)
+ , m_needsBoundariesOrTransformUpdate(true)
{
setReplaced(true);
}
@@ -124,6 +125,13 @@ void RenderSVGRoot::layout()
SVGRenderSupport::layoutChildren(this, needsLayout);
m_isLayoutSizeChanged = false;
+ // At this point LayoutRepainter already grabbed the old bounds,
+ // recalculate them now so repaintAfterLayout() uses the new bounds.
+ if (m_needsBoundariesOrTransformUpdate) {
+ updateCachedBoundaries();
+ m_needsBoundariesOrTransformUpdate = false;
+ }
+
repainter.repaintAfterLayout();
view()->enableLayoutState();
@@ -196,6 +204,13 @@ void RenderSVGRoot::destroy()
RenderBox::destroy();
}
+void RenderSVGRoot::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+{
+ if (diff == StyleDifferenceLayout)
+ setNeedsBoundariesUpdate();
+ RenderBox::styleWillChange(diff, newStyle);
+}
+
void RenderSVGRoot::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBox::styleDidChange(diff, oldStyle);
@@ -267,24 +282,6 @@ const AffineTransform& RenderSVGRoot::localToParentTransform() const
return m_localToParentTransform;
}
-FloatRect RenderSVGRoot::objectBoundingBox() const
-{
- return SVGRenderSupport::computeContainerBoundingBox(this, SVGRenderSupport::ObjectBoundingBox);
-}
-
-FloatRect RenderSVGRoot::strokeBoundingBox() const
-{
- return SVGRenderSupport::computeContainerBoundingBox(this, SVGRenderSupport::StrokeBoundingBox);
-}
-
-FloatRect RenderSVGRoot::repaintRectInLocalCoordinates() const
-{
- FloatRect repaintRect = SVGRenderSupport::computeContainerBoundingBox(this, SVGRenderSupport::RepaintBoundingBox);
- style()->svgStyle()->inflateForShadow(repaintRect);
- repaintRect.inflate(borderAndPaddingWidth());
- return repaintRect;
-}
-
IntRect RenderSVGRoot::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer);
@@ -299,7 +296,10 @@ void RenderSVGRoot::computeRectForRepaint(RenderBoxModelObject* repaintContainer
// Apply initial viewport clip - not affected by overflow settings
repaintRect.intersect(enclosingIntRect(FloatRect(FloatPoint(), m_viewportSize)));
- style()->svgStyle()->inflateForShadow(repaintRect);
+ const SVGRenderStyle* svgStyle = style()->svgStyle();
+ if (const ShadowData* shadow = svgStyle->shadow())
+ shadow->adjustRectForShadow(repaintRect);
+
RenderBox::computeRectForRepaint(repaintContainer, repaintRect, fixed);
}
@@ -313,6 +313,17 @@ void RenderSVGRoot::mapLocalToContainer(RenderBoxModelObject* repaintContainer,
RenderBox::mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
}
+void RenderSVGRoot::updateCachedBoundaries()
+{
+ m_objectBoundingBox = FloatRect();
+ m_strokeBoundingBox = FloatRect();
+ m_repaintBoundingBox = FloatRect();
+
+ SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_strokeBoundingBox, m_repaintBoundingBox);
+ SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
+ m_repaintBoundingBox.inflate(borderAndPaddingWidth());
+}
+
bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
{
IntPoint pointInContainer(_x, _y);
diff --git a/WebCore/rendering/RenderSVGRoot.h b/WebCore/rendering/RenderSVGRoot.h
index b90113c..63a7b3f 100644
--- a/WebCore/rendering/RenderSVGRoot.h
+++ b/WebCore/rendering/RenderSVGRoot.h
@@ -41,6 +41,8 @@ public:
RenderObjectChildList* children() { return &m_children; }
bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
+ virtual void setNeedsBoundariesUpdate() { m_needsBoundariesOrTransformUpdate = true; }
+ virtual void setNeedsTransformUpdate() { m_needsBoundariesOrTransformUpdate = true; }
private:
virtual RenderObjectChildList* virtualChildren() { return children(); }
@@ -58,6 +60,7 @@ private:
virtual void paint(PaintInfo&, int parentX, int parentY);
virtual void destroy();
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void updateFromElement();
@@ -66,9 +69,9 @@ private:
bool fillContains(const FloatPoint&) const;
bool strokeContains(const FloatPoint&) const;
- virtual FloatRect objectBoundingBox() const;
- virtual FloatRect strokeBoundingBox() const;
- virtual FloatRect repaintRectInLocalCoordinates() const;
+ virtual FloatRect objectBoundingBox() const { return m_objectBoundingBox; }
+ virtual FloatRect strokeBoundingBox() const { return m_strokeBoundingBox; }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -80,6 +83,7 @@ private:
void calcViewport();
bool selfWillPaint();
+ void updateCachedBoundaries();
IntSize parentOriginToBorderBox() const;
IntSize borderOriginToContentBox() const;
@@ -88,8 +92,12 @@ private:
RenderObjectChildList m_children;
FloatSize m_viewportSize;
+ FloatRect m_objectBoundingBox;
+ FloatRect m_strokeBoundingBox;
+ FloatRect m_repaintBoundingBox;
mutable AffineTransform m_localToParentTransform;
bool m_isLayoutSizeChanged : 1;
+ bool m_needsBoundariesOrTransformUpdate : 1;
};
inline RenderSVGRoot* toRenderSVGRoot(RenderObject* object)
diff --git a/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp b/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
index 888dd57..d3064c6 100644
--- a/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
+++ b/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
@@ -53,7 +53,7 @@ void RenderSVGShadowTreeRootContainer::updateFromElement()
SVGUseElement* useElement = static_cast<SVGUseElement*>(node());
if (!m_shadowRoot) {
ASSERT(!m_recreateTree);
- m_shadowRoot = new SVGShadowTreeRootElement(document(), useElement);
+ m_shadowRoot = SVGShadowTreeRootElement::create(document(), useElement);
useElement->buildPendingResource();
}
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp
index 20c8a7c..80b8a91 100644
--- a/WebCore/rendering/RenderSVGText.cpp
+++ b/WebCore/rendering/RenderSVGText.cpp
@@ -75,10 +75,12 @@ void RenderSVGText::layout()
ASSERT(needsLayout());
LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
+ bool updateCachedBoundariesInParents = false;
if (m_needsTransformUpdate) {
SVGTextElement* text = static_cast<SVGTextElement*>(node());
m_localTransform = text->animatedLocalTransform();
m_needsTransformUpdate = false;
+ updateCachedBoundariesInParents = true;
}
// Reduced version of RenderBlock::layoutBlock(), which only takes care of SVG text.
@@ -95,13 +97,22 @@ void RenderSVGText::layout()
if (!firstChild())
setChildrenInline(true);
+ // FIXME: We need to find a way to only layout the child boxes, if needed.
+ FloatRect oldBoundaries = objectBoundingBox();
ASSERT(childrenInline());
forceLayoutInlineChildren();
+ if (!updateCachedBoundariesInParents)
+ updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox();
+
// Invalidate all resources of this client if our layout changed.
if (m_everHadLayout && selfNeedsLayout())
SVGResourcesCache::clientLayoutChanged(this);
+ // If our bounds changed, notify the parents.
+ if (updateCachedBoundariesInParents)
+ RenderSVGBlock::setNeedsBoundariesUpdate();
+
repainter.repaintAfterLayout();
setNeedsLayout(false);
}
@@ -178,6 +189,9 @@ FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
FloatRect repaintRect = strokeBoundingBox();
SVGRenderSupport::intersectRepaintRectWithResources(this, repaintRect);
+ if (const ShadowData* textShadow = style()->textShadow())
+ textShadow->adjustRectForShadow(repaintRect);
+
return repaintRect;
}
diff --git a/WebCore/rendering/RenderSVGTransformableContainer.cpp b/WebCore/rendering/RenderSVGTransformableContainer.cpp
index 94b9eea..c7d2029 100644
--- a/WebCore/rendering/RenderSVGTransformableContainer.cpp
+++ b/WebCore/rendering/RenderSVGTransformableContainer.cpp
@@ -35,7 +35,7 @@ RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGStyledTransf
{
}
-void RenderSVGTransformableContainer::calculateLocalTransform()
+bool RenderSVGTransformableContainer::calculateLocalTransform()
{
SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
@@ -46,17 +46,18 @@ void RenderSVGTransformableContainer::calculateLocalTransform()
}
if (!element->hasTagName(SVGNames::gTag) || !static_cast<SVGGElement*>(element)->isShadowTreeContainerElement())
- return;
+ return needsUpdate;
FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(element)->containerTranslation();
if (translation.width() == 0 && translation.height() == 0)
- return;
+ return needsUpdate;
// FIXME: Could optimize this case for use to avoid refetching the animatedLocalTransform() here, if only the containerTranslation() changed.
if (!needsUpdate)
m_localTransform = element->animatedLocalTransform();
m_localTransform.translate(translation.width(), translation.height());
+ return true;
}
}
diff --git a/WebCore/rendering/RenderSVGTransformableContainer.h b/WebCore/rendering/RenderSVGTransformableContainer.h
index e6de054..b63b91c 100644
--- a/WebCore/rendering/RenderSVGTransformableContainer.h
+++ b/WebCore/rendering/RenderSVGTransformableContainer.h
@@ -35,7 +35,7 @@ namespace WebCore {
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
private:
- virtual void calculateLocalTransform();
+ virtual bool calculateLocalTransform();
virtual AffineTransform localTransform() const { return m_localTransform; }
bool m_needsTransformUpdate : 1;
diff --git a/WebCore/rendering/RenderSVGViewportContainer.cpp b/WebCore/rendering/RenderSVGViewportContainer.cpp
index f314bde..ccf67fa 100644
--- a/WebCore/rendering/RenderSVGViewportContainer.cpp
+++ b/WebCore/rendering/RenderSVGViewportContainer.cpp
@@ -48,10 +48,15 @@ void RenderSVGViewportContainer::calcViewport()
SVGElement* element = static_cast<SVGElement*>(node());
if (element->hasTagName(SVGNames::svgTag)) {
SVGSVGElement* svg = static_cast<SVGSVGElement*>(element);
+
+ FloatRect oldViewport = m_viewport;
m_viewport = FloatRect(svg->x().value(svg)
, svg->y().value(svg)
, svg->width().value(svg)
, svg->height().value(svg));
+
+ if (oldViewport != m_viewport)
+ setNeedsBoundariesUpdate();
}
}
diff --git a/WebCore/rendering/RenderScrollbar.cpp b/WebCore/rendering/RenderScrollbar.cpp
index 7378056..e7a70a4 100644
--- a/WebCore/rendering/RenderScrollbar.cpp
+++ b/WebCore/rendering/RenderScrollbar.cpp
@@ -27,6 +27,7 @@
#include "RenderScrollbar.h"
#include "Frame.h"
+#include "FrameView.h"
#include "RenderPart.h"
#include "RenderScrollbarPart.h"
#include "RenderScrollbarTheme.h"
@@ -150,6 +151,14 @@ PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart p
RefPtr<RenderStyle> result = owningRenderer()->getUncachedPseudoStyle(pseudoId, owningRenderer()->style());
s_styleResolvePart = NoPart;
s_styleResolveScrollbar = 0;
+
+ // Scrollbars for root frames should always have background color
+ // unless explicitly specified as transparent. So we force it.
+ // This is because WebKit assumes scrollbar to be always painted and missing background
+ // causes visual artifact like non-repainted dirty region.
+ if (result && m_owningFrame && m_owningFrame->view() && !m_owningFrame->view()->isTransparent() && !result->hasBackground())
+ result->setBackgroundColor(Color::white);
+
return result;
}
diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp
index f9f0f56..48f3920 100644
--- a/WebCore/rendering/RenderTable.cpp
+++ b/WebCore/rendering/RenderTable.cpp
@@ -392,7 +392,7 @@ void RenderTable::layout()
toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, th - calculatedHeight) : 0);
}
- if (!m_firstBody && th > calculatedHeight && !style()->htmlHacks()) {
+ if (!m_firstBody && th > calculatedHeight && !document()->inQuirksMode()) {
// Completely empty tables (with no sections or anything) should at least honor specified height
// in strict mode.
setHeight(height() + th);
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index 8cb54c0..a9052ce 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -386,7 +386,7 @@ int RenderTableSection::calcRowHeight()
// Explicit heights use the border box in quirks mode. In strict mode do the right
// thing and actually add in the border and padding.
ch = cell->style()->height().calcValue(0) +
- (cell->style()->htmlHacks() ? 0 : (adjustedPaddingTop + adjustedPaddingBottom +
+ (document()->inQuirksMode() ? 0 : (adjustedPaddingTop + adjustedPaddingBottom +
cell->borderTop() + cell->borderBottom()));
ch = max(ch, adjustedHeight);
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index 9098bab..e66e4ed 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -355,26 +355,22 @@ String RenderTextControl::textWithHardLineBreaks()
{
if (!m_innerText)
return "";
- Node* firstChild = m_innerText->firstChild();
- if (!firstChild)
- return "";
- RenderObject* renderer = firstChild->renderer();
+ RenderBlock* renderer = toRenderBlock(m_innerText->renderer());
if (!renderer)
return "";
- InlineBox* box = renderer->isText() ? toRenderText(renderer)->firstTextBox() : toRenderBox(renderer)->inlineBoxWrapper();
- if (!box)
- return "";
-
Node* breakNode;
unsigned breakOffset;
- RootInlineBox* line = box->root();
+ RootInlineBox* line = renderer->firstRootBox();
+ if (!line)
+ return "";
+
getNextSoftBreak(line, breakNode, breakOffset);
Vector<UChar> result;
- for (Node* n = firstChild; n; n = n->traverseNextNode(m_innerText.get())) {
+ for (Node* n = m_innerText->firstChild(); n; n = n->traverseNextNode(m_innerText.get())) {
if (n->hasTagName(brTag))
result.append(&newlineCharacter, 1);
else if (n->isTextNode()) {
diff --git a/WebCore/rendering/RenderTextControlSingleLine.h b/WebCore/rendering/RenderTextControlSingleLine.h
index e57e37e..0deb063 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/WebCore/rendering/RenderTextControlSingleLine.h
@@ -82,7 +82,7 @@ private:
virtual int scrollHeight() const;
virtual void setScrollLeft(int);
virtual void setScrollTop(int);
- virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0);
+ virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1, Node** stopNode = 0);
int textBlockWidth() const;
virtual float getAvgCharWidth(AtomicString family);
diff --git a/WebCore/rendering/RenderTheme.cpp b/WebCore/rendering/RenderTheme.cpp
index 5d00f5a..522bd4d 100644
--- a/WebCore/rendering/RenderTheme.cpp
+++ b/WebCore/rendering/RenderTheme.cpp
@@ -1043,7 +1043,7 @@ void RenderTheme::platformColorsDidChange()
m_activeListBoxSelectionBackgroundColor = Color();
m_inactiveListBoxSelectionForegroundColor = Color();
- Page::setNeedsReapplyStyles();
+ Page::scheduleForcedStyleRecalcForAllPages();
}
Color RenderTheme::systemColor(int cssValueId) const
diff --git a/WebCore/rendering/RenderVideo.cpp b/WebCore/rendering/RenderVideo.cpp
index 0f444b2..3f4e2bf 100644
--- a/WebCore/rendering/RenderVideo.cpp
+++ b/WebCore/rendering/RenderVideo.cpp
@@ -110,7 +110,7 @@ IntSize RenderVideo::calculateIntrinsicSize()
if (player() && video->readyState() >= HTMLVideoElement::HAVE_METADATA)
return player()->naturalSize();
- if (video->shouldDisplayPosterImage() && !m_cachedImageSize.isEmpty() && !errorOccurred())
+ if (video->shouldDisplayPosterImage() && !m_cachedImageSize.isEmpty() && !imageResource()->errorOccurred())
return m_cachedImageSize;
// When the natural size of the video is unavailable, we use the provided
diff --git a/WebCore/rendering/RootInlineBox.cpp b/WebCore/rendering/RootInlineBox.cpp
index bec288c..e8f24b5 100644
--- a/WebCore/rendering/RootInlineBox.cpp
+++ b/WebCore/rendering/RootInlineBox.cpp
@@ -215,14 +215,10 @@ int RootInlineBox::verticallyAlignBoxes(int heightOfBlock, GlyphOverflowAndFallb
int maxAscent = 0;
int maxDescent = 0;
- // Figure out if we're in strict mode. Note that we can't simply use !style()->htmlHacks(),
- // because that would match almost strict mode as well.
- RenderObject* curr = renderer();
- while (curr && !curr->node())
- curr = curr->container();
- bool strictMode = (curr && curr->document()->inStrictMode());
+ // Figure out if we're in no-quirks mode.
+ bool noQuirksMode = renderer()->document()->inNoQuirksMode();
- computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode, textBoxDataMap);
+ computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, noQuirksMode, textBoxDataMap);
if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom))
adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
@@ -230,8 +226,8 @@ int RootInlineBox::verticallyAlignBoxes(int heightOfBlock, GlyphOverflowAndFallb
int maxHeight = maxAscent + maxDescent;
int lineTop = heightOfBlock;
int lineBottom = heightOfBlock;
- placeBoxesVertically(heightOfBlock, maxHeight, maxAscent, strictMode, lineTop, lineBottom);
- computeVerticalOverflow(lineTop, lineBottom, strictMode, textBoxDataMap);
+ placeBoxesVertically(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom);
+ computeVerticalOverflow(lineTop, lineBottom, noQuirksMode, textBoxDataMap);
setLineTopBottomPositions(lineTop, lineBottom);
heightOfBlock += maxHeight;
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index 12d6d77..644ff70 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -61,7 +61,9 @@ IntRect SVGRenderSupport::clippedOverflowRectForRepaint(RenderObject* object, Re
void SVGRenderSupport::computeRectForRepaint(RenderObject* object, RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
- object->style()->svgStyle()->inflateForShadow(repaintRect);
+ const SVGRenderStyle* svgStyle = object->style()->svgStyle();
+ if (const ShadowData* shadow = svgStyle->shadow())
+ shadow->adjustRectForShadow(repaintRect);
// Translate to coords in our parent renderer, and then call computeRectForRepaint on our parent
repaintRect = object->localToParentTransform().mapRect(repaintRect);
@@ -86,24 +88,22 @@ bool SVGRenderSupport::prepareToRenderSVGContent(RenderObject* object, PaintInfo
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
- FloatRect repaintRect;
-
// Setup transparency layers before setting up SVG resources!
float opacity = style->opacity();
- if (opacity < 1) {
- repaintRect = object->repaintRectInLocalCoordinates();
- paintInfo.context->clip(repaintRect);
- paintInfo.context->beginTransparencyLayer(opacity);
- }
+ const ShadowData* shadow = svgStyle->shadow();
+ if (opacity < 1 || shadow) {
+ FloatRect repaintRect = object->repaintRectInLocalCoordinates();
- if (const ShadowData* shadow = svgStyle->shadow()) {
- // Eventually compute repaint rect, if not done so far.
- if (opacity >= 1)
- repaintRect = object->repaintRectInLocalCoordinates();
+ if (opacity < 1) {
+ paintInfo.context->clip(repaintRect);
+ paintInfo.context->beginTransparencyLayer(opacity);
+ }
- paintInfo.context->clip(repaintRect);
- paintInfo.context->setShadow(IntSize(shadow->x(), shadow->y()), shadow->blur(), shadow->color(), style->colorSpace());
- paintInfo.context->beginTransparencyLayer(1);
+ if (shadow) {
+ paintInfo.context->clip(repaintRect);
+ paintInfo.context->setShadow(IntSize(shadow->x(), shadow->y()), shadow->blur(), shadow->color(), style->colorSpace());
+ paintInfo.context->beginTransparencyLayer(1);
+ }
}
SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
@@ -154,39 +154,38 @@ void SVGRenderSupport::finishRenderSVGContent(RenderObject* object, PaintInfo& p
}
#endif
- float opacity = style->opacity();
- if (opacity < 1)
+ if (style->opacity() < 1)
paintInfo.context->endTransparencyLayer();
- // This needs to be done separately from opacity, because if both properties are set,
- // then the transparency layers are nested.
if (svgStyle->shadow())
paintInfo.context->endTransparencyLayer();
}
-FloatRect SVGRenderSupport::computeContainerBoundingBox(const RenderObject* container, ContainerBoundingBoxMode mode)
+void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox)
{
- FloatRect boundingBox;
-
for (RenderObject* current = container->firstChild(); current; current = current->nextSibling()) {
- FloatRect childBoundingBox;
-
- switch (mode) {
- case ObjectBoundingBox:
- childBoundingBox = current->objectBoundingBox();
- break;
- case StrokeBoundingBox:
- childBoundingBox = current->strokeBoundingBox();
- break;
- case RepaintBoundingBox:
- childBoundingBox = current->repaintRectInLocalCoordinates();
- break;
+ if (current->isSVGHiddenContainer())
+ continue;
+
+ const AffineTransform& transform = current->localToParentTransform();
+ if (transform.isIdentity()) {
+ objectBoundingBox.unite(current->objectBoundingBox());
+ strokeBoundingBox.unite(current->strokeBoundingBox());
+ repaintBoundingBox.unite(current->repaintRectInLocalCoordinates());
+ } else {
+ objectBoundingBox.unite(transform.mapRect(current->objectBoundingBox()));
+ strokeBoundingBox.unite(transform.mapRect(current->strokeBoundingBox()));
+ repaintBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
}
-
- boundingBox.unite(current->localToParentTransform().mapRect(childBoundingBox));
}
+}
+
+bool SVGRenderSupport::paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo)
+{
+ if (localTransform.isIdentity())
+ return localRepaintRect.intersects(paintInfo.rect);
- return boundingBox;
+ return localTransform.mapRect(localRepaintRect).intersects(paintInfo.rect);
}
const RenderSVGRoot* SVGRenderSupport::findTreeRootObject(const RenderObject* start)
@@ -281,7 +280,8 @@ void SVGRenderSupport::intersectRepaintRectWithResources(const RenderObject* obj
RenderObject* renderer = const_cast<RenderObject*>(object);
SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
if (!resources) {
- svgStyle->inflateForShadow(repaintRect);
+ if (const ShadowData* shadow = svgStyle->shadow())
+ shadow->adjustRectForShadow(repaintRect);
return;
}
@@ -296,7 +296,8 @@ void SVGRenderSupport::intersectRepaintRectWithResources(const RenderObject* obj
if (RenderSVGResourceMasker* masker = resources->masker())
repaintRect.intersect(masker->resourceBoundingBox(renderer));
- svgStyle->inflateForShadow(repaintRect);
+ if (const ShadowData* shadow = svgStyle->shadow())
+ shadow->adjustRectForShadow(repaintRect);
}
bool SVGRenderSupport::pointInClippingArea(RenderObject* object, const FloatPoint& point)
diff --git a/WebCore/rendering/SVGRenderSupport.h b/WebCore/rendering/SVGRenderSupport.h
index 2de1e99..54622d2 100644
--- a/WebCore/rendering/SVGRenderSupport.h
+++ b/WebCore/rendering/SVGRenderSupport.h
@@ -58,15 +58,8 @@ public:
// Determines whether the passed point lies in a clipping area
static bool pointInClippingArea(RenderObject*, const FloatPoint&);
- enum ContainerBoundingBoxMode {
- ObjectBoundingBox,
- StrokeBoundingBox,
- RepaintBoundingBox
- };
-
- // Used to share the "walk all the children" logic between objectBoundingBox
- // and repaintRectInLocalCoordinates in RenderSVGRoot and RenderSVGContainer
- static FloatRect computeContainerBoundingBox(const RenderObject* container, ContainerBoundingBoxMode);
+ static void computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox);
+ static bool paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo);
// Important functions used by nearly all SVG renderers centralizing coordinate transformations / repaint rect calculations
static IntRect clippedOverflowRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer);
diff --git a/WebCore/rendering/SVGResources.h b/WebCore/rendering/SVGResources.h
index 5f6e746..49591cf 100644
--- a/WebCore/rendering/SVGResources.h
+++ b/WebCore/rendering/SVGResources.h
@@ -38,7 +38,7 @@ class RenderSVGResourceMasker;
class SVGRenderStyle;
// Holds a set of resources associated with a RenderObject
-class SVGResources {
+class SVGResources : public Noncopyable {
public:
SVGResources();
diff --git a/WebCore/rendering/SVGResourcesCache.cpp b/WebCore/rendering/SVGResourcesCache.cpp
index a4089d6..88cbb3a 100644
--- a/WebCore/rendering/SVGResourcesCache.cpp
+++ b/WebCore/rendering/SVGResourcesCache.cpp
@@ -34,11 +34,7 @@ SVGResourcesCache::SVGResourcesCache()
SVGResourcesCache::~SVGResourcesCache()
{
- if (m_cache.isEmpty())
- return;
-
deleteAllValues(m_cache);
- m_cache.clear();
}
void SVGResourcesCache::addResourcesFromRenderObject(RenderObject* object, const RenderStyle* style)
diff --git a/WebCore/rendering/SVGShadowTreeElements.cpp b/WebCore/rendering/SVGShadowTreeElements.cpp
index 311874c..8a66991 100644
--- a/WebCore/rendering/SVGShadowTreeElements.cpp
+++ b/WebCore/rendering/SVGShadowTreeElements.cpp
@@ -26,17 +26,20 @@
#include "FloatSize.h"
#include "RenderObject.h"
#include "SVGNames.h"
+#include "SVGUseElement.h"
namespace WebCore {
// SVGShadowTreeContainerElement
+
SVGShadowTreeContainerElement::SVGShadowTreeContainerElement(Document* document)
: SVGGElement(SVGNames::gTag, document)
{
}
-
-SVGShadowTreeContainerElement::~SVGShadowTreeContainerElement()
+
+PassRefPtr<SVGShadowTreeContainerElement> SVGShadowTreeContainerElement::create(Document* document)
{
+ return adoptRef(new SVGShadowTreeContainerElement(document));
}
FloatSize SVGShadowTreeContainerElement::containerTranslation() const
@@ -45,15 +48,17 @@ FloatSize SVGShadowTreeContainerElement::containerTranslation() const
}
// SVGShadowTreeRootElement
-SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, Element* shadowParent)
+
+inline SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, SVGUseElement* shadowParent)
: SVGShadowTreeContainerElement(document)
, m_shadowParent(shadowParent)
{
setInDocument();
}
-SVGShadowTreeRootElement::~SVGShadowTreeRootElement()
+PassRefPtr<SVGShadowTreeRootElement> SVGShadowTreeRootElement::create(Document* document, SVGUseElement* shadowParent)
{
+ return adoptRef(new SVGShadowTreeRootElement(document, shadowParent));
}
void SVGShadowTreeRootElement::attachElement(PassRefPtr<RenderStyle> style, RenderArena* arena)
diff --git a/WebCore/rendering/SVGShadowTreeElements.h b/WebCore/rendering/SVGShadowTreeElements.h
index 7611b8a..d49fbaa 100644
--- a/WebCore/rendering/SVGShadowTreeElements.h
+++ b/WebCore/rendering/SVGShadowTreeElements.h
@@ -27,13 +27,11 @@
namespace WebCore {
class FloatSize;
+class SVGUseElement;
class SVGShadowTreeContainerElement : public SVGGElement {
public:
- SVGShadowTreeContainerElement(Document*);
- virtual ~SVGShadowTreeContainerElement();
-
- virtual bool isShadowTreeContainerElement() const { return true; }
+ static PassRefPtr<SVGShadowTreeContainerElement> create(Document*);
FloatSize containerTranslation() const;
void setContainerOffset(const SVGLength& x, const SVGLength& y)
@@ -42,22 +40,29 @@ public:
m_yOffset = y;
}
+protected:
+ SVGShadowTreeContainerElement(Document*);
+
private:
+ virtual bool isShadowTreeContainerElement() const { return true; }
+
SVGLength m_xOffset;
SVGLength m_yOffset;
};
class SVGShadowTreeRootElement : public SVGShadowTreeContainerElement {
public:
- SVGShadowTreeRootElement(Document*, Element* shadowParent);
- virtual ~SVGShadowTreeRootElement();
-
- virtual bool isShadowNode() const { return m_shadowParent; }
- virtual ContainerNode* shadowParentNode() { return m_shadowParent; }
+ static PassRefPtr<SVGShadowTreeRootElement> create(Document*, SVGUseElement* shadowParent);
void attachElement(PassRefPtr<RenderStyle>, RenderArena*);
+ virtual ContainerNode* shadowParentNode() { return m_shadowParent; }
+
private:
+ SVGShadowTreeRootElement(Document*, SVGUseElement* shadowParent);
+
+ virtual bool isShadowNode() const { return m_shadowParent; }
+
ContainerNode* m_shadowParent;
};
diff --git a/WebCore/rendering/style/BorderData.h b/WebCore/rendering/style/BorderData.h
index 96caf97..03635d9 100644
--- a/WebCore/rendering/style/BorderData.h
+++ b/WebCore/rendering/style/BorderData.h
@@ -26,7 +26,7 @@
#define BorderData_h
#include "BorderValue.h"
-#include "IntSize.h"
+#include "LengthSize.h"
#include "NinePieceImage.h"
namespace WebCore {
@@ -34,6 +34,12 @@ namespace WebCore {
class BorderData {
friend class RenderStyle;
public:
+ BorderData() : m_topLeft(Length(0, Fixed), Length(0, Fixed))
+ , m_topRight(Length(0, Fixed), Length(0, Fixed))
+ , m_bottomLeft(Length(0, Fixed), Length(0, Fixed))
+ , m_bottomRight(Length(0, Fixed), Length(0, Fixed))
+ {
+ }
bool hasBorder() const
{
bool haveImage = m_image.hasImage();
@@ -42,13 +48,13 @@ public:
bool hasBorderRadius() const
{
- if (m_topLeft.width() > 0)
+ if (m_topLeft.width().rawValue() > 0)
return true;
- if (m_topRight.width() > 0)
+ if (m_topRight.width().rawValue() > 0)
return true;
- if (m_bottomLeft.width() > 0)
+ if (m_bottomLeft.width().rawValue() > 0)
return true;
- if (m_bottomRight.width() > 0)
+ if (m_bottomRight.width().rawValue() > 0)
return true;
return false;
}
@@ -99,10 +105,10 @@ public:
const NinePieceImage& image() const { return m_image; }
- const IntSize& topLeft() const { return m_topLeft; }
- const IntSize& topRight() const { return m_topRight; }
- const IntSize& bottomLeft() const { return m_bottomLeft; }
- const IntSize& bottomRight() const { return m_bottomRight; }
+ const LengthSize& topLeft() const { return m_topLeft; }
+ const LengthSize& topRight() const { return m_topRight; }
+ const LengthSize& bottomLeft() const { return m_bottomLeft; }
+ const LengthSize& bottomRight() const { return m_bottomRight; }
private:
BorderValue m_left;
@@ -112,10 +118,10 @@ private:
NinePieceImage m_image;
- IntSize m_topLeft;
- IntSize m_topRight;
- IntSize m_bottomLeft;
- IntSize m_bottomRight;
+ LengthSize m_topLeft;
+ LengthSize m_topRight;
+ LengthSize m_bottomLeft;
+ LengthSize m_bottomRight;
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/ContentData.cpp b/WebCore/rendering/style/ContentData.cpp
index b0f9e81..d150f77 100644
--- a/WebCore/rendering/style/ContentData.cpp
+++ b/WebCore/rendering/style/ContentData.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -22,7 +22,6 @@
#include "config.h"
#include "ContentData.h"
-#include "CounterContent.h"
#include "StyleImage.h"
#include <wtf/text/StringImpl.h>
@@ -32,42 +31,26 @@ void ContentData::clear()
{
deleteContent();
- ContentData* n = m_next;
- m_next = 0;
-
- // Reverse the list so we can delete without recursing.
- ContentData* last = 0;
- ContentData* c;
- while ((c = n)) {
- n = c->m_next;
- c->m_next = last;
- last = c;
- }
- for (c = last; c; c = n) {
- n = c->m_next;
- c->m_next = 0;
- delete c;
- }
+ // Delete the singly-linked list without recursing.
+ for (OwnPtr<ContentData> next = m_next.release(); next; next = next->m_next.release()) { }
}
+// FIXME: Why isn't this just operator==?
+// FIXME: This is not a good name for a boolean-returning function.
bool ContentData::dataEquivalent(const ContentData& other) const
{
if (type() != other.type())
return false;
switch (type()) {
- case CONTENT_NONE:
- return true;
- break;
- case CONTENT_TEXT:
- return equal(text(), other.text());
- break;
- case CONTENT_OBJECT:
- return StyleImage::imagesEquivalent(image(), other.image());
- break;
- case CONTENT_COUNTER:
- return *counter() == *other.counter();
- break;
+ case CONTENT_NONE:
+ return true;
+ case CONTENT_TEXT:
+ return equal(text(), other.text());
+ case CONTENT_OBJECT:
+ return StyleImage::imagesEquivalent(image(), other.image());
+ case CONTENT_COUNTER:
+ return *counter() == *other.counter();
}
ASSERT_NOT_REACHED();
@@ -77,17 +60,17 @@ bool ContentData::dataEquivalent(const ContentData& other) const
void ContentData::deleteContent()
{
switch (m_type) {
- case CONTENT_NONE:
- break;
- case CONTENT_OBJECT:
- m_content.m_image->deref();
- break;
- case CONTENT_TEXT:
- m_content.m_text->deref();
- break;
- case CONTENT_COUNTER:
- delete m_content.m_counter;
- break;
+ case CONTENT_NONE:
+ break;
+ case CONTENT_OBJECT:
+ m_content.m_image->deref();
+ break;
+ case CONTENT_TEXT:
+ m_content.m_text->deref();
+ break;
+ case CONTENT_COUNTER:
+ delete m_content.m_counter;
+ break;
}
m_type = CONTENT_NONE;
diff --git a/WebCore/rendering/style/ContentData.h b/WebCore/rendering/style/ContentData.h
index 5c3565e..4f964a2 100644
--- a/WebCore/rendering/style/ContentData.h
+++ b/WebCore/rendering/style/ContentData.h
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* (C) 2000 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
*
* This library is free software; you can redistribute it and/or
@@ -25,21 +25,18 @@
#ifndef ContentData_h
#define ContentData_h
-#include "RenderStyleConstants.h"
-#include <wtf/Forward.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/PassRefPtr.h>
+#include "CounterContent.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class CounterContent;
class StyleImage;
struct ContentData : Noncopyable {
public:
ContentData()
: m_type(CONTENT_NONE)
- , m_next(0)
{
}
@@ -59,35 +56,44 @@ public:
bool dataEquivalent(const ContentData&) const;
- StyleImage* image() const { return m_content.m_image; }
+ StyleImage* image() const
+ {
+ ASSERT(isImage());
+ return m_content.m_image;
+ }
void setImage(PassRefPtr<StyleImage> image)
{
deleteContent();
m_type = CONTENT_OBJECT;
- m_content.m_image = image.releaseRef();
+ m_content.m_image = image.leakRef();
}
- StringImpl* text() const { return m_content.m_text; }
+ StringImpl* text() const
+ {
+ ASSERT(isText());
+ return m_content.m_text;
+ }
void setText(PassRefPtr<StringImpl> text)
{
deleteContent();
m_type = CONTENT_TEXT;
- m_content.m_text = text.releaseRef();
+ m_content.m_text = text.leakRef();
}
- CounterContent* counter() const { return m_content.m_counter; }
- void setCounter(CounterContent* counter)
+ CounterContent* counter() const
+ {
+ ASSERT(isCounter());
+ return m_content.m_counter;
+ }
+ void setCounter(PassOwnPtr<CounterContent> counter)
{
deleteContent();
m_type = CONTENT_COUNTER;
- m_content.m_counter = counter;
+ m_content.m_counter = counter.leakPtr();
}
- ContentData* next() const { return m_next; }
- void setNext(ContentData* next)
- {
- m_next = next;
- }
+ ContentData* next() const { return m_next.get(); }
+ void setNext(PassOwnPtr<ContentData> next) { m_next = next; }
private:
void deleteContent();
@@ -98,7 +104,7 @@ private:
StringImpl* m_text;
CounterContent* m_counter;
} m_content;
- ContentData* m_next;
+ OwnPtr<ContentData> m_next;
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/CursorData.h b/WebCore/rendering/style/CursorData.h
index 2341e71..6d0a273 100644
--- a/WebCore/rendering/style/CursorData.h
+++ b/WebCore/rendering/style/CursorData.h
@@ -25,15 +25,14 @@
#ifndef CursorData_h
#define CursorData_h
-#include "CachedImage.h"
-#include "CachedResourceHandle.h"
#include "IntPoint.h"
+#include "StyleImage.h"
namespace WebCore {
class CursorData {
public:
- CursorData(CachedImage* image, const IntPoint& hotSpot)
+ CursorData(PassRefPtr<StyleImage> image, const IntPoint& hotSpot)
: m_image(image)
, m_hotSpot(hotSpot)
{
@@ -49,11 +48,13 @@ public:
return !(*this == o);
}
- const CachedImage* image() const { return m_image.get(); }
+ StyleImage* image() const { return m_image.get(); }
+ void setImage(PassRefPtr<StyleImage> image) { m_image = image; }
+
const IntPoint& hotSpot() const { return m_hotSpot; }
private:
- CachedResourceHandle<CachedImage> m_image;
+ RefPtr<StyleImage> m_image;
IntPoint m_hotSpot; // for CSS3 support
};
diff --git a/WebCore/rendering/style/CursorList.h b/WebCore/rendering/style/CursorList.h
index bdd65d4..1b82684 100644
--- a/WebCore/rendering/style/CursorList.h
+++ b/WebCore/rendering/style/CursorList.h
@@ -39,6 +39,7 @@ public:
}
const CursorData& operator[](int i) const { return m_vector[i]; }
+ CursorData& operator[](int i) { return m_vector[i]; }
bool operator==(const CursorList& o) const { return m_vector == o.m_vector; }
bool operator!=(const CursorList& o) const { return m_vector != o.m_vector; }
diff --git a/WebCore/rendering/style/KeyframeList.cpp b/WebCore/rendering/style/KeyframeList.cpp
index 41fbbe2..bafa426 100644
--- a/WebCore/rendering/style/KeyframeList.cpp
+++ b/WebCore/rendering/style/KeyframeList.cpp
@@ -43,10 +43,10 @@ bool KeyframeList::operator==(const KeyframeList& o) const
Vector<KeyframeValue>::const_iterator it2 = o.m_keyframes.begin();
for (Vector<KeyframeValue>::const_iterator it1 = m_keyframes.begin(); it1 != m_keyframes.end(); ++it1) {
- if (it1->m_key != it2->m_key)
+ if (it1->key() != it2->key())
return false;
- const RenderStyle& style1 = *it1->m_style;
- const RenderStyle& style2 = *it2->m_style;
+ const RenderStyle& style1 = *it1->style();
+ const RenderStyle& style2 = *it2->style();
if (style1 != style2)
return false;
++it2;
@@ -55,34 +55,43 @@ bool KeyframeList::operator==(const KeyframeList& o) const
return true;
}
-void KeyframeList::insert(float key, PassRefPtr<RenderStyle> style)
+void KeyframeList::insert(const KeyframeValue& keyframe)
{
- if (key < 0 || key > 1)
+ if (keyframe.key() < 0 || keyframe.key() > 1)
return;
- int index = -1;
-
+ bool inserted = false;
+ bool replaced = false;
for (size_t i = 0; i < m_keyframes.size(); ++i) {
- if (m_keyframes[i].m_key == key) {
- index = (int) i;
+ if (m_keyframes[i].key() == keyframe.key()) {
+ m_keyframes[i] = keyframe;
+ replaced = true;
break;
}
- if (m_keyframes[i].m_key > key) {
+
+ if (m_keyframes[i].key() > keyframe.key()) {
// insert before
- m_keyframes.insert(i, KeyframeValue());
- index = (int) i;
+ m_keyframes.insert(i, keyframe);
+ inserted = true;
break;
}
}
- if (index < 0) {
- // append
- index = (int) m_keyframes.size();
- m_keyframes.append(KeyframeValue());
+ if (!replaced && !inserted)
+ m_keyframes.append(keyframe);
+
+ if (replaced) {
+ // We have to rebuild the properties list from scratch.
+ m_properties.clear();
+ for (Vector<KeyframeValue>::const_iterator it = m_keyframes.begin(); it != m_keyframes.end(); ++it) {
+ const KeyframeValue& currKeyframe = *it;
+ for (HashSet<int>::const_iterator it = currKeyframe.properties().begin(); it != currKeyframe.properties().end(); ++it)
+ m_properties.add(*it);
+ }
+ } else {
+ for (HashSet<int>::const_iterator it = keyframe.properties().begin(); it != keyframe.properties().end(); ++it)
+ m_properties.add(*it);
}
-
- m_keyframes[index].m_key = key;
- m_keyframes[index].m_style = style;
}
} // namespace WebCore
diff --git a/WebCore/rendering/style/KeyframeList.h b/WebCore/rendering/style/KeyframeList.h
index bb5f180..64170ce 100644
--- a/WebCore/rendering/style/KeyframeList.h
+++ b/WebCore/rendering/style/KeyframeList.h
@@ -37,15 +37,25 @@ class RenderStyle;
class KeyframeValue {
public:
- KeyframeValue()
- : m_key(-1)
+ KeyframeValue(float key, PassRefPtr<RenderStyle> style)
+ : m_key(key)
+ , m_style(style)
{
}
+ void addProperty(int prop) { m_properties.add(prop); }
+ bool containsProperty(int prop) const { return m_properties.contains(prop); }
+ const HashSet<int>& properties() const { return m_properties; }
+
float key() const { return m_key; }
+ void setKey(float key) { m_key = key; }
+
const RenderStyle* style() const { return m_style.get(); }
+ void setStyle(PassRefPtr<RenderStyle> style) { m_style = style; }
+private:
float m_key;
+ HashSet<int> m_properties; // The properties specified in this keyframe.
RefPtr<RenderStyle> m_style;
};
@@ -55,8 +65,8 @@ public:
: m_animationName(animationName)
, m_renderer(renderer)
{
- insert(0, 0);
- insert(1, 0);
+ insert(KeyframeValue(0, 0));
+ insert(KeyframeValue(1, 0));
}
~KeyframeList();
@@ -65,7 +75,7 @@ public:
const AtomicString& animationName() const { return m_animationName; }
- void insert(float key, PassRefPtr<RenderStyle> style);
+ void insert(const KeyframeValue& keyframe);
void addProperty(int prop) { m_properties.add(prop); }
bool containsProperty(int prop) const { return m_properties.contains(prop); }
@@ -75,13 +85,12 @@ public:
void clear();
bool isEmpty() const { return m_keyframes.isEmpty(); }
size_t size() const { return m_keyframes.size(); }
- Vector<KeyframeValue>::const_iterator beginKeyframes() const { return m_keyframes.begin(); }
- Vector<KeyframeValue>::const_iterator endKeyframes() const { return m_keyframes.end(); }
+ const KeyframeValue& operator[](size_t index) const { return m_keyframes[index]; }
private:
AtomicString m_animationName;
- Vector<KeyframeValue> m_keyframes;
- HashSet<int> m_properties; // the properties being animated
+ Vector<KeyframeValue> m_keyframes; // kept sorted by key
+ HashSet<int> m_properties; // the properties being animated
RenderObject* m_renderer;
};
diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp
index aaccbf7..93cd8de 100644
--- a/WebCore/rendering/style/RenderStyle.cpp
+++ b/WebCore/rendering/style/RenderStyle.cpp
@@ -24,8 +24,6 @@
#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
-#include "CachedImage.h"
-#include "CounterContent.h"
#include "FontSelector.h"
#include "RenderArena.h"
#include "RenderObject.h"
@@ -403,7 +401,6 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
inherited->vertical_border_spacing != other->inherited->vertical_border_spacing ||
inherited_flags._box_direction != other->inherited_flags._box_direction ||
inherited_flags._visuallyOrdered != other->inherited_flags._visuallyOrdered ||
- inherited_flags._htmlHacks != other->inherited_flags._htmlHacks ||
noninherited_flags._position != other->noninherited_flags._position ||
noninherited_flags._floating != other->noninherited_flags._floating ||
noninherited_flags._originalDisplay != other->noninherited_flags._originalDisplay)
@@ -552,7 +549,7 @@ void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)
data->clip.m_left = left;
}
-void RenderStyle::addCursor(CachedImage* image, const IntPoint& hotSpot)
+void RenderStyle::addCursor(PassRefPtr<StyleImage> image, const IntPoint& hotSpot)
{
if (!rareInheritedData.access()->cursorData)
rareInheritedData.access()->cursorData = CursorList::create();
@@ -576,92 +573,59 @@ void RenderStyle::clearContent()
rareNonInheritedData->m_content->clear();
}
-void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add)
+ContentData* RenderStyle::prepareToSetContent(StringImpl* string, bool add)
{
- if (!image)
- return; // The object is null. Nothing to do. Just bail.
-
OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
ContentData* lastContent = content.get();
while (lastContent && lastContent->next())
lastContent = lastContent->next();
+ if (string && add && lastContent && lastContent->isText()) {
+ // Augment the existing string and share the existing ContentData node.
+ String newText = lastContent->text();
+ newText.append(string);
+ lastContent->setText(newText.impl());
+ return 0;
+ }
+
bool reuseContent = !add;
- ContentData* newContentData;
+ OwnPtr<ContentData> newContentData;
if (reuseContent && content) {
content->clear();
- newContentData = content.leakPtr();
+ newContentData = content.release();
} else
- newContentData = new ContentData;
+ newContentData = adoptPtr(new ContentData);
+
+ ContentData* result = newContentData.get();
if (lastContent && !reuseContent)
- lastContent->setNext(newContentData);
+ lastContent->setNext(newContentData.release());
else
- content.set(newContentData);
+ content = newContentData.release();
- newContentData->setImage(image);
+ return result;
}
-void RenderStyle::setContent(PassRefPtr<StringImpl> s, bool add)
+void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add)
{
- if (!s)
- return; // The string is null. Nothing to do. Just bail.
-
- OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
- ContentData* lastContent = content.get();
- while (lastContent && lastContent->next())
- lastContent = lastContent->next();
-
- bool reuseContent = !add;
- if (add && lastContent) {
- if (lastContent->isText()) {
- // We can augment the existing string and share this ContentData node.
- String newStr = lastContent->text();
- newStr.append(s.get());
- lastContent->setText(newStr.impl());
- return;
- }
- }
-
- ContentData* newContentData = 0;
- if (reuseContent && content) {
- content->clear();
- newContentData = content.leakPtr();
- } else
- newContentData = new ContentData;
-
- if (lastContent && !reuseContent)
- lastContent->setNext(newContentData);
- else
- content.set(newContentData);
-
- newContentData->setText(s);
+ if (!image)
+ return;
+ prepareToSetContent(0, add)->setImage(image);
}
-void RenderStyle::setContent(CounterContent* c, bool add)
+void RenderStyle::setContent(PassRefPtr<StringImpl> string, bool add)
{
- if (!c)
+ if (!string)
return;
+ if (ContentData* data = prepareToSetContent(string.get(), add))
+ data->setText(string);
+}
- OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
- ContentData* lastContent = content.get();
- while (lastContent && lastContent->next())
- lastContent = lastContent->next();
-
- bool reuseContent = !add;
- ContentData* newContentData = 0;
- if (reuseContent && content) {
- content->clear();
- newContentData = content.leakPtr();
- } else
- newContentData = new ContentData;
-
- if (lastContent && !reuseContent)
- lastContent->setNext(newContentData);
- else
- content.set(newContentData);
-
- newContentData->setCounter(c);
+void RenderStyle::setContent(PassOwnPtr<CounterContent> counter, bool add)
+{
+ if (!counter)
+ return;
+ prepareToSetContent(0, add)->setCounter(counter);
}
void RenderStyle::applyTransform(TransformationMatrix& transform, const IntSize& borderBoxSize, ApplyTransformOrigin applyOrigin) const
@@ -774,21 +738,22 @@ static void constrainCornerRadiiForRect(const IntRect& r, IntSize& topLeft, IntS
void RenderStyle::getBorderRadiiForRect(const IntRect& r, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight) const
{
- topLeft = surround->border.topLeft();
- topRight = surround->border.topRight();
+ topLeft = IntSize(surround->border.topLeft().width().calcValue(r.width()), surround->border.topLeft().height().calcValue(r.height()));
+ topRight = IntSize(surround->border.topRight().width().calcValue(r.width()), surround->border.topRight().height().calcValue(r.height()));
- bottomLeft = surround->border.bottomLeft();
- bottomRight = surround->border.bottomRight();
+ bottomLeft = IntSize(surround->border.bottomLeft().width().calcValue(r.width()), surround->border.bottomLeft().height().calcValue(r.height()));
+ bottomRight = IntSize(surround->border.bottomRight().width().calcValue(r.width()), surround->border.bottomRight().height().calcValue(r.height()));
constrainCornerRadiiForRect(r, topLeft, topRight, bottomLeft, bottomRight);
}
void RenderStyle::getInnerBorderRadiiForRectWithBorderWidths(const IntRect& innerRect, unsigned short topWidth, unsigned short bottomWidth, unsigned short leftWidth, unsigned short rightWidth, IntSize& innerTopLeft, IntSize& innerTopRight, IntSize& innerBottomLeft, IntSize& innerBottomRight) const
{
- innerTopLeft = surround->border.topLeft();
- innerTopRight = surround->border.topRight();
- innerBottomLeft = surround->border.bottomLeft();
- innerBottomRight = surround->border.bottomRight();
+ innerTopLeft = IntSize(surround->border.topLeft().width().calcValue(innerRect.width()), surround->border.topLeft().height().calcValue(innerRect.height()));
+ innerTopRight = IntSize(surround->border.topRight().width().calcValue(innerRect.width()), surround->border.topRight().height().calcValue(innerRect.height()));
+ innerBottomLeft = IntSize(surround->border.bottomLeft().width().calcValue(innerRect.width()), surround->border.bottomLeft().height().calcValue(innerRect.height()));
+ innerBottomRight = IntSize(surround->border.bottomRight().width().calcValue(innerRect.width()), surround->border.bottomRight().height().calcValue(innerRect.height()));
+
innerTopLeft.setWidth(max(0, innerTopLeft.width() - leftWidth));
innerTopLeft.setHeight(max(0, innerTopLeft.height() - topWidth));
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index 1681890..e696735 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -35,7 +35,6 @@
#include "CSSPropertyNames.h"
#include "CSSReflectionDirection.h"
#include "CSSValueList.h"
-#include "CachedImage.h"
#include "CollapsedBorderValue.h"
#include "Color.h"
#include "ColorSpace.h"
@@ -103,7 +102,6 @@ using std::max;
class CSSStyleSelector;
class CSSValueList;
-class CachedImage;
class Pair;
class StyleImage;
@@ -178,7 +176,6 @@ protected:
(_white_space == other._white_space) &&
(_box_direction == other._box_direction) &&
(_visuallyOrdered == other._visuallyOrdered) &&
- (_htmlHacks == other._htmlHacks) &&
(_force_backgrounds_to_white == other._force_backgrounds_to_white) &&
(_pointerEvents == other._pointerEvents) &&
(_insideLink == other._insideLink);
@@ -203,7 +200,6 @@ protected:
// non CSS2 inherited
bool _visuallyOrdered : 1;
- bool _htmlHacks : 1;
bool _force_backgrounds_to_white : 1;
unsigned _pointerEvents : 4; // EPointerEvents
unsigned _insideLink : 2; // EInsideLink
@@ -279,7 +275,6 @@ protected:
inherited_flags._border_collapse = initialBorderCollapse();
inherited_flags._white_space = initialWhiteSpace();
inherited_flags._visuallyOrdered = initialVisuallyOrdered();
- inherited_flags._htmlHacks=false;
inherited_flags._box_direction = initialBoxDirection();
inherited_flags._force_backgrounds_to_white = false;
inherited_flags._pointerEvents = initialPointerEvents();
@@ -348,6 +343,14 @@ public:
bool hasFixedBackgroundImage() const { return m_background->background().hasFixedImage(); }
bool hasAppearance() const { return appearance() != NoControlPart; }
+ bool hasBackground() const
+ {
+ Color color = visitedDependentColor(CSSPropertyBackgroundColor);
+ if (color.isValid() && color.alpha() > 0)
+ return true;
+ return hasBackgroundImage();
+ }
+
bool visuallyOrdered() const { return inherited_flags._visuallyOrdered; }
void setVisuallyOrdered(bool b) { inherited_flags._visuallyOrdered = b; }
@@ -390,10 +393,10 @@ public:
const NinePieceImage& borderImage() const { return surround->border.image(); }
- const IntSize& borderTopLeftRadius() const { return surround->border.topLeft(); }
- const IntSize& borderTopRightRadius() const { return surround->border.topRight(); }
- const IntSize& borderBottomLeftRadius() const { return surround->border.bottomLeft(); }
- const IntSize& borderBottomRightRadius() const { return surround->border.bottomRight(); }
+ const LengthSize& borderTopLeftRadius() const { return surround->border.topLeft(); }
+ const LengthSize& borderTopRightRadius() const { return surround->border.topRight(); }
+ const LengthSize& borderBottomLeftRadius() const { return surround->border.bottomLeft(); }
+ const LengthSize& borderBottomRightRadius() const { return surround->border.bottomRight(); }
bool hasBorderRadius() const { return surround->border.hasBorderRadius(); }
unsigned short borderLeftWidth() const { return surround->border.borderLeftWidth(); }
@@ -788,18 +791,23 @@ public:
void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.m_image, b) }
- void setBorderTopLeftRadius(const IntSize& s) { SET_VAR(surround, border.m_topLeft, s) }
- void setBorderTopRightRadius(const IntSize& s) { SET_VAR(surround, border.m_topRight, s) }
- void setBorderBottomLeftRadius(const IntSize& s) { SET_VAR(surround, border.m_bottomLeft, s) }
- void setBorderBottomRightRadius(const IntSize& s) { SET_VAR(surround, border.m_bottomRight, s) }
+ void setBorderTopLeftRadius(const LengthSize& s) { SET_VAR(surround, border.m_topLeft, s) }
+ void setBorderTopRightRadius(const LengthSize& s) { SET_VAR(surround, border.m_topRight, s) }
+ void setBorderBottomLeftRadius(const LengthSize& s) { SET_VAR(surround, border.m_bottomLeft, s) }
+ void setBorderBottomRightRadius(const LengthSize& s) { SET_VAR(surround, border.m_bottomRight, s) }
- void setBorderRadius(const IntSize& s)
+ void setBorderRadius(const LengthSize& s)
{
setBorderTopLeftRadius(s);
setBorderTopRightRadius(s);
setBorderBottomLeftRadius(s);
setBorderBottomRightRadius(s);
}
+ void setBorderRadius(const IntSize& s)
+ {
+ setBorderRadius(LengthSize(Length(s.width(), Fixed), Length(s.height(), Fixed)));
+ }
+
void getBorderRadiiForRect(const IntRect&, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight) const;
void getInnerBorderRadiiForRectWithBorderWidths(const IntRect&, unsigned short topWidth,
@@ -914,7 +922,7 @@ public:
void setCounterReset(short v) { SET_VAR(rareNonInheritedData, m_counterReset, v) }
void setListStyleType(EListStyleType v) { inherited_flags._list_style_type = v; }
- void setListStyleImage(StyleImage* v) { if (inherited->list_style_image != v) inherited.access()->list_style_image = v; }
+ void setListStyleImage(PassRefPtr<StyleImage> v) { if (inherited->list_style_image != v) inherited.access()->list_style_image = v; }
void setListStylePosition(EListStylePosition v) { inherited_flags._list_style_position = v; }
void resetMargin() { SET_VAR(surround, margin, LengthBox(Fixed)) }
@@ -931,7 +939,7 @@ public:
void setPaddingRight(Length v) { SET_VAR(surround, padding.m_right, v) }
void setCursor(ECursor c) { inherited_flags._cursor_style = c; }
- void addCursor(CachedImage*, const IntPoint& = IntPoint());
+ void addCursor(PassRefPtr<StyleImage>, const IntPoint& hotSpot = IntPoint());
void setCursorList(PassRefPtr<CursorList>);
void clearCursorList();
@@ -941,9 +949,6 @@ public:
bool forceBackgroundsToWhite() const { return inherited_flags._force_backgrounds_to_white; }
void setForceBackgroundsToWhite(bool b=true) { inherited_flags._force_backgrounds_to_white = b; }
- bool htmlHacks() const { return inherited_flags._htmlHacks; }
- void setHtmlHacks(bool b=true) { inherited_flags._htmlHacks = b; }
-
bool hasAutoZIndex() const { return m_box->hasAutoZIndex(); }
void setHasAutoZIndex() { SET_VAR(m_box, m_hasAutoZIndex, true); SET_VAR(m_box, m_zIndex, 0) }
int zIndex() const { return m_box->zIndex(); }
@@ -1091,7 +1096,7 @@ public:
void clearContent();
void setContent(PassRefPtr<StringImpl>, bool add = false);
void setContent(PassRefPtr<StyleImage>, bool add = false);
- void setContent(CounterContent*, bool add = false);
+ void setContent(PassOwnPtr<CounterContent>, bool add = false);
const CounterDirectiveMap* counterDirectives() const;
CounterDirectiveMap& accessCounterDirectives();
@@ -1153,7 +1158,7 @@ public:
static bool initialBorderCollapse() { return false; }
static EBorderStyle initialBorderStyle() { return BNONE; }
static NinePieceImage initialNinePieceImage() { return NinePieceImage(); }
- static IntSize initialBorderRadius() { return IntSize(0, 0); }
+ static LengthSize initialBorderRadius() { return LengthSize(Length(0, Fixed), Length(0, Fixed)); }
static ECaptionSide initialCaptionSide() { return CAPTOP; }
static EClear initialClear() { return CNONE; }
static TextDirection initialDirection() { return LTR; }
@@ -1281,6 +1286,8 @@ private:
const Color& textStrokeColor() const { return rareInheritedData->textStrokeColor; }
const Color colorIncludingFallback(int colorProperty, EBorderStyle borderStyle) const;
+
+ ContentData* prepareToSetContent(StringImpl*, bool add);
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/RenderStyleConstants.h b/WebCore/rendering/style/RenderStyleConstants.h
index 70b128b..68c8113 100644
--- a/WebCore/rendering/style/RenderStyleConstants.h
+++ b/WebCore/rendering/style/RenderStyleConstants.h
@@ -79,6 +79,7 @@ enum PseudoId {
METER_HORIZONTAL_BAR, METER_HORIZONTAL_OPTIMUM, METER_HORIZONTAL_SUBOPTIMAL, METER_HORIZONTAL_EVEN_LESS_GOOD,
METER_VERTICAL_BAR, METER_VERTICAL_OPTIMUM, METER_VERTICAL_SUBOPTIMAL, METER_VERTICAL_EVEN_LESS_GOOD,
AFTER_LAST_INTERNAL_PSEUDOID,
+ FULL_SCREEN, FULL_SCREEN_DOCUMENT,
FIRST_PUBLIC_PSEUDOID = FIRST_LINE,
FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON,
PUBLIC_PSEUDOID_MASK = ((1 << FIRST_INTERNAL_PSEUDOID) - 1) & ~((1 << FIRST_PUBLIC_PSEUDOID) - 1)
@@ -276,6 +277,8 @@ enum EListStyleType {
EthiopicAbegedeTiEt,
UpperGreek,
UpperNorwegian,
+ Asterisks,
+ Footnotes,
Hebrew,
Armenian,
Georgian,
diff --git a/WebCore/rendering/style/SVGRenderStyle.cpp b/WebCore/rendering/style/SVGRenderStyle.cpp
index dc8a5af..7d1ad3b 100644
--- a/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -162,6 +162,10 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
|| svg_inherited_flags._joinStyle != other->svg_inherited_flags._joinStyle)
return StyleDifferenceLayout;
+ // Shadow changes require relayouts, as they affect the repaint rects.
+ if (shadowSVG != other->shadowSVG)
+ return StyleDifferenceLayout;
+
// Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
if (stroke != other->stroke) {
if (stroke->width != other->stroke->width
@@ -178,10 +182,6 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
// NOTE: All comparisions below may only return StyleDifferenceRepaint
- // Shadow changes need to cause repaints.
- if (shadowSVG != other->shadowSVG)
- return StyleDifferenceRepaint;
-
// Painting related properties only need repaints.
if (miscNotEqual) {
if (misc->floodColor != other->misc->floodColor
@@ -215,48 +215,6 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
return StyleDifferenceEqual;
}
-static void getSVGShadowExtent(ShadowData* shadow, float& top, float& right, float& bottom, float& left)
-{
- top = 0.0f;
- right = 0.0f;
- bottom = 0.0f;
- left = 0.0f;
-
- float blurAndSpread = shadow->blur() + shadow->spread();
-
- top = min(top, shadow->y() - blurAndSpread);
- right = max(right, shadow->x() + blurAndSpread);
- bottom = max(bottom, shadow->y() + blurAndSpread);
- left = min(left, shadow->x() - blurAndSpread);
-}
-
-void SVGRenderStyle::inflateForShadow(IntRect& repaintRect) const
-{
- ShadowData* svgShadow = shadow();
- if (!svgShadow)
- return;
-
- FloatRect repaintFloatRect = FloatRect(repaintRect);
- inflateForShadow(repaintFloatRect);
- repaintRect = enclosingIntRect(repaintFloatRect);
-}
-
-void SVGRenderStyle::inflateForShadow(FloatRect& repaintRect) const
-{
- ShadowData* svgShadow = shadow();
- if (!svgShadow)
- return;
-
- float shadowTop;
- float shadowRight;
- float shadowBottom;
- float shadowLeft;
- getSVGShadowExtent(svgShadow, shadowTop, shadowRight, shadowBottom, shadowLeft);
-
- repaintRect.move(shadowLeft, shadowTop);
- repaintRect.setSize(repaintRect.size() + FloatSize(shadowRight - shadowLeft, shadowBottom - shadowTop));
-}
-
}
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/style/SVGRenderStyle.h b/WebCore/rendering/style/SVGRenderStyle.h
index f071755..d57e4cf 100644
--- a/WebCore/rendering/style/SVGRenderStyle.h
+++ b/WebCore/rendering/style/SVGRenderStyle.h
@@ -47,10 +47,6 @@ public:
bool inheritedNotEqual(const SVGRenderStyle*) const;
void inheritFrom(const SVGRenderStyle*);
- // FIXME: These functions should move to ShadowData.
- void inflateForShadow(IntRect&) const;
- void inflateForShadow(FloatRect&) const;
-
StyleDifference diff(const SVGRenderStyle*) const;
bool operator==(const SVGRenderStyle&) const;
diff --git a/WebCore/rendering/style/ShadowData.cpp b/WebCore/rendering/style/ShadowData.cpp
index d4569d0..3a8f81d 100644
--- a/WebCore/rendering/style/ShadowData.cpp
+++ b/WebCore/rendering/style/ShadowData.cpp
@@ -22,6 +22,11 @@
#include "config.h"
#include "ShadowData.h"
+#include "FloatRect.h"
+#include "IntRect.h"
+
+using namespace std;
+
namespace WebCore {
ShadowData::ShadowData(const ShadowData& o)
@@ -44,4 +49,45 @@ bool ShadowData::operator==(const ShadowData& o) const
return m_x == o.m_x && m_y == o.m_y && m_blur == o.m_blur && m_spread == o.m_spread && m_style == o.m_style && m_color == o.m_color;
}
+static inline void calculateShadowExtent(const ShadowData* shadow, int additionalOutlineSize, int& shadowLeft, int& shadowRight, int& shadowTop, int& shadowBottom)
+{
+ do {
+ int blurAndSpread = shadow->blur() + shadow->spread() + additionalOutlineSize;
+ if (shadow->style() == Normal) {
+ shadowLeft = min(shadow->x() - blurAndSpread, shadowLeft);
+ shadowRight = max(shadow->x() + blurAndSpread, shadowRight);
+ shadowTop = min(shadow->y() - blurAndSpread, shadowTop);
+ shadowBottom = max(shadow->y() + blurAndSpread, shadowBottom);
+ }
+
+ shadow = shadow->next();
+ } while (shadow);
+}
+
+void ShadowData::adjustRectForShadow(IntRect& rect, int additionalOutlineSize) const
+{
+ int shadowLeft = 0;
+ int shadowRight = 0;
+ int shadowTop = 0;
+ int shadowBottom = 0;
+ calculateShadowExtent(this, additionalOutlineSize, shadowLeft, shadowRight, shadowTop, shadowBottom);
+
+ rect.move(shadowLeft, shadowTop);
+ rect.setWidth(rect.width() - shadowLeft + shadowRight);
+ rect.setHeight(rect.height() - shadowTop + shadowBottom);
+}
+
+void ShadowData::adjustRectForShadow(FloatRect& rect, int additionalOutlineSize) const
+{
+ int shadowLeft = 0;
+ int shadowRight = 0;
+ int shadowTop = 0;
+ int shadowBottom = 0;
+ calculateShadowExtent(this, additionalOutlineSize, shadowLeft, shadowRight, shadowTop, shadowBottom);
+
+ rect.move(shadowLeft, shadowTop);
+ rect.setWidth(rect.width() - shadowLeft + shadowRight);
+ rect.setHeight(rect.height() - shadowTop + shadowBottom);
+}
+
} // namespace WebCore
diff --git a/WebCore/rendering/style/ShadowData.h b/WebCore/rendering/style/ShadowData.h
index 9252e13..ca83af0 100644
--- a/WebCore/rendering/style/ShadowData.h
+++ b/WebCore/rendering/style/ShadowData.h
@@ -30,6 +30,9 @@
namespace WebCore {
+class FloatRect;
+class IntRect;
+
enum ShadowStyle { Normal, Inset };
// This struct holds information about shadows for the text-shadow and box-shadow properties.
@@ -76,6 +79,9 @@ public:
const ShadowData* next() const { return m_next; }
void setNext(ShadowData* shadow) { m_next = shadow; }
+ void adjustRectForShadow(IntRect&, int additionalOutlineSize = 0) const;
+ void adjustRectForShadow(FloatRect&, int additionalOutlineSize = 0) const;
+
private:
int m_x;
int m_y;
diff --git a/WebCore/rendering/style/StyleCachedImage.cpp b/WebCore/rendering/style/StyleCachedImage.cpp
index b55c5b9..1d7aba8 100644
--- a/WebCore/rendering/style/StyleCachedImage.cpp
+++ b/WebCore/rendering/style/StyleCachedImage.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-PassRefPtr<CSSValue> StyleCachedImage::cssValue()
+PassRefPtr<CSSValue> StyleCachedImage::cssValue() const
{
return CSSPrimitiveValue::create(m_image->url(), CSSPrimitiveValue::CSS_URI);
}
diff --git a/WebCore/rendering/style/StyleCachedImage.h b/WebCore/rendering/style/StyleCachedImage.h
index 3d22868..3d6e1a2 100644
--- a/WebCore/rendering/style/StyleCachedImage.h
+++ b/WebCore/rendering/style/StyleCachedImage.h
@@ -38,7 +38,7 @@ public:
virtual bool isCachedImage() const { return true; }
- virtual PassRefPtr<CSSValue> cssValue();
+ virtual PassRefPtr<CSSValue> cssValue() const;
CachedImage* cachedImage() const { return m_image.get(); }
diff --git a/WebCore/rendering/style/StyleGeneratedImage.cpp b/WebCore/rendering/style/StyleGeneratedImage.cpp
index 610e73d..2322f5f 100644
--- a/WebCore/rendering/style/StyleGeneratedImage.cpp
+++ b/WebCore/rendering/style/StyleGeneratedImage.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-PassRefPtr<CSSValue> StyleGeneratedImage::cssValue()
+PassRefPtr<CSSValue> StyleGeneratedImage::cssValue() const
{
return m_generator;
}
diff --git a/WebCore/rendering/style/StyleGeneratedImage.h b/WebCore/rendering/style/StyleGeneratedImage.h
index 532e383..7be1f6a 100644
--- a/WebCore/rendering/style/StyleGeneratedImage.h
+++ b/WebCore/rendering/style/StyleGeneratedImage.h
@@ -42,7 +42,7 @@ public:
virtual bool isGeneratedImage() const { return true; }
- virtual PassRefPtr<CSSValue> cssValue();
+ virtual PassRefPtr<CSSValue> cssValue() const;
virtual IntSize imageSize(const RenderObject*, float multiplier) const;
virtual bool imageHasRelativeWidth() const { return !m_fixedSize; }
diff --git a/WebCore/rendering/style/StyleImage.h b/WebCore/rendering/style/StyleImage.h
index cb90288..ead8d4a 100644
--- a/WebCore/rendering/style/StyleImage.h
+++ b/WebCore/rendering/style/StyleImage.h
@@ -24,6 +24,7 @@
#ifndef StyleImage_h
#define StyleImage_h
+#include "CSSValue.h"
#include "IntSize.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -41,12 +42,12 @@ class StyleImage : public RefCounted<StyleImage> {
public:
virtual ~StyleImage() { }
- bool operator==(const StyleImage& other)
+ bool operator==(const StyleImage& other) const
{
return data() == other.data();
}
-
- virtual PassRefPtr<CSSValue> cssValue() = 0;
+
+ virtual PassRefPtr<CSSValue> cssValue() const = 0;
virtual bool canRender(float /*multiplier*/) const { return true; }
virtual bool isLoaded() const { return true; }
@@ -60,7 +61,9 @@ public:
virtual void removeClient(RenderObject*) = 0;
virtual Image* image(RenderObject*, const IntSize&) const = 0;
virtual WrappedImagePtr data() const = 0;
+
virtual bool isCachedImage() const { return false; }
+ virtual bool isPendingImage() const { return false; }
virtual bool isGeneratedImage() const { return false; }
static bool imagesEquivalent(StyleImage* image1, StyleImage* image2)
diff --git a/WebCore/rendering/style/StylePendingImage.h b/WebCore/rendering/style/StylePendingImage.h
new file mode 100644
index 0000000..b0c9b01
--- /dev/null
+++ b/WebCore/rendering/style/StylePendingImage.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StylePendingImage_h
+#define StylePendingImage_h
+
+#include "StyleImage.h"
+
+namespace WebCore {
+
+// StylePendingImage is a placeholder StyleImage that is entered into the RenderStyle during
+// style resolution, in order to avoid loading images that are not referenced by the final style.
+// They should never exist in a RenderStyle after it has been returned from the style selector.
+
+class StylePendingImage : public StyleImage {
+public:
+ static PassRefPtr<StylePendingImage> create(CSSImageValue* value) { return adoptRef(new StylePendingImage(value)); }
+
+ virtual WrappedImagePtr data() const { return m_value; }
+
+ virtual bool isPendingImage() const { return true; }
+
+ virtual PassRefPtr<CSSValue> cssValue() const { return m_value; }
+ CSSImageValue* cssImageValue() const { return m_value; }
+
+ virtual IntSize imageSize(const RenderObject*, float /*multiplier*/) const { return IntSize(); }
+ virtual bool imageHasRelativeWidth() const { return false; }
+ virtual bool imageHasRelativeHeight() const { return false; }
+ virtual bool usesImageContainerSize() const { return false; }
+ virtual void setImageContainerSize(const IntSize&) { }
+ virtual void addClient(RenderObject*) { }
+ virtual void removeClient(RenderObject*) { }
+ virtual Image* image(RenderObject*, const IntSize&) const
+ {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+
+private:
+ StylePendingImage(CSSImageValue* value)
+ : m_value(value)
+ {
+ }
+
+ CSSImageValue* m_value; // Not retained; it owns us.
+};
+
+}
+#endif