summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/InlineBox.cpp2
-rw-r--r--WebCore/rendering/MediaControlElements.cpp6
-rw-r--r--WebCore/rendering/RenderApplet.cpp4
-rw-r--r--WebCore/rendering/RenderBlock.cpp10
-rw-r--r--WebCore/rendering/RenderBox.cpp66
-rw-r--r--WebCore/rendering/RenderBox.h1
-rw-r--r--WebCore/rendering/RenderBoxModelObject.h3
-rw-r--r--WebCore/rendering/RenderDataGrid.cpp2
-rw-r--r--WebCore/rendering/RenderFieldset.cpp2
-rw-r--r--WebCore/rendering/RenderFileUploadControl.cpp4
-rw-r--r--WebCore/rendering/RenderFlexibleBox.cpp10
-rw-r--r--WebCore/rendering/RenderIFrame.cpp4
-rw-r--r--WebCore/rendering/RenderImage.cpp6
-rw-r--r--WebCore/rendering/RenderInline.cpp2
-rw-r--r--WebCore/rendering/RenderInline.h3
-rw-r--r--WebCore/rendering/RenderLayer.cpp57
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp25
-rw-r--r--WebCore/rendering/RenderLayerBacking.h2
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp150
-rw-r--r--WebCore/rendering/RenderLayerCompositor.h11
-rw-r--r--WebCore/rendering/RenderListBox.cpp4
-rw-r--r--WebCore/rendering/RenderMenuList.cpp2
-rw-r--r--WebCore/rendering/RenderObject.cpp10
-rw-r--r--WebCore/rendering/RenderObject.h10
-rw-r--r--WebCore/rendering/RenderPath.cpp202
-rw-r--r--WebCore/rendering/RenderPath.h21
-rw-r--r--WebCore/rendering/RenderProgress.cpp99
-rw-r--r--WebCore/rendering/RenderProgress.h7
-rw-r--r--WebCore/rendering/RenderReplaced.cpp6
-rw-r--r--WebCore/rendering/RenderSVGBlock.h2
-rw-r--r--WebCore/rendering/RenderSVGGradientStop.cpp6
-rw-r--r--WebCore/rendering/RenderSVGGradientStop.h50
-rw-r--r--WebCore/rendering/RenderSVGImage.h1
-rw-r--r--WebCore/rendering/RenderSVGInline.cpp10
-rw-r--r--WebCore/rendering/RenderSVGInline.h2
-rw-r--r--WebCore/rendering/RenderSVGModelObject.h2
-rw-r--r--WebCore/rendering/RenderSVGResource.cpp202
-rw-r--r--WebCore/rendering/RenderSVGResource.h101
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.cpp18
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.h9
-rw-r--r--WebCore/rendering/RenderSVGResourceContainer.h111
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.cpp29
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.h10
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.cpp265
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.h75
-rw-r--r--WebCore/rendering/RenderSVGResourceLinearGradient.cpp66
-rw-r--r--WebCore/rendering/RenderSVGResourceLinearGradient.h48
-rw-r--r--WebCore/rendering/RenderSVGResourceMarker.cpp5
-rw-r--r--WebCore/rendering/RenderSVGResourceMarker.h9
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.cpp17
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.h14
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.cpp329
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.h74
-rw-r--r--WebCore/rendering/RenderSVGResourceRadialGradient.cpp71
-rw-r--r--WebCore/rendering/RenderSVGResourceRadialGradient.h48
-rw-r--r--WebCore/rendering/RenderSVGResourceSolidColor.cpp103
-rw-r--r--WebCore/rendering/RenderSVGResourceSolidColor.h56
-rw-r--r--WebCore/rendering/RenderSVGRoot.cpp6
-rw-r--r--WebCore/rendering/RenderSVGText.cpp5
-rw-r--r--WebCore/rendering/RenderSVGText.h2
-rw-r--r--WebCore/rendering/RenderSlider.cpp10
-rw-r--r--WebCore/rendering/RenderTableCell.cpp2
-rw-r--r--WebCore/rendering/RenderText.cpp47
-rw-r--r--WebCore/rendering/RenderTextControl.cpp16
-rw-r--r--WebCore/rendering/RenderTextControl.h2
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp96
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.h10
-rw-r--r--WebCore/rendering/RenderTheme.cpp32
-rw-r--r--WebCore/rendering/RenderTheme.h2
-rw-r--r--WebCore/rendering/RenderThemeChromiumMac.h161
-rw-r--r--WebCore/rendering/RenderThemeChromiumMac.mm1496
-rw-r--r--WebCore/rendering/RenderThemeMac.h13
-rw-r--r--WebCore/rendering/RenderThemeMac.mm58
-rw-r--r--WebCore/rendering/RenderTreeAsText.cpp20
-rw-r--r--WebCore/rendering/RenderTreeAsText.h4
-rw-r--r--WebCore/rendering/RenderVideo.cpp8
-rw-r--r--WebCore/rendering/RenderView.cpp10
-rw-r--r--WebCore/rendering/RenderView.h1
-rw-r--r--WebCore/rendering/RenderWidget.cpp4
-rw-r--r--WebCore/rendering/SVGCharacterData.cpp55
-rw-r--r--WebCore/rendering/SVGCharacterData.h102
-rw-r--r--WebCore/rendering/SVGCharacterLayoutInfo.cpp64
-rw-r--r--WebCore/rendering/SVGCharacterLayoutInfo.h220
-rw-r--r--WebCore/rendering/SVGInlineTextBox.cpp19
-rw-r--r--WebCore/rendering/SVGInlineTextBox.h9
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp95
-rw-r--r--WebCore/rendering/SVGRenderSupport.h9
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp184
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.h6
-rw-r--r--WebCore/rendering/SVGRootInlineBox.cpp165
-rw-r--r--WebCore/rendering/SVGRootInlineBox.h3
-rw-r--r--WebCore/rendering/SVGShadowTreeElements.cpp2
-rw-r--r--WebCore/rendering/SVGTextChunkLayoutInfo.h178
-rw-r--r--WebCore/rendering/TextControlInnerElements.cpp73
-rw-r--r--WebCore/rendering/TextControlInnerElements.h15
-rw-r--r--WebCore/rendering/style/RenderStyle.cpp6
-rw-r--r--WebCore/rendering/style/RenderStyle.h2
-rw-r--r--WebCore/rendering/style/RenderStyleConstants.h2
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.h5
-rw-r--r--WebCore/rendering/style/StyleRareInheritedData.h2
-rw-r--r--WebCore/rendering/style/StyleRareNonInheritedData.h3
101 files changed, 3123 insertions, 2565 deletions
diff --git a/WebCore/rendering/InlineBox.cpp b/WebCore/rendering/InlineBox.cpp
index 2575fb7..213737c 100644
--- a/WebCore/rendering/InlineBox.cpp
+++ b/WebCore/rendering/InlineBox.cpp
@@ -102,7 +102,7 @@ int InlineBox::height() const
const Font& font = renderer()->style(m_firstLine)->font();
int result = font.height();
if (parent())
- result += flowObject->borderTop() + flowObject->paddingTop() + flowObject->borderBottom() + flowObject->paddingBottom();
+ result += flowObject->borderAndPaddingHeight();
return result;
}
diff --git a/WebCore/rendering/MediaControlElements.cpp b/WebCore/rendering/MediaControlElements.cpp
index 569f214..16827f5 100644
--- a/WebCore/rendering/MediaControlElements.cpp
+++ b/WebCore/rendering/MediaControlElements.cpp
@@ -74,7 +74,7 @@ MediaControlShadowRootElement::MediaControlShadowRootElement(Document* document,
renderer->setStyle(rootStyle.release());
setRenderer(renderer);
setAttached();
- setInDocument(true);
+ setInDocument();
}
void MediaControlShadowRootElement::updateStyle()
@@ -92,7 +92,7 @@ MediaControlElement::MediaControlElement(Document* document, PseudoId pseudo, HT
, m_mediaElement(mediaElement)
, m_pseudoStyleId(pseudo)
{
- setInDocument(true);
+ setInDocument();
switch (pseudo) {
case MEDIA_CONTROLS_CURRENT_TIME_DISPLAY:
m_displayType = MediaCurrentTimeDisplay;
@@ -318,7 +318,7 @@ MediaControlInputElement::MediaControlInputElement(Document* document, PseudoId
, m_pseudoStyleId(pseudo)
{
setInputType(type);
- setInDocument(true);
+ setInDocument();
switch (pseudo) {
case MEDIA_CONTROLS_MUTE_BUTTON:
diff --git a/WebCore/rendering/RenderApplet.cpp b/WebCore/rendering/RenderApplet.cpp
index 062641e..7411c54 100644
--- a/WebCore/rendering/RenderApplet.cpp
+++ b/WebCore/rendering/RenderApplet.cpp
@@ -59,9 +59,9 @@ void RenderApplet::createWidgetIfNecessary()
// use fixed widths/heights from the style system when we can, since the widget might
// not have an accurate m_width/m_height.
int contentWidth = style()->width().isFixed() ? style()->width().value() :
- width() - borderLeft() - borderRight() - paddingLeft() - paddingRight();
+ width() - borderAndPaddingWidth();
int contentHeight = style()->height().isFixed() ? style()->height().value() :
- height() - borderTop() - borderBottom() - paddingTop() - paddingBottom();
+ height() - borderAndPaddingHeight();
for (Node* child = element->firstChild(); child; child = child->nextSibling()) {
if (child->hasTagName(paramTag)) {
HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 3f53456..cf4101b 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -589,10 +589,10 @@ bool RenderBlock::isSelfCollapsingBlock() const
// (c) have border/padding,
// (d) have a min-height
// (e) have specified that one of our margins can't collapse using a CSS extension
- if (height() > 0 ||
- isTable() || (borderBottom() + paddingBottom() + borderTop() + paddingTop()) != 0 ||
- style()->minHeight().isPositive() ||
- style()->marginTopCollapse() == MSEPARATE || style()->marginBottomCollapse() == MSEPARATE)
+ if (height() > 0
+ || isTable() || borderAndPaddingHeight()
+ || style()->minHeight().isPositive()
+ || style()->marginTopCollapse() == MSEPARATE || style()->marginBottomCollapse() == MSEPARATE)
return false;
bool hasAutoHeight = style()->height().isAuto();
@@ -4011,7 +4011,7 @@ void RenderBlock::calcPrefWidths()
}
int toAdd = 0;
- toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight();
+ toAdd = borderAndPaddingWidth();
if (hasOverflowClip() && style()->overflowY() == OSCROLL)
toAdd += verticalScrollbarWidth();
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index bd82683..e38cf25 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -514,7 +514,7 @@ int RenderBox::overrideHeight() const
int RenderBox::calcBorderBoxWidth(int width) const
{
- int bordersPlusPadding = borderLeft() + borderRight() + paddingLeft() + paddingRight();
+ int bordersPlusPadding = borderAndPaddingWidth();
if (style()->boxSizing() == CONTENT_BOX)
return width + bordersPlusPadding;
return max(width, bordersPlusPadding);
@@ -522,7 +522,7 @@ int RenderBox::calcBorderBoxWidth(int width) const
int RenderBox::calcBorderBoxHeight(int height) const
{
- int bordersPlusPadding = borderTop() + borderBottom() + paddingTop() + paddingBottom();
+ int bordersPlusPadding = borderAndPaddingHeight();
if (style()->boxSizing() == CONTENT_BOX)
return height + bordersPlusPadding;
return max(height, bordersPlusPadding);
@@ -531,14 +531,14 @@ int RenderBox::calcBorderBoxHeight(int height) const
int RenderBox::calcContentBoxWidth(int width) const
{
if (style()->boxSizing() == BORDER_BOX)
- width -= (borderLeft() + borderRight() + paddingLeft() + paddingRight());
+ width -= borderAndPaddingWidth();
return max(0, width);
}
int RenderBox::calcContentBoxHeight(int height) const
{
if (style()->boxSizing() == BORDER_BOX)
- height -= (borderTop() + borderBottom() + paddingTop() + paddingBottom());
+ height -= borderAndPaddingHeight();
return max(0, height);
}
@@ -635,34 +635,36 @@ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
return;
}
- int w = width();
- int h = height();
+ return paintBoxDecorationsWithSize(paintInfo, tx, ty, width(), height());
+}
+void RenderBox::paintBoxDecorationsWithSize(PaintInfo& paintInfo, int tx, int ty, int width, int height)
+{
// border-fit can adjust where we paint our border and background. If set, we snugly fit our line box descendants. (The iChat
// balloon layout is an example of this).
- borderFitAdjust(tx, w);
+ borderFitAdjust(tx, width);
// FIXME: Should eventually give the theme control over whether the box shadow should paint, since controls could have
// custom shadows of their own.
- paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal);
+ paintBoxShadow(paintInfo.context, tx, ty, width, height, style(), Normal);
// If we have a native theme appearance, paint that before painting our background.
// The theme will tell us whether or not we should also paint the CSS background.
- bool themePainted = style()->hasAppearance() && !theme()->paint(this, paintInfo, IntRect(tx, ty, w, h));
+ bool themePainted = style()->hasAppearance() && !theme()->paint(this, paintInfo, IntRect(tx, ty, width, height));
if (!themePainted) {
// The <body> only paints its background if the root element has defined a background
// independent of the body. Go through the DOM to get to the root element's render object,
// since the root could be inline and wrapped in an anonymous block.
if (!isBody() || document()->documentElement()->renderer()->style()->hasBackground())
- paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, w, h);
+ paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, width, height);
if (style()->hasAppearance())
- theme()->paintDecorations(this, paintInfo, IntRect(tx, ty, w, h));
+ theme()->paintDecorations(this, paintInfo, IntRect(tx, ty, width, height));
}
- paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset);
+ paintBoxShadow(paintInfo.context, tx, ty, width, height, style(), Inset);
// The theme will tell us whether or not we should also paint the CSS border.
- if ((!style()->hasAppearance() || (!themePainted && theme()->paintBorderOnly(this, paintInfo, IntRect(tx, ty, w, h)))) && style()->hasBorder())
- paintBorder(paintInfo.context, tx, ty, w, h, style());
+ if ((!style()->hasAppearance() || (!themePainted && theme()->paintBorderOnly(this, paintInfo, IntRect(tx, ty, width, height)))) && style()->hasBorder())
+ paintBorder(paintInfo.context, tx, ty, width, height, style());
}
void RenderBox::paintMask(PaintInfo& paintInfo, int tx, int ty)
@@ -1318,8 +1320,12 @@ void RenderBox::calcWidth()
if (treatAsReplaced) {
#else
if (treatAsReplaced)
+<<<<<<< HEAD:WebCore/rendering/RenderBox.cpp
#endif
setWidth(max(w.value() + borderLeft() + borderRight() + paddingLeft() + paddingRight(), minPrefWidth()));
+=======
+ setWidth(max(w.value() + borderAndPaddingWidth(), minPrefWidth()));
+>>>>>>> webkit.org at r58956:WebCore/rendering/RenderBox.cpp
#ifdef ANDROID_LAYOUT
// in SSR mode with replaced box, if the box width is wider than the container width,
@@ -1337,7 +1343,7 @@ void RenderBox::calcWidth()
// Width calculations
if (treatAsReplaced)
- setWidth(w.value() + borderLeft() + borderRight() + paddingLeft() + paddingRight());
+ setWidth(w.value() + borderAndPaddingWidth());
else {
// Calculate Width
setWidth(calcWidthUsing(Width, containerWidth));
@@ -1508,7 +1514,7 @@ void RenderBox::calcHeight()
// grab our cached flexible height.
if (hasOverrideSize() && parent()->isFlexibleBox() && parent()->style()->boxOrient() == VERTICAL
&& parent()->isFlexingChildren())
- h = Length(overrideSize() - borderTop() - borderBottom() - paddingTop() - paddingBottom(), Fixed);
+ h = Length(overrideSize() - borderAndPaddingHeight(), Fixed);
else if (treatAsReplaced)
h = Length(calcReplacedHeight(), Fixed);
else {
@@ -1519,8 +1525,7 @@ void RenderBox::calcHeight()
// Block children of horizontal flexible boxes fill the height of the box.
if (h.isAuto() && parent()->isFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL
&& parent()->isStretchingChildren()) {
- h = Length(parentBox()->contentHeight() - marginTop() - marginBottom() -
- borderTop() - paddingTop() - borderBottom() - paddingBottom(), Fixed);
+ h = Length(parentBox()->contentHeight() - marginTop() - marginBottom() - borderAndPaddingHeight(), Fixed);
checkMinMaxHeight = false;
}
@@ -1545,7 +1550,7 @@ void RenderBox::calcHeight()
// The only times we don't check min/max height are when a fixed length has
// been given as an override. Just use that. The value has already been adjusted
// for box-sizing.
- heightResult = h.value() + borderTop() + borderBottom() + paddingTop() + paddingBottom();
+ heightResult = h.value() + borderAndPaddingHeight();
}
setHeight(heightResult);
@@ -1564,9 +1569,7 @@ void RenderBox::calcHeight()
if (isRoot())
setHeight(max(height(), visHeight - margins));
else {
- int marginsBordersPadding = margins + parentBox()->marginTop() + parentBox()->marginBottom()
- + parentBox()->borderTop() + parentBox()->borderBottom()
- + parentBox()->paddingTop() + parentBox()->paddingBottom();
+ int marginsBordersPadding = margins + parentBox()->marginTop() + parentBox()->marginBottom() + parentBox()->borderAndPaddingHeight();
setHeight(max(height(), visHeight - marginsBordersPadding));
}
}
@@ -1660,7 +1663,7 @@ int RenderBox::calcPercentageHeight(const Length& height)
// It is necessary to use the border-box to match WinIE's broken
// box model. This is essential for sizing inside
// table cells using percentage heights.
- result -= (borderTop() + paddingTop() + borderBottom() + paddingBottom());
+ result -= borderAndPaddingHeight();
result = max(0, result);
}
}
@@ -1733,8 +1736,7 @@ int RenderBox::calcReplacedHeightUsing(Length height) const
// Don't let table cells squeeze percent-height replaced elements
// <http://bugs.webkit.org/show_bug.cgi?id=15359>
availableHeight = max(availableHeight, intrinsicSize().height());
- return height.calcValue(availableHeight - (borderTop() + borderBottom()
- + paddingTop() + paddingBottom()));
+ return height.calcValue(availableHeight - borderAndPaddingHeight());
}
return calcContentBoxHeight(height.calcValue(availableHeight));
@@ -1761,7 +1763,7 @@ int RenderBox::availableHeightUsing(const Length& h) const
// artificially. We're going to rely on this cell getting expanded to some new
// height, and then when we lay out again we'll use the calculation below.
if (isTableCell() && (h.isAuto() || h.isPercent()))
- return overrideSize() - (borderLeft() + borderRight() + paddingLeft() + paddingRight());
+ return overrideSize() - borderAndPaddingWidth();
if (h.isPercent())
return calcContentBoxHeight(h.calcValue(containingBlock()->availableHeight()));
@@ -1878,7 +1880,7 @@ void RenderBox::calcAbsoluteHorizontal()
// instead of the the container block's.
TextDirection containerDirection = (style()->htmlHacks()) ? parent()->style()->direction() : containerBlock->style()->direction();
- const int bordersPlusPadding = borderLeft() + borderRight() + paddingLeft() + paddingRight();
+ const int bordersPlusPadding = borderAndPaddingWidth();
const Length marginLeft = style()->marginLeft();
const Length marginRight = style()->marginRight();
Length left = style()->left();
@@ -2187,7 +2189,7 @@ void RenderBox::calcAbsoluteVertical()
const int containerHeight = containingBlockHeightForPositioned(containerBlock);
- const int bordersPlusPadding = borderTop() + borderBottom() + paddingTop() + paddingBottom();
+ const int bordersPlusPadding = borderAndPaddingHeight();
const Length marginTop = style()->marginTop();
const Length marginBottom = style()->marginBottom();
Length top = style()->top();
@@ -2428,7 +2430,7 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
// NOTE: This value of width is FINAL in that the min/max width calculations
// are dealt with in calcReplacedWidth(). This means that the steps to produce
// correct max/min in the non-replaced version, are not necessary.
- setWidth(calcReplacedWidth() + borderLeft() + borderRight() + paddingLeft() + paddingRight());
+ setWidth(calcReplacedWidth() + borderAndPaddingWidth());
const int availableSpace = containerWidth - width();
/*-----------------------------------------------------------------------*\
@@ -2601,7 +2603,7 @@ void RenderBox::calcAbsoluteVerticalReplaced()
// NOTE: This value of height is FINAL in that the min/max height calculations
// are dealt with in calcReplacedHeight(). This means that the steps to produce
// correct max/min in the non-replaced version, are not necessary.
- setHeight(calcReplacedHeight() + borderTop() + borderBottom() + paddingTop() + paddingBottom());
+ setHeight(calcReplacedHeight() + borderAndPaddingHeight());
const int availableSpace = containerHeight - height();
/*-----------------------------------------------------------------------*\
@@ -2787,8 +2789,8 @@ VisiblePosition RenderBox::positionForPoint(const IntPoint& point)
int yPos = point.y();
if (isTable() && node()) {
- int right = contentWidth() + borderRight() + paddingRight() + borderLeft() + paddingLeft();
- int bottom = contentHeight() + borderTop() + paddingTop() + borderBottom() + paddingBottom();
+ int right = contentWidth() + borderAndPaddingWidth();
+ int bottom = contentHeight() + borderAndPaddingHeight();
if (xPos < 0 || xPos > right || yPos < 0 || yPos > bottom) {
if (xPos <= right / 2)
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index 68bbd51..1c766aa 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -308,6 +308,7 @@ protected:
void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator op, RenderObject* backgroundObject);
void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
+ void paintBoxDecorationsWithSize(PaintInfo&, int tx, int ty, int width, int height);
void paintMaskImages(const PaintInfo&, int tx, int ty, int width, int height);
#if PLATFORM(MAC)
diff --git a/WebCore/rendering/RenderBoxModelObject.h b/WebCore/rendering/RenderBoxModelObject.h
index db7538d..a4cf54a 100644
--- a/WebCore/rendering/RenderBoxModelObject.h
+++ b/WebCore/rendering/RenderBoxModelObject.h
@@ -75,6 +75,9 @@ public:
virtual int borderLeft() const { return style()->borderLeftWidth(); }
virtual int borderRight() const { return style()->borderRightWidth(); }
+ int borderAndPaddingHeight() const { return borderTop() + borderBottom() + paddingTop() + paddingBottom(); }
+ int borderAndPaddingWidth() const { return borderLeft() + borderRight() + paddingLeft() + paddingRight(); }
+
virtual int marginTop() const = 0;
virtual int marginBottom() const = 0;
virtual int marginLeft() const = 0;
diff --git a/WebCore/rendering/RenderDataGrid.cpp b/WebCore/rendering/RenderDataGrid.cpp
index bdf723f..00cbd7c 100644
--- a/WebCore/rendering/RenderDataGrid.cpp
+++ b/WebCore/rendering/RenderDataGrid.cpp
@@ -111,7 +111,7 @@ void RenderDataGrid::calcPrefWidths()
m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
}
- int toAdd = paddingLeft() + paddingRight() + borderLeft() + borderRight();
+ int toAdd = borderAndPaddingWidth();
m_minPrefWidth += toAdd;
m_maxPrefWidth += toAdd;
diff --git a/WebCore/rendering/RenderFieldset.cpp b/WebCore/rendering/RenderFieldset.cpp
index d8cbd00..306e111 100644
--- a/WebCore/rendering/RenderFieldset.cpp
+++ b/WebCore/rendering/RenderFieldset.cpp
@@ -59,7 +59,7 @@ void RenderFieldset::calcPrefWidths()
if (legendMarginRight.isFixed())
legendMinWidth += legendMarginRight.value();
- m_minPrefWidth = max(m_minPrefWidth, legendMinWidth + paddingLeft() + paddingRight() + borderLeft() + borderRight());
+ m_minPrefWidth = max(m_minPrefWidth, legendMinWidth + borderAndPaddingWidth());
}
}
diff --git a/WebCore/rendering/RenderFileUploadControl.cpp b/WebCore/rendering/RenderFileUploadControl.cpp
index 6a5c1e0..fa2a998 100644
--- a/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/WebCore/rendering/RenderFileUploadControl.cpp
@@ -152,7 +152,7 @@ void RenderFileUploadControl::updateFromElement()
renderer->setStyle(buttonStyle.release());
renderer->updateFromElement();
m_button->setAttached();
- m_button->setInDocument(true);
+ m_button->setInDocument();
addChild(renderer);
}
@@ -285,7 +285,7 @@ void RenderFileUploadControl::calcPrefWidths()
m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
}
- int toAdd = paddingLeft() + paddingRight() + borderLeft() + borderRight();
+ int toAdd = borderAndPaddingWidth();
m_minPrefWidth += toAdd;
m_maxPrefWidth += toAdd;
diff --git a/WebCore/rendering/RenderFlexibleBox.cpp b/WebCore/rendering/RenderFlexibleBox.cpp
index 6882097..d0222cb 100644
--- a/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/WebCore/rendering/RenderFlexibleBox.cpp
@@ -195,7 +195,7 @@ void RenderFlexibleBox::calcPrefWidths()
m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
}
- int toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight();
+ int toAdd = borderAndPaddingWidth();
if (hasOverflowClip() && style()->overflowY() == OSCROLL)
toAdd += verticalScrollbarWidth();
@@ -1035,7 +1035,7 @@ int RenderFlexibleBox::allowedChildFlex(RenderBox* child, bool expanding, unsign
if (isHorizontal()) {
// FIXME: For now just handle fixed values.
int maxW = INT_MAX;
- int w = child->overrideWidth() - (child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight());
+ int w = child->overrideWidth() - child->borderAndPaddingWidth();
if (!child->style()->maxWidth().isUndefined() &&
child->style()->maxWidth().isFixed())
maxW = child->style()->maxWidth().value();
@@ -1049,7 +1049,7 @@ int RenderFlexibleBox::allowedChildFlex(RenderBox* child, bool expanding, unsign
} else {
// FIXME: For now just handle fixed values.
int maxH = INT_MAX;
- int h = child->overrideHeight() - (child->borderTop() + child->borderBottom() + child->paddingTop() + child->paddingBottom());
+ int h = child->overrideHeight() - child->borderAndPaddingHeight();
if (!child->style()->maxHeight().isUndefined() &&
child->style()->maxHeight().isFixed())
maxH = child->style()->maxHeight().value();
@@ -1062,7 +1062,7 @@ int RenderFlexibleBox::allowedChildFlex(RenderBox* child, bool expanding, unsign
// FIXME: For now just handle fixed values.
if (isHorizontal()) {
int minW = child->minPrefWidth();
- int w = child->overrideWidth() - (child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight());
+ int w = child->overrideWidth() - child->borderAndPaddingWidth();
if (child->style()->minWidth().isFixed())
minW = child->style()->minWidth().value();
else if (child->style()->minWidth().type() == Intrinsic)
@@ -1075,7 +1075,7 @@ int RenderFlexibleBox::allowedChildFlex(RenderBox* child, bool expanding, unsign
} else {
if (child->style()->minHeight().isFixed()) {
int minH = child->style()->minHeight().value();
- int h = child->overrideHeight() - (child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight());
+ int h = child->overrideHeight() - child->borderAndPaddingHeight();
int allowedShrinkage = min(0, minH - h);
return allowedShrinkage;
}
diff --git a/WebCore/rendering/RenderIFrame.cpp b/WebCore/rendering/RenderIFrame.cpp
index 5852468..90cac14 100644
--- a/WebCore/rendering/RenderIFrame.cpp
+++ b/WebCore/rendering/RenderIFrame.cpp
@@ -77,6 +77,8 @@ void RenderIFrame::calcHeight()
if (isScrollable || !style()->height().isFixed()) {
FrameView* view = static_cast<FrameView*>(widget());
+ if (!view)
+ return;
int border = borderTop() + borderBottom();
setHeight(max(height(), view->contentsHeight() + border));
}
@@ -126,6 +128,8 @@ void RenderIFrame::calcWidth()
if (isScrollable || !style()->width().isFixed()) {
FrameView* view = static_cast<FrameView*>(widget());
+ if (!view)
+ return;
int border = borderLeft() + borderRight();
setWidth(max(width(), view->contentsWidth() + border));
}
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index a2052fe..73cf73c 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -679,11 +679,11 @@ void RenderImage::calcPrefWidths()
{
ASSERT(prefWidthsDirty());
- int paddingAndBorders = paddingLeft() + paddingRight() + borderLeft() + borderRight();
- m_maxPrefWidth = calcReplacedWidth(false) + paddingAndBorders;
+ int borderAndPadding = borderAndPaddingWidth();
+ m_maxPrefWidth = calcReplacedWidth(false) + borderAndPadding;
if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength)
- m_maxPrefWidth = min(m_maxPrefWidth, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? paddingAndBorders : 0));
+ m_maxPrefWidth = min(m_maxPrefWidth, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? borderAndPadding : 0));
if (style()->width().isPercent() || style()->height().isPercent() ||
style()->maxWidth().isPercent() || style()->maxHeight().isPercent() ||
diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp
index 6d3f462..69e6eab 100644
--- a/WebCore/rendering/RenderInline.cpp
+++ b/WebCore/rendering/RenderInline.cpp
@@ -274,7 +274,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
// has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after
// content gets properly destroyed.
if (document()->usesBeforeAfterRules())
- inlineCurr->children()->updateBeforeAfterContent(this, AFTER);
+ inlineCurr->children()->updateBeforeAfterContent(inlineCurr, AFTER);
// Now we need to take all of the children starting from the first child
// *after* currChild and append them all to the clone.
diff --git a/WebCore/rendering/RenderInline.h b/WebCore/rendering/RenderInline.h
index 7fcb516..4084b6e 100644
--- a/WebCore/rendering/RenderInline.h
+++ b/WebCore/rendering/RenderInline.h
@@ -71,6 +71,8 @@ public:
int verticalPositionFromCache(bool firstLine) const;
void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; }
+ RenderInline* inlineContinuation() const;
+
private:
virtual RenderObjectChildList* virtualChildren() { return children(); }
virtual const RenderObjectChildList* virtualChildren() const { return children(); }
@@ -126,7 +128,6 @@ private:
virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
- RenderInline* inlineContinuation() const;
void setContinuation(RenderBoxModelObject* c) { m_continuation = c; }
virtual void childBecameNonInline(RenderObject* child);
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 7994325..ea29087 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -47,6 +47,7 @@
#include "CSSPropertyNames.h"
#include "CSSStyleDeclaration.h"
#include "CSSStyleSelector.h"
+#include "Chrome.h"
#include "Document.h"
#include "EventHandler.h"
#include "EventNames.h"
@@ -79,12 +80,12 @@
#include "ScrollbarTheme.h"
#include "SelectionController.h"
#include "TextStream.h"
-#include "TransformationMatrix.h"
#include "TransformState.h"
+#include "TransformationMatrix.h"
#include "TranslateTransformOperation.h"
-#include <wtf/text/CString.h>
#include <wtf/StdLibExtras.h>
#include <wtf/UnusedParam.h>
+#include <wtf/text/CString.h>
#if USE(ACCELERATED_COMPOSITING)
#include "RenderLayerBacking.h"
@@ -1277,17 +1278,6 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
child->updateLayerPositions(0);
-#if USE(ACCELERATED_COMPOSITING)
- if (compositor()->inCompositingMode()) {
- // Our stacking context is guaranteed to contain all of our descendants that may need
- // repositioning, so update compositing layers from there.
- if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
- bool isUpdateRoot = true;
- compositingAncestor->backing()->updateAfterLayout(RenderLayerBacking::AllDescendants, isUpdateRoot);
- }
- }
-#endif
-
RenderView* view = renderer()->view();
// We should have a RenderView if we're trying to scroll.
@@ -1302,6 +1292,21 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
view->updateWidgetPositions();
}
+#if USE(ACCELERATED_COMPOSITING)
+ if (compositor()->inCompositingMode()) {
+ // Our stacking context is guaranteed to contain all of our descendants that may need
+ // repositioning, so update compositing layers from there.
+ if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
+ if (compositor()->compositingConsultsOverlap())
+ compositor()->updateCompositingLayers(CompositingUpdateOnScroll, compositingAncestor);
+ else {
+ bool isUpdateRoot = true;
+ compositingAncestor->backing()->updateAfterLayout(RenderLayerBacking::AllDescendants, isUpdateRoot);
+ }
+ }
+ }
+#endif
+
RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
IntRect rectForRepaint = renderer()->clippedOverflowRectForRepaint(repaintContainer);
@@ -1334,7 +1339,7 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
}
}
-void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
+void RenderLayer::scrollRectToVisible(const IntRect& rect, bool scrollToAnchor, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
{
RenderLayer* parentLayer = 0;
IntRect newRect = rect;
@@ -1399,9 +1404,17 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor,
IntRect viewRect = frameView->visibleContentRect(true);
IntRect r = getRectToExpose(viewRect, rect, alignX, alignY);
- // If this is the outermost view that RenderLayer needs to scroll, then we should scroll the view recursively
- // Other apps, like Mail, rely on this feature.
- frameView->scrollRectIntoViewRecursively(r);
+ frameView->setScrollPosition(r.location());
+
+ // This is the outermost view of a web page, so after scrolling this view we
+ // scroll its container by calling Page::scrollRectIntoView.
+ // This only has an effect on the Mac platform in applications
+ // that put web views into scrolling containers, such as Mac OS X Mail.
+ // The canAutoscroll function in EventHandler also knows about this.
+ if (Frame* frame = frameView->frame()) {
+ if (Page* page = frame->page())
+ page->chrome()->scrollRectIntoView(rect);
+ }
}
}
}
@@ -1548,8 +1561,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset
style->setProperty(CSSPropertyMarginLeft, String::number(renderer->marginLeft() / zoomFactor) + "px", false, ec);
style->setProperty(CSSPropertyMarginRight, String::number(renderer->marginRight() / zoomFactor) + "px", false, ec);
}
- int baseWidth = renderer->width() - (isBoxSizingBorder ? 0
- : renderer->borderLeft() + renderer->paddingLeft() + renderer->borderRight() + renderer->paddingRight());
+ int baseWidth = renderer->width() - (isBoxSizingBorder ? 0 : renderer->borderAndPaddingWidth());
baseWidth = baseWidth / zoomFactor;
style->setProperty(CSSPropertyWidth, String::number(baseWidth + difference.width()) + "px", false, ec);
}
@@ -1560,8 +1572,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset
style->setProperty(CSSPropertyMarginTop, String::number(renderer->marginTop() / zoomFactor) + "px", false, ec);
style->setProperty(CSSPropertyMarginBottom, String::number(renderer->marginBottom() / zoomFactor) + "px", false, ec);
}
- int baseHeight = renderer->height() - (isBoxSizingBorder ? 0
- : renderer->borderTop() + renderer->paddingTop() + renderer->borderBottom() + renderer->paddingBottom());
+ int baseHeight = renderer->height() - (isBoxSizingBorder ? 0 : renderer->borderAndPaddingHeight());
baseHeight = baseHeight / zoomFactor;
style->setProperty(CSSPropertyHeight, String::number(baseHeight + difference.height()) + "px", false, ec);
}
@@ -3186,7 +3197,7 @@ void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestR
// We are clearing the :active chain because the mouse has been released.
for (RenderObject* curr = activeNode->renderer(); curr; curr = curr->parent()) {
if (curr->node() && !curr->isText())
- curr->node()->setInActiveChain(false);
+ curr->node()->clearInActiveChain();
}
doc->setActiveNode(0);
} else {
@@ -3196,7 +3207,7 @@ void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestR
// will need to reference this chain.
for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) {
if (curr->node() && !curr->isText()) {
- curr->node()->setInActiveChain(true);
+ curr->node()->setInActiveChain();
}
}
doc->setActiveNode(newActiveNode);
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index b5f74c6..b857420 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -38,6 +38,7 @@
#include "GraphicsLayer.h"
#include "HTMLCanvasElement.h"
#include "HTMLElement.h"
+#include "HTMLIFrameElement.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "InspectorTimelineAgent.h"
@@ -384,6 +385,24 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
m_graphicsLayer->setContentsRect(contentsBox());
m_graphicsLayer->setDrawsContent(containsPaintedContent());
+
+ // If this is an iframe parent, update the iframe content's box
+ RenderLayerCompositor* innerCompositor = innerRenderLayerCompositor();
+ if (innerCompositor)
+ innerCompositor->setRootPlatformLayerClippingBox(contentsBox());
+}
+
+RenderLayerCompositor* RenderLayerBacking::innerRenderLayerCompositor() const
+{
+ if (renderer()->isRenderIFrame()) {
+ HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(renderer()->node());
+ if (Document* contentDocument = element->contentDocument()) {
+ if (RenderView* view = contentDocument->renderView())
+ return view->compositor();
+ }
+ }
+
+ return 0;
}
void RenderLayerBacking::updateInternalHierarchy()
@@ -823,7 +842,11 @@ FloatPoint RenderLayerBacking::contentsToGraphicsLayerCoordinates(const Graphics
bool RenderLayerBacking::paintingGoesToWindow() const
{
- return m_owningLayer->isRootLayer();
+ if (!m_owningLayer->isRootLayer())
+ return false;
+
+ // Iframe root layers paint into backing store.
+ return !toRenderView(renderer())->document()->ownerElement();
}
void RenderLayerBacking::setContentsNeedDisplay()
diff --git a/WebCore/rendering/RenderLayerBacking.h b/WebCore/rendering/RenderLayerBacking.h
index a6907e7..8e0ee23 100644
--- a/WebCore/rendering/RenderLayerBacking.h
+++ b/WebCore/rendering/RenderLayerBacking.h
@@ -124,6 +124,8 @@ public:
IntRect contentsBox() const;
+ RenderLayerCompositor* innerRenderLayerCompositor() const;
+
private:
void createGraphicsLayer();
void destroyGraphicsLayer();
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index 25d8eda..e96e375 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -37,6 +37,7 @@
#include "GraphicsLayer.h"
#include "HitTestResult.h"
#include "HTMLCanvasElement.h"
+#include "HTMLIFrameElement.h"
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
@@ -124,7 +125,12 @@ void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
else
destroyRootPlatformLayer();
- m_renderView->compositingStateChanged(m_compositing);
+ if (shouldPropagateCompositingToIFrameParent()) {
+ if (Element* ownerElement = m_renderView->document()->ownerElement()) {
+ // Trigger a recalcStyle in the parent document, to update compositing in that document.
+ ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
+ }
+ }
}
}
@@ -592,6 +598,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
childState.m_compositingAncestor = layer;
if (overlapMap)
addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
+ willBeComposited = true;
}
}
}
@@ -622,6 +629,8 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
}
}
+ ASSERT(willBeComposited == needsToBeComposited(layer));
+
// If we have a software transform, and we have layers under us, we need to also
// be composited. Also, if we have opacity < 1, then we need to be a layer so that
// the child layers are opaque, then rendered with opacity on this layer.
@@ -699,19 +708,6 @@ void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
hostingLayer->removeAllChildren();
}
-void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer)
-{
- ASSERT(layer->isComposited());
-
- GraphicsLayer* layerAnchor = layer->backing()->childForSuperlayers();
-
- if (layerAnchor->parent() != m_rootPlatformLayer) {
- layerAnchor->removeFromParent();
- if (m_rootPlatformLayer)
- m_rootPlatformLayer->addChild(layerAnchor);
- }
-}
-
#if ENABLE(VIDEO)
bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
{
@@ -799,11 +795,30 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, cons
}
if (layerBacking) {
- layerBacking->parentForSublayers()->setChildren(layerChildren);
+ if (shouldPropagateCompositingToIFrameParent() && layer->renderer()->isRenderIFrame()) {
+ // This is an iframe parent. Make it the parent of the iframe document's root
+ layerBacking->parentForSublayers()->removeAllChildren();
+
+ RenderLayerCompositor* innerCompositor = layerBacking->innerRenderLayerCompositor();
+ if (innerCompositor) {
+ GraphicsLayer* innerRootLayer = innerCompositor->rootPlatformLayer();
+ if (innerRootLayer)
+ layerBacking->parentForSublayers()->addChild(innerRootLayer);
+ }
+ } else
+ layerBacking->parentForSublayers()->setChildren(layerChildren);
childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
}
}
+void RenderLayerCompositor::setRootPlatformLayerClippingBox(const IntRect& contentsBox)
+{
+ if (m_clippingLayer) {
+ m_clippingLayer->setPosition(FloatPoint(contentsBox.x(), contentsBox.y()));
+ m_clippingLayer->setSize(FloatSize(contentsBox.width(), contentsBox.height()));
+ }
+}
+
// This just updates layer geometry without changing the hierarchy.
void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
{
@@ -957,7 +972,7 @@ RenderLayer* RenderLayerCompositor::rootRenderLayer() const
GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const
{
- return m_rootPlatformLayer.get();
+ return m_clippingLayer ? m_clippingLayer.get() : m_rootPlatformLayer.get();
}
void RenderLayerCompositor::didMoveOnscreen()
@@ -965,13 +980,28 @@ void RenderLayerCompositor::didMoveOnscreen()
if (!m_rootPlatformLayer)
return;
- Frame* frame = m_renderView->frameView()->frame();
- Page* page = frame ? frame->page() : 0;
- if (!page)
- return;
+ bool attached = false;
+ if (shouldPropagateCompositingToIFrameParent()) {
+ if (Element* ownerElement = m_renderView->document()->ownerElement()) {
+ RenderObject* renderer = ownerElement->renderer();
+ if (renderer && renderer->isRenderIFrame()) {
+ // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
+ // for the iframe's renderer in the parent document.
+ ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
+ attached = true;
+ }
+ }
+ }
+
+ if (!attached) {
+ Frame* frame = m_renderView->frameView()->frame();
+ Page* page = frame ? frame->page() : 0;
+ if (!page)
+ return;
- page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer.get());
- m_rootLayerAttached = true;
+ page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer.get());
+ }
+ m_rootLayerAttached = true;
}
void RenderLayerCompositor::willMoveOffscreen()
@@ -979,19 +1009,45 @@ void RenderLayerCompositor::willMoveOffscreen()
if (!m_rootPlatformLayer || !m_rootLayerAttached)
return;
- Frame* frame = m_renderView->frameView()->frame();
- Page* page = frame ? frame->page() : 0;
- if (!page)
- return;
+ bool detached = false;
+ if (shouldPropagateCompositingToIFrameParent()) {
+ if (Element* ownerElement = m_renderView->document()->ownerElement()) {
+ RenderObject* renderer = ownerElement->renderer();
+ if (renderer->isRenderIFrame()) {
+ // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
+ // for the iframe's renderer in the parent document.
+ ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
+ detached = true;
+ }
+ }
+ }
+
+ if (!detached) {
+ Frame* frame = m_renderView->frameView()->frame();
+ Page* page = frame ? frame->page() : 0;
+ if (!page)
+ return;
- page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
+ page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
+ }
m_rootLayerAttached = false;
}
void RenderLayerCompositor::updateRootLayerPosition()
{
- if (m_rootPlatformLayer)
- m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow()));
+ if (m_rootPlatformLayer) {
+ // FIXME: Adjust the y position of the m_rootPlatformLayer if we are clipping by its top edge
+ // Eventually this will be taken care of by scrolling logic
+ // https://bugs.webkit.org/show_bug.cgi?id=38518
+ float height = m_renderView->bottomLayoutOverflow();
+ float yOffset = 0;
+
+ if (m_clippingLayer && height > m_clippingLayer->size().height())
+ yOffset = m_clippingLayer->size().height() - height;
+
+ m_rootPlatformLayer->setPosition(FloatPoint(0, yOffset));
+ m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), height));
+ }
}
void RenderLayerCompositor::didStartAcceleratedAnimation()
@@ -1007,6 +1063,18 @@ bool RenderLayerCompositor::has3DContent() const
return layerHas3DContent(rootRenderLayer());
}
+bool RenderLayerCompositor::shouldPropagateCompositingToIFrameParent()
+{
+ // Parent document content needs to be able to render on top of a composited iframe, so correct behavior
+ // is to have the parent document become composited too. However, this can cause problems on platforms that
+ // use native views for frames (like Mac), so disable that behavior on those platforms for now.
+#if !PLATFORM(MAC)
+ return true;
+#else
+ return false;
+#endif
+}
+
bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
{
if (!canBeComposited(layer))
@@ -1194,7 +1262,9 @@ bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer)
bool RenderLayerCompositor::requiresCompositingForIFrame(RenderObject* renderer) const
{
- return renderer->isRenderIFrame() && toRenderIFrame(renderer)->requiresAcceleratedCompositing();
+ return shouldPropagateCompositingToIFrameParent()
+ && renderer->isRenderIFrame()
+ && toRenderIFrame(renderer)->requiresAcceleratedCompositing();
}
bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
@@ -1226,13 +1296,31 @@ void RenderLayerCompositor::ensureRootPlatformLayer()
m_rootPlatformLayer = GraphicsLayer::create(0);
m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow()));
- m_rootPlatformLayer->setPosition(FloatPoint(0, 0));
+ m_rootPlatformLayer->setPosition(FloatPoint());
+
// The root layer does flipping if we need it on this platform.
m_rootPlatformLayer->setGeometryOrientation(GraphicsLayer::compositingCoordinatesOrientation());
// Need to clip to prevent transformed content showing outside this frame
m_rootPlatformLayer->setMasksToBounds(true);
+ if (shouldPropagateCompositingToIFrameParent()) {
+ // Create a clipping layer if this is an iframe
+ if (Element* ownerElement = m_renderView->document()->ownerElement()) {
+ RenderObject* renderer = ownerElement->renderer();
+ if (renderer && renderer->isRenderIFrame()) {
+ m_clippingLayer = GraphicsLayer::create(0);
+ m_clippingLayer->setGeometryOrientation(GraphicsLayer::compositingCoordinatesOrientation());
+#ifndef NDEBUG
+ m_clippingLayer->setName("iframe Clipping");
+#endif
+ m_clippingLayer->setMasksToBounds(true);
+ m_clippingLayer->setAnchorPoint(FloatPoint());
+ m_clippingLayer->addChild(m_rootPlatformLayer.get());
+ }
+ }
+ }
+
didMoveOnscreen();
}
diff --git a/WebCore/rendering/RenderLayerCompositor.h b/WebCore/rendering/RenderLayerCompositor.h
index 43b8a17..36f7c15 100644
--- a/WebCore/rendering/RenderLayerCompositor.h
+++ b/WebCore/rendering/RenderLayerCompositor.h
@@ -136,6 +136,12 @@ public:
// Walk the tree looking for layers with 3d transforms. Useful in case you need
// to know if there is non-affine content, e.g. for drawing into an image.
bool has3DContent() const;
+
+ // Some platforms may wish to connect compositing layer trees between iframes and
+ // their parent document.
+ static bool shouldPropagateCompositingToIFrameParent();
+
+ void setRootPlatformLayerClippingBox(const IntRect& contentsBox);
private:
// Whether the given RL needs a compositing layer.
@@ -168,8 +174,6 @@ private:
void setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer);
void removeCompositedChildren(RenderLayer*);
- void parentInRootLayer(RenderLayer*);
-
bool layerHas3DContent(const RenderLayer*) const;
void ensureRootPlatformLayer();
@@ -199,6 +203,9 @@ private:
bool m_compositing;
bool m_rootLayerAttached;
bool m_compositingLayersNeedRebuild;
+
+ // Enclosing clipping layer for iframe content
+ OwnPtr<GraphicsLayer> m_clippingLayer;
#if PROFILE_LAYER_REBUILD
int m_rootLayerUpdateCount;
diff --git a/WebCore/rendering/RenderListBox.cpp b/WebCore/rendering/RenderListBox.cpp
index 15c652c..68591d6 100644
--- a/WebCore/rendering/RenderListBox.cpp
+++ b/WebCore/rendering/RenderListBox.cpp
@@ -188,7 +188,7 @@ void RenderListBox::calcPrefWidths()
m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
}
- int toAdd = paddingLeft() + paddingRight() + borderLeft() + borderRight();
+ int toAdd = borderAndPaddingWidth();
m_minPrefWidth += toAdd;
m_maxPrefWidth += toAdd;
@@ -221,7 +221,7 @@ int RenderListBox::listHeight() const
void RenderListBox::calcHeight()
{
- int toAdd = paddingTop() + paddingBottom() + borderTop() + borderBottom();
+ int toAdd = borderAndPaddingHeight();
int itemHeight = RenderListBox::itemHeight();
setHeight(itemHeight * size() - rowSpacing + toAdd);
diff --git a/WebCore/rendering/RenderMenuList.cpp b/WebCore/rendering/RenderMenuList.cpp
index 518925a..e2c6fd5 100644
--- a/WebCore/rendering/RenderMenuList.cpp
+++ b/WebCore/rendering/RenderMenuList.cpp
@@ -262,7 +262,7 @@ void RenderMenuList::calcPrefWidths()
m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
}
- int toAdd = paddingLeft() + paddingRight() + borderLeft() + borderRight();
+ int toAdd = borderAndPaddingWidth();
m_minPrefWidth += toAdd;
m_maxPrefWidth += toAdd;
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index d63997a..1c93ac4 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -69,7 +69,7 @@
#endif
#if ENABLE(SVG)
-#include "RenderSVGResource.h"
+#include "RenderSVGResourceContainer.h"
#include "SVGRenderSupport.h"
#endif
@@ -2494,19 +2494,19 @@ VisiblePosition RenderObject::createVisiblePosition(const Position& position)
}
#if ENABLE(SVG)
-const SVGRenderBase* RenderObject::toSVGRenderBase() const
+RenderSVGResourceContainer* RenderObject::toRenderSVGResourceContainer()
{
ASSERT_NOT_REACHED();
return 0;
}
-RenderSVGResource* RenderObject::toRenderSVGResource()
+FloatRect RenderObject::objectBoundingBox() const
{
ASSERT_NOT_REACHED();
- return 0;
+ return FloatRect();
}
-FloatRect RenderObject::objectBoundingBox() const
+FloatRect RenderObject::strokeBoundingBox() const
{
ASSERT_NOT_REACHED();
return FloatRect();
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index ae12758..9d8a306 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -54,8 +54,7 @@ class RenderTheme;
class TransformState;
class VisiblePosition;
#if ENABLE(SVG)
-class RenderSVGResource;
-class SVGRenderBase;
+class RenderSVGResourceContainer;
#endif
/*
@@ -332,16 +331,16 @@ public:
// to add SVG renderer methods to RenderObject with an ASSERT_NOT_REACHED() default implementation.
virtual bool isSVGRoot() const { return false; }
virtual bool isSVGContainer() const { return false; }
+ virtual bool isSVGGradientStop() const { return false; }
virtual bool isSVGHiddenContainer() const { return false; }
virtual bool isRenderPath() const { return false; }
virtual bool isSVGText() const { return false; }
virtual bool isSVGImage() const { return false; }
virtual bool isSVGForeignObject() const { return false; }
- virtual bool isSVGResource() const { return false; }
+ virtual bool isSVGResourceContainer() const { return false; }
virtual bool isSVGShadowTreeRootContainer() const { return false; }
- virtual const SVGRenderBase* toSVGRenderBase() const;
- virtual RenderSVGResource* toRenderSVGResource();
+ virtual RenderSVGResourceContainer* toRenderSVGResourceContainer();
// FIXME: Those belong into a SVG specific base-class for all renderers (see above)
// Unfortunately we don't have such a class yet, because it's not possible for all renderers
@@ -356,6 +355,7 @@ public:
// objectBoundingBox is returned local coordinates.
// The name objectBoundingBox is taken from the SVG 1.1 spec.
virtual FloatRect objectBoundingBox() const;
+ virtual FloatRect strokeBoundingBox() const;
// Returns the smallest rectangle enclosing all of the painted content
// respecting clipping, masking, filters, opacity, stroke-width and markers
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index b1e2a8f..ccb9562 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -4,6 +4,7 @@
2005, 2007 Eric Seidel <eric@webkit.org>
2009 Google, Inc.
2009 Dirk Schulze <krit@webkit.org>
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -34,7 +35,6 @@
#include "RenderSVGResourceFilter.h"
#include "RenderSVGResourceMarker.h"
#include "StrokeStyleApplier.h"
-#include "SVGPaintServer.h"
#include "SVGRenderSupport.h"
#include "SVGStyledTransformableElement.h"
#include "SVGTransformList.h"
@@ -65,7 +65,7 @@ private:
RenderPath::RenderPath(SVGStyledTransformableElement* node)
: RenderSVGModelObject(node)
- , m_needsBoundariesUpdate(false) // default is false, as this is only used when a RenderSVGResource tells us that the boundaries need to be recached
+ , m_needsBoundariesUpdate(false) // default is false, the cached rects are empty from the beginning
, m_needsPathUpdate(true) // default is true, so we grab a Path object once from SVGStyledTransformableElement
, m_needsTransformUpdate(true) // default is true, so we grab a AffineTransform object once from SVGStyledTransformableElement
{
@@ -73,10 +73,10 @@ RenderPath::RenderPath(SVGStyledTransformableElement* node)
bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill) const
{
- if (m_path.isEmpty())
+ if (!m_fillBoundingBox.contains(point))
return false;
- if (requiresFill && !SVGPaintServer::fillPaintServer(style(), this))
+ if (requiresFill && !RenderSVGResource::fillPaintingResource(this, style()))
return false;
return m_path.contains(point, style()->svgStyle()->fillRule());
@@ -84,87 +84,16 @@ bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill) const
bool RenderPath::strokeContains(const FloatPoint& point, bool requiresStroke) const
{
- if (m_path.isEmpty())
+ if (!m_strokeAndMarkerBoundingBox.contains(point))
return false;
- if (requiresStroke && !SVGPaintServer::strokePaintServer(style(), this))
+ if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style()))
return false;
BoundingRectStrokeStyleApplier strokeStyle(this, style());
return m_path.strokeContains(&strokeStyle, point);
}
-FloatRect RenderPath::objectBoundingBox() const
-{
- if (m_path.isEmpty())
- return FloatRect();
-
- if (m_cachedLocalFillBBox.isEmpty())
- m_cachedLocalFillBBox = m_path.boundingRect();
-
- return m_cachedLocalFillBBox;
-}
-
-FloatRect RenderPath::strokeBoundingBox() const
-{
- if (m_path.isEmpty())
- return FloatRect();
-
- if (!m_cachedLocalStrokeBBox.isEmpty())
- return m_cachedLocalStrokeBBox;
-
- m_cachedLocalStrokeBBox = objectBoundingBox();
- if (style()->svgStyle()->hasStroke()) {
- BoundingRectStrokeStyleApplier strokeStyle(this, style());
- m_cachedLocalStrokeBBox.unite(m_path.strokeBoundingRect(&strokeStyle));
- }
-
- return m_cachedLocalStrokeBBox;
-}
-
-FloatRect RenderPath::markerBoundingBox() const
-{
- if (m_path.isEmpty())
- return FloatRect();
-
- if (m_cachedLocalMarkerBBox.isEmpty())
- calculateMarkerBoundsIfNeeded();
-
- return m_cachedLocalMarkerBBox;
-}
-
-FloatRect RenderPath::repaintRectInLocalCoordinates() const
-{
- if (m_path.isEmpty())
- return FloatRect();
-
- // If we already have a cached repaint rect, return that
- if (!m_cachedLocalRepaintRect.isEmpty())
- return m_cachedLocalRepaintRect;
-
- // FIXME: We need to be careful here. We assume that there is no filter,
- // clipper, marker or masker if the rects are empty.
- FloatRect rect = filterBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_cachedLocalRepaintRect = rect;
- else {
- m_cachedLocalRepaintRect = strokeBoundingBox();
- m_cachedLocalRepaintRect.unite(markerBoundingBox());
- }
-
- rect = clipperBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_cachedLocalRepaintRect.intersect(rect);
-
- rect = maskerBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_cachedLocalRepaintRect.intersect(rect);
-
- style()->svgStyle()->inflateForShadow(m_cachedLocalRepaintRect);
-
- return m_cachedLocalRepaintRect;
-}
-
void RenderPath::layout()
{
LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
@@ -173,15 +102,11 @@ void RenderPath::layout()
// We need to update the Path object whenever the underlying SVGStyledTransformableElement uses relative values
// as the viewport size may have changed. It would be nice to optimize this to detect these changes, and only
// update when needed, even when using relative values.
- if (!m_needsPathUpdate && element->hasRelativeValues())
- m_needsPathUpdate = true;
-
- bool needsUpdate = m_needsPathUpdate || m_needsTransformUpdate || m_needsBoundariesUpdate;
+ bool needsPathUpdate = m_needsPathUpdate;
+ if (!needsPathUpdate && element->hasRelativeValues())
+ needsPathUpdate = true;
- if (m_needsBoundariesUpdate)
- m_needsBoundariesUpdate = false;
-
- if (m_needsPathUpdate) {
+ if (needsPathUpdate) {
m_path = element->toPathData();
m_needsPathUpdate = false;
}
@@ -191,27 +116,31 @@ void RenderPath::layout()
m_needsTransformUpdate = false;
}
- if (needsUpdate)
- invalidateCachedBoundaries();
+ // At this point LayoutRepainter already grabbed the old bounds,
+ // recalculate them now so repaintAfterLayout() uses the new bounds
+ if (needsPathUpdate || m_needsBoundariesUpdate) {
+ updateCachedBoundaries();
+ m_needsBoundariesUpdate = false;
+ }
repainter.repaintAfterLayout();
setNeedsLayout(false);
}
-static inline void fillAndStrokePath(const Path& path, GraphicsContext* context, RenderStyle* style, RenderPath* object)
+static inline void fillAndStrokePath(const Path& path, GraphicsContext* context, RenderPath* object)
{
context->beginPath();
- SVGPaintServer* fillPaintServer = SVGPaintServer::fillPaintServer(style, object);
- if (fillPaintServer) {
+ if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(object, object->style())) {
context->addPath(path);
- fillPaintServer->draw(context, object, ApplyToFillTargetType);
+ if (fillPaintingResource->applyResource(object, object->style(), context, ApplyToFillMode))
+ fillPaintingResource->postApplyResource(object, context, ApplyToFillMode);
}
-
- SVGPaintServer* strokePaintServer = SVGPaintServer::strokePaintServer(style, object);
- if (strokePaintServer) {
- context->addPath(path); // path is cleared when filled.
- strokePaintServer->draw(context, object, ApplyToStrokeTargetType);
+
+ if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(object, object->style())) {
+ context->addPath(path);
+ if (strokePaintingResource->applyResource(object, object->style(), context, ApplyToStrokeMode))
+ strokePaintingResource->postApplyResource(object, context, ApplyToStrokeMode);
}
}
@@ -222,10 +151,7 @@ void RenderPath::paint(PaintInfo& paintInfo, int, int)
FloatRect boundingBox = repaintRectInLocalCoordinates();
FloatRect nonLocalBoundingBox = m_localTransform.mapRect(boundingBox);
- // FIXME: The empty rect check is to deal with incorrect initial clip in renderSubtreeToImage
- // unfortunately fixing that problem is fairly complex unless we were willing to just futz the
- // rect to something "close enough"
- if (!nonLocalBoundingBox.intersects(paintInfo.rect) && !paintInfo.rect.isEmpty())
+ if (!nonLocalBoundingBox.intersects(paintInfo.rect))
return;
PaintInfo childPaintInfo(paintInfo);
@@ -239,13 +165,16 @@ void RenderPath::paint(PaintInfo& paintInfo, int, int)
PaintInfo savedInfo(childPaintInfo);
if (prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter)) {
- if (style()->svgStyle()->shapeRendering() == SR_CRISPEDGES)
+ const SVGRenderStyle* svgStyle = style()->svgStyle();
+ if (svgStyle->shapeRendering() == SR_CRISPEDGES)
childPaintInfo.context->setShouldAntialias(false);
- fillAndStrokePath(m_path, childPaintInfo.context, style(), this);
- if (static_cast<SVGStyledElement*>(node())->supportsMarkers())
+ fillAndStrokePath(m_path, childPaintInfo.context, this);
+
+ if (svgStyle->hasMarkers())
m_markerLayoutInfo.drawMarkers(childPaintInfo);
}
+
finishRenderSVGContent(this, childPaintInfo, filter, savedInfo.context);
}
@@ -288,20 +217,22 @@ bool RenderPath::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result,
return false;
}
-void RenderPath::calculateMarkerBoundsIfNeeded() const
+FloatRect RenderPath::calculateMarkerBoundsIfNeeded()
{
Document* doc = document();
SVGElement* svgElement = static_cast<SVGElement*>(node());
ASSERT(svgElement && svgElement->document());
if (!svgElement->isStyled())
- return;
+ return FloatRect();
SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
if (!styledElement->supportsMarkers())
- return;
+ return FloatRect();
const SVGRenderStyle* svgStyle = style()->svgStyle();
+ ASSERT(svgStyle->hasMarkers());
+
AtomicString startMarkerId(svgStyle->markerStartResource());
AtomicString midMarkerId(svgStyle->markerMidResource());
AtomicString endMarkerId(svgStyle->markerEndResource());
@@ -326,24 +257,63 @@ void RenderPath::calculateMarkerBoundsIfNeeded() const
endMarker->addClient(this);
if (!startMarker && !midMarker && !endMarker)
- return;
+ return FloatRect();
float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, svgStyle->strokeWidth(), 1.0f);
- m_cachedLocalMarkerBBox = m_markerLayoutInfo.calculateBoundaries(startMarker, midMarker, endMarker, strokeWidth, m_path);
+ return m_markerLayoutInfo.calculateBoundaries(startMarker, midMarker, endMarker, strokeWidth, m_path);
}
-void RenderPath::invalidateCachedBoundaries()
+void RenderPath::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
- m_cachedLocalRepaintRect = FloatRect();
- m_cachedLocalStrokeBBox = FloatRect();
- m_cachedLocalFillBBox = FloatRect();
- m_cachedLocalMarkerBBox = FloatRect();
+ setNeedsBoundariesUpdate();
+ RenderSVGModelObject::styleWillChange(diff, newStyle);
}
-void RenderPath::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderPath::updateCachedBoundaries()
{
- invalidateCachedBoundaries();
- RenderSVGModelObject::styleWillChange(diff, newStyle);
+ if (m_path.isEmpty()) {
+ m_fillBoundingBox = FloatRect();
+ m_strokeAndMarkerBoundingBox = FloatRect();
+ m_repaintBoundingBox = FloatRect();
+ return;
+ }
+
+ // Cache _unclipped_ fill bounding box, used for calculations in resources
+ m_fillBoundingBox = m_path.boundingRect();
+
+ // Cache _unclipped_ stroke bounding box, used for calculations in resources (includes marker boundaries)
+ m_strokeAndMarkerBoundingBox = m_fillBoundingBox;
+
+ const SVGRenderStyle* svgStyle = style()->svgStyle();
+ if (svgStyle->hasStroke()) {
+ BoundingRectStrokeStyleApplier strokeStyle(this, style());
+ m_strokeAndMarkerBoundingBox.unite(m_path.strokeBoundingRect(&strokeStyle));
+ }
+
+ if (svgStyle->hasMarkers()) {
+ FloatRect markerBounds = calculateMarkerBoundsIfNeeded();
+ if (!markerBounds.isEmpty())
+ m_strokeAndMarkerBoundingBox.unite(markerBounds);
+ }
+
+ // Cache smallest possible repaint rectangle
+
+ // FIXME: We need to be careful here. We assume that there is no resource, if the rect is empty.
+ FloatRect rect = filterBoundingBoxForRenderer(this);
+ if (rect.isEmpty())
+ m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
+ else
+ m_repaintBoundingBox = rect;
+
+ rect = clipperBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ m_repaintBoundingBox.intersect(rect);
+
+ rect = maskerBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ m_repaintBoundingBox.intersect(rect);
+
+ svgStyle->inflateForShadow(m_repaintBoundingBox);
}
}
diff --git a/WebCore/rendering/RenderPath.h b/WebCore/rendering/RenderPath.h
index ea4de40..5509057 100644
--- a/WebCore/rendering/RenderPath.h
+++ b/WebCore/rendering/RenderPath.h
@@ -50,11 +50,9 @@ private:
bool fillContains(const FloatPoint&, bool requiresFill = true) const;
bool strokeContains(const FloatPoint&, bool requiresStroke = true) const;
- virtual FloatRect objectBoundingBox() const;
- virtual FloatRect strokeBoundingBox() const;
- virtual FloatRect markerBoundingBox() const;
- virtual FloatRect repaintRectInLocalCoordinates() const;
-
+ virtual FloatRect objectBoundingBox() const { return m_fillBoundingBox; }
+ virtual FloatRect strokeBoundingBox() const { return m_strokeAndMarkerBoundingBox; }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
virtual bool isRenderPath() const { return true; }
@@ -67,8 +65,8 @@ private:
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
virtual void styleWillChange(StyleDifference, const RenderStyle*);
- void calculateMarkerBoundsIfNeeded() const;
- void invalidateCachedBoundaries();
+ FloatRect calculateMarkerBoundsIfNeeded();
+ void updateCachedBoundaries();
private:
virtual AffineTransform localTransform() const { return m_localTransform; }
@@ -78,11 +76,10 @@ private:
bool m_needsTransformUpdate : 1;
mutable Path m_path;
- mutable FloatRect m_cachedLocalFillBBox;
- mutable FloatRect m_cachedLocalStrokeBBox;
- mutable FloatRect m_cachedLocalRepaintRect;
- mutable FloatRect m_cachedLocalMarkerBBox;
- mutable SVGMarkerLayoutInfo m_markerLayoutInfo;
+ FloatRect m_fillBoundingBox;
+ FloatRect m_strokeAndMarkerBoundingBox;
+ FloatRect m_repaintBoundingBox;
+ SVGMarkerLayoutInfo m_markerLayoutInfo;
AffineTransform m_localTransform;
};
diff --git a/WebCore/rendering/RenderProgress.cpp b/WebCore/rendering/RenderProgress.cpp
index a9dbfe8..b42cc8b 100644
--- a/WebCore/rendering/RenderProgress.cpp
+++ b/WebCore/rendering/RenderProgress.cpp
@@ -23,9 +23,12 @@
#include "RenderProgress.h"
+#include "HTMLDivElement.h"
#include "HTMLProgressElement.h"
#include "RenderTheme.h"
+#include "RenderView.h"
#include <wtf/CurrentTime.h>
+#include <wtf/RefPtr.h>
using namespace std;
@@ -33,6 +36,23 @@ namespace WebCore {
using namespace HTMLNames;
+class ProgressValueElement : public HTMLDivElement {
+public:
+ ProgressValueElement(Document*, Node* shadowParent);
+
+private:
+ virtual bool isShadowNode() const { return true; }
+ virtual Node* shadowParentNode() { return m_shadowParent; }
+
+ Node* m_shadowParent;
+};
+
+ProgressValueElement::ProgressValueElement(Document* document, Node* shadowParent)
+: HTMLDivElement(divTag, document)
+, m_shadowParent(shadowParent)
+{
+}
+
RenderProgress::RenderProgress(HTMLProgressElement* element)
: RenderBlock(element)
, m_position(-1)
@@ -41,19 +61,48 @@ RenderProgress::RenderProgress(HTMLProgressElement* element)
, m_animationDuration(0)
, m_animating(false)
, m_animationTimer(this, &RenderProgress::animationTimerFired)
+ , m_valuePart(0)
{
}
+RenderProgress::~RenderProgress()
+{
+ if (m_valuePart)
+ m_valuePart->detach();
+}
+
void RenderProgress::layout()
{
ASSERT(needsLayout());
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+ IntSize oldSize = size();
+
calcWidth();
calcHeight();
-
- m_overflow.clear();
+ if (m_valuePart) {
+ IntRect valuePartRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), lround((width() - borderLeft() - paddingLeft() - borderRight() - paddingRight()) * position()), height() - borderTop() - paddingTop() - borderBottom() - paddingBottom());
+ if (style()->direction() == RTL)
+ valuePartRect.setX(width() - borderRight() - paddingRight() - valuePartRect.width());
+ toRenderBox(m_valuePart->renderer())->setFrameRect(valuePartRect);
+
+ if (oldSize != size())
+ m_valuePart->renderer()->setChildNeedsLayout(true, false);
+
+ LayoutStateMaintainer statePusher(view(), this, size());
+
+ IntRect oldRect = toRenderBox(m_valuePart->renderer())->frameRect();
+
+ m_valuePart->renderer()->layoutIfNeeded();
+
+ toRenderBox(m_valuePart->renderer())->setFrameRect(valuePartRect);
+ if (m_valuePart->renderer()->checkForRepaintDuringLayout())
+ m_valuePart->renderer()->repaintDuringLayoutIfMoved(oldRect);
+
+ statePusher.pop();
+ addOverflowFromChild(toRenderBox(m_valuePart->renderer()));
+ }
updateAnimationState();
@@ -62,6 +111,13 @@ void RenderProgress::layout()
setNeedsLayout(false);
}
+void RenderProgress::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderBlock::styleDidChange(diff, oldStyle);
+
+ updateValuePartState();
+}
+
void RenderProgress::updateFromElement()
{
HTMLProgressElement* element = progressElement();
@@ -71,9 +127,46 @@ void RenderProgress::updateFromElement()
updateAnimationState();
+ updateValuePartState();
+
repaint();
}
+void RenderProgress::updateValuePartState()
+{
+ bool needLayout = !style()->hasAppearance() || m_valuePart;
+ if (!style()->hasAppearance() && !m_valuePart) {
+ m_valuePart = new ProgressValueElement(document(), node());
+ RefPtr<RenderStyle> styleForValuePart = createStyleForValuePart(style());
+ m_valuePart->setRenderer(m_valuePart->createRenderer(renderArena(), styleForValuePart.get()));
+ m_valuePart->renderer()->setStyle(styleForValuePart.release());
+ m_valuePart->setAttached();
+ m_valuePart->setInDocument();
+ addChild(m_valuePart->renderer());
+ } else if (style()->hasAppearance() && m_valuePart) {
+ m_valuePart->detach();
+ m_valuePart = 0;
+ }
+ if (needLayout)
+ setNeedsLayout(true);
+}
+
+PassRefPtr<RenderStyle> RenderProgress::createStyleForValuePart(RenderStyle* parentStyle)
+{
+ RefPtr<RenderStyle> styleForValuePart;
+ RenderStyle* pseudoStyle = getCachedPseudoStyle(PROGRESS_BAR_VALUE);
+ if (pseudoStyle)
+ styleForValuePart = RenderStyle::clone(pseudoStyle);
+ else
+ styleForValuePart = RenderStyle::create();
+
+ if (parentStyle)
+ styleForValuePart->inheritFrom(parentStyle);
+ styleForValuePart->setDisplay(BLOCK);
+ styleForValuePart->setAppearance(ProgressBarValuePart);
+ return styleForValuePart.release();
+}
+
double RenderProgress::animationProgress()
{
return m_animating ? (fmod((currentTime() - m_animationStartTime), m_animationDuration) / m_animationDuration) : 0;
@@ -99,7 +192,7 @@ void RenderProgress::updateAnimationState()
m_animationDuration = theme()->animationDurationForProgressBar(this);
m_animationRepeatInterval = theme()->animationRepeatIntervalForProgressBar(this);
- bool animating = m_animationDuration > 0;
+ bool animating = style()->hasAppearance() && m_animationDuration > 0;
if (animating == m_animating)
return;
diff --git a/WebCore/rendering/RenderProgress.h b/WebCore/rendering/RenderProgress.h
index d6f5078..0d93ae7 100644
--- a/WebCore/rendering/RenderProgress.h
+++ b/WebCore/rendering/RenderProgress.h
@@ -27,10 +27,13 @@
namespace WebCore {
class HTMLProgressElement;
+class ProgressValueElement;
class RenderProgress : public RenderBlock {
public:
RenderProgress(HTMLProgressElement*);
+ virtual ~RenderProgress();
+
double position() { return m_position; }
double animationProgress();
@@ -42,9 +45,12 @@ private:
virtual void layout();
virtual void updateFromElement();
virtual void paint(PaintInfo&, int tx, int ty);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void animationTimerFired(Timer<RenderProgress>*);
void updateAnimationState();
+ void updateValuePartState();
+ PassRefPtr<RenderStyle> createStyleForValuePart(RenderStyle*);
double m_position;
double m_animationStartTime;
@@ -52,6 +58,7 @@ private:
double m_animationDuration;
bool m_animating;
Timer<RenderProgress> m_animationTimer;
+ RefPtr<ProgressValueElement> m_valuePart;
};
inline RenderProgress* toRenderProgress(RenderObject* object)
diff --git a/WebCore/rendering/RenderReplaced.cpp b/WebCore/rendering/RenderReplaced.cpp
index 0ba99f5..d579b99 100644
--- a/WebCore/rendering/RenderReplaced.cpp
+++ b/WebCore/rendering/RenderReplaced.cpp
@@ -196,11 +196,11 @@ void RenderReplaced::calcPrefWidths()
{
ASSERT(prefWidthsDirty());
- int paddingAndBorders = paddingLeft() + paddingRight() + borderLeft() + borderRight();
- int width = calcReplacedWidth(false) + paddingAndBorders;
+ int borderAndPadding = borderAndPaddingWidth();
+ int width = calcReplacedWidth(false) + borderAndPadding;
if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength)
- width = min(width, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? paddingAndBorders : 0));
+ width = min(width, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? borderAndPadding : 0));
if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent())) {
m_minPrefWidth = 0;
diff --git a/WebCore/rendering/RenderSVGBlock.h b/WebCore/rendering/RenderSVGBlock.h
index 19cac62..a250c00 100644
--- a/WebCore/rendering/RenderSVGBlock.h
+++ b/WebCore/rendering/RenderSVGBlock.h
@@ -33,8 +33,6 @@ class RenderSVGBlock : public RenderBlock, protected SVGRenderBase {
public:
RenderSVGBlock(SVGElement*);
- virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
-
private:
virtual void setStyle(PassRefPtr<RenderStyle>);
virtual void updateBoxModelInfoFromStyle();
diff --git a/WebCore/rendering/RenderSVGGradientStop.cpp b/WebCore/rendering/RenderSVGGradientStop.cpp
index 66391c8..754f31f 100644
--- a/WebCore/rendering/RenderSVGGradientStop.cpp
+++ b/WebCore/rendering/RenderSVGGradientStop.cpp
@@ -48,10 +48,8 @@ void RenderSVGGradientStop::styleDidChange(StyleDifference diff, const RenderSty
// <stop> elements should only be allowed to make renderers under gradient elements
// but I can imagine a few cases we might not be catching, so let's not crash if our parent isn't a gradient.
- if (SVGGradientElement* gradient = gradientElement()) {
- if (SVGResource* resource = gradient->canvasResource(this))
- resource->invalidate();
- }
+ if (SVGGradientElement* gradient = gradientElement())
+ gradient->invalidateResourceClients();
}
void RenderSVGGradientStop::layout()
diff --git a/WebCore/rendering/RenderSVGGradientStop.h b/WebCore/rendering/RenderSVGGradientStop.h
index 1d0858d..45da7b4 100644
--- a/WebCore/rendering/RenderSVGGradientStop.h
+++ b/WebCore/rendering/RenderSVGGradientStop.h
@@ -27,32 +27,40 @@
namespace WebCore {
- class SVGGradientElement;
- class SVGStopElement;
-
- // This class exists mostly so we can hear about gradient stop style changes
- class RenderSVGGradientStop : public RenderObject {
- public:
- RenderSVGGradientStop(SVGStopElement*);
- virtual ~RenderSVGGradientStop();
+class SVGGradientElement;
+class SVGStopElement;
+
+// This class exists mostly so we can hear about gradient stop style changes
+class RenderSVGGradientStop : public RenderObject {
+public:
+ RenderSVGGradientStop(SVGStopElement*);
+ virtual ~RenderSVGGradientStop();
+
+ virtual bool isSVGGradientStop() const { return true; }
+ virtual const char* renderName() const { return "RenderSVGGradientStop"; }
- virtual const char* renderName() const { return "RenderSVGGradientStop"; }
+ virtual void layout();
- virtual void layout();
+ // This overrides are needed to prevent ASSERTs on <svg><stop /></svg>
+ // RenderObject's default implementations ASSERT_NOT_REACHED()
+ // https://bugs.webkit.org/show_bug.cgi?id=20400
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject*) { return IntRect(); }
+ virtual FloatRect objectBoundingBox() const { return FloatRect(); }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
- // This overrides are needed to prevent ASSERTs on <svg><stop /></svg>
- // RenderObject's default implementations ASSERT_NOT_REACHED()
- // https://bugs.webkit.org/show_bug.cgi?id=20400
- virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject*) { return IntRect(); }
- virtual FloatRect objectBoundingBox() const { return FloatRect(); }
- virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
+protected:
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- protected:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+private:
+ SVGGradientElement* gradientElement() const;
+};
+
+inline const RenderSVGGradientStop* toRenderSVGGradientStop(const RenderObject* object)
+{
+ ASSERT(!object || object->isSVGGradientStop());
+ return static_cast<const RenderSVGGradientStop*>(object);
+}
- private:
- SVGGradientElement* gradientElement() const;
- };
}
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/RenderSVGImage.h b/WebCore/rendering/RenderSVGImage.h
index 120ac72..512892c 100644
--- a/WebCore/rendering/RenderSVGImage.h
+++ b/WebCore/rendering/RenderSVGImage.h
@@ -41,7 +41,6 @@ public:
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
private:
- virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
virtual const char* renderName() const { return "RenderSVGImage"; }
virtual bool isSVGImage() const { return true; }
diff --git a/WebCore/rendering/RenderSVGInline.cpp b/WebCore/rendering/RenderSVGInline.cpp
index 33459ce..85d148e 100644
--- a/WebCore/rendering/RenderSVGInline.cpp
+++ b/WebCore/rendering/RenderSVGInline.cpp
@@ -75,14 +75,10 @@ FloatRect RenderSVGInline::objectBoundingBox() const
FloatRect RenderSVGInline::strokeBoundingBox() const
{
- const RenderObject* object = findTextRootObject(this);
- ASSERT(object);
-
- const SVGRenderBase* renderer = object->toSVGRenderBase();
- if (!renderer)
- return FloatRect();
+ if (const RenderObject* object = findTextRootObject(this))
+ return object->strokeBoundingBox();
- return renderer->strokeBoundingBox();
+ return FloatRect();
}
FloatRect RenderSVGInline::repaintRectInLocalCoordinates() const
diff --git a/WebCore/rendering/RenderSVGInline.h b/WebCore/rendering/RenderSVGInline.h
index e57b936..1afbb97 100644
--- a/WebCore/rendering/RenderSVGInline.h
+++ b/WebCore/rendering/RenderSVGInline.h
@@ -35,8 +35,6 @@ class RenderSVGInline : public RenderInline, protected SVGRenderBase {
public:
RenderSVGInline(Node*);
- virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
-
virtual const char* renderName() const { return "RenderSVGInline"; }
virtual bool requiresLayer() const { return false; }
diff --git a/WebCore/rendering/RenderSVGModelObject.h b/WebCore/rendering/RenderSVGModelObject.h
index 760e79a..affa18d 100644
--- a/WebCore/rendering/RenderSVGModelObject.h
+++ b/WebCore/rendering/RenderSVGModelObject.h
@@ -49,8 +49,6 @@ class RenderSVGModelObject : public RenderObject, protected SVGRenderBase {
public:
RenderSVGModelObject(SVGStyledElement*);
- virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
-
virtual bool requiresLayer() const { return false; }
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
diff --git a/WebCore/rendering/RenderSVGResource.cpp b/WebCore/rendering/RenderSVGResource.cpp
new file mode 100644
index 0000000..821e58a
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResource.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * 2007 Rob Buis <buis@kde.org>
+ * 2008 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGResource.h"
+
+#include "RenderSVGResourceContainer.h"
+#include "RenderSVGResourceSolidColor.h"
+#include "SVGURIReference.h"
+
+namespace WebCore {
+
+static inline void registerPendingResource(const AtomicString& id, const SVGPaint::SVGPaintType& paintType, const RenderObject* object)
+{
+ if (paintType != SVGPaint::SVG_PAINTTYPE_URI)
+ return;
+
+ SVGElement* svgElement = static_cast<SVGElement*>(object->node());
+ ASSERT(svgElement);
+ ASSERT(svgElement->isStyled());
+
+ object->document()->accessSVGExtensions()->addPendingResource(id, static_cast<SVGStyledElement*>(svgElement));
+}
+
+static inline void adjustColorForPseudoRules(const RenderStyle* style, bool useFillPaint, Color& color)
+{
+ if (style->insideLink() != InsideVisitedLink)
+ return;
+
+ RenderStyle* visitedStyle = style->getCachedPseudoStyle(VISITED_LINK);
+ SVGPaint* visitedPaint = useFillPaint ? visitedStyle->svgStyle()->fillPaint() : visitedStyle->svgStyle()->strokePaint();
+ if (visitedPaint->paintType() == SVGPaint::SVG_PAINTTYPE_URI)
+ return;
+
+ Color visitedColor;
+ if (visitedPaint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
+ visitedColor = visitedStyle->color();
+ else
+ visitedColor = visitedPaint->color();
+
+ if (visitedColor.isValid())
+ color = Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), color.alpha());
+}
+
+// FIXME: This method and strokePaintingResource() should be refactored, to share even more code
+RenderSVGResource* RenderSVGResource::fillPaintingResource(const RenderObject* object, const RenderStyle* style)
+{
+ ASSERT(object);
+ ASSERT(style);
+
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+ if (!svgStyle || !svgStyle->hasFill())
+ return 0;
+
+ SVGPaint* fillPaint = svgStyle->fillPaint();
+ ASSERT(fillPaint);
+
+ RenderSVGResource* fillPaintingResource = 0;
+
+ SVGPaint::SVGPaintType paintType = fillPaint->paintType();
+ if (paintType == SVGPaint::SVG_PAINTTYPE_URI
+ || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) {
+ AtomicString id(SVGURIReference::getTarget(fillPaint->uri()));
+ fillPaintingResource = getRenderSVGResourceContainerById(object->document(), id);
+
+ if (!fillPaintingResource)
+ registerPendingResource(id, paintType, object);
+ }
+
+ if (paintType != SVGPaint::SVG_PAINTTYPE_URI && !fillPaintingResource) {
+ RenderSVGResourceSolidColor* solidResource = sharedSolidPaintingResource();
+ fillPaintingResource = solidResource;
+
+ Color fillColor;
+ if (fillPaint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
+ fillColor = style->color();
+ else
+ fillColor = fillPaint->color();
+
+ adjustColorForPseudoRules(style, true /* useFillPaint */, fillColor);
+
+ // FIXME: Ideally invalid colors would never get set on the RenderStyle and this could turn into an ASSERT
+ if (fillColor.isValid())
+ solidResource->setColor(fillColor);
+ else
+ fillPaintingResource = 0;
+ }
+
+ if (!fillPaintingResource) {
+ // default value (black), see bug 11017
+ RenderSVGResourceSolidColor* solidResource = sharedSolidPaintingResource();
+ solidResource->setColor(Color::black);
+ fillPaintingResource = solidResource;
+ }
+
+ return fillPaintingResource;
+}
+
+RenderSVGResource* RenderSVGResource::strokePaintingResource(const RenderObject* object, const RenderStyle* style)
+{
+ ASSERT(object);
+ ASSERT(style);
+
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+ if (!svgStyle || !svgStyle->hasStroke())
+ return 0;
+
+ SVGPaint* strokePaint = svgStyle->strokePaint();
+ ASSERT(strokePaint);
+
+ RenderSVGResource* strokePaintingResource = 0;
+ FloatRect objectBoundingBox = object->objectBoundingBox();
+
+ SVGPaint::SVGPaintType paintType = strokePaint->paintType();
+ if (!objectBoundingBox.isEmpty()
+ && (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)) {
+ AtomicString id(SVGURIReference::getTarget(strokePaint->uri()));
+ strokePaintingResource = getRenderSVGResourceContainerById(object->document(), id);
+
+ if (!strokePaintingResource)
+ registerPendingResource(id, paintType, object);
+ }
+
+ if (paintType != SVGPaint::SVG_PAINTTYPE_URI && !strokePaintingResource) {
+ RenderSVGResourceSolidColor* solidResource = sharedSolidPaintingResource();
+ strokePaintingResource = solidResource;
+
+ Color strokeColor;
+ if (strokePaint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
+ strokeColor = style->color();
+ else
+ strokeColor = strokePaint->color();
+
+ adjustColorForPseudoRules(style, false /* useFillPaint */, strokeColor);
+
+ // FIXME: Ideally invalid colors would never get set on the RenderStyle and this could turn into an ASSERT
+ if (strokeColor.isValid())
+ solidResource->setColor(strokeColor);
+ else
+ strokePaintingResource = 0;
+ }
+
+ if (!strokePaintingResource) {
+ // default value (black), see bug 11017
+ RenderSVGResourceSolidColor* solidResource = sharedSolidPaintingResource();
+ solidResource->setColor(Color::black);
+ strokePaintingResource = solidResource;
+ }
+
+ return strokePaintingResource;
+}
+
+RenderSVGResourceSolidColor* RenderSVGResource::sharedSolidPaintingResource()
+{
+ static RenderSVGResourceSolidColor* s_sharedSolidPaintingResource = 0;
+ if (!s_sharedSolidPaintingResource)
+ s_sharedSolidPaintingResource = new RenderSVGResourceSolidColor;
+ return s_sharedSolidPaintingResource;
+}
+
+void RenderSVGResource::markForLayoutAndResourceInvalidation(RenderObject* object)
+{
+ ASSERT(object);
+ ASSERT(object->node());
+ ASSERT(object->node()->isSVGElement());
+
+ // Mark the renderer for layout
+ object->setNeedsLayout(true);
+
+ // Notify any resources in the ancestor chain, that we've been invalidated
+ SVGElement* element = static_cast<SVGElement*>(object->node());
+ if (!element->isStyled())
+ return;
+
+ static_cast<SVGStyledElement*>(element)->invalidateResourcesInAncestorChain();
+}
+
+}
+
+#endif
diff --git a/WebCore/rendering/RenderSVGResource.h b/WebCore/rendering/RenderSVGResource.h
index 1665404..f14fa4a 100644
--- a/WebCore/rendering/RenderSVGResource.h
+++ b/WebCore/rendering/RenderSVGResource.h
@@ -22,64 +22,47 @@
#define RenderSVGResource_h
#if ENABLE(SVG)
-#include "FloatRect.h"
-#include "RenderSVGHiddenContainer.h"
+#include "SVGDocumentExtensions.h"
namespace WebCore {
enum RenderSVGResourceType {
MaskerResourceType,
MarkerResourceType,
+ PatternResourceType,
+ LinearGradientResourceType,
+ RadialGradientResourceType,
+ SolidColorResourceType,
FilterResourceType,
ClipperResourceType
};
-class RenderSVGResource : public RenderSVGHiddenContainer {
-public:
- RenderSVGResource(SVGStyledElement* node)
- : RenderSVGHiddenContainer(node)
- , m_id(node->getIDAttribute())
- {
- ASSERT(node->document());
- node->document()->accessSVGExtensions()->addResource(m_id, this);
- }
-
- virtual ~RenderSVGResource()
- {
- ASSERT(node());
- ASSERT(node()->document());
- node()->document()->accessSVGExtensions()->removeResource(m_id);
- }
-
- void idChanged()
- {
- ASSERT(node());
- ASSERT(node()->document());
- SVGDocumentExtensions* extensions = node()->document()->accessSVGExtensions();
-
- // Remove old id, that is guaranteed to be present in cache
- extensions->removeResource(m_id);
+enum RenderSVGResourceMode {
+ ApplyToDefaultMode = 1 << 0, // used for all resources except gradient/pattern
+ ApplyToFillMode = 1 << 1,
+ ApplyToStrokeMode = 1 << 2,
+ ApplyToTextMode = 1 << 3 // used in combination with ApplyTo{Fill|Stroke}Mode
+};
- m_id = static_cast<Element*>(node())->getIDAttribute();
+class FloatRect;
+class GraphicsContext;
+class RenderObject;
+class RenderStyle;
+class RenderSVGResourceSolidColor;
- // It's possible that an element is referencing us with the new id, and has to be notified that we're existing now
- if (extensions->isPendingResource(m_id)) {
- OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(m_id));
- if (clients->isEmpty())
- return;
+class RenderSVGResource {
+public:
+ RenderSVGResource() { }
+ virtual ~RenderSVGResource() { }
- HashSet<SVGStyledElement*>::const_iterator it = clients->begin();
- const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+ virtual void invalidateClients() = 0;
+ virtual void invalidateClient(RenderObject*) = 0;
- for (; it != end; ++it) {
- if (RenderObject* renderer = (*it)->renderer())
- renderer->setNeedsLayout(true);
- }
- }
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) = 0;
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short) { }
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const = 0;
- // Recache us with the new id
- extensions->addResource(m_id, this);
- }
+ virtual RenderSVGResourceType resourceType() const = 0;
template<class Renderer>
Renderer* cast()
@@ -90,35 +73,15 @@ public:
return 0;
}
- virtual RenderSVGResource* toRenderSVGResource() { return this; }
- virtual bool isSVGResource() const { return true; }
- virtual bool drawsContents() { return false; }
-
- virtual void invalidateClients() = 0;
- virtual void invalidateClient(RenderObject*) = 0;
-
- virtual bool applyResource(RenderObject*, GraphicsContext*&) = 0;
- virtual void postApplyResource(RenderObject*, GraphicsContext*&) { }
- virtual FloatRect resourceBoundingBox(const FloatRect&) const = 0;
-
- virtual RenderSVGResourceType resourceType() const = 0;
+ // Helper utilities used in the render tree to access resources used for painting shapes/text (gradients & patterns only)
+ static RenderSVGResource* fillPaintingResource(const RenderObject*, const RenderStyle*);
+ static RenderSVGResource* strokePaintingResource(const RenderObject*, const RenderStyle*);
+ static RenderSVGResourceSolidColor* sharedSolidPaintingResource();
-private:
- AtomicString m_id;
+protected:
+ void markForLayoutAndResourceInvalidation(RenderObject*);
};
-template<typename Renderer>
-Renderer* getRenderSVGResourceById(Document* document, const AtomicString& id)
-{
- if (id.isEmpty())
- return 0;
-
- if (RenderSVGResource* renderResource = document->accessSVGExtensions()->resourceById(id))
- return renderResource->cast<Renderer>();
-
- return 0;
-}
-
}
#endif
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
index ccb7397..2759976 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.cpp
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -38,13 +38,14 @@
#include "SVGStyledTransformableElement.h"
#include "SVGUnitTypes.h"
#include "SVGUseElement.h"
+#include <wtf/UnusedParam.h>
namespace WebCore {
RenderSVGResourceType RenderSVGResourceClipper::s_resourceType = ClipperResourceType;
-RenderSVGResourceClipper::RenderSVGResourceClipper(SVGStyledElement* node)
- : RenderSVGResource(node)
+RenderSVGResourceClipper::RenderSVGResourceClipper(SVGClipPathElement* node)
+ : RenderSVGResourceContainer(node)
{
}
@@ -78,10 +79,18 @@ void RenderSVGResourceClipper::invalidateClient(RenderObject* object)
return;
delete m_clipper.take(object);
+ markForLayoutAndResourceInvalidation(object);
}
-bool RenderSVGResourceClipper::applyResource(RenderObject* object, GraphicsContext*& context)
+bool RenderSVGResourceClipper::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
{
+ ASSERT(object);
+ ASSERT(context);
+#ifndef NDEBUG
+ ASSERT(resourceMode == ApplyToDefaultMode);
+#else
+ UNUSED_PARAM(resourceMode);
+#endif
applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
return true;
}
@@ -142,9 +151,6 @@ bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const
bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* object, const FloatRect& objectBoundingBox,
const FloatRect& repaintRect, GraphicsContext* context)
{
- ASSERT(object);
- ASSERT(context);
-
if (!m_clipper.contains(object))
m_clipper.set(object, new ClipperData);
diff --git a/WebCore/rendering/RenderSVGResourceClipper.h b/WebCore/rendering/RenderSVGResourceClipper.h
index 8de17d4..0b6f2b3 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.h
+++ b/WebCore/rendering/RenderSVGResourceClipper.h
@@ -27,7 +27,7 @@
#include "ImageBuffer.h"
#include "IntSize.h"
#include "Path.h"
-#include "RenderSVGResource.h"
+#include "RenderSVGResourceContainer.h"
#include "SVGClipPathElement.h"
#include "SVGUnitTypes.h"
@@ -40,10 +40,9 @@ struct ClipperData {
OwnPtr<ImageBuffer> clipMaskImage;
};
-class RenderSVGResourceClipper : public RenderSVGResource {
-
+class RenderSVGResourceClipper : public RenderSVGResourceContainer {
public:
- RenderSVGResourceClipper(SVGStyledElement*);
+ RenderSVGResourceClipper(SVGClipPathElement*);
virtual ~RenderSVGResourceClipper();
virtual const char* renderName() const { return "RenderSVGResourceClipper"; }
@@ -51,7 +50,7 @@ public:
virtual void invalidateClients();
virtual void invalidateClient(RenderObject*);
- virtual bool applyResource(RenderObject*, GraphicsContext*&);
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual FloatRect resourceBoundingBox(const FloatRect&) const;
virtual RenderSVGResourceType resourceType() const { return ClipperResourceType; }
diff --git a/WebCore/rendering/RenderSVGResourceContainer.h b/WebCore/rendering/RenderSVGResourceContainer.h
new file mode 100644
index 0000000..b63575d
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceContainer.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderSVGResourceContainer_h
+#define RenderSVGResourceContainer_h
+
+#if ENABLE(SVG)
+#include "RenderSVGHiddenContainer.h"
+#include "RenderSVGResource.h"
+
+namespace WebCore {
+
+class RenderSVGResourceContainer : public RenderSVGHiddenContainer,
+ public RenderSVGResource {
+public:
+ RenderSVGResourceContainer(SVGStyledElement* node)
+ : RenderSVGHiddenContainer(node)
+ , RenderSVGResource()
+ , m_id(node->getIDAttribute())
+ {
+ ASSERT(node->document());
+ node->document()->accessSVGExtensions()->addResource(m_id, this);
+ }
+
+ virtual ~RenderSVGResourceContainer()
+ {
+ ASSERT(node());
+ ASSERT(node()->document());
+ node()->document()->accessSVGExtensions()->removeResource(m_id);
+ }
+
+ void idChanged()
+ {
+ ASSERT(node());
+ ASSERT(node()->document());
+ SVGDocumentExtensions* extensions = node()->document()->accessSVGExtensions();
+
+ // Remove old id, that is guaranteed to be present in cache
+ extensions->removeResource(m_id);
+
+ m_id = static_cast<Element*>(node())->getIDAttribute();
+
+ // It's possible that an element is referencing us with the new id, and has to be notified that we're existing now
+ if (extensions->isPendingResource(m_id)) {
+ OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(m_id));
+ if (clients->isEmpty())
+ return;
+
+ HashSet<SVGStyledElement*>::const_iterator it = clients->begin();
+ const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+
+ for (; it != end; ++it) {
+ if (RenderObject* renderer = (*it)->renderer())
+ renderer->setNeedsLayout(true);
+ }
+ }
+
+ // Recache us with the new id
+ extensions->addResource(m_id, this);
+ }
+
+ virtual bool isSVGResourceContainer() const { return true; }
+ virtual bool drawsContents() { return false; }
+
+ virtual RenderSVGResourceContainer* toRenderSVGResourceContainer() { return this; }
+
+private:
+ AtomicString m_id;
+};
+
+inline RenderSVGResourceContainer* getRenderSVGResourceContainerById(Document* document, const AtomicString& id)
+{
+ if (id.isEmpty())
+ return 0;
+
+ if (RenderSVGResourceContainer* renderResource = document->accessSVGExtensions()->resourceById(id))
+ return renderResource;
+
+ return 0;
+}
+
+template<typename Renderer>
+Renderer* getRenderSVGResourceById(Document* document, const AtomicString& id)
+{
+ if (RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(document, id))
+ return container->cast<Renderer>();
+
+ return 0;
+}
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp
index cbedfe3..ac3ea49 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.cpp
+++ b/WebCore/rendering/RenderSVGResourceFilter.cpp
@@ -43,6 +43,7 @@
#include "SVGStyledElement.h"
#include "SVGUnitTypes.h"
#include <wtf/Vector.h>
+#include <wtf/UnusedParam.h>
static const float kMaxFilterSize = 5000.0f;
@@ -52,8 +53,8 @@ namespace WebCore {
RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceType;
-RenderSVGResourceFilter::RenderSVGResourceFilter(SVGStyledElement* node)
- : RenderSVGResource(node)
+RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node)
+ : RenderSVGResourceContainer(node)
, m_savedContext(0)
, m_sourceGraphicBuffer(0)
{
@@ -88,7 +89,8 @@ void RenderSVGResourceFilter::invalidateClient(RenderObject* object)
if (!m_filter.contains(object))
return;
- delete m_filter.take(object);
+ delete m_filter.take(object);
+ markForLayoutAndResourceInvalidation(object);
}
PassOwnPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives()
@@ -134,10 +136,15 @@ bool RenderSVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size, Floa
return matchesFilterSize;
}
-bool RenderSVGResourceFilter::applyResource(RenderObject* object, GraphicsContext*& context)
+bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
ASSERT(context);
+#ifndef NDEBUG
+ ASSERT(resourceMode == ApplyToDefaultMode);
+#else
+ UNUSED_PARAM(resourceMode);
+#endif
// Returning false here, to avoid drawings onto the context. We just want to
// draw the stored filter output, not the unfiltered object as well.
@@ -154,12 +161,7 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, GraphicsContex
if (!filterData->builder)
return false;
- const SVGRenderBase* renderer = object->toSVGRenderBase();
- if (!renderer)
- return false;
-
- FloatRect paintRect = renderer->strokeBoundingBox();
- paintRect.unite(renderer->markerBoundingBox());
+ FloatRect paintRect = object->strokeBoundingBox();
// Calculate the scale factor for the use of filterRes.
// Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
@@ -228,10 +230,15 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, GraphicsContex
return true;
}
-void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context)
+void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
ASSERT(context);
+#ifndef NDEBUG
+ ASSERT(resourceMode == ApplyToDefaultMode);
+#else
+ UNUSED_PARAM(resourceMode);
+#endif
if (!m_filter.contains(object))
return;
diff --git a/WebCore/rendering/RenderSVGResourceFilter.h b/WebCore/rendering/RenderSVGResourceFilter.h
index 2cd4b6c..ce4a7e1 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.h
+++ b/WebCore/rendering/RenderSVGResourceFilter.h
@@ -28,7 +28,7 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "FloatRect.h"
#include "ImageBuffer.h"
-#include "RenderSVGResource.h"
+#include "RenderSVGResourceContainer.h"
#include "SVGFilter.h"
#include "SVGFilterBuilder.h"
#include "SVGFilterElement.h"
@@ -55,9 +55,9 @@ struct FilterData {
class GraphicsContext;
-class RenderSVGResourceFilter : public RenderSVGResource {
+class RenderSVGResourceFilter : public RenderSVGResourceContainer {
public:
- RenderSVGResourceFilter(SVGStyledElement*);
+ RenderSVGResourceFilter(SVGFilterElement*);
virtual ~RenderSVGResourceFilter();
virtual const char* renderName() const { return "RenderSVGResourceFilter"; }
@@ -65,8 +65,8 @@ public:
virtual void invalidateClients();
virtual void invalidateClient(RenderObject*);
- virtual bool applyResource(RenderObject*, GraphicsContext*&);
- virtual void postApplyResource(RenderObject*, GraphicsContext*&);
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
virtual FloatRect resourceBoundingBox(const FloatRect&) const;
diff --git a/WebCore/rendering/RenderSVGResourceGradient.cpp b/WebCore/rendering/RenderSVGResourceGradient.cpp
new file mode 100644
index 0000000..6c9d784
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceGradient.cpp
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * 2008 Eric Seidel <eric@webkit.org>
+ * 2008 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGResourceGradient.h"
+
+#include "GradientAttributes.h"
+#include "GraphicsContext.h"
+#include "SVGRenderSupport.h"
+#include <wtf/UnusedParam.h>
+
+namespace WebCore {
+
+RenderSVGResourceGradient::RenderSVGResourceGradient(SVGGradientElement* node)
+ : RenderSVGResourceContainer(node)
+#if PLATFORM(CG)
+ , m_savedContext(0)
+#endif
+{
+}
+
+RenderSVGResourceGradient::~RenderSVGResourceGradient()
+{
+ deleteAllValues(m_gradient);
+ m_gradient.clear();
+}
+
+void RenderSVGResourceGradient::invalidateClients()
+{
+ const HashMap<RenderObject*, GradientData*>::const_iterator end = m_gradient.end();
+ for (HashMap<RenderObject*, GradientData*>::const_iterator it = m_gradient.begin(); it != end; ++it)
+ markForLayoutAndResourceInvalidation(it->first);
+
+ deleteAllValues(m_gradient);
+ m_gradient.clear();
+}
+
+void RenderSVGResourceGradient::invalidateClient(RenderObject* object)
+{
+ ASSERT(object);
+
+ // FIXME: The HashMap should always contain the object on calling invalidateClient. A race condition
+ // during the parsing can causes a call of invalidateClient right before the call of applyResource.
+ // We return earlier for the moment. This bug should be fixed in:
+ // https://bugs.webkit.org/show_bug.cgi?id=35181
+ if (!m_gradient.contains(object))
+ return;
+
+ delete m_gradient.take(object);
+ markForLayoutAndResourceInvalidation(object);
+}
+
+#if PLATFORM(CG)
+static inline AffineTransform absoluteTransformForRenderer(const RenderObject* object)
+{
+ AffineTransform absoluteTransform;
+
+ const RenderObject* currentObject = object;
+ while (currentObject) {
+ absoluteTransform = currentObject->localToParentTransform() * absoluteTransform;
+ currentObject = currentObject->parent();
+ }
+
+ return absoluteTransform;
+}
+
+static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& context,
+ GraphicsContext*& savedContext,
+ OwnPtr<ImageBuffer>& imageBuffer,
+ const RenderObject* object)
+{
+ const RenderObject* textRootBlock = findTextRootObject(object);
+
+ AffineTransform transform = absoluteTransformForRenderer(textRootBlock);
+ FloatRect maskAbsoluteBoundingBox = transform.mapRect(textRootBlock->repaintRectInLocalCoordinates());
+
+ IntRect maskImageRect = enclosingIntRect(maskAbsoluteBoundingBox);
+ if (maskImageRect.isEmpty())
+ return false;
+
+ // Allocate an image buffer as big as the absolute unclipped size of the object
+ OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskImageRect.size());
+ if (!maskImage)
+ return false;
+
+ GraphicsContext* maskImageContext = maskImage->context();
+
+ // Transform the mask image coordinate system to absolute screen coordinates
+ maskImageContext->translate(-maskAbsoluteBoundingBox.x(), -maskAbsoluteBoundingBox.y());
+ maskImageContext->concatCTM(transform);
+
+ imageBuffer.set(maskImage.release());
+ savedContext = context;
+ context = maskImageContext;
+
+ return true;
+}
+
+static inline AffineTransform clipToTextMask(GraphicsContext* context,
+ OwnPtr<ImageBuffer>& imageBuffer,
+ const RenderObject* object,
+ GradientData* gradientData)
+{
+ const RenderObject* textRootBlock = findTextRootObject(object);
+ context->clipToImageBuffer(textRootBlock->repaintRectInLocalCoordinates(), imageBuffer.get());
+
+ AffineTransform matrix;
+ if (gradientData->boundingBoxMode) {
+ FloatRect maskBoundingBox = textRootBlock->objectBoundingBox();
+ matrix.translate(maskBoundingBox.x(), maskBoundingBox.y());
+ matrix.scaleNonUniform(maskBoundingBox.width(), maskBoundingBox.height());
+ }
+ matrix.multiply(gradientData->transform);
+ return matrix;
+}
+#endif
+
+bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
+{
+ ASSERT(object);
+ ASSERT(style);
+ ASSERT(context);
+ ASSERT(resourceMode != ApplyToDefaultMode);
+
+ // Be sure to synchronize all SVG properties on the gradientElement _before_ processing any further.
+ // Otherwhise the call to collectGradientAttributes() in createTileImage(), may cause the SVG DOM property
+ // synchronization to kick in, which causes invalidateClients() to be called, which in turn deletes our
+ // GradientData object! Leaving out the line below will cause svg/dynamic-updates/SVG*GradientElement-svgdom* to crash.
+ SVGGradientElement* gradientElement = static_cast<SVGGradientElement*>(node());
+ if (!gradientElement)
+ return false;
+
+ gradientElement->updateAnimatedSVGAttribute(anyQName());
+
+ if (!m_gradient.contains(object))
+ m_gradient.set(object, new GradientData);
+
+ GradientData* gradientData = m_gradient.get(object);
+
+ // Create gradient object
+ if (!gradientData->gradient)
+ buildGradient(gradientData, gradientElement);
+
+ if (!gradientData->gradient)
+ return false;
+
+ // Draw gradient
+ context->save();
+
+ bool isPaintingText = resourceMode & ApplyToTextMode;
+ if (isPaintingText) {
+#if PLATFORM(CG)
+ if (!createMaskAndSwapContextForTextGradient(context, m_savedContext, m_imageBuffer, object)) {
+ context->restore();
+ return false;
+ }
+#endif
+
+ context->setTextDrawingMode(resourceMode & ApplyToFillMode ? cTextFill : cTextStroke);
+ }
+
+ AffineTransform transform;
+
+ // CG platforms will handle the gradient space transform for text after applying the
+ // resource, so don't apply it here. For non-CG platforms, we want the text bounding
+ // box applied to the gradient space transform now, so the gradient shader can use it.
+#if PLATFORM(CG)
+ if (gradientData->boundingBoxMode && !isPaintingText) {
+#else
+ if (gradientData->boundingBoxMode) {
+#endif
+ FloatRect objectBoundingBox = object->objectBoundingBox();
+ transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ }
+
+ transform.multiply(gradientData->transform);
+ gradientData->gradient->setGradientSpaceTransform(transform);
+
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+ ASSERT(svgStyle);
+
+ if (resourceMode & ApplyToFillMode) {
+ context->setAlpha(svgStyle->fillOpacity());
+ context->setFillGradient(gradientData->gradient);
+ context->setFillRule(svgStyle->fillRule());
+ } else if (resourceMode & ApplyToStrokeMode) {
+ context->setAlpha(svgStyle->strokeOpacity());
+ context->setStrokeGradient(gradientData->gradient);
+ applyStrokeStyleToContext(context, style, object);
+ }
+
+ return true;
+}
+
+void RenderSVGResourceGradient::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode)
+{
+ ASSERT(context);
+ ASSERT(resourceMode != ApplyToDefaultMode);
+
+ if (resourceMode & ApplyToTextMode) {
+#if PLATFORM(CG)
+ // CG requires special handling for gradient on text
+ if (m_savedContext && m_gradient.contains(object)) {
+ GradientData* gradientData = m_gradient.get(object);
+
+ // Restore on-screen drawing context
+ context = m_savedContext;
+ m_savedContext = 0;
+
+ gradientData->gradient->setGradientSpaceTransform(clipToTextMask(context, m_imageBuffer, object, gradientData));
+ context->setFillGradient(gradientData->gradient);
+
+ const RenderObject* textRootBlock = findTextRootObject(object);
+ context->fillRect(textRootBlock->repaintRectInLocalCoordinates());
+
+ m_imageBuffer.clear();
+ }
+#else
+ UNUSED_PARAM(object);
+#endif
+ } else {
+ if (resourceMode & ApplyToFillMode)
+ context->fillPath();
+ else if (resourceMode & ApplyToStrokeMode)
+ context->strokePath();
+ }
+
+ context->restore();
+}
+
+void RenderSVGResourceGradient::addStops(GradientData* gradientData, const Vector<Gradient::ColorStop>& stops) const
+{
+ ASSERT(gradientData->gradient);
+
+ const Vector<Gradient::ColorStop>::const_iterator end = stops.end();
+ for (Vector<Gradient::ColorStop>::const_iterator it = stops.begin(); it != end; ++it)
+ gradientData->gradient->addColorStop(*it);
+}
+
+}
+
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceGradient.h b/WebCore/rendering/RenderSVGResourceGradient.h
new file mode 100644
index 0000000..2fd9cf4
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceGradient.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 RenderSVGResourceGradient_h
+#define RenderSVGResourceGradient_h
+
+#if ENABLE(SVG)
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "Gradient.h"
+#include "ImageBuffer.h"
+#include "RenderSVGResourceContainer.h"
+#include "SVGGradientElement.h"
+
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+struct GradientData {
+ RefPtr<Gradient> gradient;
+
+ bool boundingBoxMode;
+ AffineTransform transform;
+};
+
+class GraphicsContext;
+
+class RenderSVGResourceGradient : public RenderSVGResourceContainer {
+public:
+ RenderSVGResourceGradient(SVGGradientElement*);
+ virtual ~RenderSVGResourceGradient();
+
+ virtual void invalidateClients();
+ virtual void invalidateClient(RenderObject*);
+
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const { return FloatRect(); }
+
+protected:
+ void addStops(GradientData*, const Vector<Gradient::ColorStop>&) const;
+ virtual void buildGradient(GradientData*, SVGGradientElement*) const = 0;
+
+private:
+ HashMap<RenderObject*, GradientData*> m_gradient;
+
+#if PLATFORM(CG)
+ GraphicsContext* m_savedContext;
+ OwnPtr<ImageBuffer> m_imageBuffer;
+#endif
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceLinearGradient.cpp b/WebCore/rendering/RenderSVGResourceLinearGradient.cpp
new file mode 100644
index 0000000..e34e524
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceLinearGradient.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGResourceLinearGradient.h"
+
+#include "LinearGradientAttributes.h"
+#include "SVGLinearGradientElement.h"
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourceLinearGradient::s_resourceType = LinearGradientResourceType;
+
+RenderSVGResourceLinearGradient::RenderSVGResourceLinearGradient(SVGLinearGradientElement* node)
+ : RenderSVGResourceGradient(node)
+{
+}
+
+RenderSVGResourceLinearGradient::~RenderSVGResourceLinearGradient()
+{
+}
+
+void RenderSVGResourceLinearGradient::buildGradient(GradientData* gradientData, SVGGradientElement* gradientElement) const
+{
+ SVGLinearGradientElement* linearGradientElement = static_cast<SVGLinearGradientElement*>(gradientElement);
+ LinearGradientAttributes attributes = linearGradientElement->collectGradientProperties();
+
+ // Determine gradient start/end points
+ FloatPoint startPoint;
+ FloatPoint endPoint;
+ linearGradientElement->calculateStartEndPoints(attributes, startPoint, endPoint);
+
+ gradientData->gradient = Gradient::create(startPoint, endPoint);
+ gradientData->gradient->setSpreadMethod(attributes.spreadMethod());
+
+ // Record current gradient transform
+ gradientData->transform = attributes.gradientTransform();
+ gradientData->boundingBoxMode = attributes.boundingBoxMode();
+
+ // Add stops
+ addStops(gradientData, attributes.stops());
+}
+
+}
+
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceLinearGradient.h b/WebCore/rendering/RenderSVGResourceLinearGradient.h
new file mode 100644
index 0000000..c1f84c2
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceLinearGradient.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 RenderSVGResourceLinearGradient_h
+#define RenderSVGResourceLinearGradient_h
+
+#if ENABLE(SVG)
+#include "RenderSVGResourceGradient.h"
+
+namespace WebCore {
+
+class SVGLinearGradientElement;
+
+class RenderSVGResourceLinearGradient : public RenderSVGResourceGradient {
+public:
+ RenderSVGResourceLinearGradient(SVGLinearGradientElement*);
+ virtual ~RenderSVGResourceLinearGradient();
+
+ virtual const char* renderName() const { return "RenderSVGResourceLinearGradient"; }
+
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
+
+ virtual void buildGradient(GradientData*, SVGGradientElement*) const;
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceMarker.cpp b/WebCore/rendering/RenderSVGResourceMarker.cpp
index c526962..460239b 100644
--- a/WebCore/rendering/RenderSVGResourceMarker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMarker.cpp
@@ -35,8 +35,8 @@ namespace WebCore {
RenderSVGResourceType RenderSVGResourceMarker::s_resourceType = MarkerResourceType;
-RenderSVGResourceMarker::RenderSVGResourceMarker(SVGStyledElement* node)
- : RenderSVGResource(node)
+RenderSVGResourceMarker::RenderSVGResourceMarker(SVGMarkerElement* node)
+ : RenderSVGResourceContainer(node)
{
}
@@ -82,6 +82,7 @@ void RenderSVGResourceMarker::invalidateClient(RenderObject* object)
return;
m_marker.remove(object);
+ markForLayoutAndResourceInvalidation(object);
}
void RenderSVGResourceMarker::applyViewportClip(PaintInfo& paintInfo)
diff --git a/WebCore/rendering/RenderSVGResourceMarker.h b/WebCore/rendering/RenderSVGResourceMarker.h
index 9e39b99..efbbdfa 100644
--- a/WebCore/rendering/RenderSVGResourceMarker.h
+++ b/WebCore/rendering/RenderSVGResourceMarker.h
@@ -24,7 +24,7 @@
#if ENABLE(SVG)
#include "FloatRect.h"
#include "RenderObject.h"
-#include "RenderSVGResource.h"
+#include "RenderSVGResourceContainer.h"
#include "SVGMarkerElement.h"
#include "SVGStyledElement.h"
@@ -34,10 +34,9 @@ namespace WebCore {
class AffineTransform;
-class RenderSVGResourceMarker : public RenderSVGResource {
-
+class RenderSVGResourceMarker : public RenderSVGResourceContainer {
public:
- RenderSVGResourceMarker(SVGStyledElement*);
+ RenderSVGResourceMarker(SVGMarkerElement*);
virtual ~RenderSVGResourceMarker();
virtual const char* renderName() const { return "RenderSVGResourceMarker"; }
@@ -58,7 +57,7 @@ public:
virtual const AffineTransform& localToParentTransform() const;
AffineTransform markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const;
- virtual bool applyResource(RenderObject*, GraphicsContext*&) { return false; }
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short) { return false; }
virtual FloatRect resourceBoundingBox(const FloatRect&) const { return FloatRect(); }
FloatPoint referencePoint() const;
diff --git a/WebCore/rendering/RenderSVGResourceMasker.cpp b/WebCore/rendering/RenderSVGResourceMasker.cpp
index 8bb16de..abf8e48 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -37,13 +37,14 @@
#include "SVGStyledElement.h"
#include "SVGUnitTypes.h"
#include <wtf/Vector.h>
+#include <wtf/UnusedParam.h>
namespace WebCore {
RenderSVGResourceType RenderSVGResourceMasker::s_resourceType = MaskerResourceType;
-RenderSVGResourceMasker::RenderSVGResourceMasker(SVGStyledElement* node)
- : RenderSVGResource(node)
+RenderSVGResourceMasker::RenderSVGResourceMasker(SVGMaskElement* node)
+ : RenderSVGResourceContainer(node)
{
}
@@ -77,13 +78,19 @@ void RenderSVGResourceMasker::invalidateClient(RenderObject* object)
if (!m_masker.contains(object))
return;
- delete m_masker.take(object);
+ delete m_masker.take(object);
+ markForLayoutAndResourceInvalidation(object);
}
-bool RenderSVGResourceMasker::applyResource(RenderObject* object, GraphicsContext*& context)
+bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
ASSERT(context);
+#ifndef NDEBUG
+ ASSERT(resourceMode == ApplyToDefaultMode);
+#else
+ UNUSED_PARAM(resourceMode);
+#endif
if (!m_masker.contains(object))
m_masker.set(object, new MaskerData);
@@ -151,7 +158,7 @@ void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGM
maskImageRect.setLocation(IntPoint());
// Don't create ImageBuffers with image size of 0
- if (!maskImageRect.width() || !maskImageRect.height()) {
+ if (maskImageRect.isEmpty()) {
maskerData->emptyMask = true;
return;
}
diff --git a/WebCore/rendering/RenderSVGResourceMasker.h b/WebCore/rendering/RenderSVGResourceMasker.h
index 3127e3c..b022f7b 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.h
+++ b/WebCore/rendering/RenderSVGResourceMasker.h
@@ -26,7 +26,7 @@
#include "GraphicsContext.h"
#include "ImageBuffer.h"
#include "IntSize.h"
-#include "RenderSVGResource.h"
+#include "RenderSVGResourceContainer.h"
#include "SVGMaskElement.h"
#include "SVGUnitTypes.h"
@@ -36,9 +36,8 @@
namespace WebCore {
struct MaskerData {
- MaskerData(FloatRect rect = FloatRect(), bool emptyObject = false)
- : maskRect(rect)
- , emptyMask(emptyObject)
+ MaskerData()
+ : emptyMask(false)
{
}
@@ -47,10 +46,9 @@ struct MaskerData {
bool emptyMask;
};
-class RenderSVGResourceMasker : public RenderSVGResource {
-
+class RenderSVGResourceMasker : public RenderSVGResourceContainer {
public:
- RenderSVGResourceMasker(SVGStyledElement*);
+ RenderSVGResourceMasker(SVGMaskElement*);
virtual ~RenderSVGResourceMasker();
virtual const char* renderName() const { return "RenderSVGResourceMasker"; }
@@ -58,7 +56,7 @@ public:
virtual void invalidateClients();
virtual void invalidateClient(RenderObject*);
- virtual bool applyResource(RenderObject*, GraphicsContext*&);
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual FloatRect resourceBoundingBox(const FloatRect&) const;
SVGUnitTypes::SVGUnitType maskUnits() const { return toUnitType(static_cast<SVGMaskElement*>(node())->maskUnits()); }
diff --git a/WebCore/rendering/RenderSVGResourcePattern.cpp b/WebCore/rendering/RenderSVGResourcePattern.cpp
new file mode 100644
index 0000000..8302030
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourcePattern.cpp
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGResourcePattern.h"
+
+#include "GraphicsContext.h"
+#include "PatternAttributes.h"
+#include "SVGRenderSupport.h"
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourcePattern::s_resourceType = PatternResourceType;
+
+RenderSVGResourcePattern::RenderSVGResourcePattern(SVGPatternElement* node)
+ : RenderSVGResourceContainer(node)
+{
+}
+
+RenderSVGResourcePattern::~RenderSVGResourcePattern()
+{
+ deleteAllValues(m_pattern);
+ m_pattern.clear();
+}
+
+void RenderSVGResourcePattern::invalidateClients()
+{
+ const HashMap<RenderObject*, PatternData*>::const_iterator end = m_pattern.end();
+ for (HashMap<RenderObject*, PatternData*>::const_iterator it = m_pattern.begin(); it != end; ++it)
+ markForLayoutAndResourceInvalidation(it->first);
+
+ deleteAllValues(m_pattern);
+ m_pattern.clear();
+}
+
+void RenderSVGResourcePattern::invalidateClient(RenderObject* object)
+{
+ ASSERT(object);
+
+ // FIXME: The HashMap should always contain the object on calling invalidateClient. A race condition
+ // during the parsing can causes a call of invalidateClient right before the call of applyResource.
+ // We return earlier for the moment. This bug should be fixed in:
+ // https://bugs.webkit.org/show_bug.cgi?id=35181
+ if (!m_pattern.contains(object))
+ return;
+
+ delete m_pattern.take(object);
+ markForLayoutAndResourceInvalidation(object);
+}
+
+bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
+{
+ ASSERT(object);
+ ASSERT(style);
+ ASSERT(context);
+ ASSERT(resourceMode != ApplyToDefaultMode);
+
+ // Be sure to synchronize all SVG properties on the patternElement _before_ processing any further.
+ // Otherwhise the call to collectPatternAttributes() in createTileImage(), may cause the SVG DOM property
+ // synchronization to kick in, which causes invalidateClients() to be called, which in turn deletes our
+ // PatternData object! Leaving out the line below will cause svg/dynamic-updates/SVGPatternElement-svgdom* to crash.
+ SVGPatternElement* patternElement = static_cast<SVGPatternElement*>(node());
+ if (!patternElement)
+ return false;
+
+ patternElement->updateAnimatedSVGAttribute(anyQName());
+
+ if (!m_pattern.contains(object))
+ m_pattern.set(object, new PatternData);
+
+ PatternData* patternData = m_pattern.get(object);
+ if (!patternData->pattern) {
+ FloatRect patternBoundaries;
+ AffineTransform patternTransform;
+
+ // Create tile image
+ OwnPtr<ImageBuffer> tileImage = createTileImage(patternBoundaries, patternTransform, patternElement, object);
+ if (!tileImage)
+ return false;
+
+ // Create pattern object
+ buildPattern(patternData, patternBoundaries, tileImage.release());
+
+ if (!patternData->pattern)
+ return false;
+
+ // Compute pattern transformation
+ AffineTransform transform;
+ transform.translate(patternBoundaries.x(), patternBoundaries.y());
+ transform.multiply(patternTransform);
+ patternData->pattern->setPatternSpaceTransform(transform);
+ }
+
+ // Draw pattern
+ context->save();
+
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+ ASSERT(svgStyle);
+
+ if (resourceMode & ApplyToFillMode) {
+ context->setAlpha(svgStyle->fillOpacity());
+ context->setFillPattern(patternData->pattern);
+ context->setFillRule(svgStyle->fillRule());
+ } else if (resourceMode & ApplyToStrokeMode) {
+ context->setAlpha(svgStyle->strokeOpacity());
+ context->setStrokePattern(patternData->pattern);
+ applyStrokeStyleToContext(context, style, object);
+ }
+
+ if (resourceMode & ApplyToTextMode) {
+ if (resourceMode & ApplyToFillMode) {
+ context->setTextDrawingMode(cTextFill);
+
+#if PLATFORM(CG)
+ context->applyFillPattern();
+#endif
+ } else if (resourceMode & ApplyToStrokeMode) {
+ context->setTextDrawingMode(cTextStroke);
+
+#if PLATFORM(CG)
+ context->applyStrokePattern();
+#endif
+ }
+ }
+
+ return true;
+}
+
+void RenderSVGResourcePattern::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode)
+{
+ ASSERT(context);
+ ASSERT(resourceMode != ApplyToDefaultMode);
+
+ if (!(resourceMode & ApplyToTextMode)) {
+ if (resourceMode & ApplyToFillMode)
+ context->fillPath();
+ else if (resourceMode & ApplyToStrokeMode)
+ context->strokePath();
+ }
+
+ context->restore();
+}
+
+static inline FloatRect calculatePatternBoundaries(PatternAttributes& attributes,
+ const FloatRect& objectBoundingBox,
+ const SVGPatternElement* patternElement)
+{
+ if (attributes.boundingBoxMode())
+ return FloatRect(attributes.x().valueAsPercentage() * objectBoundingBox.width(),
+ attributes.y().valueAsPercentage() * objectBoundingBox.height(),
+ attributes.width().valueAsPercentage() * objectBoundingBox.width(),
+ attributes.height().valueAsPercentage() * objectBoundingBox.height());
+
+ return FloatRect(attributes.x().value(patternElement),
+ attributes.y().value(patternElement),
+ attributes.width().value(patternElement),
+ attributes.height().value(patternElement));
+}
+
+FloatRect RenderSVGResourcePattern::calculatePatternBoundariesIncludingOverflow(PatternAttributes& attributes,
+ const FloatRect& objectBoundingBox,
+ const AffineTransform& viewBoxCTM,
+ const FloatRect& patternBoundaries) const
+{
+ // Eventually calculate the pattern content boundaries (only needed with overflow="visible").
+ FloatRect patternContentBoundaries;
+
+ const RenderStyle* style = this->style();
+ if (style->overflowX() == OVISIBLE && style->overflowY() == OVISIBLE) {
+ for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
+ if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyledTransformable() || !node->renderer())
+ continue;
+ patternContentBoundaries.unite(node->renderer()->repaintRectInLocalCoordinates());
+ }
+ }
+
+ if (patternContentBoundaries.isEmpty())
+ return patternBoundaries;
+
+ FloatRect patternBoundariesIncludingOverflow = patternBoundaries;
+
+ // Respect objectBoundingBoxMode for patternContentUnits, if viewBox is not set.
+ if (!viewBoxCTM.isIdentity())
+ patternContentBoundaries = viewBoxCTM.mapRect(patternContentBoundaries);
+ else if (attributes.boundingBoxModeContent())
+ patternContentBoundaries = FloatRect(patternContentBoundaries.x() * objectBoundingBox.width(),
+ patternContentBoundaries.y() * objectBoundingBox.height(),
+ patternContentBoundaries.width() * objectBoundingBox.width(),
+ patternContentBoundaries.height() * objectBoundingBox.height());
+
+ patternBoundariesIncludingOverflow.unite(patternContentBoundaries);
+ return patternBoundariesIncludingOverflow;
+}
+
+PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(FloatRect& patternBoundaries,
+ AffineTransform& patternTransform,
+ const SVGPatternElement* patternElement,
+ RenderObject* object) const
+{
+ PatternAttributes attributes = patternElement->collectPatternProperties();
+
+ // If we couldn't determine the pattern content element root, stop here.
+ if (!attributes.patternContentElement())
+ return 0;
+
+ FloatRect objectBoundingBox = object->objectBoundingBox();
+ patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement);
+ patternTransform = attributes.patternTransform();
+
+ AffineTransform viewBoxCTM = patternElement->viewBoxToViewTransform(patternElement->viewBox(),
+ patternElement->preserveAspectRatio(),
+ patternBoundaries.width(),
+ patternBoundaries.height());
+
+ FloatRect patternBoundariesIncludingOverflow = calculatePatternBoundariesIncludingOverflow(attributes,
+ objectBoundingBox,
+ viewBoxCTM,
+ patternBoundaries);
+
+ IntSize imageSize(lroundf(patternBoundariesIncludingOverflow.width()), lroundf(patternBoundariesIncludingOverflow.height()));
+
+ // FIXME: We should be able to clip this more, needs investigation
+ clampImageBufferSizeToViewport(object->document()->view(), imageSize);
+
+ // Don't create ImageBuffers with image size of 0
+ if (imageSize.isEmpty())
+ return 0;
+
+ OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(imageSize);
+
+ GraphicsContext* context = tileImage->context();
+ ASSERT(context);
+
+ context->save();
+
+ // Translate to pattern start origin
+ if (patternBoundariesIncludingOverflow.location() != patternBoundaries.location()) {
+ context->translate(patternBoundaries.x() - patternBoundariesIncludingOverflow.x(),
+ patternBoundaries.y() - patternBoundariesIncludingOverflow.y());
+
+ patternBoundaries.setLocation(patternBoundariesIncludingOverflow.location());
+ }
+
+ // Process viewBox or boundingBoxModeContent correction
+ if (!viewBoxCTM.isIdentity())
+ context->concatCTM(viewBoxCTM);
+ else if (attributes.boundingBoxModeContent()) {
+ context->translate(objectBoundingBox.x(), objectBoundingBox.y());
+ context->scale(FloatSize(objectBoundingBox.width(), objectBoundingBox.height()));
+ }
+
+ // Render subtree into ImageBuffer
+ for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
+ if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer())
+ continue;
+ renderSubtreeToImage(tileImage.get(), node->renderer());
+ }
+
+ context->restore();
+ return tileImage.release();
+}
+
+void RenderSVGResourcePattern::buildPattern(PatternData* patternData, const FloatRect& patternBoundaries, PassOwnPtr<ImageBuffer> tileImage) const
+{
+ if (!tileImage->image()) {
+ patternData->pattern = 0;
+ return;
+ }
+
+ IntRect tileRect = tileImage->image()->rect();
+ if (tileRect.width() <= patternBoundaries.width() && tileRect.height() <= patternBoundaries.height()) {
+ patternData->pattern = Pattern::create(tileImage->image(), true, true);
+ return;
+ }
+
+ // Draw the first cell of the pattern manually to support overflow="visible" on all platforms.
+ int tileWidth = static_cast<int>(patternBoundaries.width() + 0.5f);
+ int tileHeight = static_cast<int>(patternBoundaries.height() + 0.5f);
+
+ // Don't create ImageBuffers with image size of 0
+ if (!tileWidth || !tileHeight) {
+ patternData->pattern = 0;
+ return;
+ }
+
+ OwnPtr<ImageBuffer> newTileImage = ImageBuffer::create(IntSize(tileWidth, tileHeight));
+ GraphicsContext* newTileImageContext = newTileImage->context();
+
+ int numY = static_cast<int>(ceilf(tileRect.height() / tileHeight)) + 1;
+ int numX = static_cast<int>(ceilf(tileRect.width() / tileWidth)) + 1;
+
+ newTileImageContext->save();
+ newTileImageContext->translate(-patternBoundaries.width() * numX, -patternBoundaries.height() * numY);
+ for (int i = numY; i > 0; --i) {
+ newTileImageContext->translate(0, patternBoundaries.height());
+ for (int j = numX; j > 0; --j) {
+ newTileImageContext->translate(patternBoundaries.width(), 0);
+ newTileImageContext->drawImage(tileImage->image(), style()->colorSpace(), tileRect, tileRect);
+ }
+ newTileImageContext->translate(-patternBoundaries.width() * numX, 0);
+ }
+ newTileImageContext->restore();
+
+ patternData->pattern = Pattern::create(newTileImage->image(), true, true);
+}
+
+}
+
+#endif
diff --git a/WebCore/rendering/RenderSVGResourcePattern.h b/WebCore/rendering/RenderSVGResourcePattern.h
new file mode 100644
index 0000000..2f9d553
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourcePattern.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 RenderSVGResourcePattern_h
+#define RenderSVGResourcePattern_h
+
+#if ENABLE(SVG)
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "ImageBuffer.h"
+#include "Pattern.h"
+#include "RenderSVGResourceContainer.h"
+#include "SVGPatternElement.h"
+#include "SVGUnitTypes.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+struct PatternData {
+ RefPtr<Pattern> pattern;
+};
+
+struct PatternAttributes;
+
+class RenderSVGResourcePattern : public RenderSVGResourceContainer {
+public:
+ RenderSVGResourcePattern(SVGPatternElement*);
+ virtual ~RenderSVGResourcePattern();
+
+ virtual const char* renderName() const { return "RenderSVGResourcePattern"; }
+
+ virtual void invalidateClients();
+ virtual void invalidateClient(RenderObject*);
+
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const { return FloatRect(); }
+
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
+
+private:
+ PassOwnPtr<ImageBuffer> createTileImage(FloatRect& patternBoundaries, AffineTransform& patternTransform, const SVGPatternElement*, RenderObject*) const;
+ void buildPattern(PatternData*, const FloatRect& patternBoundaries, PassOwnPtr<ImageBuffer> tileImage) const;
+ FloatRect calculatePatternBoundariesIncludingOverflow(PatternAttributes&, const FloatRect& objectBoundingBox,
+ const AffineTransform& viewBoxCTM, const FloatRect& patternBoundaries) const;
+
+ HashMap<RenderObject*, PatternData*> m_pattern;
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceRadialGradient.cpp b/WebCore/rendering/RenderSVGResourceRadialGradient.cpp
new file mode 100644
index 0000000..a8904c8
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceRadialGradient.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGResourceRadialGradient.h"
+
+#include "RadialGradientAttributes.h"
+#include "SVGRadialGradientElement.h"
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourceRadialGradient::s_resourceType = RadialGradientResourceType;
+
+RenderSVGResourceRadialGradient::RenderSVGResourceRadialGradient(SVGRadialGradientElement* node)
+ : RenderSVGResourceGradient(node)
+{
+}
+
+RenderSVGResourceRadialGradient::~RenderSVGResourceRadialGradient()
+{
+}
+
+void RenderSVGResourceRadialGradient::buildGradient(GradientData* gradientData, SVGGradientElement* gradientElement) const
+{
+ SVGRadialGradientElement* radialGradientElement = static_cast<SVGRadialGradientElement*>(gradientElement);
+ RadialGradientAttributes attributes = radialGradientElement->collectGradientProperties();
+
+ // Determine gradient focal/center points and radius
+ FloatPoint focalPoint;
+ FloatPoint centerPoint;
+ float radius;
+ radialGradientElement->calculateFocalCenterPointsAndRadius(attributes, focalPoint, centerPoint, radius);
+
+ gradientData->gradient = Gradient::create(focalPoint,
+ 0.0f, // SVG does not support a "focus radius"
+ centerPoint,
+ radius);
+
+ gradientData->gradient->setSpreadMethod(attributes.spreadMethod());
+
+ // Record current gradient transform
+ gradientData->transform = attributes.gradientTransform();
+ gradientData->boundingBoxMode = attributes.boundingBoxMode();
+
+ // Add stops
+ addStops(gradientData, attributes.stops());
+}
+
+}
+
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceRadialGradient.h b/WebCore/rendering/RenderSVGResourceRadialGradient.h
new file mode 100644
index 0000000..0583f99
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceRadialGradient.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 RenderSVGResourceRadialGradient_h
+#define RenderSVGResourceRadialGradient_h
+
+#if ENABLE(SVG)
+#include "RenderSVGResourceGradient.h"
+
+namespace WebCore {
+
+class SVGRadialGradientElement;
+
+class RenderSVGResourceRadialGradient : public RenderSVGResourceGradient {
+public:
+ RenderSVGResourceRadialGradient(SVGRadialGradientElement*);
+ virtual ~RenderSVGResourceRadialGradient();
+
+ virtual const char* renderName() const { return "RenderSVGResourceRadialGradient"; }
+
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
+
+ virtual void buildGradient(GradientData*, SVGGradientElement*) const;
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceSolidColor.cpp b/WebCore/rendering/RenderSVGResourceSolidColor.cpp
new file mode 100644
index 0000000..9d34d79
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceSolidColor.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGResourceSolidColor.h"
+
+#include "GraphicsContext.h"
+#include "SVGRenderSupport.h"
+
+#if PLATFORM(SKIA)
+#include "PlatformContextSkia.h"
+#endif
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourceSolidColor::s_resourceType = SolidColorResourceType;
+
+RenderSVGResourceSolidColor::RenderSVGResourceSolidColor()
+{
+}
+
+RenderSVGResourceSolidColor::~RenderSVGResourceSolidColor()
+{
+}
+
+bool RenderSVGResourceSolidColor::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
+{
+ // We are NOT allowed to ASSERT(object) here, unlike all other resources.
+ // RenderSVGResourceSolidColor is the only resource which may be used from HTML, when rendering
+ // SVG Fonts for a HTML document. This will be indicated by a null RenderObject pointer.
+ ASSERT(context);
+ ASSERT(resourceMode != ApplyToDefaultMode);
+
+ const SVGRenderStyle* svgStyle = style ? style->svgStyle() : 0;
+ ColorSpace colorSpace = style ? style->colorSpace() : DeviceColorSpace;
+
+ if (resourceMode & ApplyToFillMode) {
+ context->setAlpha(svgStyle ? svgStyle->fillOpacity() : 1.0f);
+ context->setFillColor(m_color, colorSpace);
+ context->setFillRule(svgStyle ? svgStyle->fillRule() : RULE_NONZERO);
+
+ if (resourceMode & ApplyToTextMode)
+ context->setTextDrawingMode(cTextFill);
+ } else if (resourceMode & ApplyToStrokeMode) {
+ context->setAlpha(svgStyle ? svgStyle->strokeOpacity() : 1.0f);
+ context->setStrokeColor(m_color, colorSpace);
+
+ if (style)
+ applyStrokeStyleToContext(context, style, object);
+
+ if (resourceMode & ApplyToTextMode)
+ context->setTextDrawingMode(cTextStroke);
+ }
+
+ return true;
+}
+
+void RenderSVGResourceSolidColor::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode)
+{
+ ASSERT(context);
+ ASSERT(resourceMode != ApplyToDefaultMode);
+
+ if (!(resourceMode & ApplyToTextMode)) {
+ if (resourceMode & ApplyToFillMode)
+ context->fillPath();
+ else if (resourceMode & ApplyToStrokeMode)
+ context->strokePath();
+ }
+
+#if PLATFORM(SKIA)
+ // FIXME: Move this into the GraphicsContext
+ // WebKit implicitly expects us to reset the path.
+ // For example in fillAndStrokePath() of RenderPath.cpp the path is
+ // added back to the context after filling. This is because internally it
+ // calls CGContextFillPath() which closes the path.
+ context->beginPath();
+ context->platformContext()->setFillShader(0);
+ context->platformContext()->setStrokeShader(0);
+#endif
+}
+
+}
+
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceSolidColor.h b/WebCore/rendering/RenderSVGResourceSolidColor.h
new file mode 100644
index 0000000..a1a8863
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceSolidColor.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderSVGResourceSolidColor_h
+#define RenderSVGResourceSolidColor_h
+
+#if ENABLE(SVG)
+#include "Color.h"
+#include "FloatRect.h"
+#include "RenderSVGResource.h"
+
+namespace WebCore {
+
+class RenderSVGResourceSolidColor : public RenderSVGResource {
+public:
+ RenderSVGResourceSolidColor();
+ virtual ~RenderSVGResourceSolidColor();
+
+ virtual void invalidateClients() { }
+ virtual void invalidateClient(RenderObject*) { }
+
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode);
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const { return FloatRect(); }
+
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
+
+ const Color& color() const { return m_color; }
+ void setColor(const Color& color) { m_color = color; }
+
+private:
+ Color m_color;
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index 5ed0871..67a3b2a 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -62,11 +62,11 @@ void RenderSVGRoot::calcPrefWidths()
{
ASSERT(prefWidthsDirty());
- int paddingAndBorders = paddingLeft() + paddingRight() + borderLeft() + borderRight();
- int width = calcReplacedWidth(false) + paddingAndBorders;
+ int borderAndPadding = borderAndPaddingWidth();
+ int width = calcReplacedWidth(false) + borderAndPadding;
if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength)
- width = min(width, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? paddingAndBorders : 0));
+ width = min(width, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? borderAndPadding : 0));
if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent())) {
m_minPrefWidth = 0;
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp
index c0c4650..966196b 100644
--- a/WebCore/rendering/RenderSVGText.cpp
+++ b/WebCore/rendering/RenderSVGText.cpp
@@ -160,7 +160,10 @@ void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads)
}
void RenderSVGText::paint(PaintInfo& paintInfo, int, int)
-{
+{
+ if (paintInfo.context->paintingDisabled())
+ return;
+
PaintInfo pi(paintInfo);
pi.context->save();
applyTransformToPaintInfo(pi, localToParentTransform());
diff --git a/WebCore/rendering/RenderSVGText.h b/WebCore/rendering/RenderSVGText.h
index fe53086..66f7eb3 100644
--- a/WebCore/rendering/RenderSVGText.h
+++ b/WebCore/rendering/RenderSVGText.h
@@ -42,8 +42,6 @@ public:
private:
virtual const char* renderName() const { return "RenderSVGText"; }
- virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
-
virtual bool isSVGText() const { return true; }
virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index 37b5e19..ed5fe76 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -30,6 +30,7 @@
#include "HTMLInputElement.h"
#include "HTMLDivElement.h"
#include "HTMLNames.h"
+#include "HTMLParser.h"
#include "MediaControlElements.h"
#include "MouseEvent.h"
#include "RenderLayer.h"
@@ -186,7 +187,7 @@ void RenderSlider::calcPrefWidths()
m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
}
- int toAdd = paddingLeft() + paddingRight() + borderLeft() + borderRight();
+ int toAdd = borderAndPaddingWidth();
m_minPrefWidth += toAdd;
m_maxPrefWidth += toAdd;
@@ -260,8 +261,7 @@ void RenderSlider::layout()
RenderBox* thumb = m_thumb ? toRenderBox(m_thumb->renderer()) : 0;
- IntSize baseSize(borderLeft() + paddingLeft() + paddingRight() + borderRight(),
- borderTop() + paddingTop() + paddingBottom() + borderBottom());
+ IntSize baseSize(borderAndPaddingWidth(), borderAndPaddingHeight());
if (thumb) {
// Allow the theme to set the size of the thumb.
@@ -314,7 +314,7 @@ void RenderSlider::updateFromElement()
m_thumb->setRenderer(m_thumb->createRenderer(renderArena(), thumbStyle.get()));
m_thumb->renderer()->setStyle(thumbStyle.release());
m_thumb->setAttached();
- m_thumb->setInDocument(true);
+ m_thumb->setInDocument();
addChild(m_thumb->renderer());
}
setNeedsLayout(true);
@@ -361,7 +361,7 @@ void RenderSlider::setValueForPosition(int position)
if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart)
fraction = 1 - fraction;
double value = range.clampValue(range.valueFromProportion(fraction));
- element->setValueFromRenderer(HTMLInputElement::serializeForNumberType(value));
+ element->setValueFromRenderer(serializeForNumberType(value));
// Also update the position if appropriate.
if (position != currentPosition()) {
diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp
index 4506e77..5779422 100644
--- a/WebCore/rendering/RenderTableCell.cpp
+++ b/WebCore/rendering/RenderTableCell.cpp
@@ -120,7 +120,7 @@ Length RenderTableCell::styleOrColWidth() const
// Percentages don't need to be handled since they're always treated this way (even when specified on the cells).
// See Bugzilla bug 8126 for details.
if (colWidthSum.isFixed() && colWidthSum.value() > 0)
- colWidthSum = Length(max(0, colWidthSum.value() - borderLeft() - borderRight() - paddingLeft() - paddingRight()), Fixed);
+ colWidthSum = Length(max(0, colWidthSum.value() - borderAndPaddingWidth()), Fixed);
return colWidthSum;
}
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index 90ad6d8..bede6a6 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -455,23 +455,40 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
*extraWidthToEndOfLine = (box->root()->width() + rootLeft) - (left + 1);
RenderBlock* cb = containingBlock();
+ RenderStyle* cbStyle = cb->style();
+ int leftEdge;
+ int rightEdge;
if (style()->autoWrap()) {
- int availableWidth = cb->lineWidth(top, false);
- if (box->direction() == LTR)
- left = min(left, rootLeft + availableWidth - caretWidthRightOfOffset);
- else
- left = max(left, cb->x());
+ leftEdge = cb->x();
+ rightEdge = cb->frameRect().right();
} else {
- // If there is no wrapping, the caret can leave its containing block, but not its root line box.
- if (cb->style()->direction() == LTR) {
- int rightEdge = max(cb->width(), rootRight);
- left = min(left, rightEdge - caretWidthRightOfOffset);
- left = max(left, rootLeft);
- } else {
- int leftEdge = min(cb->x(), rootLeft);
- left = max(left, leftEdge);
- left = min(left, rootRight - caretWidth);
- }
+ leftEdge = min(cb->x(), rootLeft);
+ rightEdge = max(cb->frameRect().right(), rootRight);
+ }
+
+ bool rightAligned = false;
+ switch (cbStyle->textAlign()) {
+ case TAAUTO:
+ case JUSTIFY:
+ rightAligned = cbStyle->direction() == RTL;
+ break;
+ case RIGHT:
+ case WEBKIT_RIGHT:
+ rightAligned = true;
+ break;
+ case LEFT:
+ case WEBKIT_LEFT:
+ case CENTER:
+ case WEBKIT_CENTER:
+ break;
+ }
+
+ if (rightAligned) {
+ left = max(left, leftEdge);
+ left = min(left, rootRight - caretWidth);
+ } else {
+ left = min(left, rightEdge - caretWidthRightOfOffset);
+ left = max(left, rootLeft);
}
return IntRect(left, top, caretWidth, height);
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index 5e19362..1e80ff0 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -151,13 +151,12 @@ void RenderTextControl::createSubtreeIfNeeded(TextControlInnerElement* innerBloc
int RenderTextControl::textBlockHeight() const
{
- return height() - paddingTop() - paddingBottom() - borderTop() - borderBottom();
+ return height() - borderAndPaddingHeight();
}
int RenderTextControl::textBlockWidth() const
{
- return width() - paddingLeft() - paddingRight() - borderLeft() - borderRight()
- - m_innerText->renderBox()->paddingLeft() - m_innerText->renderBox()->paddingRight();
+ return width() - borderAndPaddingWidth() - m_innerText->renderBox()->paddingLeft() - m_innerText->renderBox()->paddingRight();
}
void RenderTextControl::updateFromElement()
@@ -410,7 +409,7 @@ void RenderTextControl::calcHeight()
m_innerText->renderBox()->marginTop() + m_innerText->renderBox()->marginBottom());
adjustControlHeightBasedOnLineHeight(m_innerText->renderer()->lineHeight(true, true));
- setHeight(height() + paddingTop() + paddingBottom() + borderTop() + borderBottom());
+ setHeight(height() + borderAndPaddingHeight());
// We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
if (style()->overflowX() == OSCROLL || (style()->overflowX() == OAUTO && m_innerText->renderer()->style()->wordWrap() == NormalWordWrap))
@@ -434,13 +433,6 @@ void RenderTextControl::forwardEvent(Event* event)
m_innerText->defaultEventHandler(event);
}
-IntRect RenderTextControl::controlClipRect(int tx, int ty) const
-{
- IntRect clipRect = contentBoxRect();
- clipRect.move(tx, ty);
- return clipRect;
-}
-
static const char* fontFamiliesWithInvalidCharWidth[] = {
"American Typewriter",
"Arial Hebrew",
@@ -541,7 +533,7 @@ void RenderTextControl::calcPrefWidths()
m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
}
- int toAdd = paddingLeft() + paddingRight() + borderLeft() + borderRight();
+ int toAdd = borderAndPaddingWidth();
m_minPrefWidth += toAdd;
m_maxPrefWidth += toAdd;
diff --git a/WebCore/rendering/RenderTextControl.h b/WebCore/rendering/RenderTextControl.h
index 2fc8edc..b76d1f2 100644
--- a/WebCore/rendering/RenderTextControl.h
+++ b/WebCore/rendering/RenderTextControl.h
@@ -95,8 +95,6 @@ protected:
private:
virtual const char* renderName() const { return "RenderTextControl"; }
virtual bool isTextControl() const { return true; }
- virtual bool hasControlClip() const { return false; }
- virtual IntRect controlClipRect(int tx, int ty) const;
virtual void calcPrefWidths();
virtual void removeLeftoverAnonymousBlock(RenderBlock*) { }
virtual bool canHaveChildren() const { return false; }
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index 4edd203..37d44c4 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
* (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -66,6 +66,9 @@ RenderTextControlSingleLine::~RenderTextControlSingleLine()
if (m_innerBlock)
m_innerBlock->detach();
+
+ if (m_outerSpinButton)
+ m_outerSpinButton->detach();
}
RenderStyle* RenderTextControlSingleLine::textBaseStyle() const
@@ -185,12 +188,27 @@ void RenderTextControlSingleLine::paint(PaintInfo& paintInfo, int tx, int ty)
if (paintInfo.phase == PaintPhaseBlockBackground && m_shouldDrawCapsLockIndicator) {
IntRect contentsRect = contentBoxRect();
+ // Center vertically like the text.
+ contentsRect.setY((height() - contentsRect.height()) / 2);
+
// Convert the rect into the coords used for painting the content
contentsRect.move(tx + x(), ty + y());
theme()->paintCapsLockIndicator(this, paintInfo, contentsRect);
}
}
+void RenderTextControlSingleLine::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
+{
+ paintBoxDecorationsWithSize(paintInfo, tx, ty, width() - decorationWidthRight(), height());
+}
+
+void RenderTextControlSingleLine::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
+{
+ int w = width() - decorationWidthRight();
+ if (w && height())
+ rects.append(IntRect(tx, ty, w, height()));
+}
+
void RenderTextControlSingleLine::layout()
{
int oldHeight = height();
@@ -234,7 +252,7 @@ void RenderTextControlSingleLine::layout()
innerTextRenderer->style()->setWidth(Length(desiredWidth, Fixed));
if (m_innerBlock) {
- int innerBlockWidth = width() - paddingLeft() - paddingRight() - borderLeft() - borderRight();
+ int innerBlockWidth = width() - borderAndPaddingWidth();
if (innerBlockWidth != innerBlockRenderer->width())
relayoutChildren = true;
innerBlockRenderer->style()->setWidth(Length(innerBlockWidth, Fixed));
@@ -246,7 +264,18 @@ void RenderTextControlSingleLine::layout()
RenderBox* childBlock = innerBlockRenderer ? innerBlockRenderer : innerTextRenderer;
currentHeight = childBlock->height();
if (currentHeight < height())
- childBlock->setLocation(childBlock->x(), (height() - currentHeight) / 2);
+ childBlock->setY((height() - currentHeight) / 2);
+
+ // Center the spin button vertically, and move it to the right by
+ // padding + border of the text fields.
+ if (RenderBox* spinBox = m_outerSpinButton ? m_outerSpinButton->renderBox() : 0) {
+ int diff = height() - spinBox->height();
+ // If the diff is odd, the top area over the spin button takes the
+ // remaining one pixel. It's good for Mac NSStepper because it has
+ // shadow at the bottom.
+ int y = (diff / 2) + (diff % 2);
+ spinBox->setLocation(spinBox->x() + paddingRight() + borderRight(), y);
+ }
}
bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction hitTestAction)
@@ -266,6 +295,9 @@ bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, Hit
if (result.innerNode()->isDescendantOf(innerTextElement()) || result.innerNode() == node())
hitInnerTextElement(result, xPos, yPos, tx, ty);
+ // If we found a spin button, we're done.
+ if (m_outerSpinButton && result.innerNode() == m_outerSpinButton)
+ return true;
// If we're not a search field, or we already found the results or cancel buttons, we're done.
if (!m_innerBlock || result.innerNode() == m_resultsButton || result.innerNode() == m_cancelButton)
return true;
@@ -316,10 +348,13 @@ void RenderTextControlSingleLine::forwardEvent(Event* event)
}
FloatPoint localPoint = innerTextRenderer->absoluteToLocal(static_cast<MouseEvent*>(event)->absoluteLocation(), false, true);
+ int textRight = innerTextRenderer->borderBoxRect().right();
if (m_resultsButton && localPoint.x() < innerTextRenderer->borderBoxRect().x())
m_resultsButton->defaultEventHandler(event);
- else if (m_cancelButton && localPoint.x() > innerTextRenderer->borderBoxRect().right())
+ else if (m_cancelButton && localPoint.x() > textRight)
m_cancelButton->defaultEventHandler(event);
+ else if (m_outerSpinButton && localPoint.x() > textRight)
+ m_outerSpinButton->defaultEventHandler(event);
else
RenderTextControl::forwardEvent(event);
}
@@ -342,6 +377,9 @@ void RenderTextControlSingleLine::styleDidChange(StyleDifference diff, const Ren
if (RenderObject* cancelRenderer = m_cancelButton ? m_cancelButton->renderer() : 0)
cancelRenderer->setStyle(createCancelButtonStyle(style()));
+ if (RenderObject* spinRenderer = m_outerSpinButton ? m_outerSpinButton->renderer() : 0)
+ spinRenderer->setStyle(createOuterSpinButtonStyle());
+
setHasOverflowClip(false);
}
@@ -369,6 +407,16 @@ void RenderTextControlSingleLine::capsLockStateMayHaveChanged()
}
}
+IntRect RenderTextControlSingleLine::controlClipRect(int tx, int ty) const
+{
+ // This should only get called for search inputs.
+ ASSERT(hasControlClip());
+
+ IntRect clipRect = IntRect(m_innerBlock->renderBox()->frameRect());
+ clipRect.move(tx, ty);
+ return clipRect;
+}
+
int RenderTextControlSingleLine::textBlockWidth() const
{
int width = RenderTextControl::textBlockWidth();
@@ -383,6 +431,18 @@ int RenderTextControlSingleLine::textBlockWidth() const
width -= cancelRenderer->width() + cancelRenderer->marginLeft() + cancelRenderer->marginRight();
}
+ return width - decorationWidthRight();
+}
+
+int RenderTextControlSingleLine::decorationWidthRight() const
+{
+ int width = 0;
+ if (RenderBox* spinRenderer = m_outerSpinButton ? m_outerSpinButton->renderBox() : 0) {
+ spinRenderer->calcWidth();
+ width += spinRenderer->width() + spinRenderer->marginLeft() + spinRenderer->marginRight();
+ }
+ if (width > 0)
+ width += paddingRight() + borderRight();
return width;
}
@@ -432,6 +492,18 @@ int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
return result;
}
+int RenderTextControlSingleLine::preferredDecorationWidthRight() const
+{
+ int width = 0;
+ if (RenderBox* spinRenderer = m_outerSpinButton ? m_outerSpinButton->renderBox() : 0) {
+ spinRenderer->calcWidth();
+ width += spinRenderer->minPrefWidth() + spinRenderer->marginLeft() + spinRenderer->marginRight();
+ }
+ if (width > 0)
+ width += paddingRight() + borderRight();
+ return width;
+}
+
void RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
{
if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0) {
@@ -459,6 +531,10 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded()
{
if (!inputElement()->isSearchField()) {
RenderTextControl::createSubtreeIfNeeded(m_innerBlock.get());
+ if (inputElement()->hasSpinButton() && !m_outerSpinButton) {
+ m_outerSpinButton = new SpinButtonElement(document(), node());
+ m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena());
+ }
return;
}
@@ -535,7 +611,7 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const
if (textBlockStyle->font().lineSpacing() > lineHeight(true, true))
textBlockStyle->setLineHeight(Length(-100.0f, Percent));
- textBlockStyle->setDisplay(m_innerBlock ? INLINE_BLOCK : BLOCK);
+ textBlockStyle->setDisplay(m_innerBlock || inputElement()->hasSpinButton() ? INLINE_BLOCK : BLOCK);
// We're adding one extra pixel of padding to match WinIE.
textBlockStyle->setPaddingLeft(Length(1, Fixed));
@@ -607,6 +683,16 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createCancelButtonStyle(con
return cancelBlockStyle.release();
}
+PassRefPtr<RenderStyle> RenderTextControlSingleLine::createOuterSpinButtonStyle() const
+{
+ ASSERT(node()->isHTMLElement());
+ RefPtr<RenderStyle> buttonStyle = getCachedPseudoStyle(OUTER_SPIN_BUTTON);
+ if (!buttonStyle)
+ buttonStyle = RenderStyle::create();
+ buttonStyle->inheritFrom(style());
+ return buttonStyle.release();
+}
+
void RenderTextControlSingleLine::updateCancelButtonVisibility() const
{
if (!m_cancelButton->renderer())
diff --git a/WebCore/rendering/RenderTextControlSingleLine.h b/WebCore/rendering/RenderTextControlSingleLine.h
index e1bcc84..b093954 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/WebCore/rendering/RenderTextControlSingleLine.h
@@ -32,6 +32,7 @@ class InputElement;
class SearchFieldCancelButtonElement;
class SearchFieldResultsButtonElement;
class SearchPopupMenu;
+class SpinButtonElement;
class TextControlInnerElement;
class RenderTextControlSingleLine : public RenderTextControl, private PopupMenuClient {
@@ -53,12 +54,19 @@ public:
void capsLockStateMayHaveChanged();
+ // Decoration width outside of the text field.
+ int decorationWidthRight() const;
+
private:
+ int preferredDecorationWidthRight() const;
virtual bool hasControlClip() const { return m_cancelButton; }
+ virtual IntRect controlClipRect(int tx, int ty) const;
virtual bool isTextField() const { return true; }
virtual void subtreeHasChanged();
virtual void paint(PaintInfo&, int tx, int ty);
+ virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
virtual void layout();
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -89,6 +97,7 @@ private:
PassRefPtr<RenderStyle> createInnerBlockStyle(const RenderStyle* startStyle) const;
PassRefPtr<RenderStyle> createResultsButtonStyle(const RenderStyle* startStyle) const;
PassRefPtr<RenderStyle> createCancelButtonStyle(const RenderStyle* startStyle) const;
+ PassRefPtr<RenderStyle> createOuterSpinButtonStyle() const;
void updateCancelButtonVisibility() const;
EVisibility visibilityForCancelButton() const;
@@ -130,6 +139,7 @@ private:
RefPtr<TextControlInnerElement> m_innerBlock;
RefPtr<SearchFieldResultsButtonElement> m_resultsButton;
RefPtr<SearchFieldCancelButtonElement> m_cancelButton;
+ RefPtr<TextControlInnerElement> m_outerSpinButton;
Timer<RenderTextControlSingleLine> m_searchEventTimer;
RefPtr<SearchPopupMenu> m_searchPopup;
diff --git a/WebCore/rendering/RenderTheme.cpp b/WebCore/rendering/RenderTheme.cpp
index b3b7a1e..76af001 100644
--- a/WebCore/rendering/RenderTheme.cpp
+++ b/WebCore/rendering/RenderTheme.cpp
@@ -36,6 +36,7 @@
#include "RenderView.h"
#include "SelectionController.h"
#include "Settings.h"
+#include "TextControlInnerElements.h"
// The methods in this file are shared by all themes on every platform.
@@ -617,6 +618,7 @@ bool RenderTheme::isControlStyled(const RenderStyle* style, const BorderData& bo
case ButtonPart:
case ListboxPart:
case MenulistPart:
+ case ProgressBarPart:
// FIXME: Uncomment this when making search fields style-able.
// case SearchFieldPart:
case TextFieldPart:
@@ -660,10 +662,16 @@ bool RenderTheme::stateChanged(RenderObject* o, ControlState state) const
ControlStates RenderTheme::controlStatesForRenderer(const RenderObject* o) const
{
ControlStates result = 0;
- if (isHovered(o))
+ if (isHovered(o)) {
result |= HoverState;
- if (isPressed(o))
+ if (isSpinUpButtonPartHovered(o))
+ result |= SpinUpState;
+ }
+ if (isPressed(o)) {
result |= PressedState;
+ if (isSpinUpButtonPartPressed(o))
+ result |= SpinUpState;
+ }
if (isFocused(o) && o->style()->outlineStyleIsAuto())
result |= FocusState;
if (isEnabled(o))
@@ -747,6 +755,16 @@ bool RenderTheme::isPressed(const RenderObject* o) const
return o->node()->active();
}
+bool RenderTheme::isSpinUpButtonPartPressed(const RenderObject* o) const
+{
+ Node* node = o->node();
+ if (!node || !node->active() || !node->isElementNode()
+ || !static_cast<Element*>(node)->isSpinButtonElement())
+ return false;
+ SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
+ return element->onUpButton();
+}
+
bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
{
Node* node = o->node();
@@ -762,6 +780,16 @@ bool RenderTheme::isHovered(const RenderObject* o) const
return o->node()->hovered();
}
+bool RenderTheme::isSpinUpButtonPartHovered(const RenderObject* o) const
+{
+ Node* node = o->node();
+ if (!node || !node->active() || !node->isElementNode()
+ || !static_cast<Element*>(node)->isSpinButtonElement())
+ return false;
+ SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
+ return element->onUpButton();
+}
+
bool RenderTheme::isDefault(const RenderObject* o) const
{
// A button should only have the default appearance if the page is active
diff --git a/WebCore/rendering/RenderTheme.h b/WebCore/rendering/RenderTheme.h
index 1526138..6edc878 100644
--- a/WebCore/rendering/RenderTheme.h
+++ b/WebCore/rendering/RenderTheme.h
@@ -292,7 +292,9 @@ public:
bool isEnabled(const RenderObject*) const;
bool isFocused(const RenderObject*) const;
bool isPressed(const RenderObject*) const;
+ bool isSpinUpButtonPartPressed(const RenderObject*) const;
bool isHovered(const RenderObject*) const;
+ bool isSpinUpButtonPartHovered(const RenderObject*) const;
bool isReadOnlyControl(const RenderObject*) const;
bool isDefault(const RenderObject*) const;
diff --git a/WebCore/rendering/RenderThemeChromiumMac.h b/WebCore/rendering/RenderThemeChromiumMac.h
index 8101038..aaaade0 100644
--- a/WebCore/rendering/RenderThemeChromiumMac.h
+++ b/WebCore/rendering/RenderThemeChromiumMac.h
@@ -24,173 +24,32 @@
#ifndef RenderThemeChromiumMac_h
#define RenderThemeChromiumMac_h
-#import "RenderTheme.h"
-#import <wtf/HashMap.h>
-#import <wtf/RetainPtr.h>
-
-#ifdef __OBJC__
-@class WebCoreRenderThemeNotificationObserver;
-#else
-class WebCoreRenderThemeNotificationObserver;
-#endif
-
-// This file (and its associated .mm file) is a clone of RenderThemeMac.h. See
-// the .mm file for details.
+#import "RenderThemeMac.h"
namespace WebCore {
-class RenderStyle;
-
-class RenderThemeChromiumMac : public RenderTheme {
+class RenderThemeChromiumMac : public RenderThemeMac {
public:
static PassRefPtr<RenderTheme> create();
-
- // A method asking if the control changes its tint when the window has focus or not.
- virtual bool controlSupportsTints(const RenderObject*) const;
-
- // A general method asking if any control tinting is supported at all.
- virtual bool supportsControlTints() const { return true; }
-
- virtual void adjustRepaintRect(const RenderObject*, IntRect&);
-
- virtual bool isControlStyled(const RenderStyle*, const BorderData&,
- const FillLayer&, const Color& backgroundColor) const;
-
- virtual Color platformActiveSelectionBackgroundColor() const;
- virtual Color platformInactiveSelectionBackgroundColor() const;
- virtual Color platformActiveListBoxSelectionBackgroundColor() const;
- virtual Color platformActiveListBoxSelectionForegroundColor() const;
- virtual Color platformInactiveListBoxSelectionBackgroundColor() const;
- virtual Color platformInactiveListBoxSelectionForegroundColor() const;
- virtual Color platformFocusRingColor() const;
-
- virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return SmallScrollbar; }
-
- virtual void platformColorsDidChange();
-
- // System fonts.
- virtual void systemFont(int cssValueId, FontDescription&) const;
-
- virtual int minimumMenuListSize(RenderStyle*) const;
-
- virtual void adjustSliderThumbSize(RenderObject*) const;
-
- virtual int popupInternalPaddingLeft(RenderStyle*) const;
- virtual int popupInternalPaddingRight(RenderStyle*) const;
- virtual int popupInternalPaddingTop(RenderStyle*) const;
- virtual int popupInternalPaddingBottom(RenderStyle*) const;
-
- virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
-
- virtual Color systemColor(int cssValueId) const;
-
protected:
- virtual bool supportsSelectionForegroundColors() const { return false; }
-
- virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
-
- virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
-
- virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
-
- virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
-
- virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
-
- virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
-
- virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
-
- virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
- virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
-
- virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
- virtual bool paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
-
- virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
- virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
-
- virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
- virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
-
#if ENABLE(VIDEO)
- virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
+ virtual void adjustMediaSliderThumbSize(RenderObject*) const;
virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual bool paintMediaVolumeSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- virtual bool paintMediaVolumeSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaControlsBackground(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
-
- // Media controls
+ virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
virtual String extraMediaControlsStyleSheet();
-#endif
-
-private:
- RenderThemeChromiumMac();
- virtual ~RenderThemeChromiumMac();
-
- IntRect inflateRect(const IntRect&, const IntSize&, const int* margins, float zoomLevel = 1.0f) const;
-
- FloatRect convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const;
-
- // Get the control size based off the font. Used by some of the controls (like buttons).
- NSControlSize controlSizeForFont(RenderStyle*) const;
- NSControlSize controlSizeForSystemFont(RenderStyle*) const;
- void setControlSize(NSCell*, const IntSize* sizes, const IntSize& minSize, float zoomLevel = 1.0f);
- void setSizeFromFont(RenderStyle*, const IntSize* sizes) const;
- IntSize sizeForFont(RenderStyle*, const IntSize* sizes) const;
- IntSize sizeForSystemFont(RenderStyle*, const IntSize* sizes) const;
- void setFontFromControlSize(CSSStyleSelector*, RenderStyle*, NSControlSize) const;
- void updateActiveState(NSCell*, const RenderObject*);
- void updateCheckedState(NSCell*, const RenderObject*);
- void updateEnabledState(NSCell*, const RenderObject*);
- void updateFocusedState(NSCell*, const RenderObject*);
- void updatePressedState(NSCell*, const RenderObject*);
-
- // Helpers for adjusting appearance and for painting
-
- void setPopupButtonCellState(const RenderObject*, const IntRect&);
- const IntSize* popupButtonSizes() const;
- const int* popupButtonMargins() const;
- const int* popupButtonPadding(NSControlSize) const;
- void paintMenuListButtonGradients(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- const IntSize* menuListSizes() const;
+ virtual bool paintMediaVolumeSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaVolumeSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
- const IntSize* searchFieldSizes() const;
- const IntSize* cancelButtonSizes() const;
- const IntSize* resultsButtonSizes() const;
- void setSearchCellState(RenderObject*, const IntRect&);
- void setSearchFieldSize(RenderStyle*) const;
-
- NSPopUpButtonCell* popupButton() const;
- NSSearchFieldCell* search() const;
- NSMenu* searchMenuTemplate() const;
- NSSliderCell* sliderThumbHorizontal() const;
- NSSliderCell* sliderThumbVertical() const;
+#endif
+ virtual bool usesTestModeFocusRingColor() const;
+ virtual NSView* documentViewFor(RenderObject*) const;
private:
- mutable RetainPtr<NSPopUpButtonCell> m_popupButton;
- mutable RetainPtr<NSSearchFieldCell> m_search;
- mutable RetainPtr<NSMenu> m_searchMenuTemplate;
- mutable RetainPtr<NSSliderCell> m_sliderThumbHorizontal;
- mutable RetainPtr<NSSliderCell> m_sliderThumbVertical;
-
- bool m_isSliderThumbHorizontalPressed;
- bool m_isSliderThumbVerticalPressed;
-
- mutable HashMap<int, RGBA32> m_systemColorCache;
-
- RetainPtr<WebCoreRenderThemeNotificationObserver> m_notificationObserver;
+ virtual void updateActiveState(NSCell*, const RenderObject*);
};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeChromiumMac.mm b/WebCore/rendering/RenderThemeChromiumMac.mm
index 03aab1c..47a872d 100644
--- a/WebCore/rendering/RenderThemeChromiumMac.mm
+++ b/WebCore/rendering/RenderThemeChromiumMac.mm
@@ -20,29 +20,8 @@
#import "config.h"
#import "RenderThemeChromiumMac.h"
-
-#import "BitmapImage.h"
#import "ChromiumBridge.h"
-#import "ColorMac.h"
-#import "CSSStyleSelector.h"
-#import "CSSValueKeywords.h"
-#import "Document.h"
-#import "Element.h"
-#import "FrameView.h"
-#import "GraphicsContext.h"
-#import "HTMLInputElement.h"
-#import "HTMLMediaElement.h"
-#import "HTMLNames.h"
-#import "Image.h"
-#import "LocalCurrentGraphicsContext.h"
-#import "MediaControlElements.h"
-#import "RenderMedia.h"
#import "RenderMediaControlsChromium.h"
-#import "RenderSlider.h"
-#import "RenderView.h"
-#import "SharedBuffer.h"
-#import "TimeRanges.h"
-#import "WebCoreSystemInterface.h"
#import "UserAgentStyleSheets.h"
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
@@ -50,64 +29,6 @@
#import <wtf/StdLibExtras.h>
#import <math.h>
-#ifdef BUILDING_ON_TIGER
-typedef int NSInteger;
-typedef unsigned NSUInteger;
-#endif
-
-using std::min;
-
-// This file (and its associated .h file) is a clone of RenderThemeMac.mm.
-// Because the original file is designed to run in-process inside a Cocoa view,
-// we must maintain a fork. Please maintain this file by performing parallel
-// changes to it.
-//
-// The only changes from RenderThemeMac should be:
-// - The classname change from RenderThemeMac to RenderThemeChromiumMac.
-// - The introduction of RTCMFlippedView and FlippedView() and its use as the
-// parent view for cell rendering.
-// - In platformFocusRingColor(), the use of ChromiumBridge to determine if
-// we're in layout test mode.
-// - updateActiveState() and its use to update the cells' visual appearance.
-// - All the paintMedia*() functions and extraMediaControlsStyleSheet()
-// are forked from RenderThemeChromiumSkia instead of RenderThemeMac.
-//
-// For all other differences, if it was introduced in this file, then the
-// maintainer forgot to include it in the list; otherwise it is an update that
-// should have been applied to this file but was not.
-
-// The methods in this file are specific to the Mac OS X platform.
-
-// FIXME: The platform-independent code in this class should be factored out and merged with RenderThemeSafari.
-
-@interface WebCoreRenderThemeNotificationObserver : NSObject
-{
- WebCore::RenderTheme *_theme;
-}
-
-- (id)initWithTheme:(WebCore::RenderTheme *)theme;
-- (void)systemColorsDidChange:(NSNotification *)notification;
-
-@end
-
-@implementation WebCoreRenderThemeNotificationObserver
-
-- (id)initWithTheme:(WebCore::RenderTheme *)theme
-{
- [super init];
- _theme = theme;
-
- return self;
-}
-
-- (void)systemColorsDidChange:(NSNotification *)unusedNotification
-{
- ASSERT_UNUSED(unusedNotification, [[unusedNotification name] isEqualToString:NSSystemColorsDidChangeNotification]);
- _theme->platformColorsDidChange();
-}
-
-@end
-
@interface RTCMFlippedView : NSView
{}
@@ -130,26 +51,6 @@ using std::min;
namespace WebCore {
-using namespace HTMLNames;
-
-enum {
- topMargin,
- rightMargin,
- bottomMargin,
- leftMargin
-};
-
-enum {
- topPadding,
- rightPadding,
- bottomPadding,
- leftPadding
-};
-
-// In Snow Leopard, many cells only check to see if the view they're passed is
-// flipped, and if a nil view is passed, neglect to check if the current
-// graphics context is flipped. Thus we pass a sham view to them, one whose
-// flipped state just reflects the state of the context.
NSView* FlippedView()
{
static NSView* view = [[RTCMFlippedView alloc] init];
@@ -167,422 +68,14 @@ PassRefPtr<RenderTheme> RenderThemeChromiumMac::create()
return adoptRef(new RenderThemeChromiumMac);
}
-RenderThemeChromiumMac::RenderThemeChromiumMac()
- : m_isSliderThumbHorizontalPressed(false)
- , m_isSliderThumbVerticalPressed(false)
- , m_notificationObserver(AdoptNS, [[WebCoreRenderThemeNotificationObserver alloc] initWithTheme:this])
+bool RenderThemeChromiumMac::usesTestModeFocusRingColor() const
{
- [[NSNotificationCenter defaultCenter] addObserver:m_notificationObserver.get()
- selector:@selector(systemColorsDidChange:)
- name:NSSystemColorsDidChangeNotification
- object:nil];
+ return ChromiumBridge::layoutTestMode();
}
-RenderThemeChromiumMac::~RenderThemeChromiumMac()
+NSView* RenderThemeChromiumMac::documentViewFor(RenderObject*) const
{
- [[NSNotificationCenter defaultCenter] removeObserver:m_notificationObserver.get()];
-}
-
-Color RenderThemeChromiumMac::platformActiveSelectionBackgroundColor() const
-{
- NSColor* color = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
- return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
-}
-
-Color RenderThemeChromiumMac::platformInactiveSelectionBackgroundColor() const
-{
- NSColor* color = [[NSColor secondarySelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
- return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
-}
-
-Color RenderThemeChromiumMac::platformActiveListBoxSelectionBackgroundColor() const
-{
- NSColor* color = [[NSColor alternateSelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
- return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
-}
-
-Color RenderThemeChromiumMac::platformActiveListBoxSelectionForegroundColor() const
-{
- return Color::white;
-}
-
-Color RenderThemeChromiumMac::platformInactiveListBoxSelectionForegroundColor() const
-{
- return Color::black;
-}
-
-Color RenderThemeChromiumMac::platformFocusRingColor() const
-{
- if (ChromiumBridge::layoutTestMode())
- return oldAquaFocusRingColor();
-
- return systemColor(CSSValueWebkitFocusRingColor);
-}
-
-Color RenderThemeChromiumMac::platformInactiveListBoxSelectionBackgroundColor() const
-{
- return platformInactiveSelectionBackgroundColor();
-}
-
-static FontWeight toFontWeight(NSInteger appKitFontWeight)
-{
- ASSERT(appKitFontWeight > 0 && appKitFontWeight < 15);
- if (appKitFontWeight > 14)
- appKitFontWeight = 14;
- else if (appKitFontWeight < 1)
- appKitFontWeight = 1;
-
- static FontWeight fontWeights[] = {
- FontWeight100,
- FontWeight100,
- FontWeight200,
- FontWeight300,
- FontWeight400,
- FontWeight500,
- FontWeight600,
- FontWeight600,
- FontWeight700,
- FontWeight800,
- FontWeight800,
- FontWeight900,
- FontWeight900,
- FontWeight900
- };
- return fontWeights[appKitFontWeight - 1];
-}
-
-void RenderThemeChromiumMac::systemFont(int cssValueId, FontDescription& fontDescription) const
-{
- DEFINE_STATIC_LOCAL(FontDescription, systemFont, ());
- DEFINE_STATIC_LOCAL(FontDescription, smallSystemFont, ());
- DEFINE_STATIC_LOCAL(FontDescription, menuFont, ());
- DEFINE_STATIC_LOCAL(FontDescription, labelFont, ());
- DEFINE_STATIC_LOCAL(FontDescription, miniControlFont, ());
- DEFINE_STATIC_LOCAL(FontDescription, smallControlFont, ());
- DEFINE_STATIC_LOCAL(FontDescription, controlFont, ());
-
- FontDescription* cachedDesc;
- NSFont* font = nil;
- switch (cssValueId) {
- case CSSValueSmallCaption:
- cachedDesc = &smallSystemFont;
- if (!smallSystemFont.isAbsoluteSize())
- font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
- break;
- case CSSValueMenu:
- cachedDesc = &menuFont;
- if (!menuFont.isAbsoluteSize())
- font = [NSFont menuFontOfSize:[NSFont systemFontSize]];
- break;
- case CSSValueStatusBar:
- cachedDesc = &labelFont;
- if (!labelFont.isAbsoluteSize())
- font = [NSFont labelFontOfSize:[NSFont labelFontSize]];
- break;
- case CSSValueWebkitMiniControl:
- cachedDesc = &miniControlFont;
- if (!miniControlFont.isAbsoluteSize())
- font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];
- break;
- case CSSValueWebkitSmallControl:
- cachedDesc = &smallControlFont;
- if (!smallControlFont.isAbsoluteSize())
- font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]];
- break;
- case CSSValueWebkitControl:
- cachedDesc = &controlFont;
- if (!controlFont.isAbsoluteSize())
- font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
- break;
- default:
- cachedDesc = &systemFont;
- if (!systemFont.isAbsoluteSize())
- font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
- }
-
- if (font) {
- NSFontManager *fontManager = [NSFontManager sharedFontManager];
- cachedDesc->setIsAbsoluteSize(true);
- cachedDesc->setGenericFamily(FontDescription::NoFamily);
- cachedDesc->firstFamily().setFamily([font familyName]);
- cachedDesc->setSpecifiedSize([font pointSize]);
- cachedDesc->setWeight(toFontWeight([fontManager weightOfFont:font]));
- cachedDesc->setItalic([fontManager traitsOfFont:font] & NSItalicFontMask);
- }
- fontDescription = *cachedDesc;
-}
-
-static RGBA32 convertNSColorToColor(NSColor *color)
-{
- NSColor *colorInColorSpace = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
- if (colorInColorSpace) {
- static const double scaleFactor = nextafter(256.0, 0.0);
- return makeRGB(static_cast<int>(scaleFactor * [colorInColorSpace redComponent]),
- static_cast<int>(scaleFactor * [colorInColorSpace greenComponent]),
- static_cast<int>(scaleFactor * [colorInColorSpace blueComponent]));
- }
-
- // This conversion above can fail if the NSColor in question is an NSPatternColor
- // (as many system colors are). These colors are actually a repeating pattern
- // not just a solid color. To work around this we simply draw a 1x1 image of
- // the color and use that pixel's color. It might be better to use an average of
- // the colors in the pattern instead.
- NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
- pixelsWide:1
- pixelsHigh:1
- bitsPerSample:8
- samplesPerPixel:4
- hasAlpha:YES
- isPlanar:NO
- colorSpaceName:NSDeviceRGBColorSpace
- bytesPerRow:4
- bitsPerPixel:32];
-
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep]];
- NSEraseRect(NSMakeRect(0, 0, 1, 1));
- [color drawSwatchInRect:NSMakeRect(0, 0, 1, 1)];
- [NSGraphicsContext restoreGraphicsState];
-
- NSUInteger pixel[4];
- [offscreenRep getPixel:pixel atX:0 y:0];
-
- [offscreenRep release];
-
- return makeRGB(pixel[0], pixel[1], pixel[2]);
-}
-
-static RGBA32 menuBackgroundColor()
-{
- NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
- pixelsWide:1
- pixelsHigh:1
- bitsPerSample:8
- samplesPerPixel:4
- hasAlpha:YES
- isPlanar:NO
- colorSpaceName:NSDeviceRGBColorSpace
- bytesPerRow:4
- bitsPerPixel:32];
-
- CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep] graphicsPort]);
- CGRect rect = CGRectMake(0, 0, 1, 1);
- HIThemeMenuDrawInfo drawInfo;
- drawInfo.version = 0;
- drawInfo.menuType = kThemeMenuTypePopUp;
- HIThemeDrawMenuBackground(&rect, &drawInfo, context, kHIThemeOrientationInverted);
-
- NSUInteger pixel[4];
- [offscreenRep getPixel:pixel atX:0 y:0];
-
- [offscreenRep release];
-
- return makeRGB(pixel[0], pixel[1], pixel[2]);
-}
-
-void RenderThemeChromiumMac::platformColorsDidChange()
-{
- m_systemColorCache.clear();
- RenderTheme::platformColorsDidChange();
-}
-
-Color RenderThemeChromiumMac::systemColor(int cssValueId) const
-{
- if (m_systemColorCache.contains(cssValueId))
- return m_systemColorCache.get(cssValueId);
-
- Color color;
- switch (cssValueId) {
- case CSSValueActiveborder:
- color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]);
- break;
- case CSSValueActivecaption:
- color = convertNSColorToColor([NSColor windowFrameTextColor]);
- break;
- case CSSValueAppworkspace:
- color = convertNSColorToColor([NSColor headerColor]);
- break;
- case CSSValueBackground:
- // Use theme independent default
- break;
- case CSSValueButtonface:
- // We use this value instead of NSColor's controlColor to avoid website incompatibilities.
- // We may want to change this to use the NSColor in future.
- color = 0xFFC0C0C0;
- break;
- case CSSValueButtonhighlight:
- color = convertNSColorToColor([NSColor controlHighlightColor]);
- break;
- case CSSValueButtonshadow:
- color = convertNSColorToColor([NSColor controlShadowColor]);
- break;
- case CSSValueButtontext:
- color = convertNSColorToColor([NSColor controlTextColor]);
- break;
- case CSSValueCaptiontext:
- color = convertNSColorToColor([NSColor textColor]);
- break;
- case CSSValueGraytext:
- color = convertNSColorToColor([NSColor disabledControlTextColor]);
- break;
- case CSSValueHighlight:
- color = convertNSColorToColor([NSColor selectedTextBackgroundColor]);
- break;
- case CSSValueHighlighttext:
- color = convertNSColorToColor([NSColor selectedTextColor]);
- break;
- case CSSValueInactiveborder:
- color = convertNSColorToColor([NSColor controlBackgroundColor]);
- break;
- case CSSValueInactivecaption:
- color = convertNSColorToColor([NSColor controlBackgroundColor]);
- break;
- case CSSValueInactivecaptiontext:
- color = convertNSColorToColor([NSColor textColor]);
- break;
- case CSSValueInfobackground:
- // There is no corresponding NSColor for this so we use a hard coded value.
- color = 0xFFFBFCC5;
- break;
- case CSSValueInfotext:
- color = convertNSColorToColor([NSColor textColor]);
- break;
- case CSSValueMenu:
- color = menuBackgroundColor();
- break;
- case CSSValueMenutext:
- color = convertNSColorToColor([NSColor selectedMenuItemTextColor]);
- break;
- case CSSValueScrollbar:
- color = convertNSColorToColor([NSColor scrollBarColor]);
- break;
- case CSSValueText:
- color = convertNSColorToColor([NSColor textColor]);
- break;
- case CSSValueThreeddarkshadow:
- color = convertNSColorToColor([NSColor controlDarkShadowColor]);
- break;
- case CSSValueThreedshadow:
- color = convertNSColorToColor([NSColor shadowColor]);
- break;
- case CSSValueThreedface:
- // We use this value instead of NSColor's controlColor to avoid website incompatibilities.
- // We may want to change this to use the NSColor in future.
- color = 0xFFC0C0C0;
- break;
- case CSSValueThreedhighlight:
- color = convertNSColorToColor([NSColor highlightColor]);
- break;
- case CSSValueThreedlightshadow:
- color = convertNSColorToColor([NSColor controlLightHighlightColor]);
- break;
- case CSSValueWebkitFocusRingColor:
- color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]);
- break;
- case CSSValueWindow:
- color = convertNSColorToColor([NSColor windowBackgroundColor]);
- break;
- case CSSValueWindowframe:
- color = convertNSColorToColor([NSColor windowFrameColor]);
- break;
- case CSSValueWindowtext:
- color = convertNSColorToColor([NSColor windowFrameTextColor]);
- break;
- }
-
- if (!color.isValid())
- color = RenderTheme::systemColor(cssValueId);
-
- if (color.isValid())
- m_systemColorCache.set(cssValueId, color.rgb());
-
- return color;
-}
-
-bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const BorderData& border,
- const FillLayer& background, const Color& backgroundColor) const
-{
- if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart || style->appearance() == ListboxPart)
- return style->border() != border;
-
- // FIXME: This is horrible, but there is not much else that can be done. Menu lists cannot draw properly when
- // scaled. They can't really draw properly when transformed either. We can't detect the transform case at style
- // adjustment time so that will just have to stay broken. We can however detect that we're zooming. If zooming
- // is in effect we treat it like the control is styled.
- if (style->appearance() == MenulistPart && style->effectiveZoom() != 1.0f)
- return true;
-
- return RenderTheme::isControlStyled(style, border, background, backgroundColor);
-}
-
-void RenderThemeChromiumMac::adjustRepaintRect(const RenderObject* o, IntRect& r)
-{
- ControlPart part = o->style()->appearance();
-
-#if USE(NEW_THEME)
- switch (part) {
- case CheckboxPart:
- case RadioPart:
- case PushButtonPart:
- case SquareButtonPart:
- case ListButtonPart:
- case DefaultButtonPart:
- case ButtonPart:
- return RenderTheme::adjustRepaintRect(o, r);
- default:
- break;
- }
-#endif
-
- float zoomLevel = o->style()->effectiveZoom();
-
- if (part == MenulistPart) {
- setPopupButtonCellState(o, r);
- IntSize size = popupButtonSizes()[[popupButton() controlSize]];
- size.setHeight(size.height() * zoomLevel);
- size.setWidth(r.width());
- r = inflateRect(r, size, popupButtonMargins(), zoomLevel);
- }
-}
-
-IntRect RenderThemeChromiumMac::inflateRect(const IntRect& r, const IntSize& size, const int* margins, float zoomLevel) const
-{
- // Only do the inflation if the available width/height are too small. Otherwise try to
- // fit the glow/check space into the available box's width/height.
- int widthDelta = r.width() - (size.width() + margins[leftMargin] * zoomLevel + margins[rightMargin] * zoomLevel);
- int heightDelta = r.height() - (size.height() + margins[topMargin] * zoomLevel + margins[bottomMargin] * zoomLevel);
- IntRect result(r);
- if (widthDelta < 0) {
- result.setX(result.x() - margins[leftMargin] * zoomLevel);
- result.setWidth(result.width() - widthDelta);
- }
- if (heightDelta < 0) {
- result.setY(result.y() - margins[topMargin] * zoomLevel);
- result.setHeight(result.height() - heightDelta);
- }
- return result;
-}
-
-FloatRect RenderThemeChromiumMac::convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const
-{
- FloatRect partRect(inputRect);
-
- // Compute an offset between the part renderer and the input renderer
- FloatSize offsetFromInputRenderer;
- const RenderObject* renderer = partRenderer;
- while (renderer && renderer != inputRenderer) {
- RenderObject* containingRenderer = renderer->container();
- offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer, IntPoint());
- renderer = containingRenderer;
- }
- // If the input renderer was not a container, something went wrong
- ASSERT(renderer == inputRenderer);
- // Move the rect into partRenderer's coords
- partRect.move(offsetFromInputRenderer);
- // Account for the local drawing offset (tx, ty)
- partRect.move(r.x(), r.y());
-
- return partRect;
+ return FlippedView();
}
// Updates the control tint (a.k.a. active state) of |cell| (from |o|).
@@ -604,917 +97,13 @@ void RenderThemeChromiumMac::updateActiveState(NSCell* cell, const RenderObject*
[cell setControlTint:tint];
}
-void RenderThemeChromiumMac::updateCheckedState(NSCell* cell, const RenderObject* o)
-{
- bool oldIndeterminate = [cell state] == NSMixedState;
- bool indeterminate = isIndeterminate(o);
- bool checked = isChecked(o);
-
- if (oldIndeterminate != indeterminate) {
- [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)];
- return;
- }
-
- bool oldChecked = [cell state] == NSOnState;
- if (checked != oldChecked)
- [cell setState:checked ? NSOnState : NSOffState];
-}
-
-void RenderThemeChromiumMac::updateEnabledState(NSCell* cell, const RenderObject* o)
-{
- bool oldEnabled = [cell isEnabled];
- bool enabled = isEnabled(o);
- if (enabled != oldEnabled)
- [cell setEnabled:enabled];
-}
-
-void RenderThemeChromiumMac::updateFocusedState(NSCell* cell, const RenderObject* o)
-{
- bool oldFocused = [cell showsFirstResponder];
- bool focused = isFocused(o) && o->style()->outlineStyleIsAuto();
- if (focused != oldFocused)
- [cell setShowsFirstResponder:focused];
-}
-
-void RenderThemeChromiumMac::updatePressedState(NSCell* cell, const RenderObject* o)
-{
- bool oldPressed = [cell isHighlighted];
- bool pressed = (o->node() && o->node()->active());
- if (pressed != oldPressed)
- [cell setHighlighted:pressed];
-}
-
-bool RenderThemeChromiumMac::controlSupportsTints(const RenderObject* o) const
-{
- // An alternate way to implement this would be to get the appropriate cell object
- // and call the private _needRedrawOnWindowChangedKeyState method. An advantage of
- // that would be that we would match AppKit behavior more closely, but a disadvantage
- // would be that we would rely on an AppKit SPI method.
-
- if (!isEnabled(o))
- return false;
-
- // Checkboxes only have tint when checked.
- if (o->style()->appearance() == CheckboxPart)
- return isChecked(o);
-
- // For now assume other controls have tint if enabled.
- return true;
-}
-
-NSControlSize RenderThemeChromiumMac::controlSizeForFont(RenderStyle* style) const
-{
- int fontSize = style->fontSize();
- if (fontSize >= 16)
- return NSRegularControlSize;
- if (fontSize >= 11)
- return NSSmallControlSize;
- return NSMiniControlSize;
-}
-
-void RenderThemeChromiumMac::setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minSize, float zoomLevel)
-{
- NSControlSize size;
- if (minSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomLevel) &&
- minSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomLevel))
- size = NSRegularControlSize;
- else if (minSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomLevel) &&
- minSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomLevel))
- size = NSSmallControlSize;
- else
- size = NSMiniControlSize;
- if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same.
- [cell setControlSize:size];
-}
-
-IntSize RenderThemeChromiumMac::sizeForFont(RenderStyle* style, const IntSize* sizes) const
-{
- if (style->effectiveZoom() != 1.0f) {
- IntSize result = sizes[controlSizeForFont(style)];
- return IntSize(result.width() * style->effectiveZoom(), result.height() * style->effectiveZoom());
- }
- return sizes[controlSizeForFont(style)];
-}
-
-IntSize RenderThemeChromiumMac::sizeForSystemFont(RenderStyle* style, const IntSize* sizes) const
-{
- if (style->effectiveZoom() != 1.0f) {
- IntSize result = sizes[controlSizeForSystemFont(style)];
- return IntSize(result.width() * style->effectiveZoom(), result.height() * style->effectiveZoom());
- }
- return sizes[controlSizeForSystemFont(style)];
-}
-
-void RenderThemeChromiumMac::setSizeFromFont(RenderStyle* style, const IntSize* sizes) const
-{
- // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
- IntSize size = sizeForFont(style, sizes);
- if (style->width().isIntrinsicOrAuto() && size.width() > 0)
- style->setWidth(Length(size.width(), Fixed));
- if (style->height().isAuto() && size.height() > 0)
- style->setHeight(Length(size.height(), Fixed));
-}
-
-void RenderThemeChromiumMac::setFontFromControlSize(CSSStyleSelector*, RenderStyle* style, NSControlSize controlSize) const
-{
- FontDescription fontDescription;
- fontDescription.setIsAbsoluteSize(true);
- fontDescription.setGenericFamily(FontDescription::SerifFamily);
-
- NSFont* font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSize]];
- fontDescription.firstFamily().setFamily([font familyName]);
- fontDescription.setComputedSize([font pointSize] * style->effectiveZoom());
- fontDescription.setSpecifiedSize([font pointSize] * style->effectiveZoom());
-
- // Reset line height
- style->setLineHeight(RenderStyle::initialLineHeight());
-
- if (style->setFontDescription(fontDescription))
- style->font().update(0);
-}
-
-NSControlSize RenderThemeChromiumMac::controlSizeForSystemFont(RenderStyle* style) const
-{
- int fontSize = style->fontSize();
- if (fontSize >= [NSFont systemFontSizeForControlSize:NSRegularControlSize])
- return NSRegularControlSize;
- if (fontSize >= [NSFont systemFontSizeForControlSize:NSSmallControlSize])
- return NSSmallControlSize;
- return NSMiniControlSize;
-}
-
-bool RenderThemeChromiumMac::paintTextField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- LocalCurrentGraphicsContext localContext(paintInfo.context);
- wkDrawBezeledTextFieldCell(r, isEnabled(o) && !isReadOnlyControl(o));
- return false;
-}
-
-void RenderThemeChromiumMac::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const
-{
-}
-
-bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- if (paintInfo.context->paintingDisabled())
- return true;
-
- LocalCurrentGraphicsContext localContext(paintInfo.context);
- wkDrawCapsLockIndicator(paintInfo.context->platformContext(), r);
-
- return false;
-}
-
-bool RenderThemeChromiumMac::paintTextArea(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- LocalCurrentGraphicsContext localContext(paintInfo.context);
- wkDrawBezeledTextArea(r, isEnabled(o) && !isReadOnlyControl(o));
- return false;
-}
-
-void RenderThemeChromiumMac::adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const
-{
-}
-
-const int* RenderThemeChromiumMac::popupButtonMargins() const
-{
- static const int margins[3][4] =
- {
- { 0, 3, 1, 3 },
- { 0, 3, 2, 3 },
- { 0, 1, 0, 1 }
- };
- return margins[[popupButton() controlSize]];
-}
-
-const IntSize* RenderThemeChromiumMac::popupButtonSizes() const
-{
- static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
- return sizes;
-}
-
-const int* RenderThemeChromiumMac::popupButtonPadding(NSControlSize size) const
-{
- static const int padding[3][4] =
- {
- { 2, 26, 3, 8 },
- { 2, 23, 3, 8 },
- { 2, 22, 3, 10 }
- };
- return padding[size];
-}
-
-bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- setPopupButtonCellState(o, r);
-
- NSPopUpButtonCell* popupButton = this->popupButton();
-
- float zoomLevel = o->style()->effectiveZoom();
- IntSize size = popupButtonSizes()[[popupButton controlSize]];
- size.setHeight(size.height() * zoomLevel);
- size.setWidth(r.width());
-
- // Now inflate it to account for the shadow.
- IntRect inflatedRect = r;
- if (r.width() >= minimumMenuListSize(o->style()))
- inflatedRect = inflateRect(inflatedRect, size, popupButtonMargins(), zoomLevel);
-
- paintInfo.context->save();
-
-#ifndef BUILDING_ON_TIGER
- // On Leopard, the cell will draw outside of the given rect, so we have to clip to the rect
- paintInfo.context->clip(inflatedRect);
-#endif
-
- if (zoomLevel != 1.0f) {
- inflatedRect.setWidth(inflatedRect.width() / zoomLevel);
- inflatedRect.setHeight(inflatedRect.height() / zoomLevel);
- paintInfo.context->translate(inflatedRect.x(), inflatedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
- paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y());
- }
-
- [popupButton drawWithFrame:inflatedRect inView:FlippedView()];
- [popupButton setControlView:nil];
-
- paintInfo.context->restore();
-
- return false;
-}
-
-const float baseFontSize = 11.0f;
-const float baseArrowHeight = 4.0f;
-const float baseArrowWidth = 5.0f;
-const float baseSpaceBetweenArrows = 2.0f;
-const int arrowPaddingLeft = 6;
-const int arrowPaddingRight = 6;
-const int paddingBeforeSeparator = 4;
-const int baseBorderRadius = 5;
-const int styledPopupPaddingLeft = 8;
-const int styledPopupPaddingTop = 1;
-const int styledPopupPaddingBottom = 2;
-
-static void TopGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
- static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.4f };
- static float light[4] = { 1.0f, 1.0f, 1.0f, 0.15f };
- float a = inData[0];
- int i = 0;
- for (i = 0; i < 4; i++)
- outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-static void BottomGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
- static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.0f };
- static float light[4] = { 1.0f, 1.0f, 1.0f, 0.3f };
- float a = inData[0];
- int i = 0;
- for (i = 0; i < 4; i++)
- outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-static void MainGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
- static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.15f };
- static float light[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
- float a = inData[0];
- int i = 0;
- for (i = 0; i < 4; i++)
- outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-static void TrackGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
- static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.678f };
- static float light[4] = { 0.0f, 0.0f, 0.0f, 0.13f };
- float a = inData[0];
- int i = 0;
- for (i = 0; i < 4; i++)
- outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- if (r.isEmpty())
- return;
-
- CGContextRef context = paintInfo.context->platformContext();
-
- paintInfo.context->save();
-
- IntSize topLeftRadius;
- IntSize topRightRadius;
- IntSize bottomLeftRadius;
- IntSize bottomRightRadius;
-
- o->style()->getBorderRadiiForRect(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
-
- int radius = topLeftRadius.width();
-
- RetainPtr<CGColorSpaceRef> cspace(AdoptCF, CGColorSpaceCreateDeviceRGB());
-
- FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f);
- struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL };
- RetainPtr<CGFunctionRef> topFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks));
- RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.bottom()), topFunction.get(), false, false));
-
- FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f);
- struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL };
- RetainPtr<CGFunctionRef> bottomFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks));
- RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(bottomGradient.x(), bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.bottom()), bottomFunction.get(), false, false));
-
- struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL };
- RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
- RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.x(), r.y()), CGPointMake(r.x(), r.bottom()), mainFunction.get(), false, false));
-
- RetainPtr<CGShadingRef> leftShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.x(), r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false));
-
- RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.right(), r.y()), CGPointMake(r.right() - radius, r.y()), mainFunction.get(), false, false));
- paintInfo.context->save();
- CGContextClipToRect(context, r);
- paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
- CGContextDrawShading(context, mainShading.get());
- paintInfo.context->restore();
-
- paintInfo.context->save();
- CGContextClipToRect(context, topGradient);
- paintInfo.context->addRoundedRectClip(enclosingIntRect(topGradient), topLeftRadius, topRightRadius, IntSize(), IntSize());
- CGContextDrawShading(context, topShading.get());
- paintInfo.context->restore();
-
- if (!bottomGradient.isEmpty()) {
- paintInfo.context->save();
- CGContextClipToRect(context, bottomGradient);
- paintInfo.context->addRoundedRectClip(enclosingIntRect(bottomGradient), IntSize(), IntSize(), bottomLeftRadius, bottomRightRadius);
- CGContextDrawShading(context, bottomShading.get());
- paintInfo.context->restore();
- }
-
- paintInfo.context->save();
- CGContextClipToRect(context, r);
- paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
- CGContextDrawShading(context, leftShading.get());
- CGContextDrawShading(context, rightShading.get());
- paintInfo.context->restore();
-
- paintInfo.context->restore();
-}
-
-bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(),
- r.y() + o->style()->borderTopWidth(),
- r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(),
- r.height() - o->style()->borderTopWidth() - o->style()->borderBottomWidth());
- // Draw the gradients to give the styled popup menu a button appearance
- paintMenuListButtonGradients(o, paintInfo, bounds);
-
- // Since we actually know the size of the control here, we restrict the font scale to make sure the arrows will fit vertically in the bounds
- float fontScale = min(o->style()->fontSize() / baseFontSize, bounds.height() / (baseArrowHeight * 2 + baseSpaceBetweenArrows));
- float centerY = bounds.y() + bounds.height() / 2.0f;
- float arrowHeight = baseArrowHeight * fontScale;
- float arrowWidth = baseArrowWidth * fontScale;
- float leftEdge = bounds.right() - arrowPaddingRight * o->style()->effectiveZoom() - arrowWidth;
- float spaceBetweenArrows = baseSpaceBetweenArrows * fontScale;
-
- if (bounds.width() < arrowWidth + arrowPaddingLeft * o->style()->effectiveZoom())
- return false;
-
- paintInfo.context->save();
-
- paintInfo.context->setFillColor(o->style()->color(), o->style()->colorSpace());
- paintInfo.context->setStrokeStyle(NoStroke);
-
- FloatPoint arrow1[3];
- arrow1[0] = FloatPoint(leftEdge, centerY - spaceBetweenArrows / 2.0f);
- arrow1[1] = FloatPoint(leftEdge + arrowWidth, centerY - spaceBetweenArrows / 2.0f);
- arrow1[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY - spaceBetweenArrows / 2.0f - arrowHeight);
-
- // Draw the top arrow
- paintInfo.context->drawConvexPolygon(3, arrow1, true);
-
- FloatPoint arrow2[3];
- arrow2[0] = FloatPoint(leftEdge, centerY + spaceBetweenArrows / 2.0f);
- arrow2[1] = FloatPoint(leftEdge + arrowWidth, centerY + spaceBetweenArrows / 2.0f);
- arrow2[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY + spaceBetweenArrows / 2.0f + arrowHeight);
-
- // Draw the bottom arrow
- paintInfo.context->drawConvexPolygon(3, arrow2, true);
-
- Color leftSeparatorColor(0, 0, 0, 40);
- Color rightSeparatorColor(255, 255, 255, 40);
-
- // FIXME: Should the separator thickness and space be scaled up by fontScale?
- int separatorSpace = 2; // Deliberately ignores zoom since it looks nicer if it stays thin.
- int leftEdgeOfSeparator = static_cast<int>(leftEdge - arrowPaddingLeft * o->style()->effectiveZoom()); // FIXME: Round?
-
- // Draw the separator to the left of the arrows
- paintInfo.context->setStrokeThickness(1.0f); // Deliberately ignores zoom since it looks nicer if it stays thin.
- paintInfo.context->setStrokeStyle(SolidStroke);
- paintInfo.context->setStrokeColor(leftSeparatorColor, DeviceColorSpace);
- paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
- IntPoint(leftEdgeOfSeparator, bounds.bottom()));
-
- paintInfo.context->setStrokeColor(rightSeparatorColor, DeviceColorSpace);
- paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
- IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom()));
-
- paintInfo.context->restore();
- return false;
-}
-
-static const IntSize* menuListButtonSizes()
-{
- static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
- return sizes;
-}
-
-void RenderThemeChromiumMac::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
-{
- NSControlSize controlSize = controlSizeForFont(style);
-
- style->resetBorder();
- style->resetPadding();
-
- // Height is locked to auto.
- style->setHeight(Length(Auto));
-
- // White-space is locked to pre
- style->setWhiteSpace(PRE);
-
- // Set the foreground color to black or gray when we have the aqua look.
- // Cast to RGB32 is to work around a compiler bug.
- style->setColor(e && e->isEnabledFormControl() ? static_cast<RGBA32>(Color::black) : Color::darkGray);
-
- // Set the button's vertical size.
- setSizeFromFont(style, menuListButtonSizes());
-
- // Our font is locked to the appropriate system font size for the control. To clarify, we first use the CSS-specified font to figure out
- // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate
- // system font for the control size instead.
- setFontFromControlSize(selector, style, controlSize);
-
- style->setBoxShadow(0);
-}
-
-int RenderThemeChromiumMac::popupInternalPaddingLeft(RenderStyle* style) const
-{
- if (style->appearance() == MenulistPart)
- return popupButtonPadding(controlSizeForFont(style))[leftPadding] * style->effectiveZoom();
- if (style->appearance() == MenulistButtonPart)
- return styledPopupPaddingLeft * style->effectiveZoom();
- return 0;
-}
-
-int RenderThemeChromiumMac::popupInternalPaddingRight(RenderStyle* style) const
-{
- if (style->appearance() == MenulistPart)
- return popupButtonPadding(controlSizeForFont(style))[rightPadding] * style->effectiveZoom();
- if (style->appearance() == MenulistButtonPart) {
- float fontScale = style->fontSize() / baseFontSize;
- float arrowWidth = baseArrowWidth * fontScale;
- return static_cast<int>(ceilf(arrowWidth + (arrowPaddingLeft + arrowPaddingRight + paddingBeforeSeparator) * style->effectiveZoom()));
- }
- return 0;
-}
-
-int RenderThemeChromiumMac::popupInternalPaddingTop(RenderStyle* style) const
-{
- if (style->appearance() == MenulistPart)
- return popupButtonPadding(controlSizeForFont(style))[topPadding] * style->effectiveZoom();
- if (style->appearance() == MenulistButtonPart)
- return styledPopupPaddingTop * style->effectiveZoom();
- return 0;
-}
-
-int RenderThemeChromiumMac::popupInternalPaddingBottom(RenderStyle* style) const
-{
- if (style->appearance() == MenulistPart)
- return popupButtonPadding(controlSizeForFont(style))[bottomPadding] * style->effectiveZoom();
- if (style->appearance() == MenulistButtonPart)
- return styledPopupPaddingBottom * style->effectiveZoom();
- return 0;
-}
-
-void RenderThemeChromiumMac::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
-{
- float fontScale = style->fontSize() / baseFontSize;
-
- style->resetPadding();
- style->setBorderRadius(IntSize(int(baseBorderRadius + fontScale - 1), int(baseBorderRadius + fontScale - 1))); // FIXME: Round up?
-
- const int minHeight = 15;
- style->setMinHeight(Length(minHeight, Fixed));
-
- style->setLineHeight(RenderStyle::initialLineHeight());
-}
-
-void RenderThemeChromiumMac::setPopupButtonCellState(const RenderObject* o, const IntRect& r)
-{
- NSPopUpButtonCell* popupButton = this->popupButton();
-
- // Set the control size based off the rectangle we're painting into.
- setControlSize(popupButton, popupButtonSizes(), r.size(), o->style()->effectiveZoom());
-
- // Update the various states we respond to.
- updateActiveState(popupButton, o);
- updateCheckedState(popupButton, o);
- updateEnabledState(popupButton, o);
- updatePressedState(popupButton, o);
- updateFocusedState(popupButton, o);
-}
-
-const IntSize* RenderThemeChromiumMac::menuListSizes() const
-{
- static const IntSize sizes[3] = { IntSize(9, 0), IntSize(5, 0), IntSize(0, 0) };
- return sizes;
-}
-
-int RenderThemeChromiumMac::minimumMenuListSize(RenderStyle* style) const
-{
- return sizeForSystemFont(style, menuListSizes()).width();
-}
-
-const int trackWidth = 5;
-const int trackRadius = 2;
-
-void RenderThemeChromiumMac::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
-{
- style->setBoxShadow(0);
-}
-
-bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- IntRect bounds = r;
- float zoomLevel = o->style()->effectiveZoom();
- float zoomedTrackWidth = trackWidth * zoomLevel;
-
- if (o->style()->appearance() == SliderHorizontalPart || o->style()->appearance() == MediaSliderPart) {
- bounds.setHeight(zoomedTrackWidth);
- bounds.setY(r.y() + r.height() / 2 - zoomedTrackWidth / 2);
- } else if (o->style()->appearance() == SliderVerticalPart) {
- bounds.setWidth(zoomedTrackWidth);
- bounds.setX(r.x() + r.width() / 2 - zoomedTrackWidth / 2);
- }
-
- LocalCurrentGraphicsContext localContext(paintInfo.context);
- CGContextRef context = paintInfo.context->platformContext();
- RetainPtr<CGColorSpaceRef> cspace(AdoptCF, CGColorSpaceCreateDeviceRGB());
-
- paintInfo.context->save();
- CGContextClipToRect(context, bounds);
-
- struct CGFunctionCallbacks mainCallbacks = { 0, TrackGradientInterpolate, NULL };
- RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
- RetainPtr<CGShadingRef> mainShading;
- if (o->style()->appearance() == SliderVerticalPart)
- mainShading.adoptCF(CGShadingCreateAxial(cspace.get(), CGPointMake(bounds.x(), bounds.bottom()), CGPointMake(bounds.right(), bounds.bottom()), mainFunction.get(), false, false));
- else
- mainShading.adoptCF(CGShadingCreateAxial(cspace.get(), CGPointMake(bounds.x(), bounds.y()), CGPointMake(bounds.x(), bounds.bottom()), mainFunction.get(), false, false));
-
- IntSize radius(trackRadius, trackRadius);
- paintInfo.context->addRoundedRectClip(bounds,
- radius, radius,
- radius, radius);
- CGContextDrawShading(context, mainShading.get());
- paintInfo.context->restore();
-
- return false;
-}
-
-void RenderThemeChromiumMac::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
-{
- style->setBoxShadow(0);
-}
-
-const float verticalSliderHeightPadding = 0.1f;
-
-bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- ASSERT(o->parent()->isSlider());
-
- NSSliderCell* sliderThumbCell = o->style()->appearance() == SliderThumbVerticalPart
- ? sliderThumbVertical()
- : sliderThumbHorizontal();
-
- LocalCurrentGraphicsContext localContext(paintInfo.context);
-
- // Update the various states we respond to.
- updateActiveState(sliderThumbCell, o->parent());
- updateEnabledState(sliderThumbCell, o->parent());
- updateFocusedState(sliderThumbCell, o->parent());
-
- // Update the pressed state using the NSCell tracking methods, since that's how NSSliderCell keeps track of it.
- bool oldPressed;
- if (o->style()->appearance() == SliderThumbVerticalPart)
- oldPressed = m_isSliderThumbVerticalPressed;
- else
- oldPressed = m_isSliderThumbHorizontalPressed;
-
- bool pressed = toRenderSlider(o->parent())->inDragMode();
-
- if (o->style()->appearance() == SliderThumbVerticalPart)
- m_isSliderThumbVerticalPressed = pressed;
- else
- m_isSliderThumbHorizontalPressed = pressed;
-
- if (pressed != oldPressed) {
- if (pressed)
- [sliderThumbCell startTrackingAt:NSPoint() inView:nil];
- else
- [sliderThumbCell stopTracking:NSPoint() at:NSPoint() inView:nil mouseIsUp:YES];
- }
-
- FloatRect bounds = r;
- // Make the height of the vertical slider slightly larger so NSSliderCell will draw a vertical slider.
- if (o->style()->appearance() == SliderThumbVerticalPart)
- bounds.setHeight(bounds.height() + verticalSliderHeightPadding * o->style()->effectiveZoom());
-
- paintInfo.context->save();
- float zoomLevel = o->style()->effectiveZoom();
-
- FloatRect unzoomedRect = bounds;
- if (zoomLevel != 1.0f) {
- unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
- unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
- paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
- paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
- }
-
- [sliderThumbCell drawWithFrame:unzoomedRect inView:FlippedView()];
- [sliderThumbCell setControlView:nil];
-
- paintInfo.context->restore();
-
- return false;
-}
-
-bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- NSSearchFieldCell* search = this->search();
- LocalCurrentGraphicsContext localContext(paintInfo.context);
-
- setSearchCellState(o, r);
-
- paintInfo.context->save();
-
- float zoomLevel = o->style()->effectiveZoom();
-
- IntRect unzoomedRect = r;
-
- if (zoomLevel != 1.0f) {
- unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
- unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
- paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
- paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
- }
-
- // Set the search button to nil before drawing. Then reset it so we can draw it later.
- [search setSearchButtonCell:nil];
-
- [search drawWithFrame:NSRect(unzoomedRect) inView:FlippedView()];
-#ifdef BUILDING_ON_TIGER
- if ([search showsFirstResponder])
- wkDrawTextFieldCellFocusRing(search, NSRect(unzoomedRect));
-#endif
-
- [search setControlView:nil];
- [search resetSearchButtonCell];
-
- paintInfo.context->restore();
-
- return false;
-}
-
-void RenderThemeChromiumMac::setSearchCellState(RenderObject* o, const IntRect&)
-{
- NSSearchFieldCell* search = this->search();
-
- [search setControlSize:controlSizeForFont(o->style())];
-
- // Update the various states we respond to.
- updateActiveState(search, o);
- updateEnabledState(search, o);
- updateFocusedState(search, o);
-}
-
-const IntSize* RenderThemeChromiumMac::searchFieldSizes() const
-{
- static const IntSize sizes[3] = { IntSize(0, 22), IntSize(0, 19), IntSize(0, 17) };
- return sizes;
-}
-
-void RenderThemeChromiumMac::setSearchFieldSize(RenderStyle* style) const
-{
- // If the width and height are both specified, then we have nothing to do.
- if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
- return;
-
- // Use the font size to determine the intrinsic width of the control.
- setSizeFromFont(style, searchFieldSizes());
-}
-
-void RenderThemeChromiumMac::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element*) const
-{
- // Override border.
- style->resetBorder();
- const short borderWidth = 2 * style->effectiveZoom();
- style->setBorderLeftWidth(borderWidth);
- style->setBorderLeftStyle(INSET);
- style->setBorderRightWidth(borderWidth);
- style->setBorderRightStyle(INSET);
- style->setBorderBottomWidth(borderWidth);
- style->setBorderBottomStyle(INSET);
- style->setBorderTopWidth(borderWidth);
- style->setBorderTopStyle(INSET);
-
- // Override height.
- style->setHeight(Length(Auto));
- setSearchFieldSize(style);
-
- // Override padding size to match AppKit text positioning.
- const int padding = 1 * style->effectiveZoom();
- style->setPaddingLeft(Length(padding, Fixed));
- style->setPaddingRight(Length(padding, Fixed));
- style->setPaddingTop(Length(padding, Fixed));
- style->setPaddingBottom(Length(padding, Fixed));
-
- NSControlSize controlSize = controlSizeForFont(style);
- setFontFromControlSize(selector, style, controlSize);
-
- style->setBoxShadow(0);
-}
-
-bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- Node* input = o->node()->shadowAncestorNode();
- if (!input->renderer()->isBox())
- return false;
-
- setSearchCellState(input->renderer(), r);
-
- NSSearchFieldCell* search = this->search();
-
- updateActiveState([search cancelButtonCell], o);
- updatePressedState([search cancelButtonCell], o);
-
- paintInfo.context->save();
-
- float zoomLevel = o->style()->effectiveZoom();
-
- FloatRect localBounds = [search cancelButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())];
- localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r);
-
- FloatRect unzoomedRect(localBounds);
- if (zoomLevel != 1.0f) {
- unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
- unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
- paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
- paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
- }
-
- [[search cancelButtonCell] drawWithFrame:unzoomedRect inView:FlippedView()];
- [[search cancelButtonCell] setControlView:nil];
-
- paintInfo.context->restore();
- return false;
-}
-
-const IntSize* RenderThemeChromiumMac::cancelButtonSizes() const
-{
- static const IntSize sizes[3] = { IntSize(16, 13), IntSize(13, 11), IntSize(13, 9) };
- return sizes;
-}
-
-void RenderThemeChromiumMac::adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
-{
- IntSize size = sizeForSystemFont(style, cancelButtonSizes());
- style->setWidth(Length(size.width(), Fixed));
- style->setHeight(Length(size.height(), Fixed));
- style->setBoxShadow(0);
-}
-
-const IntSize* RenderThemeChromiumMac::resultsButtonSizes() const
-{
- static const IntSize sizes[3] = { IntSize(19, 13), IntSize(17, 11), IntSize(17, 9) };
- return sizes;
-}
-
-const int emptyResultsOffset = 9;
-void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
-{
- IntSize size = sizeForSystemFont(style, resultsButtonSizes());
- style->setWidth(Length(size.width() - emptyResultsOffset, Fixed));
- style->setHeight(Length(size.height(), Fixed));
- style->setBoxShadow(0);
-}
-
-bool RenderThemeChromiumMac::paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&)
-{
- return false;
-}
-
-void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
-{
- IntSize size = sizeForSystemFont(style, resultsButtonSizes());
- style->setWidth(Length(size.width(), Fixed));
- style->setHeight(Length(size.height(), Fixed));
- style->setBoxShadow(0);
-}
-
-bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- Node* input = o->node()->shadowAncestorNode();
- if (!input->renderer()->isBox())
- return false;
-
- setSearchCellState(input->renderer(), r);
-
- NSSearchFieldCell* search = this->search();
-
- updateActiveState([search searchButtonCell], o);
-
- if ([search searchMenuTemplate] != nil)
- [search setSearchMenuTemplate:nil];
-
- FloatRect localBounds = [search searchButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())];
- localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r);
-
- [[search searchButtonCell] drawWithFrame:localBounds inView:FlippedView()];
- [[search searchButtonCell] setControlView:nil];
- return false;
-}
-
-const int resultsArrowWidth = 5;
-void RenderThemeChromiumMac::adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
-{
- IntSize size = sizeForSystemFont(style, resultsButtonSizes());
- style->setWidth(Length(size.width() + resultsArrowWidth, Fixed));
- style->setHeight(Length(size.height(), Fixed));
- style->setBoxShadow(0);
-}
-
-bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
-{
- Node* input = o->node()->shadowAncestorNode();
- if (!input->renderer()->isBox())
- return false;
-
- setSearchCellState(input->renderer(), r);
-
- NSSearchFieldCell* search = this->search();
-
- updateActiveState([search searchButtonCell], o);
-
- if (![search searchMenuTemplate])
- [search setSearchMenuTemplate:searchMenuTemplate()];
-
- paintInfo.context->save();
-
- float zoomLevel = o->style()->effectiveZoom();
-
- FloatRect localBounds = [search searchButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())];
- localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r);
-
- IntRect unzoomedRect(localBounds);
- if (zoomLevel != 1.0f) {
- unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
- unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
- paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
- paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
- }
-
- [[search searchButtonCell] drawWithFrame:unzoomedRect inView:FlippedView()];
- [[search searchButtonCell] setControlView:nil];
-
- paintInfo.context->restore();
-
- return false;
-}
-
-const int sliderThumbWidth = 15;
-const int sliderThumbHeight = 15;
+#if ENABLE(VIDEO)
-void RenderThemeChromiumMac::adjustSliderThumbSize(RenderObject* o) const
+void RenderThemeChromiumMac::adjustMediaSliderThumbSize(RenderObject* o) const
{
- float zoomLevel = o->style()->effectiveZoom();
- if (o->style()->appearance() == SliderThumbHorizontalPart || o->style()->appearance() == SliderThumbVerticalPart) {
- o->style()->setWidth(Length(static_cast<int>(sliderThumbWidth * zoomLevel), Fixed));
- o->style()->setHeight(Length(static_cast<int>(sliderThumbHeight * zoomLevel), Fixed));
- }
-
-#if ENABLE(VIDEO)
RenderMediaControlsChromium::adjustMediaSliderThumbSize(o);
-#endif
}
-#if ENABLE(VIDEO)
bool RenderThemeChromiumMac::shouldRenderMediaControlPart(ControlPart part, Element* e)
{
return RenderMediaControlsChromium::shouldRenderMediaControlPart(part, e);
@@ -1535,21 +124,6 @@ bool RenderThemeChromiumMac::paintMediaSliderTrack(RenderObject* object, const R
return RenderMediaControlsChromium::paintMediaControlsPart(MediaSlider, object, paintInfo, rect);
}
-bool RenderThemeChromiumMac::paintMediaVolumeSliderTrack(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
-{
- return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSlider, object, paintInfo, rect);
-}
-
-bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
-{
- return RenderMediaControlsChromium::paintMediaControlsPart(MediaSliderThumb, object, paintInfo, rect);
-}
-
-bool RenderThemeChromiumMac::paintMediaVolumeSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
-{
- return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSliderThumb, object, paintInfo, rect);
-}
-
bool RenderThemeChromiumMac::paintMediaControlsBackground(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
return RenderMediaControlsChromium::paintMediaControlsPart(MediaTimelineContainer, object, paintInfo, rect);
@@ -1560,64 +134,16 @@ String RenderThemeChromiumMac::extraMediaControlsStyleSheet()
return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet));
}
-#endif
-
-NSPopUpButtonCell* RenderThemeChromiumMac::popupButton() const
-{
- if (!m_popupButton) {
- m_popupButton.adoptNS([[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]);
- [m_popupButton.get() setUsesItemFromMenu:NO];
- [m_popupButton.get() setFocusRingType:NSFocusRingTypeExterior];
- }
-
- return m_popupButton.get();
-}
-
-NSSearchFieldCell* RenderThemeChromiumMac::search() const
-{
- if (!m_search) {
- m_search.adoptNS([[NSSearchFieldCell alloc] initTextCell:@""]);
- [m_search.get() setBezelStyle:NSTextFieldRoundedBezel];
- [m_search.get() setBezeled:YES];
- [m_search.get() setEditable:YES];
- [m_search.get() setFocusRingType:NSFocusRingTypeExterior];
- }
-
- return m_search.get();
-}
-
-NSMenu* RenderThemeChromiumMac::searchMenuTemplate() const
+bool RenderThemeChromiumMac::paintMediaVolumeSliderTrack(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
- if (!m_searchMenuTemplate)
- m_searchMenuTemplate.adoptNS([[NSMenu alloc] initWithTitle:@""]);
-
- return m_searchMenuTemplate.get();
+ return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSlider, object, paintInfo, rect);
}
-NSSliderCell* RenderThemeChromiumMac::sliderThumbHorizontal() const
+bool RenderThemeChromiumMac::paintMediaVolumeSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
- if (!m_sliderThumbHorizontal) {
- m_sliderThumbHorizontal.adoptNS([[NSSliderCell alloc] init]);
- [m_sliderThumbHorizontal.get() setTitle:nil];
- [m_sliderThumbHorizontal.get() setSliderType:NSLinearSlider];
- [m_sliderThumbHorizontal.get() setControlSize:NSSmallControlSize];
- [m_sliderThumbHorizontal.get() setFocusRingType:NSFocusRingTypeExterior];
- }
-
- return m_sliderThumbHorizontal.get();
+ return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSliderThumb, object, paintInfo, rect);
}
-NSSliderCell* RenderThemeChromiumMac::sliderThumbVertical() const
-{
- if (!m_sliderThumbVertical) {
- m_sliderThumbVertical.adoptNS([[NSSliderCell alloc] init]);
- [m_sliderThumbVertical.get() setTitle:nil];
- [m_sliderThumbVertical.get() setSliderType:NSLinearSlider];
- [m_sliderThumbVertical.get() setControlSize:NSSmallControlSize];
- [m_sliderThumbVertical.get() setFocusRingType:NSFocusRingTypeExterior];
- }
-
- return m_sliderThumbVertical.get();
-}
+#endif
} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeMac.h b/WebCore/rendering/RenderThemeMac.h
index cba927f..cb604b9 100644
--- a/WebCore/rendering/RenderThemeMac.h
+++ b/WebCore/rendering/RenderThemeMac.h
@@ -88,8 +88,14 @@ public:
#endif
virtual Color systemColor(int cssValueId) const;
-
+ // Controls color values returned from platformFocusRingColor(). systemColor() will be used when false.
+ virtual bool usesTestModeFocusRingColor() const;
+ // A view associated to the contained document. Subclasses may not have such a view and return a fake.
+ virtual NSView* documentViewFor(RenderObject*) const;
protected:
+ RenderThemeMac();
+ virtual ~RenderThemeMac();
+
virtual bool supportsSelectionForegroundColors() const { return false; }
virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
@@ -149,11 +155,10 @@ protected:
virtual String extraMediaControlsStyleSheet();
virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
+ virtual void adjustMediaSliderThumbSize(RenderObject*) const;
#endif
private:
- RenderThemeMac();
- virtual ~RenderThemeMac();
IntRect inflateRect(const IntRect&, const IntSize&, const int* margins, float zoomLevel = 1.0f) const;
@@ -172,6 +177,8 @@ private:
void updateEnabledState(NSCell*, const RenderObject*);
void updateFocusedState(NSCell*, const RenderObject*);
void updatePressedState(NSCell*, const RenderObject*);
+ // An optional hook for subclasses to update the control tint of NSCell.
+ virtual void updateActiveState(NSCell*, const RenderObject*) {}
// Helpers for adjusting appearance and for painting
diff --git a/WebCore/rendering/RenderThemeMac.mm b/WebCore/rendering/RenderThemeMac.mm
index c0d8020..d1a3965 100644
--- a/WebCore/rendering/RenderThemeMac.mm
+++ b/WebCore/rendering/RenderThemeMac.mm
@@ -115,11 +115,13 @@ enum {
leftPadding
};
+#if PLATFORM(MAC)
PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page*)
{
static RenderTheme* rt = RenderThemeMac::create().releaseRef();
return rt;
}
+#endif
PassRefPtr<RenderTheme> RenderThemeMac::create()
{
@@ -458,6 +460,21 @@ Color RenderThemeMac::systemColor(int cssValueId) const
return color;
}
+bool RenderThemeMac::usesTestModeFocusRingColor() const
+{
+ return WebCore::usesTestModeFocusRingColor();
+}
+
+NSView* RenderThemeMac::documentViewFor(RenderObject* o) const
+{
+#if PLATFORM(MAC)
+ return ThemeMac::ensuredView(o->view()->frameView());
+#else
+ ASSERT_NOT_REACHED();
+ return 0;
+#endif
+}
+
bool RenderThemeMac::isControlStyled(const RenderStyle* style, const BorderData& border,
const FillLayer& background, const Color& backgroundColor) const
{
@@ -487,6 +504,7 @@ void RenderThemeMac::adjustRepaintRect(const RenderObject* o, IntRect& r)
case ListButtonPart:
case DefaultButtonPart:
case ButtonPart:
+ case OuterSpinButtonPart:
return RenderTheme::adjustRepaintRect(o, r);
default:
break;
@@ -776,7 +794,7 @@ bool RenderThemeMac::paintMenuList(RenderObject* o, const RenderObject::PaintInf
paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y());
}
- [popupButton drawWithFrame:inflatedRect inView:ThemeMac::ensuredView(o->view()->frameView())];
+ [popupButton drawWithFrame:inflatedRect inView:documentViewFor(o)];
[popupButton setControlView:nil];
paintInfo.context->restore();
@@ -1111,6 +1129,7 @@ void RenderThemeMac::setPopupButtonCellState(const RenderObject* o, const IntRec
setControlSize(popupButton, popupButtonSizes(), r.size(), o->style()->effectiveZoom());
// Update the various states we respond to.
+ updateActiveState(popupButton, o);
updateCheckedState(popupButton, o);
updateEnabledState(popupButton, o);
updatePressedState(popupButton, o);
@@ -1193,6 +1212,7 @@ bool RenderThemeMac::paintSliderThumb(RenderObject* o, const RenderObject::Paint
LocalCurrentGraphicsContext localContext(paintInfo.context);
// Update the various states we respond to.
+ updateActiveState(sliderThumbCell, o->parent());
updateEnabledState(sliderThumbCell, o->parent());
updateFocusedState(sliderThumbCell, o->parent());
@@ -1234,7 +1254,7 @@ bool RenderThemeMac::paintSliderThumb(RenderObject* o, const RenderObject::Paint
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
- [sliderThumbCell drawWithFrame:unzoomedRect inView:ThemeMac::ensuredView(o->view()->frameView())];
+ [sliderThumbCell drawWithFrame:unzoomedRect inView:documentViewFor(o)];
[sliderThumbCell setControlView:nil];
paintInfo.context->restore();
@@ -1266,7 +1286,7 @@ bool RenderThemeMac::paintSearchField(RenderObject* o, const RenderObject::Paint
// Set the search button to nil before drawing. Then reset it so we can draw it later.
[search setSearchButtonCell:nil];
- [search drawWithFrame:NSRect(unzoomedRect) inView:ThemeMac::ensuredView(o->view()->frameView())];
+ [search drawWithFrame:NSRect(unzoomedRect) inView:documentViewFor(o)];
#ifdef BUILDING_ON_TIGER
if ([search showsFirstResponder])
wkDrawTextFieldCellFocusRing(search, NSRect(unzoomedRect));
@@ -1287,6 +1307,7 @@ void RenderThemeMac::setSearchCellState(RenderObject* o, const IntRect&)
[search setControlSize:controlSizeForFont(o->style())];
// Update the various states we respond to.
+ updateActiveState(search, o);
updateEnabledState(search, o);
updateFocusedState(search, o);
}
@@ -1348,6 +1369,7 @@ bool RenderThemeMac::paintSearchFieldCancelButton(RenderObject* o, const RenderO
NSSearchFieldCell* search = this->search();
+ updateActiveState([search cancelButtonCell], o);
updatePressedState([search cancelButtonCell], o);
paintInfo.context->save();
@@ -1366,7 +1388,7 @@ bool RenderThemeMac::paintSearchFieldCancelButton(RenderObject* o, const RenderO
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
- [[search cancelButtonCell] drawWithFrame:unzoomedRect inView:ThemeMac::ensuredView(o->view()->frameView())];
+ [[search cancelButtonCell] drawWithFrame:unzoomedRect inView:documentViewFor(o)];
[[search cancelButtonCell] setControlView:nil];
paintInfo.context->restore();
@@ -1428,10 +1450,12 @@ bool RenderThemeMac::paintSearchFieldResultsDecoration(RenderObject* o, const Re
if ([search searchMenuTemplate] != nil)
[search setSearchMenuTemplate:nil];
+ updateActiveState([search searchButtonCell], o);
+
FloatRect localBounds = [search searchButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())];
localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r);
- [[search searchButtonCell] drawWithFrame:localBounds inView:ThemeMac::ensuredView(o->view()->frameView())];
+ [[search searchButtonCell] drawWithFrame:localBounds inView:documentViewFor(o)];
[[search searchButtonCell] setControlView:nil];
return false;
}
@@ -1455,6 +1479,8 @@ bool RenderThemeMac::paintSearchFieldResultsButton(RenderObject* o, const Render
NSSearchFieldCell* search = this->search();
+ updateActiveState([search searchButtonCell], o);
+
if (![search searchMenuTemplate])
[search setSearchMenuTemplate:searchMenuTemplate()];
@@ -1474,7 +1500,7 @@ bool RenderThemeMac::paintSearchFieldResultsButton(RenderObject* o, const Render
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
- [[search searchButtonCell] drawWithFrame:unzoomedRect inView:ThemeMac::ensuredView(o->view()->frameView())];
+ [[search searchButtonCell] drawWithFrame:unzoomedRect inView:documentViewFor(o)];
[[search searchButtonCell] setControlView:nil];
paintInfo.context->restore();
@@ -1527,7 +1553,15 @@ void RenderThemeMac::adjustSliderThumbSize(RenderObject* o) const
}
#if ENABLE(VIDEO)
- else if (o->style()->appearance() == MediaSliderThumbPart) {
+ adjustMediaSliderThumbSize(o);
+#endif
+}
+
+#if ENABLE(VIDEO)
+
+void RenderThemeMac::adjustMediaSliderThumbSize(RenderObject* o) const
+{
+ if (o->style()->appearance() == MediaSliderThumbPart) {
int width = mediaSliderThumbWidth;
int height = mediaSliderThumbHeight;
@@ -1539,15 +1573,12 @@ void RenderThemeMac::adjustSliderThumbSize(RenderObject* o) const
height = size.height;
}
+ float zoomLevel = o->style()->effectiveZoom();
o->style()->setWidth(Length(static_cast<int>(width * zoomLevel), Fixed));
o->style()->setHeight(Length(static_cast<int>(height * zoomLevel), Fixed));
}
-#endif
}
-
-#if ENABLE(VIDEO)
-
enum WKMediaControllerThemeState {
MediaUIPartDisabledFlag = 1 << 0,
MediaUIPartPressedFlag = 1 << 1,
@@ -1759,10 +1790,15 @@ bool RenderThemeMac::paintMediaTimeRemaining(RenderObject* o, const RenderObject
String RenderThemeMac::extraMediaControlsStyleSheet()
{
+#if PLATFORM(MAC)
if (mediaControllerTheme() == MediaControllerThemeQuickTime)
return String(mediaControlsQuickTimeUserAgentStyleSheet, sizeof(mediaControlsQuickTimeUserAgentStyleSheet));
else
return String();
+#else
+ ASSERT_NOT_REACHED();
+ return String();
+#endif
}
bool RenderThemeMac::shouldRenderMediaControlPart(ControlPart part, Element* element)
diff --git a/WebCore/rendering/RenderTreeAsText.cpp b/WebCore/rendering/RenderTreeAsText.cpp
index 75c35ba..311854e 100644
--- a/WebCore/rendering/RenderTreeAsText.cpp
+++ b/WebCore/rendering/RenderTreeAsText.cpp
@@ -34,6 +34,7 @@
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "InlineTextBox.h"
+#include "PrintContext.h"
#include "RenderBR.h"
#include "RenderFileUploadControl.h"
#include "RenderInline.h"
@@ -51,6 +52,7 @@
#if ENABLE(SVG)
#include "RenderPath.h"
#include "RenderSVGContainer.h"
+#include "RenderSVGGradientStop.h"
#include "RenderSVGImage.h"
#include "RenderSVGInlineText.h"
#include "RenderSVGRoot.h"
@@ -396,8 +398,12 @@ void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavi
write(ts, *toRenderPath(&o), indent);
return;
}
- if (o.isSVGResource()) {
- writeSVGResource(ts, o, indent);
+ if (o.isSVGGradientStop()) {
+ writeSVGGradientStop(ts, *toRenderSVGGradientStop(&o), indent);
+ return;
+ }
+ if (o.isSVGResourceContainer()) {
+ writeSVGResourceContainer(ts, o, indent);
return;
}
if (o.isSVGContainer()) {
@@ -612,6 +618,13 @@ static void writeSelection(TextStream& ts, const RenderObject* o)
String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior)
{
+ PrintContext printContext(frame);
+ if (behavior & RenderAsTextPrintingMode) {
+ if (!frame->contentRenderer())
+ return String();
+ printContext.begin(frame->contentRenderer()->width());
+ }
+
frame->document()->updateLayout();
RenderObject* o = frame->contentRenderer();
@@ -619,9 +632,6 @@ String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior)
return String();
TextStream ts;
-#if ENABLE(SVG)
- writeRenderResources(ts, o->document());
-#endif
if (o->hasLayer()) {
RenderLayer* l = toRenderBox(o)->layer();
writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), 0, behavior);
diff --git a/WebCore/rendering/RenderTreeAsText.h b/WebCore/rendering/RenderTreeAsText.h
index 4da0bab..1427342 100644
--- a/WebCore/rendering/RenderTreeAsText.h
+++ b/WebCore/rendering/RenderTreeAsText.h
@@ -39,10 +39,12 @@ enum RenderAsTextBehaviorFlags {
RenderAsTextShowAllLayers = 1 << 0, // Dump all layers, not just those that would paint.
RenderAsTextShowLayerNesting = 1 << 1, // Annotate the layer lists.
RenderAsTextShowCompositedLayers = 1 << 2, // Show which layers are composited.
- RenderAsTextShowAddresses = 1 << 3 // Show layer and renderer addresses.
+ RenderAsTextShowAddresses = 1 << 3, // Show layer and renderer addresses.
+ RenderAsTextPrintingMode = 1 << 4 // Dump the tree in printing mode.
};
typedef unsigned RenderAsTextBehavior;
+// You don't need pageWidthInPixels if you don't specify RenderAsTextInPrintingMode.
String externalRepresentation(Frame*, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
void write(TextStream&, const RenderObject&, int indent = 0, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
diff --git a/WebCore/rendering/RenderVideo.cpp b/WebCore/rendering/RenderVideo.cpp
index ad25c22..610fb5f 100644
--- a/WebCore/rendering/RenderVideo.cpp
+++ b/WebCore/rendering/RenderVideo.cpp
@@ -50,7 +50,7 @@ using namespace HTMLNames;
RenderVideo::RenderVideo(HTMLVideoElement* video)
: RenderMedia(video)
{
- if (video->player())
+ if (video->player() && video->readyState() >= HTMLVideoElement::HAVE_METADATA)
setIntrinsicSize(video->player()->naturalSize());
else {
// When the natural size of the video is unavailable, we use the provided
@@ -101,7 +101,11 @@ void RenderVideo::videoSizeChanged()
if (!player())
return;
IntSize size = player()->naturalSize();
- if (!size.isEmpty() && size != intrinsicSize()) {
+ if (size.isEmpty()) {
+ if (node()->ownerDocument() && node()->ownerDocument()->isMediaDocument())
+ return;
+ }
+ if (size != intrinsicSize()) {
setIntrinsicSize(size);
setPrefWidthsDirty(true);
setNeedsLayout(true);
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index a95ffdd..449e293 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -747,16 +747,6 @@ bool RenderView::usesCompositing() const
return m_compositor && m_compositor->inCompositingMode();
}
-void RenderView::compositingStateChanged(bool)
-{
- Element* elt = document()->ownerElement();
- if (!elt)
- return;
-
- // Trigger a recalcStyle in the parent document, to update compositing in that document.
- elt->setNeedsStyleRecalc(SyntheticStyleChange);
-}
-
RenderLayerCompositor* RenderView::compositor()
{
if (!m_compositor)
diff --git a/WebCore/rendering/RenderView.h b/WebCore/rendering/RenderView.h
index 0751866..05c3876 100644
--- a/WebCore/rendering/RenderView.h
+++ b/WebCore/rendering/RenderView.h
@@ -166,7 +166,6 @@ public:
#if USE(ACCELERATED_COMPOSITING)
RenderLayerCompositor* compositor();
bool usesCompositing() const;
- void compositingStateChanged(bool nowComposited);
#endif
protected:
diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp
index 485baa3..15c75f1 100644
--- a/WebCore/rendering/RenderWidget.cpp
+++ b/WebCore/rendering/RenderWidget.cpp
@@ -320,8 +320,8 @@ void RenderWidget::updateWidgetPosition()
FloatPoint absPos = localToAbsolute();
absPos.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
- int w = width() - borderLeft() - borderRight() - paddingLeft() - paddingRight();
- int h = height() - borderTop() - borderBottom() - paddingTop() - paddingBottom();
+ int w = width() - borderAndPaddingWidth();
+ int h = height() - borderAndPaddingHeight();
bool boundsChanged = setWidgetGeometry(IntRect(absPos.x(), absPos.y(), w, h));
diff --git a/WebCore/rendering/SVGCharacterData.cpp b/WebCore/rendering/SVGCharacterData.cpp
new file mode 100644
index 0000000..394a303
--- /dev/null
+++ b/WebCore/rendering/SVGCharacterData.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 "SVGCharacterData.h"
+
+#if ENABLE(SVG)
+#include "AffineTransform.h"
+
+namespace WebCore {
+
+bool SVGChar::isHidden() const
+{
+ return pathData && pathData->hidden;
+}
+
+AffineTransform SVGChar::characterTransform() const
+{
+ AffineTransform ctm;
+
+ // Rotate character around angle, and possibly scale.
+ ctm.translate(x, y);
+ ctm.rotate(angle);
+
+ if (pathData) {
+ ctm.scaleNonUniform(pathData->xScale, pathData->yScale);
+ ctm.translate(pathData->xShift, pathData->yShift);
+ ctm.rotate(pathData->orientationAngle);
+ }
+
+ ctm.translate(orientationShiftX - x, orientationShiftY - y);
+ return ctm;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/SVGCharacterData.h b/WebCore/rendering/SVGCharacterData.h
new file mode 100644
index 0000000..68682c9
--- /dev/null
+++ b/WebCore/rendering/SVGCharacterData.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 SVGCharacterData_h
+#define SVGCharacterData_h
+
+#if ENABLE(SVG)
+#include <wtf/HashMap.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class AffineTransform;
+class RenderObject;
+
+// Holds extra data, when the character is laid out on a path
+struct SVGCharOnPath : RefCounted<SVGCharOnPath> {
+ static PassRefPtr<SVGCharOnPath> create() { return adoptRef(new SVGCharOnPath); }
+
+ float xScale;
+ float yScale;
+
+ float xShift;
+ float yShift;
+
+ float orientationAngle;
+
+ bool hidden : 1;
+
+private:
+ SVGCharOnPath()
+ : xScale(1.0f)
+ , yScale(1.0f)
+ , xShift(0.0f)
+ , yShift(0.0f)
+ , orientationAngle(0.0f)
+ , hidden(false)
+ {
+ }
+};
+
+struct SVGChar {
+ SVGChar()
+ : x(0.0f)
+ , y(0.0f)
+ , angle(0.0f)
+ , orientationShiftX(0.0f)
+ , orientationShiftY(0.0f)
+ , drawnSeperated(false)
+ , newTextChunk(false)
+ {
+ }
+
+ float x;
+ float y;
+ float angle;
+
+ float orientationShiftX;
+ float orientationShiftY;
+
+ RefPtr<SVGCharOnPath> pathData;
+
+ // Determines wheter this char needs to be drawn seperated
+ bool drawnSeperated : 1;
+
+ // Determines wheter this char starts a new chunk
+ bool newTextChunk : 1;
+
+ // Helper methods
+ bool isHidden() const;
+ AffineTransform characterTransform() const;
+};
+
+struct SVGTextDecorationInfo {
+ // ETextDecoration is meant to be used here
+ HashMap<int, RenderObject*> fillServerMap;
+ HashMap<int, RenderObject*> strokeServerMap;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif // SVGCharacterData_h
diff --git a/WebCore/rendering/SVGCharacterLayoutInfo.cpp b/WebCore/rendering/SVGCharacterLayoutInfo.cpp
index 7e85672..04f0067 100644
--- a/WebCore/rendering/SVGCharacterLayoutInfo.cpp
+++ b/WebCore/rendering/SVGCharacterLayoutInfo.cpp
@@ -1,6 +1,4 @@
/*
- * This file is part of the WebKit project.
- *
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
*
* This library is free software; you can redistribute it and/or
@@ -21,16 +19,16 @@
*/
#include "config.h"
-
-#if ENABLE(SVG)
#include "SVGCharacterLayoutInfo.h"
+#if ENABLE(SVG)
#include "InlineFlowBox.h"
#include "InlineTextBox.h"
+#include "RenderSVGTextPath.h"
+#include "SVGCharacterData.h"
#include "SVGLengthList.h"
#include "SVGNumberList.h"
#include "SVGTextPositioningElement.h"
-#include "RenderSVGTextPath.h"
#include <float.h>
@@ -161,6 +159,19 @@ float SVGCharacterLayoutInfo::baselineShiftValueNext() const
return baselineShiftStack.last();
}
+
+bool SVGCharacterLayoutInfo::isInitialLayout() const
+{
+ return xStack.isEmpty()
+ && yStack.isEmpty()
+ && dxStack.isEmpty()
+ && dyStack.isEmpty()
+ && angleStack.isEmpty()
+ && baselineShiftStack.isEmpty()
+ && curx == 0.0f
+ && cury == 0.0f;
+}
+
void SVGCharacterLayoutInfo::processedSingleCharacter()
{
xStackWalk();
@@ -249,7 +260,6 @@ bool SVGCharacterLayoutInfo::nextPathLayoutPointAndAngle(float glyphAdvance, flo
angle = layoutPath.normalAngleAtLength(offset, ok);
ASSERT(ok);
- // fprintf(stderr, "t: %f, x: %f, y: %f, angle: %f, glyphAdvance: %f\n", currentOffset, x, y, angle, glyphAdvance);
return true;
}
@@ -269,10 +279,7 @@ void SVGCharacterLayoutInfo::setInPathLayout(bool value)
void SVGCharacterLayoutInfo::addLayoutInformation(InlineFlowBox* flowBox, float textAnchorStartOffset)
{
- bool isInitialLayout = xStack.isEmpty() && yStack.isEmpty() &&
- dxStack.isEmpty() && dyStack.isEmpty() &&
- angleStack.isEmpty() && baselineShiftStack.isEmpty() &&
- curx == 0.0f && cury == 0.0f;
+ bool wasInitialLayout = isInitialLayout();
RenderSVGTextPath* textPath = toRenderSVGTextPath(flowBox->renderer());
Path path = textPath->layoutPath();
@@ -296,7 +303,7 @@ void SVGCharacterLayoutInfo::addLayoutInformation(InlineFlowBox* flowBox, float
// Only baseline-shift is handled through the normal layout system
addStackContent(BaselineShiftStack, baselineShift);
- if (isInitialLayout) {
+ if (wasInitialLayout) {
xStackChanged = false;
yStackChanged = false;
dxStackChanged = false;
@@ -308,11 +315,7 @@ void SVGCharacterLayoutInfo::addLayoutInformation(InlineFlowBox* flowBox, float
void SVGCharacterLayoutInfo::addLayoutInformation(SVGTextPositioningElement* element)
{
- bool isInitialLayout = xStack.isEmpty() && yStack.isEmpty() &&
- dxStack.isEmpty() && dyStack.isEmpty() &&
- angleStack.isEmpty() && baselineShiftStack.isEmpty() &&
- curx == 0.0f && cury == 0.0f;
-
+ bool wasInitialLayout = isInitialLayout();
float baselineShift = calculateBaselineShift(element->renderer());
addStackContent(XStack, element->x(), element);
@@ -322,7 +325,7 @@ void SVGCharacterLayoutInfo::addLayoutInformation(SVGTextPositioningElement* ele
addStackContent(AngleStack, element->rotate());
addStackContent(BaselineShiftStack, baselineShift);
- if (isInitialLayout) {
+ if (wasInitialLayout) {
xStackChanged = false;
yStackChanged = false;
dxStackChanged = false;
@@ -344,7 +347,7 @@ void SVGCharacterLayoutInfo::addStackContent(StackType type, SVGNumberList* list
ExceptionCode ec = 0;
for (unsigned i = 0; i < length; ++i) {
float value = list->getItem(i, ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
newLayoutInfo.append(value);
}
@@ -363,7 +366,7 @@ void SVGCharacterLayoutInfo::addStackContent(StackType type, SVGLengthList* list
ExceptionCode ec = 0;
for (unsigned i = 0; i < length; ++i) {
float value = list->getItem(i, ec).value(context);
- ASSERT(ec == 0);
+ ASSERT(!ec);
newLayoutInfo.append(value);
}
@@ -507,29 +510,6 @@ void SVGCharacterLayoutInfo::baselineShiftStackWalk()
}
}
-bool SVGChar::isHidden() const
-{
- return pathData && pathData->hidden;
-}
-
-AffineTransform SVGChar::characterTransform() const
-{
- AffineTransform ctm;
-
- // Rotate character around angle, and possibly scale.
- ctm.translate(x, y);
- ctm.rotate(angle);
-
- if (pathData) {
- ctm.scaleNonUniform(pathData->xScale, pathData->yScale);
- ctm.translate(pathData->xShift, pathData->yShift);
- ctm.rotate(pathData->orientationAngle);
- }
-
- ctm.translate(orientationShiftX - x, orientationShiftY - y);
- return ctm;
-}
-
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/SVGCharacterLayoutInfo.h b/WebCore/rendering/SVGCharacterLayoutInfo.h
index f0d1fa4..16fd740 100644
--- a/WebCore/rendering/SVGCharacterLayoutInfo.h
+++ b/WebCore/rendering/SVGCharacterLayoutInfo.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the WebKit project.
- *
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
*
* This library is free software; you can redistribute it and/or
@@ -24,21 +22,14 @@
#define SVGCharacterLayoutInfo_h
#if ENABLE(SVG)
-#include "AffineTransform.h"
-#include "SVGRenderStyle.h"
-#include "SVGTextContentElement.h"
-
+#include "Path.h"
#include <wtf/Assertions.h>
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
namespace WebCore {
-class InlineBox;
class InlineFlowBox;
-class SVGInlineTextBox;
+class SVGElement;
class SVGLengthList;
class SVGNumberList;
class SVGTextPositioningElement;
@@ -151,6 +142,8 @@ private:
void angleStackWalk();
void baselineShiftStackWalk();
+ bool isInitialLayout() const;
+
private:
bool xStackChanged : 1;
bool yStackChanged : 1;
@@ -174,211 +167,6 @@ private:
Vector<float> baselineShiftStack;
};
-// Holds extra data, when the character is laid out on a path
-struct SVGCharOnPath : RefCounted<SVGCharOnPath> {
- static PassRefPtr<SVGCharOnPath> create() { return adoptRef(new SVGCharOnPath); }
-
- float xScale;
- float yScale;
-
- float xShift;
- float yShift;
-
- float orientationAngle;
-
- bool hidden : 1;
-
-private:
- SVGCharOnPath()
- : xScale(1.0f)
- , yScale(1.0f)
- , xShift(0.0f)
- , yShift(0.0f)
- , orientationAngle(0.0f)
- , hidden(false)
- {
- }
-};
-
-struct SVGChar {
- SVGChar()
- : x(0.0f)
- , y(0.0f)
- , angle(0.0f)
- , orientationShiftX(0.0f)
- , orientationShiftY(0.0f)
- , pathData()
- , drawnSeperated(false)
- , newTextChunk(false)
- {
- }
-
- ~SVGChar()
- {
- }
-
- float x;
- float y;
- float angle;
-
- float orientationShiftX;
- float orientationShiftY;
-
- RefPtr<SVGCharOnPath> pathData;
-
- // Determines wheter this char needs to be drawn seperated
- bool drawnSeperated : 1;
-
- // Determines wheter this char starts a new chunk
- bool newTextChunk : 1;
-
- // Helper methods
- bool isHidden() const;
- AffineTransform characterTransform() const;
-};
-
-struct SVGInlineBoxCharacterRange {
- SVGInlineBoxCharacterRange()
- : startOffset(INT_MIN)
- , endOffset(INT_MIN)
- , box(0)
- {
- }
-
- bool isOpen() const { return (startOffset == endOffset) && (endOffset == INT_MIN); }
- bool isClosed() const { return startOffset != INT_MIN && endOffset != INT_MIN; }
-
- int startOffset;
- int endOffset;
-
- InlineBox* box;
-};
-
-// Convenience typedef
-typedef SVGTextContentElement::SVGLengthAdjustType ELengthAdjust;
-
-struct SVGTextChunk {
- SVGTextChunk()
- : anchor(TA_START)
- , textLength(0.0f)
- , lengthAdjust(SVGTextContentElement::LENGTHADJUST_SPACING)
- , ctm()
- , isVerticalText(false)
- , isTextPath(false)
- , start(0)
- , end(0)
- { }
-
- // text-anchor support
- ETextAnchor anchor;
-
- // textLength & lengthAdjust support
- float textLength;
- ELengthAdjust lengthAdjust;
- AffineTransform ctm;
-
- // status flags
- bool isVerticalText : 1;
- bool isTextPath : 1;
-
- // main chunk data
- Vector<SVGChar>::iterator start;
- Vector<SVGChar>::iterator end;
-
- Vector<SVGInlineBoxCharacterRange> boxes;
-};
-
-struct SVGTextChunkWalkerBase {
- virtual ~SVGTextChunkWalkerBase() { }
-
- virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
- const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end) = 0;
-
- // Followings methods are only used for painting text chunks
- virtual void start(InlineBox*) = 0;
- virtual void end(InlineBox*) = 0;
-};
-
-template<typename CallbackClass>
-struct SVGTextChunkWalker : public SVGTextChunkWalkerBase {
-public:
- typedef void (CallbackClass::*SVGTextChunkWalkerCallback)(SVGInlineTextBox* textBox,
- int startOffset,
- const AffineTransform& chunkCtm,
- const Vector<SVGChar>::iterator& start,
- const Vector<SVGChar>::iterator& end);
-
- // These callbacks are only used for painting!
- typedef void (CallbackClass::*SVGTextChunkStartCallback)(InlineBox* box);
- typedef void (CallbackClass::*SVGTextChunkEndCallback)(InlineBox* box);
-
- SVGTextChunkWalker(CallbackClass* object,
- SVGTextChunkWalkerCallback walker,
- SVGTextChunkStartCallback start = 0,
- SVGTextChunkEndCallback end = 0)
- : m_object(object)
- , m_walkerCallback(walker)
- , m_startCallback(start)
- , m_endCallback(end)
- {
- ASSERT(object);
- ASSERT(walker);
- }
-
- virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
- const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
- {
- (*m_object.*m_walkerCallback)(textBox, startOffset, chunkCtm, start, end);
- }
-
- // Followings methods are only used for painting text chunks
- virtual void start(InlineBox* box)
- {
- if (m_startCallback)
- (*m_object.*m_startCallback)(box);
- else
- ASSERT_NOT_REACHED();
- }
-
- virtual void end(InlineBox* box)
- {
- if (m_endCallback)
- (*m_object.*m_endCallback)(box);
- else
- ASSERT_NOT_REACHED();
- }
-
-private:
- CallbackClass* m_object;
- SVGTextChunkWalkerCallback m_walkerCallback;
- SVGTextChunkStartCallback m_startCallback;
- SVGTextChunkEndCallback m_endCallback;
-};
-
-struct SVGTextChunkLayoutInfo {
- SVGTextChunkLayoutInfo(Vector<SVGTextChunk>& textChunks)
- : assignChunkProperties(true)
- , handlingTextPath(false)
- , svgTextChunks(textChunks)
- , it(0)
- {
- }
-
- bool assignChunkProperties : 1;
- bool handlingTextPath : 1;
-
- Vector<SVGTextChunk>& svgTextChunks;
- Vector<SVGChar>::iterator it;
-
- SVGTextChunk chunk;
-};
-
-struct SVGTextDecorationInfo {
- // ETextDecoration is meant to be used here
- HashMap<int, RenderObject*> fillServerMap;
- HashMap<int, RenderObject*> strokeServerMap;
-};
-
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/SVGInlineTextBox.cpp b/WebCore/rendering/SVGInlineTextBox.cpp
index bda512f..8b35507 100644
--- a/WebCore/rendering/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/SVGInlineTextBox.cpp
@@ -30,7 +30,7 @@
#include "GraphicsContext.h"
#include "InlineFlowBox.h"
#include "Range.h"
-#include "SVGPaintServer.h"
+#include "RenderSVGResource.h"
#include "SVGRootInlineBox.h"
#include "Text.h"
@@ -418,10 +418,9 @@ void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int t
TextRun run = svgTextRunForInlineTextBox(chars, length, styleToUse, this, svgChar.x);
#if ENABLE(SVG_FONTS)
- // SVG Fonts need access to the paint server used to draw the current text chunk.
- // They need to be able to call renderPath() on a SVGPaintServer object.
- ASSERT(textPaintInfo.activePaintServer);
- run.setActivePaintServer(textPaintInfo.activePaintServer);
+ // SVG Fonts need access to the painting resource used to draw the current text chunk.
+ ASSERT(textPaintInfo.activePaintingResource);
+ run.setActivePaintingResource(textPaintInfo.activePaintingResource);
#endif
int selectionStart = 0;
@@ -569,18 +568,20 @@ void SVGInlineTextBox::paintDecoration(ETextDecoration decoration, GraphicsConte
if (isFilled) {
if (RenderObject* fillObject = info.fillServerMap.get(decoration)) {
- if (SVGPaintServer* fillPaintServer = SVGPaintServer::fillPaintServer(fillObject->style(), fillObject)) {
+ if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(fillObject, fillObject->style())) {
context->addPath(pathForDecoration(decoration, fillObject, tx, ty, width));
- fillPaintServer->draw(context, fillObject, ApplyToFillTargetType);
+ if (fillPaintingResource->applyResource(fillObject, fillObject->style(), context, ApplyToFillMode))
+ fillPaintingResource->postApplyResource(fillObject, context, ApplyToFillMode);
}
}
}
if (isStroked) {
if (RenderObject* strokeObject = info.strokeServerMap.get(decoration)) {
- if (SVGPaintServer* strokePaintServer = SVGPaintServer::strokePaintServer(strokeObject->style(), strokeObject)) {
+ if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(strokeObject, strokeObject->style())) {
context->addPath(pathForDecoration(decoration, strokeObject, tx, ty, width));
- strokePaintServer->draw(context, strokeObject, ApplyToStrokeTargetType);
+ if (strokePaintingResource->applyResource(strokeObject, strokeObject->style(), context, ApplyToStrokeMode))
+ strokePaintingResource->postApplyResource(strokeObject, context, ApplyToStrokeMode);
}
}
}
diff --git a/WebCore/rendering/SVGInlineTextBox.h b/WebCore/rendering/SVGInlineTextBox.h
index 596fdf3..c586ddd 100644
--- a/WebCore/rendering/SVGInlineTextBox.h
+++ b/WebCore/rendering/SVGInlineTextBox.h
@@ -24,6 +24,7 @@
#if ENABLE(SVG)
#include "InlineTextBox.h"
+#include "RenderSVGResource.h"
namespace WebCore {
@@ -42,9 +43,13 @@ namespace WebCore {
};
struct SVGTextPaintInfo {
- SVGTextPaintInfo() : activePaintServer(0), subphase(SVGTextPaintSubphaseBackground) {}
+ SVGTextPaintInfo()
+ : activePaintingResource(0)
+ , subphase(SVGTextPaintSubphaseBackground)
+ {
+ }
- SVGPaintServer* activePaintServer;
+ RenderSVGResource* activePaintingResource;
SVGTextPaintSubphase subphase;
};
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index dd67746..2600512 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -31,6 +31,7 @@
#include "AffineTransform.h"
#include "Document.h"
#include "ImageBuffer.h"
+#include "NodeRenderStyle.h"
#include "RenderObject.h"
#include "RenderSVGContainer.h"
#include "RenderSVGResource.h"
@@ -92,7 +93,7 @@ bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
- const RenderStyle* style = object->style();
+ RenderStyle* style = object->style();
ASSERT(style);
const SVGRenderStyle* svgStyle = style->svgStyle();
@@ -132,19 +133,19 @@ bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
#endif
if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, maskerId)) {
- if (!masker->applyResource(object, paintInfo.context))
+ if (!masker->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
return false;
} else if (!maskerId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, clipperId))
- clipper->applyResource(object, paintInfo.context);
+ clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode);
else if (!clipperId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);
#if ENABLE(FILTERS)
if (filter) {
- if (!filter->applyResource(object, paintInfo.context))
+ if (!filter->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
return false;
} else if (!filterId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
@@ -167,7 +168,7 @@ void SVGRenderBase::finishRenderSVGContent(RenderObject* object, RenderObject::P
#if ENABLE(FILTERS)
if (filter) {
- filter->postApplyResource(object, paintInfo.context);
+ filter->postApplyResource(object, paintInfo.context, ApplyToDefaultMode);
paintInfo.context = savedContext;
}
#endif
@@ -306,23 +307,57 @@ FloatRect SVGRenderBase::maskerBoundingBoxForRenderer(const RenderObject* object
return FloatRect();
}
+static inline void invalidatePaintingResource(SVGPaint* paint, RenderObject* object)
+{
+ ASSERT(paint);
+
+ SVGPaint::SVGPaintType paintType = paint->paintType();
+ if (paintType != SVGPaint::SVG_PAINTTYPE_URI && paintType != SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)
+ return;
+
+ AtomicString id(SVGURIReference::getTarget(paint->uri()));
+ if (RenderSVGResourceContainer* paintingResource = getRenderSVGResourceContainerById(object->document(), id))
+ paintingResource->invalidateClient(object);
+}
+
void deregisterFromResources(RenderObject* object)
{
- // We only have the renderer for masker and clipper at the moment.
- if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskerResource()))
+ ASSERT(object);
+ ASSERT(object->style());
+
+ Document* document = object->document();
+ ASSERT(document);
+
+ const SVGRenderStyle* svgStyle = object->style()->svgStyle();
+ ASSERT(svgStyle);
+
+ // Masker
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, svgStyle->maskerResource()))
masker->invalidateClient(object);
- if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object->document(), object->style()->svgStyle()->clipperResource()))
+
+ // Clipper
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, svgStyle->clipperResource()))
clipper->invalidateClient(object);
+
+ // Filter
#if ENABLE(FILTERS)
- if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object->document(), object->style()->svgStyle()->filterResource()))
+ if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, svgStyle->filterResource()))
filter->invalidateClient(object);
#endif
- if (RenderSVGResourceMarker* startMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(object->document(), object->style()->svgStyle()->markerStartResource()))
+
+ // Markers
+ if (RenderSVGResourceMarker* startMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(document, svgStyle->markerStartResource()))
startMarker->invalidateClient(object);
- if (RenderSVGResourceMarker* midMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(object->document(), object->style()->svgStyle()->markerMidResource()))
+ if (RenderSVGResourceMarker* midMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(document, svgStyle->markerMidResource()))
midMarker->invalidateClient(object);
- if (RenderSVGResourceMarker* endMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(object->document(), object->style()->svgStyle()->markerEndResource()))
+ if (RenderSVGResourceMarker* endMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(document, svgStyle->markerEndResource()))
endMarker->invalidateClient(object);
+
+ // Gradients/Patterns
+ if (svgStyle->hasFill())
+ invalidatePaintingResource(svgStyle->fillPaint(), object);
+ if (svgStyle->hasStroke())
+ invalidatePaintingResource(svgStyle->strokePaint(), object);
}
void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const AffineTransform& localToAncestorTransform)
@@ -334,6 +369,42 @@ void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const AffineT
paintInfo.rect = localToAncestorTransform.inverse().mapRect(paintInfo.rect);
}
+DashArray dashArrayFromRenderingStyle(const RenderStyle* style, RenderStyle* rootStyle)
+{
+ DashArray array;
+
+ CSSValueList* dashes = style->svgStyle()->strokeDashArray();
+ if (dashes) {
+ CSSPrimitiveValue* dash = 0;
+ unsigned long len = dashes->length();
+ for (unsigned long i = 0; i < len; i++) {
+ dash = static_cast<CSSPrimitiveValue*>(dashes->itemWithoutBoundsCheck(i));
+ if (!dash)
+ continue;
+
+ array.append((float) dash->computeLengthFloat(const_cast<RenderStyle*>(style), rootStyle));
+ }
+ }
+
+ return array;
+}
+
+void applyStrokeStyleToContext(GraphicsContext* context, const RenderStyle* style, const RenderObject* object)
+{
+ context->setStrokeThickness(SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeWidth(), 1.0f));
+ context->setLineCap(style->svgStyle()->capStyle());
+ context->setLineJoin(style->svgStyle()->joinStyle());
+ if (style->svgStyle()->joinStyle() == MiterJoin)
+ context->setMiterLimit(style->svgStyle()->strokeMiterLimit());
+
+ const DashArray& dashes = dashArrayFromRenderingStyle(object->style(), object->document()->documentElement()->renderStyle());
+ float dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0f);
+ if (dashes.isEmpty())
+ context->setStrokeStyle(SolidStroke);
+ else
+ context->setLineDash(dashes, dashOffset);
+}
+
const RenderObject* findTextRootObject(const RenderObject* start)
{
while (start && !start->isSVGText())
diff --git a/WebCore/rendering/SVGRenderSupport.h b/WebCore/rendering/SVGRenderSupport.h
index 4b59b71..b8a014a 100644
--- a/WebCore/rendering/SVGRenderSupport.h
+++ b/WebCore/rendering/SVGRenderSupport.h
@@ -25,6 +25,7 @@
#define SVGRenderBase_h
#if ENABLE(SVG)
+#include "DashArray.h"
#include "RenderObject.h"
#include "SVGElement.h"
#include "SVGStyledElement.h"
@@ -42,8 +43,6 @@ class SVGRenderBase {
public:
virtual ~SVGRenderBase();
- virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
-
// FIXME: These are only public for SVGRootInlineBox.
// It's unclear if these should be exposed or not. SVGRootInlineBox may
// pass the wrong RenderObject* and boundingBox to these functions.
@@ -56,8 +55,8 @@ public:
// Helper function determining wheter overflow is hidden
static bool isOverflowHidden(const RenderObject*);
+ // strokeBoundingBox() includes the marker boundaries for a RenderPath object
virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
- virtual FloatRect markerBoundingBox() const { return FloatRect(); }
// returns the bounding box of filter, clipper, marker and masker (or the empty rect if no filter) in local coordinates
FloatRect filterBoundingBoxForRenderer(const RenderObject*) const;
@@ -85,7 +84,11 @@ void renderSubtreeToImage(ImageBuffer*, RenderObject*);
void deregisterFromResources(RenderObject*);
void clampImageBufferSizeToViewport(FrameView*, IntSize& imageBufferSize);
+void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*);
+DashArray dashArrayFromRenderingStyle(const RenderStyle* style, RenderStyle* rootStyle);
+
const RenderObject* findTextRootObject(const RenderObject* start);
+
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index 0f1f15d..f6fbae2 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -34,26 +34,37 @@
#include "GraphicsTypes.h"
#include "HTMLNames.h"
#include "InlineTextBox.h"
+#include "LinearGradientAttributes.h"
#include "NodeRenderStyle.h"
#include "Path.h"
+#include "PatternAttributes.h"
+#include "RadialGradientAttributes.h"
#include "RenderImage.h"
#include "RenderPath.h"
#include "RenderSVGContainer.h"
+#include "RenderSVGGradientStop.h"
#include "RenderSVGInlineText.h"
#include "RenderSVGResourceClipper.h"
#include "RenderSVGResourceFilter.h"
+#include "RenderSVGResourceGradient.h"
+#include "RenderSVGResourceLinearGradient.h"
#include "RenderSVGResourceMarker.h"
#include "RenderSVGResourceMasker.h"
+#include "RenderSVGResourcePattern.h"
+#include "RenderSVGResourceRadialGradient.h"
+#include "RenderSVGResourceSolidColor.h"
#include "RenderSVGRoot.h"
#include "RenderSVGText.h"
#include "RenderTreeAsText.h"
#include "SVGCharacterLayoutInfo.h"
#include "SVGInlineTextBox.h"
-#include "SVGPaintServerGradient.h"
-#include "SVGPaintServerPattern.h"
-#include "SVGPaintServerSolid.h"
+#include "SVGLinearGradientElement.h"
+#include "SVGPatternElement.h"
+#include "SVGRadialGradientElement.h"
#include "SVGRootInlineBox.h"
+#include "SVGStopElement.h"
#include "SVGStyledElement.h"
+
#include <math.h>
namespace WebCore {
@@ -307,6 +318,47 @@ static TextStream& operator<<(TextStream& ts, LineJoin style)
return ts;
}
+// FIXME: Maybe this should be in Gradient.cpp
+static TextStream& operator<<(TextStream& ts, GradientSpreadMethod mode)
+{
+ switch (mode) {
+ case SpreadMethodPad:
+ ts << "PAD";
+ break;
+ case SpreadMethodRepeat:
+ ts << "REPEAT";
+ break;
+ case SpreadMethodReflect:
+ ts << "REFLECT";
+ break;
+ }
+
+ return ts;
+}
+
+static void writeSVGPaintingResource(TextStream& ts, RenderSVGResource* resource)
+{
+ if (resource->resourceType() == SolidColorResourceType) {
+ ts << "[type=SOLID] [color=" << static_cast<RenderSVGResourceSolidColor*>(resource)->color() << "]";
+ return;
+ }
+
+ // All other resources derive from RenderSVGResourceContainer
+ RenderSVGResourceContainer* container = static_cast<RenderSVGResourceContainer*>(resource);
+ Node* node = container->node();
+ ASSERT(node);
+ ASSERT(node->isSVGElement());
+
+ if (resource->resourceType() == PatternResourceType)
+ ts << "[type=PATTERN]";
+ else if (resource->resourceType() == LinearGradientResourceType)
+ ts << "[type=LINEAR-GRADIENT]";
+ else if (resource->resourceType() == RadialGradientResourceType)
+ ts << "[type=RADIAL-GRADIENT]";
+
+ ts << " [id=\"" << static_cast<SVGElement*>(node)->getIDAttribute() << "\"]";
+}
+
static void writeStyle(TextStream& ts, const RenderObject& object)
{
const RenderStyle* style = object.style();
@@ -318,12 +370,11 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
writeIfNotDefault(ts, "opacity", style->opacity(), RenderStyle::initialOpacity());
if (object.isRenderPath()) {
const RenderPath& path = static_cast<const RenderPath&>(object);
- SVGPaintServer* strokePaintServer = SVGPaintServer::strokePaintServer(style, &path);
- if (strokePaintServer) {
+
+ if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(&path, path.style())) {
TextStreamSeparator s(" ");
- ts << " [stroke={";
- if (strokePaintServer)
- ts << s << *strokePaintServer;
+ ts << " [stroke={" << s;
+ writeSVGPaintingResource(ts, strokePaintingResource);
double dashOffset = SVGRenderStyle::cssPrimitiveToLength(&path, svgStyle->strokeDashOffset(), 0.0f);
const DashArray& dashArray = dashArrayFromRenderingStyle(style, object.document()->documentElement()->renderStyle());
@@ -340,12 +391,11 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
ts << "}]";
}
- SVGPaintServer* fillPaintServer = SVGPaintServer::fillPaintServer(style, &path);
- if (fillPaintServer) {
+
+ if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(&path, path.style())) {
TextStreamSeparator s(" ");
- ts << " [fill={";
- if (fillPaintServer)
- ts << s << *fillPaintServer;
+ ts << " [fill={" << s;
+ writeSVGPaintingResource(ts, fillPaintingResource);
writeIfNotDefault(ts, "opacity", svgStyle->fillOpacity(), 1.0f);
writeIfNotDefault(ts, "fill rule", svgStyle->fillRule(), RULE_NONZERO);
@@ -515,7 +565,23 @@ static void writeChildren(TextStream& ts, const RenderObject& object, int indent
write(ts, *child, indent + 1);
}
-void writeSVGResource(TextStream& ts, const RenderObject& object, int indent)
+static inline String boundingBoxModeString(bool boundingBoxMode)
+{
+ return boundingBoxMode ? "objectBoundingBox" : "userSpaceOnUse";
+}
+
+static inline void writeCommonGradientProperties(TextStream& ts, GradientSpreadMethod spreadMethod, const AffineTransform& gradientTransform, bool boundingBoxMode)
+{
+ writeNameValuePair(ts, "gradientUnits", boundingBoxModeString(boundingBoxMode));
+
+ if (spreadMethod != SpreadMethodPad)
+ ts << " [spreadMethod=" << spreadMethod << "]";
+
+ if (!gradientTransform.isIdentity())
+ ts << " [gradientTransform=" << gradientTransform << "]";
+}
+
+void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int indent)
{
writeStandardPrefix(ts, object, indent);
@@ -523,16 +589,16 @@ void writeSVGResource(TextStream& ts, const RenderObject& object, int indent)
const AtomicString& id = element->getIDAttribute();
writeNameAndQuotedValue(ts, "id", id);
- RenderSVGResource* resource = const_cast<RenderObject&>(object).toRenderSVGResource();
+ RenderSVGResourceContainer* resource = const_cast<RenderObject&>(object).toRenderSVGResourceContainer();
+ ASSERT(resource);
+
if (resource->resourceType() == MaskerResourceType) {
RenderSVGResourceMasker* masker = static_cast<RenderSVGResourceMasker*>(resource);
- ASSERT(masker);
writeNameValuePair(ts, "maskUnits", masker->maskUnits());
writeNameValuePair(ts, "maskContentUnits", masker->maskContentUnits());
#if ENABLE(FILTERS)
} else if (resource->resourceType() == FilterResourceType) {
RenderSVGResourceFilter* filter = static_cast<RenderSVGResourceFilter*>(resource);
- ASSERT(filter);
writeNameValuePair(ts, "filterUnits", filter->filterUnits());
writeNameValuePair(ts, "primitiveUnits", filter->primitiveUnits());
if (OwnPtr<SVGFilterBuilder> builder = filter->buildPrimitives()) {
@@ -558,11 +624,9 @@ void writeSVGResource(TextStream& ts, const RenderObject& object, int indent)
#endif
} else if (resource->resourceType() == ClipperResourceType) {
RenderSVGResourceClipper* clipper = static_cast<RenderSVGResourceClipper*>(resource);
- ASSERT(clipper);
writeNameValuePair(ts, "clipPathUnits", clipper->clipPathUnits());
} else if (resource->resourceType() == MarkerResourceType) {
RenderSVGResourceMarker* marker = static_cast<RenderSVGResourceMarker*>(resource);
- ASSERT(marker);
writeNameValuePair(ts, "markerUnits", marker->markerUnits());
ts << " [ref at " << marker->referencePoint() << "]";
ts << " [angle=";
@@ -570,6 +634,49 @@ void writeSVGResource(TextStream& ts, const RenderObject& object, int indent)
ts << "auto" << "]";
else
ts << marker->angle() << "]";
+ } else if (resource->resourceType() == PatternResourceType) {
+ RenderSVGResourcePattern* pattern = static_cast<RenderSVGResourcePattern*>(resource);
+
+ // Dump final results that are used for rendering. No use in asking SVGPatternElement for its patternUnits(), as it may
+ // link to other patterns using xlink:href, we need to build the full inheritance chain, aka. collectPatternProperties()
+ PatternAttributes attributes = static_cast<SVGPatternElement*>(pattern->node())->collectPatternProperties();
+ writeNameValuePair(ts, "patternUnits", boundingBoxModeString(attributes.boundingBoxMode()));
+ writeNameValuePair(ts, "patternContentUnits", boundingBoxModeString(attributes.boundingBoxModeContent()));
+
+ AffineTransform transform = attributes.patternTransform();
+ if (!transform.isIdentity())
+ ts << " [patternTransform=" << transform << "]";
+ } else if (resource->resourceType() == LinearGradientResourceType) {
+ RenderSVGResourceLinearGradient* gradient = static_cast<RenderSVGResourceLinearGradient*>(resource);
+
+ // Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may
+ // link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties()
+ SVGLinearGradientElement* linearGradientElement = static_cast<SVGLinearGradientElement*>(gradient->node());
+
+ LinearGradientAttributes attributes = linearGradientElement->collectGradientProperties();
+ writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.boundingBoxMode());
+
+ FloatPoint startPoint;
+ FloatPoint endPoint;
+ linearGradientElement->calculateStartEndPoints(attributes, startPoint, endPoint);
+
+ ts << " [start=" << startPoint << "] [end=" << endPoint << "]";
+ } else if (resource->resourceType() == RadialGradientResourceType) {
+ RenderSVGResourceRadialGradient* gradient = static_cast<RenderSVGResourceRadialGradient*>(resource);
+
+ // Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may
+ // link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties()
+ SVGRadialGradientElement* radialGradientElement = static_cast<SVGRadialGradientElement*>(gradient->node());
+
+ RadialGradientAttributes attributes = radialGradientElement->collectGradientProperties();
+ writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.boundingBoxMode());
+
+ FloatPoint focalPoint;
+ FloatPoint centerPoint;
+ float radius;
+ radialGradientElement->calculateFocalCenterPointsAndRadius(attributes, focalPoint, centerPoint, radius);
+
+ ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "]";
}
ts << "\n";
@@ -626,6 +733,20 @@ void write(TextStream& ts, const RenderPath& path, int indent)
writeResources(ts, path, indent);
}
+void writeSVGGradientStop(TextStream& ts, const RenderSVGGradientStop& stop, int indent)
+{
+ writeStandardPrefix(ts, stop, indent);
+
+ SVGStopElement* stopElement = static_cast<SVGStopElement*>(stop.node());
+ ASSERT(stopElement);
+
+ RenderStyle* style = stop.style();
+ if (!style)
+ return;
+
+ ts << " [offset=" << stopElement->offset() << "] [color=" << stopElement->stopColorIncludingOpacity() << "]\n";
+}
+
void writeResources(TextStream& ts, const RenderObject& object, int indent)
{
const RenderStyle* style = object.style();
@@ -665,31 +786,6 @@ void writeResources(TextStream& ts, const RenderObject& object, int indent)
#endif
}
-void writeRenderResources(TextStream& ts, Node* parent)
-{
- ASSERT(parent);
- Node* node = parent;
- do {
- if (!node->isSVGElement())
- continue;
- SVGElement* svgElement = static_cast<SVGElement*>(node);
- if (!svgElement->isStyled())
- continue;
-
- SVGStyledElement* styled = static_cast<SVGStyledElement*>(svgElement);
- RefPtr<SVGResource> resource(styled->canvasResource(node->renderer()));
- if (!resource)
- continue;
-
- String elementId = svgElement->getAttribute(svgElement->idAttributeName());
- // FIXME: These names are lies!
- if (resource->isPaintServer()) {
- RefPtr<SVGPaintServer> paintServer = WTF::static_pointer_cast<SVGPaintServer>(resource);
- ts << "KRenderingPaintServer {id=\"" << elementId << "\" " << *paintServer << "}" << "\n";
- }
- } while ((node = node->traverseNextNode(parent)));
-}
-
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/SVGRenderTreeAsText.h b/WebCore/rendering/SVGRenderTreeAsText.h
index 905652b..0fda958 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.h
+++ b/WebCore/rendering/SVGRenderTreeAsText.h
@@ -43,6 +43,7 @@ namespace WebCore {
class RenderImage;
class RenderObject;
class RenderPath;
+ class RenderSVGGradientStop;
class RenderSVGRoot;
class RenderText;
class AffineTransform;
@@ -51,15 +52,14 @@ namespace WebCore {
// functions used by the main RenderTreeAsText code
void write(TextStream&, const RenderPath&, int indent);
void write(TextStream&, const RenderSVGRoot&, int indent);
-void writeSVGResource(TextStream&, const RenderObject&, int indent);
+void writeSVGGradientStop(TextStream&, const RenderSVGGradientStop&, int indent);
+void writeSVGResourceContainer(TextStream&, const RenderObject&, int indent);
void writeSVGContainer(TextStream&, const RenderObject&, int indent);
void writeSVGImage(TextStream&, const RenderImage&, int indent);
void writeSVGInlineText(TextStream&, const RenderText&, int indent);
void writeSVGText(TextStream&, const RenderBlock&, int indent);
void writeResources(TextStream&, const RenderObject&, int indent);
-void writeRenderResources(TextStream&, Node* parent);
-
// helper operators defined used in various classes to dump the render tree.
TextStream& operator<<(TextStream&, const AffineTransform&);
TextStream& operator<<(TextStream&, const IntRect&);
diff --git a/WebCore/rendering/SVGRootInlineBox.cpp b/WebCore/rendering/SVGRootInlineBox.cpp
index 89b4375..6c99b1a 100644
--- a/WebCore/rendering/SVGRootInlineBox.cpp
+++ b/WebCore/rendering/SVGRootInlineBox.cpp
@@ -4,6 +4,7 @@
* Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
* (C) 2006 Apple Computer Inc.
* (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -32,12 +33,12 @@
#include "Frame.h"
#include "GraphicsContext.h"
#include "RenderBlock.h"
+#include "RenderSVGResource.h"
#include "RenderSVGResourceFilter.h"
#include "RenderSVGRoot.h"
#include "SVGInlineFlowBox.h"
#include "SVGInlineTextBox.h"
#include "SVGFontElement.h"
-#include "SVGPaintServer.h"
#include "SVGRenderStyleDefs.h"
#include "SVGRenderSupport.h"
#include "SVGTextPositioningElement.h"
@@ -319,7 +320,7 @@ FloatPoint topLeftPositionOfCharacterRange(Vector<SVGChar>::iterator it, Vector<
}
// Helper function
-static float calculateKerning(RenderObject* item)
+static float calculateCSSKerning(RenderObject* item)
{
const Font& font = item->style()->font();
const SVGRenderStyle* svgStyle = item->style()->svgStyle();
@@ -335,6 +336,40 @@ static float calculateKerning(RenderObject* item)
return kerning;
}
+static bool applySVGKerning(SVGCharacterLayoutInfo& info, RenderObject* item, LastGlyphInfo& lastGlyph, const String& unicodeString, const String& glyphName)
+{
+#if ENABLE(SVG_FONTS)
+ float kerning = 0.0f;
+ const RenderStyle* style = item->style();
+ SVGFontElement* svgFont = 0;
+ if (style->font().isSVGFont())
+ svgFont = style->font().svgFont();
+
+ if (lastGlyph.isValid && style->font().isSVGFont())
+ kerning = svgFont->getHorizontalKerningPairForStringsAndGlyphs(lastGlyph.unicode, lastGlyph.glyphName, unicodeString, glyphName);
+
+ if (style->font().isSVGFont()) {
+ lastGlyph.unicode = unicodeString;
+ lastGlyph.glyphName = glyphName;
+ lastGlyph.isValid = true;
+ kerning *= style->font().size() / style->font().primaryFont()->unitsPerEm();
+ } else
+ lastGlyph.isValid = false;
+
+ if (kerning != 0.0f) {
+ info.curx -= kerning;
+ return true;
+ }
+#else
+ UNUSED_PARAM(info);
+ UNUSED_PARAM(item);
+ UNUSED_PARAM(lastGlyph);
+ UNUSED_PARAM(unicodeString);
+ UNUSED_PARAM(glyphName);
+#endif
+ return false;
+}
+
// Helper class for paint()
struct SVGRootInlineBoxPaintWalker {
SVGRootInlineBoxPaintWalker(SVGRootInlineBox* rootBox, RenderSVGResourceFilter* rootFilter, RenderObject::PaintInfo paintInfo, int tx, int ty)
@@ -345,10 +380,10 @@ struct SVGRootInlineBoxPaintWalker {
, m_boundingBox(tx + rootBox->x(), ty + rootBox->y(), rootBox->width(), rootBox->height())
, m_filter(0)
, m_rootFilter(rootFilter)
- , m_fillPaintServer(0)
- , m_strokePaintServer(0)
- , m_fillPaintServerObject(0)
- , m_strokePaintServerObject(0)
+ , m_fillPaintingResource(0)
+ , m_strokePaintingResource(0)
+ , m_fillPaintingResourceObject(0)
+ , m_strokePaintingResourceObject(0)
, m_tx(tx)
, m_ty(ty)
{
@@ -357,10 +392,10 @@ struct SVGRootInlineBoxPaintWalker {
~SVGRootInlineBoxPaintWalker()
{
ASSERT(!m_filter);
- ASSERT(!m_fillPaintServer);
- ASSERT(!m_fillPaintServerObject);
- ASSERT(!m_strokePaintServer);
- ASSERT(!m_strokePaintServerObject);
+ ASSERT(!m_fillPaintingResource);
+ ASSERT(!m_fillPaintingResourceObject);
+ ASSERT(!m_strokePaintingResource);
+ ASSERT(!m_strokePaintingResourceObject);
ASSERT(!m_chunkStarted);
}
@@ -373,24 +408,22 @@ struct SVGRootInlineBoxPaintWalker {
void teardownFillPaintServer()
{
- if (!m_fillPaintServer)
+ if (!m_fillPaintingResource)
return;
- m_fillPaintServer->teardown(m_paintInfo.context, m_fillPaintServerObject, ApplyToFillTargetType, true);
-
- m_fillPaintServer = 0;
- m_fillPaintServerObject = 0;
+ m_fillPaintingResource->postApplyResource(m_fillPaintingResourceObject, m_paintInfo.context, ApplyToFillMode | ApplyToTextMode);
+ m_fillPaintingResource = 0;
+ m_fillPaintingResourceObject = 0;
}
void teardownStrokePaintServer()
{
- if (!m_strokePaintServer)
+ if (!m_strokePaintingResource)
return;
- m_strokePaintServer->teardown(m_paintInfo.context, m_strokePaintServerObject, ApplyToStrokeTargetType, true);
-
- m_strokePaintServer = 0;
- m_strokePaintServerObject = 0;
+ m_strokePaintingResource->postApplyResource(m_strokePaintingResourceObject, m_paintInfo.context, ApplyToStrokeMode | ApplyToTextMode);
+ m_strokePaintingResource = 0;
+ m_strokePaintingResourceObject = 0;
}
void chunkStartCallback(InlineBox* box)
@@ -437,7 +470,7 @@ struct SVGRootInlineBoxPaintWalker {
m_paintInfo.rect = m_savedInfo.rect;
}
- bool setupBackground(SVGInlineTextBox* /*box*/)
+ bool setupBackground(SVGInlineTextBox*)
{
m_textPaintInfo.subphase = SVGTextPaintSubphaseBackground;
return true;
@@ -451,14 +484,14 @@ struct SVGRootInlineBoxPaintWalker {
RenderObject* object = flowBox->renderer();
ASSERT(object);
- ASSERT(!m_strokePaintServer);
+ ASSERT(!m_strokePaintingResource);
teardownFillPaintServer();
m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphFill;
- m_fillPaintServer = SVGPaintServer::fillPaintServer(object->style(), object);
- if (m_fillPaintServer) {
- m_fillPaintServer->setup(m_paintInfo.context, object, ApplyToFillTargetType, true);
- m_fillPaintServerObject = object;
+ m_fillPaintingResource = RenderSVGResource::fillPaintingResource(object, object->style());
+ if (m_fillPaintingResource) {
+ m_fillPaintingResource->applyResource(object, object->style(), m_paintInfo.context, ApplyToFillMode | ApplyToTextMode);
+ m_fillPaintingResourceObject = object;
return true;
}
@@ -476,17 +509,17 @@ struct SVGRootInlineBoxPaintWalker {
if (!style)
style = object->style();
- ASSERT(!m_strokePaintServer);
+ ASSERT(!m_strokePaintingResource);
teardownFillPaintServer();
if (!mayHaveSelection(box))
return false;
m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphFillSelection;
- m_fillPaintServer = SVGPaintServer::fillPaintServer(style, object);
- if (m_fillPaintServer) {
- m_fillPaintServer->setup(m_paintInfo.context, object, style, ApplyToFillTargetType, true);
- m_fillPaintServerObject = object;
+ m_fillPaintingResource = RenderSVGResource::fillPaintingResource(object, style);
+ if (m_fillPaintingResource) {
+ m_fillPaintingResource->applyResource(object, style, m_paintInfo.context, ApplyToFillMode | ApplyToTextMode);
+ m_fillPaintingResourceObject = object;
return true;
}
@@ -506,11 +539,10 @@ struct SVGRootInlineBoxPaintWalker {
teardownStrokePaintServer();
m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphStroke;
- m_strokePaintServer = SVGPaintServer::strokePaintServer(object->style(), object);
-
- if (m_strokePaintServer) {
- m_strokePaintServer->setup(m_paintInfo.context, object, ApplyToStrokeTargetType, true);
- m_strokePaintServerObject = object;
+ m_strokePaintingResource = RenderSVGResource::strokePaintingResource(object, object->style());
+ if (m_strokePaintingResource) {
+ m_strokePaintingResource->applyResource(object, object->style(), m_paintInfo.context, ApplyToStrokeMode | ApplyToTextMode);
+ m_strokePaintingResourceObject = object;
return true;
}
@@ -536,17 +568,17 @@ struct SVGRootInlineBoxPaintWalker {
return false;
m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphStrokeSelection;
- m_strokePaintServer = SVGPaintServer::strokePaintServer(style, object);
- if (m_strokePaintServer) {
- m_strokePaintServer->setup(m_paintInfo.context, object, style, ApplyToStrokeTargetType, true);
- m_strokePaintServerObject = object;
+ m_strokePaintingResource = RenderSVGResource::strokePaintingResource(object, style);
+ if (m_strokePaintingResource) {
+ m_strokePaintingResource->applyResource(object, style, m_paintInfo.context, ApplyToStrokeMode | ApplyToTextMode);
+ m_strokePaintingResourceObject = object;
return true;
}
return false;
}
- bool setupForeground(SVGInlineTextBox* /*box*/)
+ bool setupForeground(SVGInlineTextBox*)
{
teardownFillPaintServer();
teardownStrokePaintServer();
@@ -556,17 +588,17 @@ struct SVGRootInlineBoxPaintWalker {
return true;
}
- SVGPaintServer* activePaintServer() const
+ RenderSVGResource* activePaintingResource() const
{
switch (m_textPaintInfo.subphase) {
case SVGTextPaintSubphaseGlyphFill:
case SVGTextPaintSubphaseGlyphFillSelection:
- ASSERT(m_fillPaintServer);
- return m_fillPaintServer;
+ ASSERT(m_fillPaintingResource);
+ return m_fillPaintingResource;
case SVGTextPaintSubphaseGlyphStroke:
case SVGTextPaintSubphaseGlyphStrokeSelection:
- ASSERT(m_strokePaintServer);
- return m_strokePaintServer;
+ ASSERT(m_strokePaintingResource);
+ return m_strokePaintingResource;
case SVGTextPaintSubphaseBackground:
case SVGTextPaintSubphaseForeground:
default:
@@ -646,7 +678,7 @@ struct SVGRootInlineBoxPaintWalker {
textBox->paintDecoration(OVERLINE, m_paintInfo.context, decorationOrigin.x(), decorationOrigin.y(), textWidth, *it, info);
// Paint text
- m_textPaintInfo.activePaintServer = activePaintServer();
+ m_textPaintInfo.activePaintingResource = activePaintingResource();
textBox->paintCharacters(m_paintInfo, m_tx, m_ty, *it, stringStart, stringLength, m_textPaintInfo);
// Paint decorations, that have to be drawn afterwards
@@ -672,11 +704,11 @@ private:
RenderSVGResourceFilter* m_filter;
RenderSVGResourceFilter* m_rootFilter;
- SVGPaintServer* m_fillPaintServer;
- SVGPaintServer* m_strokePaintServer;
+ RenderSVGResource* m_fillPaintingResource;
+ RenderSVGResource* m_strokePaintingResource;
- RenderObject* m_fillPaintServerObject;
- RenderObject* m_strokePaintServerObject;
+ RenderObject* m_fillPaintingResourceObject;
+ RenderObject* m_strokePaintingResourceObject;
int m_tx;
int m_ty;
@@ -1296,7 +1328,7 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo&
}
// Take letter & word spacing and kerning into account
- float spacing = font.letterSpacing() + calculateKerning(textBox->renderer()->node()->renderer());
+ float spacing = font.letterSpacing() + calculateCSSKerning(textBox->renderer()->node()->renderer());
const UChar* currentCharacter = text->characters() + (textBox->direction() == RTL ? textBox->end() - i : textBox->start() + i);
const UChar* lastCharacter = 0;
@@ -1309,7 +1341,9 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo&
lastCharacter = text->characters() + textBox->start() + i - 1;
}
- if (info.nextDrawnSeperated || spacing != 0.0f) {
+ // FIXME: SVG Kerning doesn't get applied on texts on path.
+ bool appliedSVGKerning = applySVGKerning(info, textBox->renderer()->node()->renderer(), lastGlyph, unicodeStr, glyphName);
+ if (info.nextDrawnSeperated || spacing != 0.0f || appliedSVGKerning) {
info.nextDrawnSeperated = false;
svgChar.drawnSeperated = true;
}
@@ -1414,35 +1448,12 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo&
}
}
- float kerning = 0.0f;
-#if ENABLE(SVG_FONTS)
- SVGFontElement* svgFont = 0;
- if (style->font().isSVGFont())
- svgFont = style->font().svgFont();
-
- if (lastGlyph.isValid && style->font().isSVGFont()) {
- SVGHorizontalKerningPair kerningPair;
- if (svgFont->getHorizontalKerningPairForStringsAndGlyphs(lastGlyph.unicode, lastGlyph.glyphName, unicodeStr, glyphName, kerningPair))
- kerning = narrowPrecisionToFloat(kerningPair.kerning);
- }
-
- if (style->font().isSVGFont()) {
- lastGlyph.unicode = unicodeStr;
- lastGlyph.glyphName = glyphName;
- lastGlyph.isValid = true;
- kerning *= style->font().size() / style->font().primaryFont()->unitsPerEm();
- } else
- lastGlyph.isValid = false;
-#endif
-
- svgChar.x -= kerning;
-
// Advance to new position
if (isVerticalText) {
svgChar.drawnSeperated = true;
info.cury += glyphAdvance + spacing;
} else
- info.curx += glyphAdvance + spacing - kerning;
+ info.curx += glyphAdvance + spacing;
// Advance to next character group
for (int k = 0; k < charsConsumed; ++k) {
diff --git a/WebCore/rendering/SVGRootInlineBox.h b/WebCore/rendering/SVGRootInlineBox.h
index 7b1dcc4..73c88a1 100644
--- a/WebCore/rendering/SVGRootInlineBox.h
+++ b/WebCore/rendering/SVGRootInlineBox.h
@@ -27,7 +27,9 @@
#if ENABLE(SVG)
#include "RootInlineBox.h"
+#include "SVGCharacterData.h"
#include "SVGCharacterLayoutInfo.h"
+#include "SVGTextChunkLayoutInfo.h"
#include "SVGRenderSupport.h"
namespace WebCore {
@@ -51,7 +53,6 @@ public:
, m_height(0)
{
}
- virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
virtual bool isSVGRootInlineBox() { return true; }
diff --git a/WebCore/rendering/SVGShadowTreeElements.cpp b/WebCore/rendering/SVGShadowTreeElements.cpp
index d9ce640..f26f87e 100644
--- a/WebCore/rendering/SVGShadowTreeElements.cpp
+++ b/WebCore/rendering/SVGShadowTreeElements.cpp
@@ -49,7 +49,7 @@ SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, Node* sha
: SVGShadowTreeContainerElement(document)
, m_shadowParent(shadowParent)
{
- setInDocument(true);
+ setInDocument();
}
SVGShadowTreeRootElement::~SVGShadowTreeRootElement()
diff --git a/WebCore/rendering/SVGTextChunkLayoutInfo.h b/WebCore/rendering/SVGTextChunkLayoutInfo.h
new file mode 100644
index 0000000..524c983
--- /dev/null
+++ b/WebCore/rendering/SVGTextChunkLayoutInfo.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 SVGTextChunkLayoutInfo_h
+#define SVGTextChunkLayoutInfo_h
+
+#if ENABLE(SVG)
+#include "AffineTransform.h"
+#include "SVGTextContentElement.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class InlineBox;
+class SVGInlineTextBox;
+
+struct SVGInlineBoxCharacterRange {
+ SVGInlineBoxCharacterRange()
+ : startOffset(INT_MIN)
+ , endOffset(INT_MIN)
+ , box(0)
+ {
+ }
+
+ bool isOpen() const { return (startOffset == endOffset) && (endOffset == INT_MIN); }
+ bool isClosed() const { return startOffset != INT_MIN && endOffset != INT_MIN; }
+
+ int startOffset;
+ int endOffset;
+
+ InlineBox* box;
+};
+
+struct SVGChar;
+
+// Convenience typedef
+typedef SVGTextContentElement::SVGLengthAdjustType ELengthAdjust;
+
+struct SVGTextChunk {
+ SVGTextChunk()
+ : anchor(TA_START)
+ , textLength(0.0f)
+ , lengthAdjust(SVGTextContentElement::LENGTHADJUST_SPACING)
+ , ctm()
+ , isVerticalText(false)
+ , isTextPath(false)
+ , start(0)
+ , end(0)
+ { }
+
+ // text-anchor support
+ ETextAnchor anchor;
+
+ // textLength & lengthAdjust support
+ float textLength;
+ ELengthAdjust lengthAdjust;
+ AffineTransform ctm;
+
+ // status flags
+ bool isVerticalText : 1;
+ bool isTextPath : 1;
+
+ // main chunk data
+ Vector<SVGChar>::iterator start;
+ Vector<SVGChar>::iterator end;
+
+ Vector<SVGInlineBoxCharacterRange> boxes;
+};
+
+struct SVGTextChunkWalkerBase {
+ virtual ~SVGTextChunkWalkerBase() { }
+
+ virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
+ const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end) = 0;
+
+ // Followings methods are only used for painting text chunks
+ virtual void start(InlineBox*) = 0;
+ virtual void end(InlineBox*) = 0;
+};
+
+template<typename CallbackClass>
+struct SVGTextChunkWalker : public SVGTextChunkWalkerBase {
+public:
+ typedef void (CallbackClass::*SVGTextChunkWalkerCallback)(SVGInlineTextBox* textBox,
+ int startOffset,
+ const AffineTransform& chunkCtm,
+ const Vector<SVGChar>::iterator& start,
+ const Vector<SVGChar>::iterator& end);
+
+ // These callbacks are only used for painting!
+ typedef void (CallbackClass::*SVGTextChunkStartCallback)(InlineBox* box);
+ typedef void (CallbackClass::*SVGTextChunkEndCallback)(InlineBox* box);
+
+ SVGTextChunkWalker(CallbackClass* object,
+ SVGTextChunkWalkerCallback walker,
+ SVGTextChunkStartCallback start = 0,
+ SVGTextChunkEndCallback end = 0)
+ : m_object(object)
+ , m_walkerCallback(walker)
+ , m_startCallback(start)
+ , m_endCallback(end)
+ {
+ ASSERT(object);
+ ASSERT(walker);
+ }
+
+ virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
+ const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
+ {
+ (*m_object.*m_walkerCallback)(textBox, startOffset, chunkCtm, start, end);
+ }
+
+ // Followings methods are only used for painting text chunks
+ virtual void start(InlineBox* box)
+ {
+ if (m_startCallback)
+ (*m_object.*m_startCallback)(box);
+ else
+ ASSERT_NOT_REACHED();
+ }
+
+ virtual void end(InlineBox* box)
+ {
+ if (m_endCallback)
+ (*m_object.*m_endCallback)(box);
+ else
+ ASSERT_NOT_REACHED();
+ }
+
+private:
+ CallbackClass* m_object;
+ SVGTextChunkWalkerCallback m_walkerCallback;
+ SVGTextChunkStartCallback m_startCallback;
+ SVGTextChunkEndCallback m_endCallback;
+};
+
+struct SVGTextChunkLayoutInfo {
+ SVGTextChunkLayoutInfo(Vector<SVGTextChunk>& textChunks)
+ : assignChunkProperties(true)
+ , handlingTextPath(false)
+ , svgTextChunks(textChunks)
+ , it(0)
+ {
+ }
+
+ bool assignChunkProperties : 1;
+ bool handlingTextPath : 1;
+
+ Vector<SVGTextChunk>& svgTextChunks;
+ Vector<SVGChar>::iterator it;
+
+ SVGTextChunk chunk;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif // SVGTextChunkLayoutInfo_h
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index 4cd55c5..84f7c0f 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -96,7 +96,7 @@ void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<Render
// Set these explicitly since this normally happens during an attach()
setAttached();
- setInDocument(true);
+ setInDocument();
// For elements without a shadow parent, add the node to the DOM normally.
if (!m_shadowParent)
@@ -116,16 +116,9 @@ void TextControlInnerTextElement::defaultEventHandler(Event* evt)
{
// FIXME: In the future, we should add a way to have default event listeners. Then we would add one to the text field's inner div, and we wouldn't need this subclass.
Node* shadowAncestor = shadowAncestorNode();
- if (shadowAncestor && shadowAncestor->renderer()) {
- ASSERT(shadowAncestor->renderer()->isTextControl());
- if (evt->isBeforeTextInsertedEvent()) {
- if (shadowAncestor->renderer()->isTextField())
- static_cast<HTMLInputElement*>(shadowAncestor)->defaultEventHandler(evt);
- else
- static_cast<HTMLTextAreaElement*>(shadowAncestor)->defaultEventHandler(evt);
- }
- if (evt->type() == eventNames().webkitEditableContentChangedEvent)
- toRenderTextControl(shadowAncestor->renderer())->subtreeHasChanged();
+ if (shadowAncestor) {
+ if (evt->isBeforeTextInsertedEvent() || evt->type() == eventNames().webkitEditableContentChangedEvent)
+ shadowAncestor->defaultEventHandler(evt);
}
if (!evt->defaultHandled())
HTMLDivElement::defaultEventHandler(evt);
@@ -211,4 +204,62 @@ void SearchFieldCancelButtonElement::defaultEventHandler(Event* evt)
HTMLDivElement::defaultEventHandler(evt);
}
+SpinButtonElement::SpinButtonElement(Document* doc, Node* shadowParent)
+ : TextControlInnerElement(doc, shadowParent)
+ , m_capturing(false)
+ , m_onUpButton(false)
+{
+}
+
+void SpinButtonElement::defaultEventHandler(Event* evt)
+{
+ if (!evt->isMouseEvent()) {
+ if (!evt->defaultHandled())
+ HTMLDivElement::defaultEventHandler(evt);
+ return;
+ }
+ const MouseEvent* mevt = static_cast<MouseEvent*>(evt);
+ if (mevt->button() != LeftButton) {
+ if (!evt->defaultHandled())
+ HTMLDivElement::defaultEventHandler(evt);
+ return;
+ }
+
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+ IntPoint local = roundedIntPoint(renderBox()->absoluteToLocal(mevt->absoluteLocation(), false, true));
+ if (evt->type() == eventNames().clickEvent) {
+ if (renderBox()->borderBoxRect().contains(local)) {
+ input->focus();
+ input->select();
+ if (local.y() < renderBox()->y() + renderBox()->height() / 2)
+ input->stepUpFromRenderer(1);
+ else
+ input->stepUpFromRenderer(-1);
+ evt->setDefaultHandled();
+ }
+ } else if (evt->type() == eventNames().mousemoveEvent) {
+ if (renderBox()->borderBoxRect().contains(local)) {
+ if (!m_capturing) {
+ if (Frame* frame = document()->frame()) {
+ frame->eventHandler()->setCapturingMouseEventsNode(input);
+ m_capturing = true;
+ }
+ }
+ bool oldOnUpButton = m_onUpButton;
+ m_onUpButton = local.y() < renderBox()->y() + renderBox()->height() / 2;
+ if (m_onUpButton != oldOnUpButton)
+ renderer()->repaint();
+ } else {
+ if (m_capturing) {
+ if (Frame* frame = document()->frame()) {
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ m_capturing = false;
+ }
+ }
+ }
+ }
+ if (!evt->defaultHandled())
+ HTMLDivElement::defaultEventHandler(evt);
+}
+
}
diff --git a/WebCore/rendering/TextControlInnerElements.h b/WebCore/rendering/TextControlInnerElements.h
index f72ddf2..f59ac96 100644
--- a/WebCore/rendering/TextControlInnerElements.h
+++ b/WebCore/rendering/TextControlInnerElements.h
@@ -68,6 +68,21 @@ private:
bool m_capturing;
};
+class SpinButtonElement : public TextControlInnerElement {
+public:
+ SpinButtonElement(Document*, Node*);
+ virtual bool isSpinButtonElement() const { return true; }
+ virtual bool isEnabledFormControl() { return static_cast<Element*>(shadowAncestorNode())->isEnabledFormControl(); }
+ virtual void defaultEventHandler(Event*);
+
+ bool onUpButton() const { return m_onUpButton; }
+ static const AtomicString& spinButtonNodeName();
+
+private:
+ bool m_capturing;
+ bool m_onUpButton;
+};
+
} //namespace
#endif
diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp
index f1cf0bc..f3b3f0c 100644
--- a/WebCore/rendering/style/RenderStyle.cpp
+++ b/WebCore/rendering/style/RenderStyle.cpp
@@ -58,7 +58,7 @@ PassRefPtr<RenderStyle> RenderStyle::clone(const RenderStyle* other)
return adoptRef(new RenderStyle(*other));
}
-RenderStyle::RenderStyle()
+ALWAYS_INLINE RenderStyle::RenderStyle()
: m_affectedByAttributeSelectors(false)
, m_unique(false)
, m_affectedByEmpty(false)
@@ -85,7 +85,7 @@ RenderStyle::RenderStyle()
setBitDefaults(); // Would it be faster to copy this from the default style?
}
-RenderStyle::RenderStyle(bool)
+ALWAYS_INLINE RenderStyle::RenderStyle(bool)
: m_affectedByAttributeSelectors(false)
, m_unique(false)
, m_affectedByEmpty(false)
@@ -118,7 +118,7 @@ RenderStyle::RenderStyle(bool)
#endif
}
-RenderStyle::RenderStyle(const RenderStyle& o)
+ALWAYS_INLINE RenderStyle::RenderStyle(const RenderStyle& o)
: RefCounted<RenderStyle>()
, m_affectedByAttributeSelectors(false)
, m_unique(false)
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index fe42339..815fb30 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -302,7 +302,7 @@ protected:
noninherited_flags._isLink = false;
}
-protected:
+private:
RenderStyle();
// used to create the default style.
RenderStyle(bool);
diff --git a/WebCore/rendering/style/RenderStyleConstants.h b/WebCore/rendering/style/RenderStyleConstants.h
index b899d57..b6dce18 100644
--- a/WebCore/rendering/style/RenderStyleConstants.h
+++ b/WebCore/rendering/style/RenderStyleConstants.h
@@ -74,7 +74,7 @@ enum PseudoId {
MEDIA_CONTROLS_SEEK_BACK_BUTTON, MEDIA_CONTROLS_SEEK_FORWARD_BUTTON, MEDIA_CONTROLS_FULLSCREEN_BUTTON, MEDIA_CONTROLS_REWIND_BUTTON,
MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON,
MEDIA_CONTROLS_STATUS_DISPLAY, SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
- INPUT_LIST_BUTTON, INNER_SPIN_BUTTON, OUTER_SPIN_BUTTON, VISITED_LINK,
+ INPUT_LIST_BUTTON, INNER_SPIN_BUTTON, OUTER_SPIN_BUTTON, VISITED_LINK, PROGRESS_BAR_VALUE,
AFTER_LAST_INTERNAL_PSEUDOID,
FIRST_PUBLIC_PSEUDOID = FIRST_LINE,
diff --git a/WebCore/rendering/style/SVGRenderStyle.h b/WebCore/rendering/style/SVGRenderStyle.h
index c6d5022..3d6a7da 100644
--- a/WebCore/rendering/style/SVGRenderStyle.h
+++ b/WebCore/rendering/style/SVGRenderStyle.h
@@ -108,8 +108,9 @@ public:
SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, inheritedResources, markerEnd, MarkerEndResource, markerEndResource, String())
// convenience
- bool hasStroke() const { return (strokePaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE); }
- bool hasFill() const { return (fillPaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE); }
+ bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); }
+ bool hasStroke() const { return strokePaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
+ bool hasFill() const { return fillPaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
static float cssPrimitiveToLength(const RenderObject*, CSSValue*, float defaultValue = 0.0f);
diff --git a/WebCore/rendering/style/StyleRareInheritedData.h b/WebCore/rendering/style/StyleRareInheritedData.h
index 1aa7b05..8f128fd 100644
--- a/WebCore/rendering/style/StyleRareInheritedData.h
+++ b/WebCore/rendering/style/StyleRareInheritedData.h
@@ -32,7 +32,7 @@
namespace WebCore {
-struct ShadowData;
+class ShadowData;
// This struct is for rarely used inherited CSS3, CSS2, and WebKit-specific properties.
// By grouping them together, we save space, and only allocate this object when someone
diff --git a/WebCore/rendering/style/StyleRareNonInheritedData.h b/WebCore/rendering/style/StyleRareNonInheritedData.h
index 452b273..21bbe94 100644
--- a/WebCore/rendering/style/StyleRareNonInheritedData.h
+++ b/WebCore/rendering/style/StyleRareNonInheritedData.h
@@ -40,13 +40,14 @@ namespace WebCore {
class AnimationList;
class CSSStyleSelector;
+class ShadowData;
class StyleFlexibleBoxData;
class StyleMarqueeData;
class StyleMultiColData;
class StyleReflection;
class StyleTransformData;
+
struct ContentData;
-struct ShadowData;
#if ENABLE(DASHBOARD_SUPPORT)
class StyleDashboardRegion;