summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-04-27 16:31:00 +0100
committerSteve Block <steveblock@google.com>2010-05-11 14:42:12 +0100
commitdcc8cf2e65d1aa555cce12431a16547e66b469ee (patch)
tree92a8d65cd5383bca9749f5327fb5e440563926e6 /WebCore/rendering
parentccac38a6b48843126402088a309597e682f40fe6 (diff)
downloadexternal_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/EllipsisBox.cpp4
-rw-r--r--WebCore/rendering/InlineFlowBox.cpp93
-rw-r--r--WebCore/rendering/InlineFlowBox.h18
-rw-r--r--WebCore/rendering/InlineRunBox.h52
-rw-r--r--WebCore/rendering/InlineTextBox.cpp104
-rw-r--r--WebCore/rendering/InlineTextBox.h33
-rw-r--r--WebCore/rendering/LayoutState.cpp9
-rw-r--r--WebCore/rendering/MediaControlElements.cpp6
-rw-r--r--WebCore/rendering/RenderBlock.cpp182
-rw-r--r--WebCore/rendering/RenderBlock.h5
-rw-r--r--WebCore/rendering/RenderBlockLineLayout.cpp23
-rw-r--r--WebCore/rendering/RenderBox.cpp35
-rw-r--r--WebCore/rendering/RenderBox.h8
-rw-r--r--WebCore/rendering/RenderBoxModelObject.cpp102
-rw-r--r--WebCore/rendering/RenderEmbeddedObject.cpp134
-rw-r--r--WebCore/rendering/RenderEmbeddedObject.h18
-rw-r--r--WebCore/rendering/RenderFieldset.cpp21
-rw-r--r--WebCore/rendering/RenderFileUploadControl.cpp5
-rw-r--r--WebCore/rendering/RenderFileUploadControl.h2
-rw-r--r--WebCore/rendering/RenderForeignObject.cpp8
-rw-r--r--WebCore/rendering/RenderForeignObject.h2
-rw-r--r--WebCore/rendering/RenderFrame.cpp5
-rw-r--r--WebCore/rendering/RenderFrame.h5
-rw-r--r--WebCore/rendering/RenderFrameBase.cpp93
-rw-r--r--WebCore/rendering/RenderFrameBase.h44
-rw-r--r--WebCore/rendering/RenderFrameSet.cpp2
-rw-r--r--WebCore/rendering/RenderFrameSet.h7
-rw-r--r--WebCore/rendering/RenderIFrame.cpp146
-rw-r--r--WebCore/rendering/RenderIFrame.h76
-rw-r--r--WebCore/rendering/RenderImage.cpp2
-rw-r--r--WebCore/rendering/RenderInline.cpp57
-rw-r--r--WebCore/rendering/RenderLayer.cpp164
-rw-r--r--WebCore/rendering/RenderLayer.h8
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp2
-rw-r--r--WebCore/rendering/RenderLayerBacking.h2
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp112
-rw-r--r--WebCore/rendering/RenderLayerCompositor.h3
-rw-r--r--WebCore/rendering/RenderLineBoxList.cpp32
-rw-r--r--WebCore/rendering/RenderListItem.cpp79
-rw-r--r--WebCore/rendering/RenderListItem.h2
-rw-r--r--WebCore/rendering/RenderMenuList.cpp27
-rw-r--r--WebCore/rendering/RenderMenuList.h12
-rw-r--r--WebCore/rendering/RenderObject.cpp160
-rw-r--r--WebCore/rendering/RenderObject.h28
-rw-r--r--WebCore/rendering/RenderObjectChildList.cpp63
-rw-r--r--WebCore/rendering/RenderPart.cpp4
-rw-r--r--WebCore/rendering/RenderPart.h10
-rw-r--r--WebCore/rendering/RenderPath.cpp129
-rw-r--r--WebCore/rendering/RenderPath.h15
-rw-r--r--WebCore/rendering/RenderProgress.cpp120
-rw-r--r--WebCore/rendering/RenderProgress.h71
-rw-r--r--WebCore/rendering/RenderReplaced.cpp2
-rw-r--r--WebCore/rendering/RenderReplaced.h1
-rw-r--r--WebCore/rendering/RenderSVGContainer.cpp8
-rw-r--r--WebCore/rendering/RenderSVGImage.cpp16
-rw-r--r--WebCore/rendering/RenderSVGImage.h3
-rw-r--r--WebCore/rendering/RenderSVGInline.cpp40
-rw-r--r--WebCore/rendering/RenderSVGInline.h15
-rw-r--r--WebCore/rendering/RenderSVGModelObject.cpp2
-rw-r--r--WebCore/rendering/RenderSVGModelObject.h2
-rw-r--r--WebCore/rendering/RenderSVGResource.h71
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.cpp271
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.h75
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.cpp286
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.h94
-rw-r--r--WebCore/rendering/RenderSVGResourceMarker.cpp199
-rw-r--r--WebCore/rendering/RenderSVGResourceMarker.h88
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.cpp11
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.h2
-rw-r--r--WebCore/rendering/RenderSVGRoot.cpp8
-rw-r--r--WebCore/rendering/RenderSVGShadowTreeRootContainer.h2
-rw-r--r--WebCore/rendering/RenderSVGTSpan.h6
-rw-r--r--WebCore/rendering/RenderSVGText.cpp28
-rw-r--r--WebCore/rendering/RenderSVGText.h4
-rw-r--r--WebCore/rendering/RenderSVGTransformableContainer.cpp26
-rw-r--r--WebCore/rendering/RenderSVGTransformableContainer.h7
-rw-r--r--WebCore/rendering/RenderSVGViewportContainer.cpp37
-rw-r--r--WebCore/rendering/RenderSVGViewportContainer.h7
-rw-r--r--WebCore/rendering/RenderSlider.cpp86
-rw-r--r--WebCore/rendering/RenderTable.cpp96
-rw-r--r--WebCore/rendering/RenderTable.h1
-rw-r--r--WebCore/rendering/RenderTableCell.cpp120
-rw-r--r--WebCore/rendering/RenderTableSection.cpp64
-rw-r--r--WebCore/rendering/RenderText.cpp262
-rw-r--r--WebCore/rendering/RenderText.h25
-rw-r--r--WebCore/rendering/RenderTextControl.cpp20
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.h1
-rw-r--r--WebCore/rendering/RenderTextFragment.cpp6
-rw-r--r--WebCore/rendering/RenderTextFragment.h2
-rw-r--r--WebCore/rendering/RenderTheme.cpp30
-rw-r--r--WebCore/rendering/RenderTheme.h15
-rw-r--r--WebCore/rendering/RenderThemeChromiumSkia.cpp117
-rw-r--r--WebCore/rendering/RenderThemeChromiumSkia.h6
-rw-r--r--WebCore/rendering/RenderThemeChromiumWin.h2
-rw-r--r--WebCore/rendering/RenderThemeMac.h14
-rw-r--r--WebCore/rendering/RenderThemeMac.mm77
-rw-r--r--WebCore/rendering/RenderTreeAsText.cpp42
-rw-r--r--WebCore/rendering/RenderTreeAsText.h7
-rw-r--r--WebCore/rendering/RenderVideo.cpp16
-rw-r--r--WebCore/rendering/RenderVideo.h4
-rw-r--r--WebCore/rendering/RenderView.cpp41
-rw-r--r--WebCore/rendering/RenderView.h1
-rw-r--r--WebCore/rendering/RenderWidget.cpp32
-rw-r--r--WebCore/rendering/RenderWidget.h14
-rw-r--r--WebCore/rendering/RootInlineBox.h4
-rw-r--r--WebCore/rendering/SVGInlineTextBox.cpp7
-rw-r--r--WebCore/rendering/SVGMarkerData.h10
-rw-r--r--WebCore/rendering/SVGMarkerLayoutInfo.cpp11
-rw-r--r--WebCore/rendering/SVGMarkerLayoutInfo.h18
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp90
-rw-r--r--WebCore/rendering/SVGRenderSupport.h11
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp121
-rw-r--r--WebCore/rendering/SVGRootInlineBox.cpp20
-rw-r--r--WebCore/rendering/TextControlInnerElements.cpp7
-rw-r--r--WebCore/rendering/style/BorderData.h70
-rw-r--r--WebCore/rendering/style/BorderValue.h24
-rw-r--r--WebCore/rendering/style/CollapsedBorderValue.h44
-rw-r--r--WebCore/rendering/style/CursorData.h18
-rw-r--r--WebCore/rendering/style/FillLayer.h6
-rw-r--r--WebCore/rendering/style/NinePieceImage.h10
-rw-r--r--WebCore/rendering/style/OutlineValue.h15
-rw-r--r--WebCore/rendering/style/RenderStyle.cpp231
-rw-r--r--WebCore/rendering/style/RenderStyle.h281
-rw-r--r--WebCore/rendering/style/RenderStyleConstants.h12
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.cpp61
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.h29
-rw-r--r--WebCore/rendering/style/SVGRenderStyleDefs.cpp184
-rw-r--r--WebCore/rendering/style/SVGRenderStyleDefs.h118
-rw-r--r--WebCore/rendering/style/ShadowData.cpp20
-rw-r--r--WebCore/rendering/style/ShadowData.h57
-rw-r--r--WebCore/rendering/style/StyleBackgroundData.h14
-rw-r--r--WebCore/rendering/style/StyleBoxData.cpp49
-rw-r--r--WebCore/rendering/style/StyleBoxData.h47
-rw-r--r--WebCore/rendering/style/StyleMultiColData.h2
134 files changed, 4457 insertions, 1890 deletions
diff --git a/WebCore/rendering/EllipsisBox.cpp b/WebCore/rendering/EllipsisBox.cpp
index 6ec3195..6f25861 100644
--- a/WebCore/rendering/EllipsisBox.cpp
+++ b/WebCore/rendering/EllipsisBox.cpp
@@ -36,8 +36,8 @@ void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
context->setFillColor(textColor, style->colorSpace());
bool setShadow = false;
if (style->textShadow()) {
- context->setShadow(IntSize(style->textShadow()->x, style->textShadow()->y),
- style->textShadow()->blur, style->textShadow()->color, style->colorSpace());
+ context->setShadow(IntSize(style->textShadow()->x(), style->textShadow()->y()),
+ style->textShadow()->blur(), style->textShadow()->color(), style->colorSpace());
setShadow = true;
}
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index 34eec30..6ee610d 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -21,6 +21,7 @@
#include "InlineFlowBox.h"
#include "CachedImage.h"
+#include "CSSPropertyNames.h"
#include "Document.h"
#include "EllipsisBox.h"
#include "GraphicsContext.h"
@@ -165,7 +166,7 @@ void InlineFlowBox::attachLineBoxToRenderObject()
void InlineFlowBox::adjustPosition(int dx, int dy)
{
- InlineRunBox::adjustPosition(dx, dy);
+ InlineBox::adjustPosition(dx, dy);
for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
child->adjustPosition(dx, dy);
if (m_overflow)
@@ -288,14 +289,16 @@ int InlineFlowBox::placeBoxesHorizontally(int xPos, bool& needsWordSpacing)
int letterSpacing = min(0, (int)rt->style(m_firstLine)->font().letterSpacing());
rightLayoutOverflow = max(xPos + text->width() - letterSpacing, rightLayoutOverflow);
- int leftGlyphOverflow = -strokeOverflow;
- int rightGlyphOverflow = strokeOverflow - letterSpacing;
+ GlyphOverflow* glyphOverflow = static_cast<InlineTextBox*>(curr)->glyphOverflow();
+
+ int leftGlyphOverflow = -strokeOverflow - (glyphOverflow ? glyphOverflow->left : 0);
+ int rightGlyphOverflow = strokeOverflow - letterSpacing + (glyphOverflow ? glyphOverflow->right : 0);
int childOverflowLeft = leftGlyphOverflow;
int childOverflowRight = rightGlyphOverflow;
- for (ShadowData* shadow = rt->style()->textShadow(); shadow; shadow = shadow->next) {
- childOverflowLeft = min(childOverflowLeft, shadow->x - shadow->blur + leftGlyphOverflow);
- childOverflowRight = max(childOverflowRight, shadow->x + shadow->blur + rightGlyphOverflow);
+ for (const ShadowData* shadow = rt->style()->textShadow(); shadow; shadow = shadow->next()) {
+ childOverflowLeft = min(childOverflowLeft, shadow->x() - shadow->blur() + leftGlyphOverflow);
+ childOverflowRight = max(childOverflowRight, shadow->x() + shadow->blur() + rightGlyphOverflow);
}
leftVisualOverflow = min(xPos + childOverflowLeft, leftVisualOverflow);
@@ -412,35 +415,35 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
int lineHeight;
int baseline;
- Vector<const SimpleFontData*> usedFonts;
+ Vector<const SimpleFontData*>* usedFonts = 0;
if (curr->isInlineTextBox())
- static_cast<InlineTextBox*>(curr)->takeFallbackFonts(usedFonts);
+ usedFonts = static_cast<InlineTextBox*>(curr)->fallbackFonts();
- if (!usedFonts.isEmpty()) {
- usedFonts.append(curr->renderer()->style(m_firstLine)->font().primaryFont());
+ if (usedFonts) {
+ usedFonts->append(curr->renderer()->style(m_firstLine)->font().primaryFont());
Length parentLineHeight = curr->renderer()->parent()->style()->lineHeight();
if (parentLineHeight.isNegative()) {
int baselineToBottom = 0;
baseline = 0;
- for (size_t i = 0; i < usedFonts.size(); ++i) {
- int halfLeading = (usedFonts[i]->lineSpacing() - usedFonts[i]->ascent() - usedFonts[i]->descent()) / 2;
- baseline = max(baseline, halfLeading + usedFonts[i]->ascent());
- baselineToBottom = max(baselineToBottom, usedFonts[i]->lineSpacing() - usedFonts[i]->ascent() - usedFonts[i]->descent() - halfLeading);
+ for (size_t i = 0; i < usedFonts->size(); ++i) {
+ int halfLeading = (usedFonts->at(i)->lineSpacing() - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent()) / 2;
+ baseline = max(baseline, halfLeading + usedFonts->at(i)->ascent());
+ baselineToBottom = max(baselineToBottom, usedFonts->at(i)->lineSpacing() - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent() - halfLeading);
}
lineHeight = baseline + baselineToBottom;
} else if (parentLineHeight.isPercent()) {
lineHeight = parentLineHeight.calcMinValue(curr->renderer()->style()->fontSize());
baseline = 0;
- for (size_t i = 0; i < usedFonts.size(); ++i) {
- int halfLeading = (lineHeight - usedFonts[i]->ascent() - usedFonts[i]->descent()) / 2;
- baseline = max(baseline, halfLeading + usedFonts[i]->ascent());
+ for (size_t i = 0; i < usedFonts->size(); ++i) {
+ int halfLeading = (lineHeight - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent()) / 2;
+ baseline = max(baseline, halfLeading + usedFonts->at(i)->ascent());
}
} else {
lineHeight = parentLineHeight.value();
baseline = 0;
- for (size_t i = 0; i < usedFonts.size(); ++i) {
- int halfLeading = (lineHeight - usedFonts[i]->ascent() - usedFonts[i]->descent()) / 2;
- baseline = max(baseline, halfLeading + usedFonts[i]->ascent());
+ for (size_t i = 0; i < usedFonts->size(); ++i) {
+ int halfLeading = (lineHeight - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent()) / 2;
+ baseline = max(baseline, halfLeading + usedFonts->at(i)->ascent());
}
}
} else {
@@ -562,15 +565,17 @@ void InlineFlowBox::computeVerticalOverflow(int lineTop, int lineBottom, bool st
continue;
int strokeOverflow = static_cast<int>(ceilf(rt->style()->textStrokeWidth() / 2.0f));
-
- int topGlyphOverflow = -strokeOverflow;
- int bottomGlyphOverflow = strokeOverflow;
-
+
+ GlyphOverflow* glyphOverflow = static_cast<InlineTextBox*>(curr)->glyphOverflow();
+
+ int topGlyphOverflow = -strokeOverflow - (glyphOverflow ? glyphOverflow->top : 0);
+ int bottomGlyphOverflow = strokeOverflow + (glyphOverflow ? glyphOverflow->bottom : 0);
+
int childOverflowTop = topGlyphOverflow;
int childOverflowBottom = bottomGlyphOverflow;
- for (ShadowData* shadow = rt->style()->textShadow(); shadow; shadow = shadow->next) {
- childOverflowTop = min(childOverflowTop, shadow->y - shadow->blur + topGlyphOverflow);
- childOverflowBottom = max(childOverflowBottom, shadow->y + shadow->blur + bottomGlyphOverflow);
+ for (const ShadowData* shadow = rt->style()->textShadow(); shadow; shadow = shadow->next()) {
+ childOverflowTop = min(childOverflowTop, shadow->y() - shadow->blur() + topGlyphOverflow);
+ childOverflowBottom = max(childOverflowBottom, shadow->y() + shadow->blur() + bottomGlyphOverflow);
}
topVisualOverflow = min(curr->y() + childOverflowTop, topVisualOverflow);
@@ -703,11 +708,11 @@ void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, con
// FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
// but it isn't even clear how this should work at all.
int xOffsetOnLine = 0;
- for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
+ for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
xOffsetOnLine += curr->width();
int startX = tx - xOffsetOnLine;
int totalWidth = xOffsetOnLine;
- for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
totalWidth += curr->width();
paintInfo.context->save();
paintInfo.context->clip(IntRect(tx, ty, width(), height()));
@@ -760,7 +765,7 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int
if (styleToUse->boxShadow())
paintBoxShadow(context, styleToUse, Normal, tx, ty, w, h);
- Color c = styleToUse->backgroundColor();
+ Color c = styleToUse->visitedDependentColor(CSSPropertyBackgroundColor);
paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), tx, ty, w, h);
if (styleToUse->boxShadow())
@@ -788,11 +793,11 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int
// FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
// but it isn't even clear how this should work at all.
int xOffsetOnLine = 0;
- for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
+ for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
xOffsetOnLine += curr->width();
int startX = tx - xOffsetOnLine;
int totalWidth = xOffsetOnLine;
- for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
totalWidth += curr->width();
context->save();
context->clip(IntRect(tx, ty, w, h));
@@ -859,11 +864,11 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty
// We have a mask image that spans multiple lines.
// We need to adjust _tx and _ty by the width of all previous lines.
int xOffsetOnLine = 0;
- for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
+ for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
xOffsetOnLine += curr->width();
int startX = tx - xOffsetOnLine;
int totalWidth = xOffsetOnLine;
- for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
totalWidth += curr->width();
paintInfo.context->save();
paintInfo.context->clip(IntRect(tx, ty, w, h));
@@ -957,7 +962,7 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
tx += borderLeft() + paddingLeft();
Color underline, overline, linethrough;
- underline = overline = linethrough = styleToUse->color();
+ underline = overline = linethrough = styleToUse->visitedDependentColor(CSSPropertyColor);
if (!parent())
renderer()->getTextDecorationColors(deco, underline, overline, linethrough);
@@ -976,15 +981,15 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
bool setClip = false;
int extraOffset = 0;
- ShadowData* shadow = styleToUse->textShadow();
- if (!linesAreOpaque && shadow && shadow->next) {
+ const ShadowData* shadow = styleToUse->textShadow();
+ if (!linesAreOpaque && shadow && shadow->next()) {
IntRect clipRect(tx, ty, w, baselinePos + 2);
- for (ShadowData* s = shadow; s; s = s->next) {
+ for (const ShadowData* s = shadow; s; s = s->next()) {
IntRect shadowRect(tx, ty, w, baselinePos + 2);
- shadowRect.inflate(s->blur);
- shadowRect.move(s->x, s->y);
+ shadowRect.inflate(s->blur());
+ shadowRect.move(s->x(), s->y());
clipRect.unite(shadowRect);
- extraOffset = max(extraOffset, max(0, s->y) + s->blur);
+ extraOffset = max(extraOffset, max(0, s->y()) + s->blur());
}
context->save();
context->clip(clipRect);
@@ -997,14 +1002,14 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
bool setShadow = false;
do {
if (shadow) {
- if (!shadow->next) {
+ if (!shadow->next()) {
// The last set of lines paints normally inside the clip.
ty -= extraOffset;
extraOffset = 0;
}
- context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color, colorSpace);
+ context->setShadow(IntSize(shadow->x(), shadow->y() - extraOffset), shadow->blur(), shadow->color(), colorSpace);
setShadow = true;
- shadow = shadow->next;
+ shadow = shadow->next();
}
if (paintUnderline) {
diff --git a/WebCore/rendering/InlineFlowBox.h b/WebCore/rendering/InlineFlowBox.h
index 23b5cc9..ecb4724 100644
--- a/WebCore/rendering/InlineFlowBox.h
+++ b/WebCore/rendering/InlineFlowBox.h
@@ -21,7 +21,7 @@
#ifndef InlineFlowBox_h
#define InlineFlowBox_h
-#include "InlineRunBox.h"
+#include "InlineBox.h"
#include "RenderOverflow.h"
namespace WebCore {
@@ -30,12 +30,14 @@ class HitTestRequest;
class HitTestResult;
class RenderLineBoxList;
-class InlineFlowBox : public InlineRunBox {
+class InlineFlowBox : public InlineBox {
public:
InlineFlowBox(RenderObject* obj)
- : InlineRunBox(obj)
+ : InlineBox(obj)
, m_firstChild(0)
, m_lastChild(0)
+ , m_prevLineBox(0)
+ , m_nextLineBox(0)
, m_includeLeftEdge(false)
, m_includeRightEdge(false)
#ifndef NDEBUG
@@ -54,8 +56,10 @@ public:
virtual ~InlineFlowBox();
#endif
- InlineFlowBox* prevFlowBox() const { return static_cast<InlineFlowBox*>(m_prevLine); }
- InlineFlowBox* nextFlowBox() const { return static_cast<InlineFlowBox*>(m_nextLine); }
+ InlineFlowBox* prevLineBox() const { return m_prevLineBox; }
+ InlineFlowBox* nextLineBox() const { return m_nextLineBox; }
+ void setNextLineBox(InlineFlowBox* n) { m_nextLineBox = n; }
+ void setPreviousLineBox(InlineFlowBox* p) { m_prevLineBox = p; }
InlineBox* firstChild() const { checkConsistency(); return m_firstChild; }
InlineBox* lastChild() const { checkConsistency(); return m_lastChild; }
@@ -164,12 +168,14 @@ public:
protected:
OwnPtr<RenderOverflow> m_overflow;
-private:
virtual bool isInlineFlowBox() const { return true; }
InlineBox* m_firstChild;
InlineBox* m_lastChild;
+ InlineFlowBox* m_prevLineBox; // The previous box that also uses our RenderObject
+ InlineFlowBox* m_nextLineBox; // The next box that also uses our RenderObject
+
bool m_includeLeftEdge : 1;
bool m_includeRightEdge : 1;
bool m_hasTextChildren : 1;
diff --git a/WebCore/rendering/InlineRunBox.h b/WebCore/rendering/InlineRunBox.h
deleted file mode 100644
index cbc82d5..0000000
--- a/WebCore/rendering/InlineRunBox.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2003, 2006 Apple Computer, Inc.
- *
- * 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 InlineRunBox_h
-#define InlineRunBox_h
-
-#include "InlineBox.h"
-
-namespace WebCore {
-
-class InlineRunBox : public InlineBox {
-public:
- InlineRunBox(RenderObject* obj)
- : InlineBox(obj)
- , m_prevLine(0)
- , m_nextLine(0)
- {
- }
-
- InlineRunBox* prevLineBox() const { return m_prevLine; }
- InlineRunBox* nextLineBox() const { return m_nextLine; }
- void setNextLineBox(InlineRunBox* n) { m_nextLine = n; }
- void setPreviousLineBox(InlineRunBox* p) { m_prevLine = p; }
-
- virtual void paintBoxDecorations(RenderObject::PaintInfo&, int /*tx*/, int /*ty*/) { }
- virtual void paintTextDecorations(RenderObject::PaintInfo&, int /*tx*/, int /*ty*/, bool /*paintedChildren*/ = false) { }
-
-protected:
- InlineRunBox* m_prevLine; // The previous box that also uses our RenderObject
- InlineRunBox* m_nextLine; // The next box that also uses our RenderObject
-};
-
-} // namespace WebCore
-
-#endif // InlineRunBox_h
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 9f17b0c..9c28b42 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -273,7 +273,7 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in
return false;
}
-static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, int startOffset, int endOffset, int truncationPoint, const IntPoint& textOrigin, int x, int y, int w, int h, ShadowData* shadow, bool stroked)
+static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, int startOffset, int endOffset, int truncationPoint, const IntPoint& textOrigin, int x, int y, int w, int h, const ShadowData* shadow, bool stroked)
{
Color fillColor = context->fillColor();
ColorSpace fillColorSpace = context->fillColorSpace();
@@ -285,11 +285,11 @@ static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
IntSize extraOffset;
if (shadow) {
- IntSize shadowOffset(shadow->x, shadow->y);
- int shadowBlur = shadow->blur;
- const Color& shadowColor = shadow->color;
+ IntSize shadowOffset(shadow->x(), shadow->y());
+ int shadowBlur = shadow->blur();
+ const Color& shadowColor = shadow->color();
- if (shadow->next || stroked || !opaque) {
+ if (shadow->next() || stroked || !opaque) {
IntRect shadowRect(x, y, w, h);
shadowRect.inflate(shadowBlur);
shadowRect.move(shadowOffset);
@@ -315,12 +315,12 @@ static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
if (!shadow)
break;
- if (shadow->next || stroked || !opaque)
+ if (shadow->next() || stroked || !opaque)
context->restore();
else
context->clearShadow();
- shadow = shadow->next;
+ shadow = shadow->next();
} while (shadow || stroked || !opaque);
}
@@ -405,24 +405,20 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
Color textFillColor;
Color textStrokeColor;
float textStrokeWidth = styleToUse->textStrokeWidth();
- ShadowData* textShadow = paintInfo.forceBlackText ? 0 : styleToUse->textShadow();
+ const ShadowData* textShadow = paintInfo.forceBlackText ? 0 : styleToUse->textShadow();
if (paintInfo.forceBlackText) {
textFillColor = Color::black;
textStrokeColor = Color::black;
} else {
- textFillColor = styleToUse->textFillColor();
- if (!textFillColor.isValid())
- textFillColor = styleToUse->color();
-
+ textFillColor = styleToUse->visitedDependentColor(CSSPropertyWebkitTextFillColor);
+
// Make the text fill color legible against a white background
if (styleToUse->forceBackgroundsToWhite())
textFillColor = correctedTextColor(textFillColor, Color::white);
- textStrokeColor = styleToUse->textStrokeColor();
- if (!textStrokeColor.isValid())
- textStrokeColor = styleToUse->color();
-
+ textStrokeColor = styleToUse->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
+
// Make the text stroke color legible against a white background
if (styleToUse->forceBackgroundsToWhite())
textStrokeColor = correctedTextColor(textStrokeColor, Color::white);
@@ -434,7 +430,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
Color selectionFillColor = textFillColor;
Color selectionStrokeColor = textStrokeColor;
float selectionStrokeWidth = textStrokeWidth;
- ShadowData* selectionShadow = textShadow;
+ const ShadowData* selectionShadow = textShadow;
if (haveSelection) {
// Check foreground color first.
Color foreground = paintInfo.forceBlackText ? Color::black : renderer()->selectionForegroundColor();
@@ -445,7 +441,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
}
if (RenderStyle* pseudoStyle = renderer()->getCachedPseudoStyle(SELECTION)) {
- ShadowData* shadow = paintInfo.forceBlackText ? 0 : pseudoStyle->textShadow();
+ const ShadowData* shadow = paintInfo.forceBlackText ? 0 : pseudoStyle->textShadow();
if (shadow != selectionShadow) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
@@ -517,7 +513,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
// Paint decorations
if (d != TDNONE && paintInfo.phase != PaintPhaseSelection && styleToUse->htmlHacks()) {
- context->setStrokeColor(styleToUse->color(), styleToUse->colorSpace());
+ context->setStrokeColor(styleToUse->visitedDependentColor(CSSPropertyColor), styleToUse->colorSpace());
paintDecoration(context, tx, ty, d, textShadow);
}
@@ -577,7 +573,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, int tx, int ty, Ren
if (sPos >= ePos)
return;
- Color textColor = style->color();
+ Color textColor = style->visitedDependentColor(CSSPropertyColor);
Color c = renderer()->selectionBackgroundColor();
if (!c.isValid() || c.alpha() == 0)
return;
@@ -644,7 +640,7 @@ void InlineTextBox::paintCustomHighlight(int tx, int ty, const AtomicString& typ
#endif
-void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, int deco, ShadowData* shadow)
+void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, int deco, const ShadowData* shadow)
{
tx += m_x;
ty += m_y;
@@ -673,15 +669,15 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
bool setClip = false;
int extraOffset = 0;
- if (!linesAreOpaque && shadow && shadow->next) {
+ if (!linesAreOpaque && shadow && shadow->next()) {
context->save();
IntRect clipRect(tx, ty, width, baseline + 2);
- for (ShadowData* s = shadow; s; s = s->next) {
+ for (const ShadowData* s = shadow; s; s = s->next()) {
IntRect shadowRect(tx, ty, width, baseline + 2);
- shadowRect.inflate(s->blur);
- shadowRect.move(s->x, s->y);
+ shadowRect.inflate(s->blur());
+ shadowRect.move(s->x(), s->y());
clipRect.unite(shadowRect);
- extraOffset = max(extraOffset, max(0, s->y) + s->blur);
+ extraOffset = max(extraOffset, max(0, s->y()) + s->blur());
}
context->save();
context->clip(clipRect);
@@ -695,14 +691,14 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
do {
if (shadow) {
- if (!shadow->next) {
+ if (!shadow->next()) {
// The last set of lines paints normally inside the clip.
ty -= extraOffset;
extraOffset = 0;
}
- context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color, colorSpace);
+ context->setShadow(IntSize(shadow->x(), shadow->y() - extraOffset), shadow->blur(), shadow->color(), colorSpace);
setShadow = true;
- shadow = shadow->next;
+ shadow = shadow->next();
}
if (deco & UNDERLINE) {
@@ -1029,30 +1025,48 @@ bool InlineTextBox::containsCaretOffset(int offset) const
return true;
}
-typedef HashMap<InlineTextBox*, Vector<const SimpleFontData*> > FallbackFontsMap;
-static FallbackFontsMap* gFallbackFontsMap;
-
void InlineTextBox::setFallbackFonts(const HashSet<const SimpleFontData*>& fallbackFonts)
{
- if (!gFallbackFontsMap)
- gFallbackFontsMap = new FallbackFontsMap;
+ if (!s_glyphOverflowAndFallbackFontsMap)
+ s_glyphOverflowAndFallbackFontsMap = new GlyphOverflowAndFallbackFontsMap;
- FallbackFontsMap::iterator it = gFallbackFontsMap->set(this, Vector<const SimpleFontData*>()).first;
- ASSERT(it->second.isEmpty());
- copyToVector(fallbackFonts, it->second);
+ GlyphOverflowAndFallbackFontsMap::iterator it = s_glyphOverflowAndFallbackFontsMap->add(this, make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first;
+ ASSERT(it->second.first.isEmpty());
+ copyToVector(fallbackFonts, it->second.first);
}
-void InlineTextBox::takeFallbackFonts(Vector<const SimpleFontData*>& fallbackFonts)
+Vector<const SimpleFontData*>* InlineTextBox::fallbackFonts() const
{
- if (!gFallbackFontsMap)
- return;
+ if (!s_glyphOverflowAndFallbackFontsMap)
+ return 0;
- FallbackFontsMap::iterator it = gFallbackFontsMap->find(this);
- if (it == gFallbackFontsMap->end())
- return;
+ GlyphOverflowAndFallbackFontsMap::iterator it = s_glyphOverflowAndFallbackFontsMap->find(this);
+ if (it == s_glyphOverflowAndFallbackFontsMap->end())
+ return 0;
+
+ return &it->second.first;
+}
+
+InlineTextBox::GlyphOverflowAndFallbackFontsMap* InlineTextBox::s_glyphOverflowAndFallbackFontsMap = 0;
+
+void InlineTextBox::setGlyphOverflow(const GlyphOverflow& glyphOverflow)
+{
+ if (!s_glyphOverflowAndFallbackFontsMap)
+ s_glyphOverflowAndFallbackFontsMap = new GlyphOverflowAndFallbackFontsMap;
+
+ GlyphOverflowAndFallbackFontsMap::iterator it = s_glyphOverflowAndFallbackFontsMap->add(this, make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first;
+ it->second.second = glyphOverflow;
+}
+
+GlyphOverflow* InlineTextBox::glyphOverflow() const
+{
+ if (!s_glyphOverflowAndFallbackFontsMap)
+ return 0;
+ GlyphOverflowAndFallbackFontsMap::iterator it = s_glyphOverflowAndFallbackFontsMap->find(this);
+ if (it == s_glyphOverflowAndFallbackFontsMap->end())
+ return 0;
- fallbackFonts.swap(it->second);
- gFallbackFontsMap->remove(it);
+ return &it->second.second;
}
} // namespace WebCore
diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h
index 0a83ddd..2eb0c42 100644
--- a/WebCore/rendering/InlineTextBox.h
+++ b/WebCore/rendering/InlineTextBox.h
@@ -23,7 +23,7 @@
#ifndef InlineTextBox_h
#define InlineTextBox_h
-#include "InlineRunBox.h"
+#include "InlineBox.h"
#include "RenderText.h" // so textRenderer() can be inline
namespace WebCore {
@@ -37,18 +37,22 @@ const unsigned short cFullTruncation = USHRT_MAX - 1;
void updateGraphicsContext(GraphicsContext*, const Color& fillColor, const Color& strokeColor, float strokeThickness, ColorSpace);
Color correctedTextColor(Color textColor, Color backgroundColor);
-class InlineTextBox : public InlineRunBox {
+class InlineTextBox : public InlineBox {
public:
InlineTextBox(RenderObject* obj)
- : InlineRunBox(obj)
+ : InlineBox(obj)
+ , m_prevTextBox(0)
+ , m_nextTextBox(0)
, m_start(0)
, m_len(0)
, m_truncation(cNoTruncation)
{
}
- InlineTextBox* nextTextBox() const { return static_cast<InlineTextBox*>(nextLineBox()); }
- InlineTextBox* prevTextBox() const { return static_cast<InlineTextBox*>(prevLineBox()); }
+ InlineTextBox* prevTextBox() const { return m_prevTextBox; }
+ InlineTextBox* nextTextBox() const { return m_nextTextBox; }
+ void setNextTextBox(InlineTextBox* n) { m_nextTextBox = n; }
+ void setPreviousTextBox(InlineTextBox* p) { m_prevTextBox = p; }
unsigned start() const { return m_start; }
unsigned end() const { return m_len ? m_start + m_len - 1 : m_start; }
@@ -60,7 +64,16 @@ public:
void offsetRun(int d) { m_start += d; }
void setFallbackFonts(const HashSet<const SimpleFontData*>&);
- void takeFallbackFonts(Vector<const SimpleFontData*>&);
+ Vector<const SimpleFontData*>* fallbackFonts() const;
+
+ void setGlyphOverflow(const GlyphOverflow&);
+ GlyphOverflow* glyphOverflow() const;
+
+ static void clearGlyphOverflowAndFallbackFontMap()
+ {
+ if (s_glyphOverflowAndFallbackFontsMap)
+ s_glyphOverflowAndFallbackFontsMap->clear();
+ }
unsigned short truncation() { return m_truncation; }
@@ -116,12 +129,18 @@ public:
bool containsCaretOffset(int offset) const; // false for offset after line break
private:
+ InlineTextBox* m_prevTextBox; // The previous box that also uses our RenderObject
+ InlineTextBox* m_nextTextBox; // The next box that also uses our RenderObject
+
int m_start;
unsigned short m_len;
unsigned short m_truncation; // Where to truncate when text overflow is applied. We use special constants to
// denote no truncation (the whole run paints) and full truncation (nothing paints at all).
+ typedef HashMap<const InlineTextBox*, pair<Vector<const SimpleFontData*>, GlyphOverflow> > GlyphOverflowAndFallbackFontsMap;
+ static GlyphOverflowAndFallbackFontsMap* s_glyphOverflowAndFallbackFontsMap;
+
protected:
void paintCompositionBackground(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&, int startPos, int endPos);
void paintDocumentMarkers(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&, bool background);
@@ -131,7 +150,7 @@ protected:
#endif
private:
- void paintDecoration(GraphicsContext*, int tx, int ty, int decoration, ShadowData*);
+ void paintDecoration(GraphicsContext*, int tx, int ty, int decoration, const ShadowData*);
void paintSelection(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&);
void paintSpellingOrGrammarMarker(GraphicsContext*, int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&, bool grammar);
void paintTextMatchMarker(GraphicsContext*, int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&);
diff --git a/WebCore/rendering/LayoutState.cpp b/WebCore/rendering/LayoutState.cpp
index 883f74d..c94e77b 100644
--- a/WebCore/rendering/LayoutState.cpp
+++ b/WebCore/rendering/LayoutState.cpp
@@ -62,20 +62,17 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const IntSize&
m_clipped = !fixed && prev->m_clipped;
if (m_clipped)
m_clipRect = prev->m_clipRect;
+
if (renderer->hasOverflowClip()) {
- int x = m_offset.width();
- int y = m_offset.height();
RenderLayer* layer = renderer->layer();
- IntRect clipRect(x, y, layer->width(), layer->height());
- clipRect.move(renderer->view()->layoutDelta());
+ IntRect clipRect(toPoint(m_offset) + renderer->view()->layoutDelta(), layer->size());
if (m_clipped)
m_clipRect.intersect(clipRect);
else {
m_clipRect = clipRect;
m_clipped = true;
}
- layer->subtractScrolledContentOffset(x, y);
- m_offset = IntSize(x, y);
+ m_offset -= layer->scrolledContentOffset();
}
m_layoutDelta = m_next->m_layoutDelta;
diff --git a/WebCore/rendering/MediaControlElements.cpp b/WebCore/rendering/MediaControlElements.cpp
index 2b7a8c8..569f214 100644
--- a/WebCore/rendering/MediaControlElements.cpp
+++ b/WebCore/rendering/MediaControlElements.cpp
@@ -615,6 +615,9 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event)
if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
return;
+ if (!attached())
+ return;
+
if (event->type() == eventNames().mousedownEvent)
m_mediaElement->beginScrubbing();
@@ -660,6 +663,9 @@ void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
return;
+ if (!attached())
+ return;
+
MediaControlInputElement::defaultEventHandler(event);
if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 62e177d..3f53456 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -187,7 +187,7 @@ void RenderBlock::destroy()
// that will outlast this block. In the non-anonymous block case those
// children will be destroyed by the time we return from this function.
if (isAnonymousBlock()) {
- for (InlineFlowBox* box = firstLineBox(); box; box = box->nextFlowBox()) {
+ for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
while (InlineBox* childBox = box->firstChild())
childBox->remove();
}
@@ -265,8 +265,14 @@ void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
// Make sure we don't append things after :after-generated content if we have it.
- if (!beforeChild && isAfterContent(lastChild()))
- beforeChild = lastChild();
+ if (!beforeChild) {
+ RenderObject* lastRenderer = lastChild();
+
+ if (isAfterContent(lastRenderer))
+ beforeChild = lastRenderer;
+ else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild()))
+ beforeChild = lastRenderer->lastChild();
+ }
bool madeBoxesNonInline = false;
@@ -786,8 +792,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
if (previousHeight != height())
relayoutChildren = true;
- // It's weird that we're treating float information as normal flow overflow, but we do this because floatRect() isn't
- // able to be propagated up the render tree yet. Overflow information is however. This check is designed to catch anyone
+ // This check is designed to catch anyone
// who wasn't going to propagate float information up to the parent and yet could potentially be painted by its ancestor.
if (isRoot() || expandsToEncloseOverhangingFloats())
addOverflowFromFloats();
@@ -827,11 +832,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
if (hasOverflowClip()) {
// Adjust repaint rect for scroll offset
- int x = repaintRect.x();
- int y = repaintRect.y();
- layer()->subtractScrolledContentOffset(x, y);
- repaintRect.setX(x);
- repaintRect.setY(y);
+ repaintRect.move(-layer()->scrolledContentOffset());
// Don't allow this rect to spill out of our overflow box.
repaintRect.intersect(IntRect(0, 0, width(), height()));
@@ -1568,7 +1569,7 @@ void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
{
- const Color& ruleColor = style()->columnRuleColor();
+ const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
bool ruleTransparent = style()->columnRuleIsTransparent();
EBorderStyle ruleStyle = style()->columnRuleStyle();
int ruleWidth = style()->columnRuleWidth();
@@ -1603,7 +1604,7 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
int ruleTop = ty + borderTop() + paddingTop();
int ruleBottom = ruleTop + contentHeight();
drawLineForBoxSide(paintInfo.context, ruleStart, ruleTop, ruleEnd, ruleBottom,
- style()->direction() == LTR ? BSLeft : BSRight, ruleColor, style()->color(), ruleStyle, 0, 0);
+ style()->direction() == LTR ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
}
ruleX = currXOffset;
@@ -1680,16 +1681,15 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
// Check for page-break-before: always, and if it's set, break and bail.
- if (isPrinting && !childrenInline() && child->style()->pageBreakBefore() == PBALWAYS &&
- inRootBlockContext() && (ty + child->y()) > paintInfo.rect.y() &&
- (ty + child->y()) < paintInfo.rect.bottom()) {
+ if (isPrinting && !childrenInline() && child->style()->pageBreakBefore() == PBALWAYS
+ && (ty + child->y()) > paintInfo.rect.y()
+ && (ty + child->y()) < paintInfo.rect.bottom()) {
view()->setBestTruncatedAt(ty + child->y(), this, true);
return;
}
// Check for page-break-inside: avoid, and it it's set, break and bail.
if (isPrinting && !childrenInline() && child->style()->pageBreakInside() == PBAVOID
- && inRootBlockContext()
&& ty + child->y() > paintInfo.rect.y()
&& ty + child->y() < paintInfo.rect.bottom()
&& ty + child->y() + child->height() > paintInfo.rect.bottom()) {
@@ -1701,9 +1701,9 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
child->paint(info, tx, ty);
// Check for page-break-after: always, and if it's set, break and bail.
- if (isPrinting && !childrenInline() && child->style()->pageBreakAfter() == PBALWAYS &&
- inRootBlockContext() && (ty + child->y() + child->height()) > paintInfo.rect.y() &&
- (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
+ if (isPrinting && !childrenInline() && child->style()->pageBreakAfter() == PBALWAYS
+ && (ty + child->y() + child->height()) > paintInfo.rect.y()
+ && (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginBottom()), this, true);
return;
}
@@ -1750,11 +1750,14 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
if (paintPhase == PaintPhaseBlockBackground)
return;
- // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).s
+ // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
int scrolledX = tx;
int scrolledY = ty;
- if (hasOverflowClip())
- layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
+ if (hasOverflowClip()) {
+ IntSize offset = layer()->scrolledContentOffset();
+ scrolledX -= offset.width();
+ scrolledY -= offset.height();
+ }
// 2. paint contents
if (paintPhase != PaintPhaseSelfOutline) {
@@ -1780,7 +1783,7 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
// 5. paint outline.
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
- paintOutline(paintInfo.context, tx, ty, width(), height(), style());
+ paintOutline(paintInfo.context, tx, ty, width(), height());
// 6. paint continuation outlines.
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
@@ -1966,18 +1969,16 @@ GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintC
// FIXME: this is broken with transforms
TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
mapLocalToContainer(repaintContainer, false, false, transformState);
- FloatPoint offsetFromRepaintContainer = transformState.mappedPoint();
- int x = offsetFromRepaintContainer.x();
- int y = offsetFromRepaintContainer.y();
+ IntPoint offsetFromRepaintContainer = roundedIntPoint(transformState.mappedPoint());
if (hasOverflowClip())
- layer()->subtractScrolledContentOffset(x, y);
+ offsetFromRepaintContainer -= layer()->scrolledContentOffset();
int lastTop = 0;
int lastLeft = leftSelectionOffset(this, lastTop);
int lastRight = rightSelectionOffset(this, lastTop);
- return fillSelectionGaps(this, x, y, x, y, lastTop, lastLeft, lastRight);
+ return fillSelectionGaps(this, offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), lastTop, lastLeft, lastRight);
}
void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
@@ -2380,8 +2381,14 @@ void RenderBlock::removeFloatingObject(RenderBox* o)
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
while (it.current()) {
if (it.current()->m_renderer == o) {
- if (childrenInline())
- markLinesDirtyInVerticalRange(0, it.current()->m_bottom);
+ if (childrenInline()) {
+ int bottom = it.current()->m_bottom;
+ // Special-case zero- and less-than-zero-height floats: those don't touch
+ // the line that they're on, but it still needs to be dirtied. This is
+ // accomplished by pretending they have a height of 1.
+ bottom = max(bottom, it.current()->m_top + 1);
+ markLinesDirtyInVerticalRange(0, bottom);
+ }
m_floatingObjects->removeRef(it.current());
}
++it;
@@ -2660,24 +2667,6 @@ RenderBlock::floatBottom() const
return bottom;
}
-IntRect RenderBlock::floatRect() const
-{
- IntRect result;
- if (!m_floatingObjects || hasOverflowClip() || hasColumns())
- return result;
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for (; (r = it.current()); ++it) {
- if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
- IntRect childRect = r->m_renderer->visibleOverflowRect();
- childRect.move(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop());
- result.unite(childRect);
- }
- }
-
- return result;
-}
-
int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
{
int bottom = includeSelf && width() > 0 ? height() : 0;
@@ -2846,7 +2835,7 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
if (!includeSelf) {
right = max(right, borderLeft() + paddingLeft() + paddingRight() + relativeOffset);
if (childrenInline()) {
- for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) {
+ for (InlineFlowBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) {
int childRightEdge = currBox->x() + currBox->width();
// If this node is a root editable element, then the rightmostPosition should account for a caret at the end.
@@ -2941,7 +2930,7 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
}
if (!includeSelf && firstLineBox()) {
- for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox())
+ for (InlineFlowBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox())
left = min(left, (int)currBox->x() + relativeOffset);
}
@@ -3050,8 +3039,8 @@ void RenderBlock::clearFloats()
addIntrudingFloats(block, xoffset, offset);
if (childrenInline()) {
- int changeTop = INT_MAX;
- int changeBottom = INT_MIN;
+ int changeTop = numeric_limits<int>::max();
+ int changeBottom = numeric_limits<int>::min();
if (m_floatingObjects) {
for (FloatingObject* f = m_floatingObjects->first(); f; f = m_floatingObjects->next()) {
FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
@@ -3228,6 +3217,32 @@ void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove
}
}
+int RenderBlock::visibleTopOfHighestFloatExtendingBelow(int bottom, int maxHeight) const
+{
+ int top = bottom;
+ if (m_floatingObjects) {
+ FloatingObject* floatingObject;
+ for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); (floatingObject = it.current()); ++it) {
+ RenderBox* floatingBox = floatingObject->m_renderer;
+ IntRect visibleOverflow = floatingBox->visibleOverflowRect();
+ visibleOverflow.move(floatingBox->x(), floatingBox->y());
+ if (visibleOverflow.y() < top && visibleOverflow.bottom() > bottom && visibleOverflow.height() <= maxHeight && floatingBox->containingBlock() == this)
+ top = visibleOverflow.y();
+ }
+ }
+
+ if (!childrenInline()) {
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->isFloatingOrPositioned() || !child->isRenderBlock())
+ continue;
+ RenderBlock* childBlock = toRenderBlock(child);
+ top = min(top, childBlock->y() + childBlock->visibleTopOfHighestFloatExtendingBelow(bottom - childBlock->y(), maxHeight));
+ }
+ }
+
+ return top;
+}
+
int RenderBlock::getClearDelta(RenderBox* child, int yPos)
{
// There is no need to compute clearance if we have no floats.
@@ -3319,8 +3334,11 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Hit test descendants first.
int scrolledX = tx;
int scrolledY = ty;
- if (hasOverflowClip())
- layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
+ if (hasOverflowClip()) {
+ IntSize offset = layer()->scrolledContentOffset();
+ scrolledX -= offset.width();
+ scrolledY -= offset.height();
+ }
// Hit test contents if we don't have columns.
if (!hasColumns() && hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction))
@@ -3595,15 +3613,16 @@ VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
void RenderBlock::offsetForContents(int& tx, int& ty) const
{
+ IntPoint contentsPoint(tx, ty);
+
if (hasOverflowClip())
- layer()->addScrolledContentOffset(tx, ty);
+ contentsPoint += layer()->scrolledContentOffset();
- if (hasColumns()) {
- IntPoint contentsPoint(tx, ty);
+ if (hasColumns())
adjustPointToColumnContents(contentsPoint);
- tx = contentsPoint.x();
- ty = contentsPoint.y();
- }
+
+ tx = contentsPoint.x();
+ ty = contentsPoint.y();
}
int RenderBlock::availableWidth() const
@@ -3765,11 +3784,13 @@ int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
// This represents the real column position.
IntRect colRect(currX, top, desiredColumnWidth, colHeight);
-
+
+ int truncationPoint = visibleTopOfHighestFloatExtendingBelow(currY + colHeight, colHeight);
+
// For the simulated paint, we pretend like everything is in one long strip.
- IntRect pageRect(left, currY, desiredColumnWidth, colHeight);
+ IntRect pageRect(left, currY, desiredColumnWidth, truncationPoint - currY);
v->setPrintRect(pageRect);
- v->setTruncatedAt(currY + colHeight);
+ v->setTruncatedAt(truncationPoint);
GraphicsContext context((PlatformGraphicsContext*)0);
RenderObject::PaintInfo paintInfo(&context, pageRect, PaintPhaseForeground, false, 0, 0);
@@ -3784,7 +3805,7 @@ int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
int adjustedBottom = v->bestTruncatedAt();
if (adjustedBottom <= currY)
- adjustedBottom = currY + colHeight;
+ adjustedBottom = truncationPoint;
colRect.setHeight(adjustedBottom - currY);
@@ -3859,8 +3880,20 @@ void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
// Add in half the column gap to the left and right of the rect.
IntRect colRect = colRects->at(i);
IntRect gapAndColumnRect(colRect.x() - leftGap, colRect.y(), colRect.width() + colGap, colRect.height());
-
- if (gapAndColumnRect.contains(point)) {
+
+ if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.right()) {
+ // FIXME: The clamping that follows is not completely right for right-to-left
+ // content.
+ // Clamp everything above the column to its top left.
+ if (point.y() < gapAndColumnRect.y())
+ point = gapAndColumnRect.location();
+ // Clamp everything below the column to the next column's top left. If there is
+ // no next column, this still maps to just after this column.
+ else if (point.y() >= gapAndColumnRect.bottom()) {
+ point = gapAndColumnRect.location();
+ point.move(0, gapAndColumnRect.height());
+ }
+
// We're inside the column. Translate the x and y into our column coordinate space.
point.move(columnPoint.x() - colRect.x(), yOffset);
return;
@@ -4635,7 +4668,7 @@ void RenderBlock::updateFirstLetter()
// Drill into inlines looking for our first text child.
RenderObject* currChild = firstLetterBlock->firstChild();
- while (currChild && currChild->needsLayout() && (!currChild->isReplaced() || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
+ while (currChild && currChild->needsLayout() && ((!currChild->isReplaced() && !currChild->isRenderButton() && !currChild->isMenuList()) || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
if (currChild->isFloatingOrPositioned()) {
if (currChild->style()->styleType() == FIRST_LETTER)
break;
@@ -4722,9 +4755,7 @@ void RenderBlock::updateFirstLetter()
// construct text fragment for the first letter
RenderTextFragment* letter =
new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
- RefPtr<RenderStyle> newStyle = RenderStyle::create();
- newStyle->inheritFrom(pseudoStyle);
- letter->setStyle(newStyle.release());
+ letter->setStyle(pseudoStyle);
firstLetter->addChild(letter);
textObj->destroy();
@@ -4733,17 +4764,6 @@ void RenderBlock::updateFirstLetter()
}
}
-bool RenderBlock::inRootBlockContext() const
-{
- if (isTableCell() || isFloatingOrPositioned() || hasOverflowClip())
- return false;
-
- if (isRoot() || isRenderView())
- return true;
-
- return containingBlock()->inRootBlockContext();
-}
-
// Helper methods for obtaining the last line, computing line counts and heights for line counts
// (crawling into blocks).
static bool shouldCheckLines(RenderObject* obj)
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index c1f8dde..751a1df 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -74,6 +74,7 @@ public:
void insertPositionedObject(RenderBox*);
void removePositionedObject(RenderBox*);
void removePositionedObjects(RenderBlock*);
+ ListHashSet<RenderBox*>* positionedObjects() const { return m_positionedObjects; }
void addPercentHeightDescendant(RenderBox*);
static void removePercentHeightDescendant(RenderBox*);
@@ -89,8 +90,6 @@ public:
bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); }
bool containsFloat(RenderObject*);
- IntRect floatRect() const;
-
int lineWidth(int y, bool firstLine) const;
virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
@@ -317,7 +316,6 @@ private:
// Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
// children.
virtual RenderBlock* firstLineBlock() const;
- bool inRootBlockContext() const;
virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth);
virtual RenderStyle* outlineStyleForRepaint() const;
@@ -386,6 +384,7 @@ private:
void calcColumnWidth();
int layoutColumns(int endOfContent = -1, int requestedColumnHeight = -1);
+ int visibleTopOfHighestFloatExtendingBelow(int bottom, int maxHeight) const;
bool expandsToEncloseOverhangingFloats() const;
diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp
index a7f3553..895db66 100644
--- a/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -349,7 +349,8 @@ void RenderBlock::computeHorizontalPositionsForLine(RootInlineBox* lineBox, bool
needsWordSpacing = !isSpaceOrNewline(rt->characters()[r->m_stop - 1]) && r->m_stop == length;
}
HashSet<const SimpleFontData*> fallbackFonts;
- r->m_box->setWidth(rt->width(r->m_start, r->m_stop - r->m_start, totWidth, firstLine, &fallbackFonts));
+ GlyphOverflow glyphOverflow;
+ r->m_box->setWidth(rt->width(r->m_start, r->m_stop - r->m_start, totWidth, firstLine, &fallbackFonts, &glyphOverflow));
if (!fallbackFonts.isEmpty()
#if ENABLE(SVG)
&& !isSVGText()
@@ -358,6 +359,14 @@ void RenderBlock::computeHorizontalPositionsForLine(RootInlineBox* lineBox, bool
ASSERT(r->m_box->isText());
static_cast<InlineTextBox*>(r->m_box)->setFallbackFonts(fallbackFonts);
}
+ if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)
+#if ENABLE(SVG)
+ && !isSVGText()
+#endif
+ ) {
+ ASSERT(r->m_box->isText());
+ static_cast<InlineTextBox*>(r->m_box)->setGlyphOverflow(glyphOverflow);
+ }
} else if (!r->m_object->isRenderInline()) {
RenderBox* renderBox = toRenderBox(r->m_object);
renderBox->calcWidth();
@@ -753,7 +762,6 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
bool endLineMatched = false;
bool checkForEndLineMatch = endLine;
bool checkForFloatsFromLastLine = false;
- int lastHeight = height();
bool isLineEmpty = true;
@@ -842,6 +850,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
// Now position our text runs vertically.
computeVerticalPositionsForLine(lineBox, resolver.firstRun());
+ InlineTextBox::clearGlyphOverflowAndFallbackFontMap();
#if ENABLE(SVG)
// Special SVG text layout code
@@ -878,8 +887,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
} else
m_floatingObjects->first();
for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next()) {
- if (f->m_bottom > lastHeight)
- lastRootBox()->floats().append(f->m_renderer);
+ lastRootBox()->floats().append(f->m_renderer);
ASSERT(f->m_renderer == floats[floatIndex].object);
// If a float's geometry has changed, give up on syncing with clean lines.
if (floats[floatIndex].rect != IntRect(f->m_left, f->m_top, f->m_width, f->m_bottom - f->m_top))
@@ -889,7 +897,6 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
lastFloat = m_floatingObjects->last();
}
- lastHeight = height();
lineMidpointState.reset();
resolver.setPosition(end);
}
@@ -949,10 +956,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
m_floatingObjects->next();
} else
m_floatingObjects->first();
- for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next()) {
- if (f->m_bottom > lastHeight)
- lastRootBox()->floats().append(f->m_renderer);
- }
+ for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next())
+ lastRootBox()->floats().append(f->m_renderer);
lastFloat = m_floatingObjects->last();
}
size_t floatCount = floats.size();
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 66a88e2..bd82683 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -152,6 +152,16 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl
removeFloatingOrPositionedChildFromBlockLists();
}
}
+ if (FrameView *frameView = view()->frameView()) {
+ bool newStyleIsFixed = newStyle && newStyle->position() == FixedPosition;
+ bool oldStyleIsFixed = style() && style()->position() == FixedPosition;
+ if (newStyleIsFixed != oldStyleIsFixed) {
+ if (newStyleIsFixed)
+ frameView->addFixedObject();
+ else
+ frameView->removeFixedObject();
+ }
+ }
RenderBoxModelObject::styleWillChange(diff, newStyle);
}
@@ -321,12 +331,17 @@ FloatQuad RenderBox::absoluteContentQuad() const
return localToAbsoluteQuad(FloatRect(rect));
}
-IntRect RenderBox::outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer) const
+IntRect RenderBox::outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer, IntPoint* cachedOffsetToRepaintContainer) const
{
IntRect box = borderBoundingBox();
adjustRectForOutlineAndShadow(box);
- FloatQuad containerRelativeQuad = localToContainerQuad(FloatRect(box), repaintContainer);
+ FloatQuad containerRelativeQuad = FloatRect(box);
+ if (cachedOffsetToRepaintContainer)
+ containerRelativeQuad.move(cachedOffsetToRepaintContainer->x(), cachedOffsetToRepaintContainer->y());
+ else
+ containerRelativeQuad = localToContainerQuad(containerRelativeQuad, repaintContainer);
+
box = containerRelativeQuad.enclosingBoundingBox();
// FIXME: layoutDelta needs to be applied in parts before/after transforms and
@@ -429,7 +444,7 @@ bool RenderBox::scroll(ScrollDirection direction, ScrollGranularity granularity,
bool RenderBox::canBeScrolledAndHasScrollableArea() const
{
- return canBeProgramaticallyScrolled(false) && (scrollHeight() != clientHeight() || scrollWidth() != clientWidth());
+ return canBeProgramaticallyScrolled(false) && (scrollHeight() != clientHeight() || scrollWidth() != clientWidth());
}
bool RenderBox::canBeProgramaticallyScrolled(bool) const
@@ -1175,10 +1190,9 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, In
IntPoint topLeft = rect.location();
topLeft.move(x(), y());
- if (style()->position() == FixedPosition)
- fixed = true;
+ EPosition position = style()->position();
- if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition) {
+ if (o->isBlockFlow() && position != AbsolutePosition && position != FixedPosition) {
RenderBlock* cb = toRenderBlock(o);
if (cb->hasColumns()) {
IntRect repaintRect(topLeft, rect.size());
@@ -1191,16 +1205,17 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, In
// We are now in our parent container's coordinate space. Apply our transform to obtain a bounding box
// in the parent's coordinate space that encloses us.
if (layer() && layer()->transform()) {
- fixed = false;
+ fixed = position == FixedPosition;
rect = layer()->transform()->mapRect(rect);
// FIXME: this clobbers topLeft adjustment done for multicol above
topLeft = rect.location();
topLeft.move(x(), y());
- }
+ } else if (position == FixedPosition)
+ fixed = true;
- if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())
+ if (position == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())
topLeft += toRenderInline(o)->relativePositionedInlineOffset(this);
- else if (style()->position() == RelativePosition && layer()) {
+ else if (position == RelativePosition && layer()) {
// Apply the relative position offset when invalidating a rectangle. The layer
// is translated, but the render box isn't, so we need to do this to get the
// right dirty rect. Since this is called from RenderObject::setStyle, the relative position
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index 2ee368d..68bbd51 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -73,7 +73,7 @@ public:
FloatQuad absoluteContentQuad() const;
// Bounds of the outline box in absolute coords. Respects transforms
- virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const;
+ virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/, IntPoint* cachedOffsetToRepaintContainer) const;
virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
// Use this with caution! No type checking is done!
@@ -271,9 +271,9 @@ public:
virtual void paintMask(PaintInfo&, int tx, int ty);
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
- // Called when a positioned object moves but doesn't change size. A simplified layout is done
- // that just updates the object's position.
- virtual void tryLayoutDoingPositionedMovementOnly()
+ // Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted
+ // that just updates the object's position. If the size does change, the object remains dirty.
+ void tryLayoutDoingPositionedMovementOnly()
{
int oldWidth = width();
calcWidth();
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index f8bf05e..9caf46f 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -131,7 +131,7 @@ bool RenderBoxModelScaleObserver::shouldPaintBackgroundAtLowQuality(GraphicsCont
data = gBoxModelObjects->get(object);
const AffineTransform& currentTransform = context->getCTM();
- bool contextIsScaled = !currentTransform.isIdentityOrTranslation();
+ bool contextIsScaled = !currentTransform.isIdentityOrTranslationOrFlipped();
if (!contextIsScaled && imageSize == size) {
// There is no scale in effect. If we had a scale in effect before, we can just delete this data.
if (data) {
@@ -158,8 +158,10 @@ bool RenderBoxModelScaleObserver::shouldPaintBackgroundAtLowQuality(GraphicsCont
return false;
}
+ const AffineTransform& tr = data->transform();
+ bool scaleUnchanged = tr.a() == currentTransform.a() && tr.b() == currentTransform.b() && tr.c() == currentTransform.c() && tr.d() == currentTransform.d();
// We are scaled, but we painted already at this size, so just keep using whatever mode we last painted with.
- if ((!contextIsScaled || data->transform() == currentTransform) && data->size() == size)
+ if ((!contextIsScaled || scaleUnchanged) && data->size() == size)
return data->useLowQualityScale();
// We have data and our size just changed. If this change happened quickly, go into low quality mode and then set a repaint
@@ -479,7 +481,9 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
context->clip(toRenderBox(this)->overflowClipRect(tx, ty));
// Now adjust our tx, ty, w, h to reflect a scrolled content box with borders at the ends.
- layer()->subtractScrolledContentOffset(tx, ty);
+ IntSize offset = layer()->scrolledContentOffset();
+ tx -= offset.width();
+ ty -= offset.height();
w = bLeft + layer()->scrollWidth() + bRight;
h = borderTop() + layer()->scrollHeight() + borderBottom();
}
@@ -604,7 +608,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this;
Image* image = bg->image(clientForBackgroundImage, tileSize);
- bool useLowQualityScaling = RenderBoxModelScaleObserver::shouldPaintBackgroundAtLowQuality(context, this, image, destRect.size());
+ bool useLowQualityScaling = RenderBoxModelScaleObserver::shouldPaintBackgroundAtLowQuality(context, this, image, tileSize);
context->drawTiledImage(image, style()->colorSpace(), destRect, phase, tileSize, compositeOp, useLowQualityScaling);
}
}
@@ -632,6 +636,7 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
case SizeLength: {
int w = positioningAreaSize.width();
int h = positioningAreaSize.height();
+
Length layerWidth = fillLayer->size().size.width();
Length layerHeight = fillLayer->size().size.height();
@@ -647,15 +652,19 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
// If one of the values is auto we have to use the appropriate
// scale to maintain our aspect ratio.
- if (layerWidth.isAuto() && !layerHeight.isAuto())
- w = image->imageSize(this, style()->effectiveZoom()).width() * h / image->imageSize(this, style()->effectiveZoom()).height();
- else if (!layerWidth.isAuto() && layerHeight.isAuto())
- h = image->imageSize(this, style()->effectiveZoom()).height() * w / image->imageSize(this, style()->effectiveZoom()).width();
- else if (layerWidth.isAuto() && layerHeight.isAuto()) {
- // If both width and height are auto, we just want to use the image's
- // intrinsic size.
- w = image->imageSize(this, style()->effectiveZoom()).width();
- h = image->imageSize(this, style()->effectiveZoom()).height();
+ if (layerWidth.isAuto() && !layerHeight.isAuto()) {
+ IntSize imageIntrinsicSize = image->imageSize(this, style()->effectiveZoom());
+ if (imageIntrinsicSize.height())
+ w = imageIntrinsicSize.width() * h / imageIntrinsicSize.height();
+ } else if (!layerWidth.isAuto() && layerHeight.isAuto()) {
+ IntSize imageIntrinsicSize = image->imageSize(this, style()->effectiveZoom());
+ if (imageIntrinsicSize.width())
+ h = imageIntrinsicSize.height() * w / imageIntrinsicSize.width();
+ } else if (layerWidth.isAuto() && layerHeight.isAuto()) {
+ // If both width and height are auto, use the image's intrinsic size.
+ IntSize imageIntrinsicSize = image->imageSize(this, style()->effectiveZoom());
+ w = imageIntrinsicSize.width();
+ h = imageIntrinsicSize.height();
}
return IntSize(max(1, w), max(1, h));
@@ -663,15 +672,17 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
case Contain:
case Cover: {
IntSize imageIntrinsicSize = image->imageSize(this, 1);
- float horizontalScaleFactor = static_cast<float>(positioningAreaSize.width()) / imageIntrinsicSize.width();
- float verticalScaleFactor = static_cast<float>(positioningAreaSize.height()) / imageIntrinsicSize.height();
+ float horizontalScaleFactor = imageIntrinsicSize.width()
+ ? static_cast<float>(positioningAreaSize.width()) / imageIntrinsicSize.width() : 1;
+ float verticalScaleFactor = imageIntrinsicSize.height()
+ ? static_cast<float>(positioningAreaSize.height()) / imageIntrinsicSize.height() : 1;
float scaleFactor = type == Contain ? min(horizontalScaleFactor, verticalScaleFactor) : max(horizontalScaleFactor, verticalScaleFactor);
-
return IntSize(max<int>(1, imageIntrinsicSize.width() * scaleFactor), max<int>(1, imageIntrinsicSize.height() * scaleFactor));
}
case SizeNone:
break;
}
+
return image->imageSize(this, style()->effectiveZoom());
}
@@ -791,7 +802,8 @@ int RenderBoxModelObject::verticalPosition(bool firstLine) const
vpos += -static_cast<int>(f.xHeight() / 2) - lineHeight(firstLine) / 2 + baselinePosition(firstLine);
else if (va == TEXT_BOTTOM) {
vpos += f.descent();
- if (!isReplaced()) // lineHeight - baselinePosition is always 0 for replaced elements, so don't bother wasting time in that case.
+ // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
+ if (!isReplaced() || style()->display() == INLINE_BLOCK)
vpos -= (lineHeight(firstLine) - baselinePosition(firstLine));
} else if (va == BASELINE_MIDDLE)
vpos += -lineHeight(firstLine) / 2 + baselinePosition(firstLine);
@@ -822,10 +834,10 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
int imageWidth = imageSize.width();
int imageHeight = imageSize.height();
- int topSlice = min(imageHeight, ninePieceImage.m_slices.top().calcValue(imageHeight));
- int bottomSlice = min(imageHeight, ninePieceImage.m_slices.bottom().calcValue(imageHeight));
- int leftSlice = min(imageWidth, ninePieceImage.m_slices.left().calcValue(imageWidth));
- int rightSlice = min(imageWidth, ninePieceImage.m_slices.right().calcValue(imageWidth));
+ int topSlice = min(imageHeight, ninePieceImage.slices().top().calcValue(imageHeight));
+ int bottomSlice = min(imageHeight, ninePieceImage.slices().bottom().calcValue(imageHeight));
+ int leftSlice = min(imageWidth, ninePieceImage.slices().left().calcValue(imageWidth));
+ int rightSlice = min(imageWidth, ninePieceImage.slices().right().calcValue(imageWidth));
ENinePieceImageRule hRule = ninePieceImage.horizontalRule();
ENinePieceImageRule vRule = ninePieceImage.verticalRule();
@@ -915,15 +927,15 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
}
void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx, int ty, int w, int h,
- const RenderStyle* style, bool begin, bool end)
+ const RenderStyle* style, bool begin, bool end)
{
if (paintNinePieceImage(graphicsContext, tx, ty, w, h, style, style->borderImage()))
return;
- const Color& topColor = style->borderTopColor();
- const Color& bottomColor = style->borderBottomColor();
- const Color& leftColor = style->borderLeftColor();
- const Color& rightColor = style->borderRightColor();
+ const Color& topColor = style->visitedDependentColor(CSSPropertyBorderTopColor);
+ const Color& bottomColor = style->visitedDependentColor(CSSPropertyBorderBottomColor);
+ const Color& leftColor = style->visitedDependentColor(CSSPropertyBorderLeftColor);
+ const Color& rightColor = style->visitedDependentColor(CSSPropertyBorderRightColor);
bool topTransparent = style->borderTopIsTransparent();
bool bottomTransparent = style->borderBottomIsTransparent();
@@ -988,7 +1000,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
x2 -= topRight.width();
}
- drawLineForBoxSide(graphicsContext, x, ty, x2, ty + style->borderTopWidth(), BSTop, topColor, style->color(), topStyle,
+ drawLineForBoxSide(graphicsContext, x, ty, x2, ty + style->borderTopWidth(), BSTop, topColor, topStyle,
ignore_left ? 0 : style->borderLeftWidth(), ignore_right ? 0 : style->borderRightWidth());
if (renderRadii) {
@@ -1016,7 +1028,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
// Draw upper left arc
drawArcForBoxSide(graphicsContext, leftX, leftY, thickness, topLeft, firstAngleStart, firstAngleSpan,
- BSTop, topColor, style->color(), topStyle, true);
+ BSTop, topColor, topStyle, true);
if (applyLeftInnerClip)
graphicsContext->restore();
}
@@ -1042,7 +1054,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
// Draw upper right arc
drawArcForBoxSide(graphicsContext, rightX, leftY, thickness, topRight, secondAngleStart, secondAngleSpan,
- BSTop, topColor, style->color(), topStyle, false);
+ BSTop, topColor, topStyle, false);
if (applyRightInnerClip)
graphicsContext->restore();
}
@@ -1065,7 +1077,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
x2 -= bottomRight.width();
}
- drawLineForBoxSide(graphicsContext, x, ty + h - style->borderBottomWidth(), x2, ty + h, BSBottom, bottomColor, style->color(), bottomStyle,
+ drawLineForBoxSide(graphicsContext, x, ty + h - style->borderBottomWidth(), x2, ty + h, BSBottom, bottomColor, bottomStyle,
ignore_left ? 0 : style->borderLeftWidth(), ignore_right ? 0 : style->borderRightWidth());
if (renderRadii) {
@@ -1093,7 +1105,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
// Draw lower left arc
drawArcForBoxSide(graphicsContext, leftX, leftY, thickness, bottomLeft, firstAngleStart, firstAngleSpan,
- BSBottom, bottomColor, style->color(), bottomStyle, true);
+ BSBottom, bottomColor, bottomStyle, true);
if (applyLeftInnerClip)
graphicsContext->restore();
}
@@ -1115,7 +1127,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
// Draw lower right arc
drawArcForBoxSide(graphicsContext, rightX, rightY, thickness, bottomRight, secondAngleStart, secondAngleSpan,
- BSBottom, bottomColor, style->color(), bottomStyle, false);
+ BSBottom, bottomColor, bottomStyle, false);
if (applyRightInnerClip)
graphicsContext->restore();
}
@@ -1138,7 +1150,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
y2 -= bottomLeft.height();
}
- drawLineForBoxSide(graphicsContext, tx, y, tx + style->borderLeftWidth(), y2, BSLeft, leftColor, style->color(), leftStyle,
+ drawLineForBoxSide(graphicsContext, tx, y, tx + style->borderLeftWidth(), y2, BSLeft, leftColor, leftStyle,
ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
if (renderRadii && (!upperLeftBorderStylesMatch || !lowerLeftBorderStylesMatch)) {
@@ -1161,7 +1173,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
// Draw top left arc
drawArcForBoxSide(graphicsContext, topX, topY, thickness, topLeft, firstAngleStart, firstAngleSpan,
- BSLeft, leftColor, style->color(), leftStyle, true);
+ BSLeft, leftColor, leftStyle, true);
if (applyTopInnerClip)
graphicsContext->restore();
}
@@ -1182,7 +1194,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
// Draw bottom left arc
drawArcForBoxSide(graphicsContext, topX, bottomY, thickness, bottomLeft, secondAngleStart, secondAngleSpan,
- BSLeft, leftColor, style->color(), leftStyle, false);
+ BSLeft, leftColor, leftStyle, false);
if (applyBottomInnerClip)
graphicsContext->restore();
}
@@ -1207,7 +1219,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
y2 -= bottomRight.height();
}
- drawLineForBoxSide(graphicsContext, tx + w - style->borderRightWidth(), y, tx + w, y2, BSRight, rightColor, style->color(), rightStyle,
+ drawLineForBoxSide(graphicsContext, tx + w - style->borderRightWidth(), y, tx + w, y2, BSRight, rightColor, rightStyle,
ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
if (renderRadii && (!upperRightBorderStylesMatch || !lowerRightBorderStylesMatch)) {
@@ -1230,7 +1242,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
// Draw top right arc
drawArcForBoxSide(graphicsContext, topX, topY, thickness, topRight, firstAngleStart, firstAngleSpan,
- BSRight, rightColor, style->color(), rightStyle, true);
+ BSRight, rightColor, rightStyle, true);
if (applyTopInnerClip)
graphicsContext->restore();
}
@@ -1252,7 +1264,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
// Draw bottom right arc
drawArcForBoxSide(graphicsContext, bottomX, bottomY, thickness, bottomRight, secondAngleStart, secondAngleSpan,
- BSRight, rightColor, style->color(), rightStyle, false);
+ BSRight, rightColor, rightStyle, false);
if (applyBottomInnerClip)
graphicsContext->restore();
}
@@ -1310,16 +1322,16 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
}
bool hasOpaqueBackground = s->backgroundColor().isValid() && s->backgroundColor().alpha() == 255;
- for (ShadowData* shadow = s->boxShadow(); shadow; shadow = shadow->next) {
- if (shadow->style != shadowStyle)
+ for (const ShadowData* shadow = s->boxShadow(); shadow; shadow = shadow->next()) {
+ if (shadow->style() != shadowStyle)
continue;
- IntSize shadowOffset(shadow->x, shadow->y);
- int shadowBlur = shadow->blur;
- int shadowSpread = shadow->spread;
- Color& shadowColor = shadow->color;
+ IntSize shadowOffset(shadow->x(), shadow->y());
+ int shadowBlur = shadow->blur();
+ int shadowSpread = shadow->spread();
+ const Color& shadowColor = shadow->color();
- if (shadow->style == Normal) {
+ if (shadow->style() == Normal) {
IntRect fillRect(rect);
fillRect.inflate(shadowSpread);
if (fillRect.isEmpty())
diff --git a/WebCore/rendering/RenderEmbeddedObject.cpp b/WebCore/rendering/RenderEmbeddedObject.cpp
index db32808..8619fc0 100644
--- a/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -24,18 +24,26 @@
#include "config.h"
#include "RenderEmbeddedObject.h"
+#include "CSSValueKeywords.h"
+#include "Font.h"
+#include "FontSelector.h"
#include "Frame.h"
#include "FrameLoaderClient.h"
+#include "GraphicsContext.h"
#include "HTMLEmbedElement.h"
#include "HTMLIFrameElement.h"
#include "HTMLNames.h"
#include "HTMLObjectElement.h"
#include "HTMLParamElement.h"
+#include "LocalizedStrings.h"
#include "MIMETypeRegistry.h"
#include "Page.h"
+#include "Path.h"
#include "PluginWidget.h"
+#include "RenderTheme.h"
#include "RenderView.h"
#include "RenderWidgetProtector.h"
+#include "Settings.h"
#include "Text.h"
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
@@ -49,9 +57,16 @@
namespace WebCore {
using namespace HTMLNames;
+
+static const float replacementTextRoundedRectHeight = 18;
+static const float replacementTextRoundedRectLeftRightTextMargin = 6;
+static const float replacementTextRoundedRectOpacity = 0.20f;
+static const float replacementTextRoundedRectRadius = 5;
+static const float replacementTextTextOpacity = 0.55f;
RenderEmbeddedObject::RenderEmbeddedObject(Element* element)
- : RenderPartObject(element)
+ : RenderPart(element)
+ , m_hasFallbackContent(false)
{
view()->frameView()->setIsVisuallyNonEmpty();
}
@@ -65,7 +80,7 @@ RenderEmbeddedObject::~RenderEmbeddedObject()
#if USE(ACCELERATED_COMPOSITING)
bool RenderEmbeddedObject::requiresLayer() const
{
- if (RenderPartObject::requiresLayer())
+ if (RenderPart::requiresLayer())
return true;
return allowsAcceleratedCompositing();
@@ -141,6 +156,9 @@ static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramV
void RenderEmbeddedObject::updateWidget(bool onlyCreateNonNetscapePlugins)
{
+ if (!m_replacementText.isNull() || !node()) // Check the node in case destroy() has been called.
+ return;
+
String url;
String serviceType;
Vector<String> paramNames;
@@ -306,29 +324,86 @@ void RenderEmbeddedObject::updateWidget(bool onlyCreateNonNetscapePlugins)
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
else if (node()->hasTagName(videoTag) || node()->hasTagName(audioTag)) {
HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node());
+ KURL kurl;
+ mediaElement->getPluginProxyParams(kurl, paramNames, paramValues);
mediaElement->setNeedWidgetUpdate(false);
- if (node()->hasTagName(videoTag)) {
- HTMLVideoElement* vid = static_cast<HTMLVideoElement*>(node());
- String poster = vid->poster();
- if (!poster.isEmpty()) {
- paramNames.append("_media_element_poster_");
- paramValues.append(poster);
- }
- }
+ frame->loader()->loadMediaPlayerProxyPlugin(node(), kurl, paramNames, paramValues);
+ }
+#endif
+}
- url = mediaElement->initialURL();
- if (!url.isEmpty()) {
- paramNames.append("_media_element_src_");
- paramValues.append(url);
- }
+void RenderEmbeddedObject::setShowsMissingPluginIndicator()
+{
+ m_replacementText = missingPluginText();
+}
- serviceType = "application/x-media-element-proxy-plugin";
-
- if (mediaElement->dispatchBeforeLoadEvent(url))
- frame->loader()->requestObject(this, url, nullAtom, serviceType, paramNames, paramValues);
+void RenderEmbeddedObject::setShowsCrashedPluginIndicator()
+{
+ m_replacementText = crashedPluginText();
+}
+
+void RenderEmbeddedObject::paint(PaintInfo& paintInfo, int tx, int ty)
+{
+ if (!m_replacementText.isNull()) {
+ RenderReplaced::paint(paintInfo, tx, ty);
+ return;
}
-#endif
+
+ RenderPart::paint(paintInfo, tx, ty);
+}
+
+void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
+{
+ if (!m_replacementText)
+ return;
+
+ if (paintInfo.phase == PaintPhaseSelection)
+ return;
+
+ GraphicsContext* context = paintInfo.context;
+ if (context->paintingDisabled())
+ return;
+
+ FloatRect pluginRect = contentBoxRect();
+ pluginRect.move(tx, ty);
+
+ FontDescription fontDescription;
+ RenderTheme::defaultTheme()->systemFont(CSSValueWebkitSmallControl, fontDescription);
+ fontDescription.setWeight(FontWeightBold);
+ Settings* settings = document()->settings();
+ ASSERT(settings);
+ if (!settings)
+ return;
+ fontDescription.setRenderingMode(settings->fontRenderingMode());
+ fontDescription.setComputedSize(fontDescription.specifiedSize());
+ Font font(fontDescription, 0, 0);
+ font.update(0);
+
+ TextRun run(m_replacementText.characters(), m_replacementText.length());
+ run.disableRoundingHacks();
+ float textWidth = font.floatWidth(run);
+
+ FloatRect replacementTextRect;
+ replacementTextRect.setSize(FloatSize(textWidth + replacementTextRoundedRectLeftRightTextMargin * 2, replacementTextRoundedRectHeight));
+ replacementTextRect.setLocation(FloatPoint((pluginRect.size().width() / 2 - replacementTextRect.size().width() / 2) + pluginRect.location().x(),
+ (pluginRect.size().height() / 2 - replacementTextRect.size().height() / 2) + pluginRect.location().y()));
+
+ Path path = Path::createRoundedRectangle(replacementTextRect, FloatSize(replacementTextRoundedRectRadius, replacementTextRoundedRectRadius));
+ context->save();
+ context->clip(pluginRect);
+ context->beginPath();
+ context->addPath(path);
+ context->setAlpha(replacementTextRoundedRectOpacity);
+ context->setFillColor(Color::white, style()->colorSpace());
+ context->fillPath();
+
+ FloatPoint labelPoint(roundf(replacementTextRect.location().x() + (replacementTextRect.size().width() - textWidth) / 2),
+ roundf(replacementTextRect.location().y()+ (replacementTextRect.size().height() - font.height()) / 2 + font.ascent()));
+ context->setAlpha(replacementTextTextOpacity);
+ context->setFillColor(Color::black, style()->colorSpace());
+ context->drawBidiText(font, run, labelPoint);
+ context->restore();
}
void RenderEmbeddedObject::layout()
@@ -349,4 +424,23 @@ void RenderEmbeddedObject::layout()
setNeedsLayout(false);
}
+void RenderEmbeddedObject::viewCleared()
+{
+ // This is required for <object> elements whose contents are rendered by WebCore (e.g. src="foo.html").
+ if (node() && widget() && widget()->isFrameView()) {
+ FrameView* view = static_cast<FrameView*>(widget());
+ int marginw = -1;
+ int marginh = -1;
+ if (node()->hasTagName(iframeTag)) {
+ HTMLIFrameElement* frame = static_cast<HTMLIFrameElement*>(node());
+ marginw = frame->getMarginWidth();
+ marginh = frame->getMarginHeight();
+ }
+ if (marginw != -1)
+ view->setMarginWidth(marginw);
+ if (marginh != -1)
+ view->setMarginHeight(marginh);
+ }
+}
+
}
diff --git a/WebCore/rendering/RenderEmbeddedObject.h b/WebCore/rendering/RenderEmbeddedObject.h
index bdaea92..b68108d 100644
--- a/WebCore/rendering/RenderEmbeddedObject.h
+++ b/WebCore/rendering/RenderEmbeddedObject.h
@@ -23,17 +23,22 @@
#ifndef RenderEmbeddedObject_h
#define RenderEmbeddedObject_h
-#include "RenderPartObject.h"
+#include "RenderPart.h"
namespace WebCore {
-// Renderer for embeds and objects.
-class RenderEmbeddedObject : public RenderPartObject {
+// Renderer for embeds and objects, often, but not always, rendered via plug-ins.
+// For example, <embed src="foo.html"> does not invoke a plug-in.
+class RenderEmbeddedObject : public RenderPart {
public:
RenderEmbeddedObject(Element*);
virtual ~RenderEmbeddedObject();
void updateWidget(bool onlyCreateNonNetscapePlugins);
+ void setShowsMissingPluginIndicator();
+ void setShowsCrashedPluginIndicator();
+
+ bool hasFallbackContent() const { return m_hasFallbackContent; }
#if USE(ACCELERATED_COMPOSITING)
virtual bool allowsAcceleratedCompositing() const;
@@ -43,11 +48,18 @@ private:
virtual const char* renderName() const { return "RenderEmbeddedObject"; }
virtual bool isEmbeddedObject() const { return true; }
+ virtual void paintReplaced(PaintInfo&, int, int);
+ virtual void paint(PaintInfo& paintInfo, int, int);
+
#if USE(ACCELERATED_COMPOSITING)
virtual bool requiresLayer() const;
#endif
virtual void layout();
+ virtual void viewCleared();
+
+ String m_replacementText;
+ bool m_hasFallbackContent;
};
inline RenderEmbeddedObject* toRenderEmbeddedObject(RenderObject* object)
diff --git a/WebCore/rendering/RenderFieldset.cpp b/WebCore/rendering/RenderFieldset.cpp
index 889b0bc..d8cbd00 100644
--- a/WebCore/rendering/RenderFieldset.cpp
+++ b/WebCore/rendering/RenderFieldset.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "RenderFieldset.h"
+#include "CSSPropertyNames.h"
#include "HTMLNames.h"
#include "GraphicsContext.h"
@@ -181,8 +182,8 @@ void RenderFieldset::paintMask(PaintInfo& paintInfo, int tx, int ty)
void RenderFieldset::paintBorderMinusLegend(GraphicsContext* graphicsContext, int tx, int ty, int w, int h,
const RenderStyle* style, int lx, int lw, int lb)
{
- const Color& tc = style->borderTopColor();
- const Color& bc = style->borderBottomColor();
+ const Color& tc = style->visitedDependentColor(CSSPropertyBorderTopColor);
+ const Color& bc = style->visitedDependentColor(CSSPropertyBorderBottomColor);
EBorderStyle ts = style->borderTopStyle();
EBorderStyle bs = style->borderBottomStyle();
@@ -199,22 +200,22 @@ void RenderFieldset::paintBorderMinusLegend(GraphicsContext* graphicsContext, in
if (render_t) {
if (lx >= borderLeftWidth)
- drawLineForBoxSide(graphicsContext, tx, ty, tx + min(lx, w), ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
+ drawLineForBoxSide(graphicsContext, tx, ty, tx + min(lx, w), ty + style->borderTopWidth(), BSTop, tc, ts,
(render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE) ? borderLeftWidth : 0),
(lx >= w && render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE) ? borderRightWidth : 0));
if (lx + lw <= w - borderRightWidth)
- drawLineForBoxSide(graphicsContext, tx + max(0, lx + lw), ty, tx + w, ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
+ drawLineForBoxSide(graphicsContext, tx + max(0, lx + lw), ty, tx + w, ty + style->borderTopWidth(), BSTop, tc, ts,
(lx + lw <= 0 && render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE) ? borderLeftWidth : 0),
(render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE) ? borderRightWidth : 0));
}
if (render_b)
- drawLineForBoxSide(graphicsContext, tx, ty + h - style->borderBottomWidth(), tx + w, ty + h, BSBottom, bc, style->color(), bs,
+ drawLineForBoxSide(graphicsContext, tx, ty + h - style->borderBottomWidth(), tx + w, ty + h, BSBottom, bc, bs,
(render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE) ? style->borderLeftWidth() : 0),
(render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE) ? style->borderRightWidth() : 0));
if (render_l) {
- const Color& lc = style->borderLeftColor();
+ const Color& lc = style->visitedDependentColor(CSSPropertyBorderLeftColor);
int startY = ty;
bool ignore_top =
@@ -233,12 +234,12 @@ void RenderFieldset::paintBorderMinusLegend(GraphicsContext* graphicsContext, in
startY = lb;
}
- drawLineForBoxSide(graphicsContext, tx, startY, tx + borderLeftWidth, ty + h, BSLeft, lc, style->color(), ls,
- ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
+ drawLineForBoxSide(graphicsContext, tx, startY, tx + borderLeftWidth, ty + h, BSLeft, lc, ls,
+ ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
}
if (render_r) {
- const Color& rc = style->borderRightColor();
+ const Color& rc = style->visitedDependentColor(CSSPropertyBorderRightColor);
int startY = ty;
bool ignore_top =
@@ -257,7 +258,7 @@ void RenderFieldset::paintBorderMinusLegend(GraphicsContext* graphicsContext, in
startY = lb;
}
- drawLineForBoxSide(graphicsContext, tx + w - borderRightWidth, startY, tx + w, ty + h, BSRight, rc, style->color(), rs,
+ drawLineForBoxSide(graphicsContext, tx + w - borderRightWidth, startY, tx + w, ty + h, BSRight, rc, rs,
ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
}
}
diff --git a/WebCore/rendering/RenderFileUploadControl.cpp b/WebCore/rendering/RenderFileUploadControl.cpp
index a31442a..6a5c1e0 100644
--- a/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/WebCore/rendering/RenderFileUploadControl.cpp
@@ -114,10 +114,10 @@ String RenderFileUploadControl::acceptTypes()
return static_cast<HTMLInputElement*>(node())->accept();
}
-void RenderFileUploadControl::iconForFiles(const Vector<String>& filenames)
+void RenderFileUploadControl::chooseIconForFiles(FileChooser* chooser, const Vector<String>& filenames)
{
if (Chrome* chromePointer = chrome())
- chromePointer->iconForFiles(filenames, m_fileChooser);
+ chromePointer->chooseIconForFiles(filenames, chooser);
}
void RenderFileUploadControl::click()
@@ -195,6 +195,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
{
if (style()->visibility() != VISIBLE)
return;
+ ASSERT(m_fileChooser);
// Push a clip.
if (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseChildBlockBackgrounds) {
diff --git a/WebCore/rendering/RenderFileUploadControl.h b/WebCore/rendering/RenderFileUploadControl.h
index 454041a..1427dbf 100644
--- a/WebCore/rendering/RenderFileUploadControl.h
+++ b/WebCore/rendering/RenderFileUploadControl.h
@@ -61,7 +61,7 @@ private:
void repaint() { RenderBlock::repaint(); }
bool allowsMultipleFiles();
String acceptTypes();
- void iconForFiles(const Vector<String>&);
+ void chooseIconForFiles(FileChooser*, const Vector<String>&);
Chrome* chrome() const;
int maxFilenameWidth() const;
diff --git a/WebCore/rendering/RenderForeignObject.cpp b/WebCore/rendering/RenderForeignObject.cpp
index aa28ff0..9f0889b 100644
--- a/WebCore/rendering/RenderForeignObject.cpp
+++ b/WebCore/rendering/RenderForeignObject.cpp
@@ -36,6 +36,7 @@ namespace WebCore {
RenderForeignObject::RenderForeignObject(SVGForeignObjectElement* node)
: RenderSVGBlock(node)
+ , m_needsTransformUpdate(true)
{
}
@@ -99,9 +100,12 @@ void RenderForeignObject::layout()
ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
-
SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
- m_localTransform = foreign->animatedLocalTransform();
+
+ if (m_needsTransformUpdate) {
+ m_localTransform = foreign->animatedLocalTransform();
+ m_needsTransformUpdate = false;
+ }
// Cache viewport boundaries
FloatPoint viewportLocation(foreign->x().value(foreign), foreign->y().value(foreign));
diff --git a/WebCore/rendering/RenderForeignObject.h b/WebCore/rendering/RenderForeignObject.h
index bb6b555..d8c1f68 100644
--- a/WebCore/rendering/RenderForeignObject.h
+++ b/WebCore/rendering/RenderForeignObject.h
@@ -54,6 +54,7 @@ public:
virtual bool isSVGForeignObject() const { return true; }
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const;
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
private:
virtual void calcWidth();
@@ -62,6 +63,7 @@ public:
virtual const AffineTransform& localToParentTransform() const;
virtual AffineTransform localTransform() const { return m_localTransform; }
+ bool m_needsTransformUpdate : 1;
FloatRect m_viewport;
AffineTransform m_localTransform;
mutable AffineTransform m_localToParentTransform;
diff --git a/WebCore/rendering/RenderFrame.cpp b/WebCore/rendering/RenderFrame.cpp
index ffe87c2..3932c9a 100644
--- a/WebCore/rendering/RenderFrame.cpp
+++ b/WebCore/rendering/RenderFrame.cpp
@@ -37,7 +37,7 @@
namespace WebCore {
RenderFrame::RenderFrame(HTMLFrameElement* frame)
- : RenderPart(frame)
+ : RenderFrameBase(frame)
{
setInline(false);
}
@@ -65,6 +65,7 @@ void RenderFrame::viewCleared()
view->setMarginHeight(marginh);
}
+<<<<<<< HEAD
#ifdef FLATTEN_FRAMESET
void RenderFrame::layout()
{
@@ -145,4 +146,6 @@ void RenderFrame::layoutWithFlattening(bool fixedWidth, bool fixedHeight)
setNeedsLayout(false);
}
+=======
+>>>>>>> webkit.org at r58033
} // namespace WebCore
diff --git a/WebCore/rendering/RenderFrame.h b/WebCore/rendering/RenderFrame.h
index a66aa14..8f87b79 100644
--- a/WebCore/rendering/RenderFrame.h
+++ b/WebCore/rendering/RenderFrame.h
@@ -23,19 +23,18 @@
#ifndef RenderFrame_h
#define RenderFrame_h
-#include "RenderPart.h"
+#include "RenderFrameBase.h"
#include "RenderFrameSet.h"
namespace WebCore {
class HTMLFrameElement;
-class RenderFrame : public RenderPart {
+class RenderFrame : public RenderFrameBase {
public:
RenderFrame(HTMLFrameElement*);
FrameEdgeInfo edgeInfo() const;
- void layoutWithFlattening(bool fixedWidth, bool fixedHeight);
private:
virtual const char* renderName() const { return "RenderFrame"; }
diff --git a/WebCore/rendering/RenderFrameBase.cpp b/WebCore/rendering/RenderFrameBase.cpp
new file mode 100644
index 0000000..4a62f8a
--- /dev/null
+++ b/WebCore/rendering/RenderFrameBase.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RenderFrameBase.h"
+
+#include "FrameView.h"
+#include "HTMLFrameElementBase.h"
+#include "RenderView.h"
+
+namespace WebCore {
+
+RenderFrameBase::RenderFrameBase(Element* element)
+ : RenderPart(element)
+{
+}
+
+void RenderFrameBase::layoutWithFlattening(bool fixedWidth, bool fixedHeight)
+{
+ FrameView* childFrameView = static_cast<FrameView*>(widget());
+ RenderView* childRoot = childFrameView ? static_cast<RenderView*>(childFrameView->frame()->contentRenderer()) : 0;
+
+ // Do not expand frames which has zero width or height
+ if (!width() || !height() || !childRoot) {
+ updateWidgetPosition();
+ if (childFrameView)
+ childFrameView->layout();
+ setNeedsLayout(false);
+ return;
+ }
+
+ // need to update to calculate min/max correctly
+ updateWidgetPosition();
+ if (childRoot->prefWidthsDirty())
+ childRoot->calcPrefWidths();
+
+ // if scrollbars are off, and the width or height are fixed
+ // we obey them and do not expand. With frame flattening
+ // no subframe much ever become scrollable.
+
+ HTMLFrameElementBase* element = static_cast<HTMLFrameElementBase*>(node());
+ bool isScrollable = element->scrollingMode() != ScrollbarAlwaysOff;
+
+ // consider iframe inset border
+ int hBorder = borderLeft() + borderRight();
+ int vBorder = borderTop() + borderBottom();
+
+ // make sure minimum preferred width is enforced
+ if (isScrollable || !fixedWidth) {
+ setWidth(max(width(), childRoot->minPrefWidth() + hBorder));
+ // update again to pass the new width to the child frame
+ updateWidgetPosition();
+ childFrameView->layout();
+ }
+
+ // expand the frame by setting frame height = content height
+ if (isScrollable || !fixedHeight || childRoot->isFrameSet())
+ setHeight(max(height(), childFrameView->contentsHeight() + vBorder));
+ if (isScrollable || !fixedWidth || childRoot->isFrameSet())
+ setWidth(max(width(), childFrameView->contentsWidth() + hBorder));
+
+ updateWidgetPosition();
+
+ ASSERT(!childFrameView->layoutPending());
+ ASSERT(!childRoot->needsLayout());
+ ASSERT(!childRoot->firstChild() || !childRoot->firstChild()->firstChild() || !childRoot->firstChild()->firstChild()->needsLayout());
+
+ setNeedsLayout(false);
+}
+
+}
diff --git a/WebCore/rendering/RenderFrameBase.h b/WebCore/rendering/RenderFrameBase.h
new file mode 100644
index 0000000..cd3cf0c
--- /dev/null
+++ b/WebCore/rendering/RenderFrameBase.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderFrameBase_h
+#define RenderFrameBase_h
+
+#include "RenderPart.h"
+
+namespace WebCore {
+
+// Base class for RenderFrame and RenderIFrame
+class RenderFrameBase : public RenderPart {
+protected:
+ RenderFrameBase(Element*);
+
+public:
+ void layoutWithFlattening(bool fixedWidth, bool fixedHeight);
+};
+
+} // namespace WebCore
+
+#endif // RenderFrameBase_h
diff --git a/WebCore/rendering/RenderFrameSet.cpp b/WebCore/rendering/RenderFrameSet.cpp
index cf78b2b..fca304c 100644
--- a/WebCore/rendering/RenderFrameSet.cpp
+++ b/WebCore/rendering/RenderFrameSet.cpp
@@ -749,7 +749,7 @@ void RenderFrameSet::positionFramesWithFlattening()
bool RenderFrameSet::flattenFrameSet() const
{
- return document()->frame() && document()->frame()->settings()->frameSetFlatteningEnabled();
+ return document()->frame() && document()->frame()->settings()->frameFlatteningEnabled();
}
void RenderFrameSet::startResizing(GridAxis& axis, int position)
diff --git a/WebCore/rendering/RenderFrameSet.h b/WebCore/rendering/RenderFrameSet.h
index a4c8963..1e192fb 100644
--- a/WebCore/rendering/RenderFrameSet.h
+++ b/WebCore/rendering/RenderFrameSet.h
@@ -70,11 +70,14 @@ public:
bool canResizeRow(const IntPoint&) const;
bool canResizeColumn(const IntPoint&) const;
+<<<<<<< HEAD
#ifdef FLATTEN_FRAMESET
void setGridNeedsLayout() { m_gridCalculated = false; }
#endif
bool flattenFrameSet() const;
+=======
+>>>>>>> webkit.org at r58033
private:
static const int noSplit = -1;
@@ -100,9 +103,11 @@ private:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual void paint(PaintInfo&, int tx, int ty);
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
-
+
inline HTMLFrameSetElement* frameSet() const;
+ bool flattenFrameSet() const;
+
void setIsResizing(bool);
void layOutAxis(GridAxis&, const Length*, int availableSpace);
diff --git a/WebCore/rendering/RenderIFrame.cpp b/WebCore/rendering/RenderIFrame.cpp
new file mode 100644
index 0000000..bfea7bd
--- /dev/null
+++ b/WebCore/rendering/RenderIFrame.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RenderIFrame.h"
+
+#include "FrameView.h"
+#include "HTMLIFrameElement.h"
+#include "RenderView.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+RenderIFrame::RenderIFrame(Element* element)
+ : RenderFrameBase(element)
+{
+}
+
+void RenderIFrame::calcHeight()
+{
+ RenderPart::calcHeight();
+ if (!flattenFrame())
+ return;
+
+ HTMLIFrameElement* frame = static_cast<HTMLIFrameElement*>(node());
+ bool isScrollable = frame->scrollingMode() != ScrollbarAlwaysOff;
+
+ if (isScrollable || !style()->height().isFixed()) {
+ FrameView* view = static_cast<FrameView*>(widget());
+ int border = borderTop() + borderBottom();
+ setHeight(max(height(), view->contentsHeight() + border));
+ }
+}
+
+void RenderIFrame::calcWidth()
+{
+ RenderPart::calcWidth();
+ if (!flattenFrame())
+ return;
+
+ HTMLIFrameElement* frame = static_cast<HTMLIFrameElement*>(node());
+ bool isScrollable = frame->scrollingMode() != ScrollbarAlwaysOff;
+
+ if (isScrollable || !style()->width().isFixed()) {
+ FrameView* view = static_cast<FrameView*>(widget());
+ int border = borderLeft() + borderRight();
+ setWidth(max(width(), view->contentsWidth() + border));
+ }
+}
+
+bool RenderIFrame::flattenFrame()
+{
+ if (!node() || !node()->hasTagName(iframeTag))
+ return false;
+
+ HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(node());
+ bool isScrollable = element->scrollingMode() != ScrollbarAlwaysOff;
+
+ if (!isScrollable && style()->width().isFixed()
+ && style()->height().isFixed())
+ return false;
+
+ Frame* frame = element->document()->frame();
+ bool enabled = frame && frame->settings()->frameFlatteningEnabled();
+
+ if (!enabled || !frame->page())
+ return false;
+
+ FrameView* view = frame->page()->mainFrame()->view();
+ if (!view)
+ return false;
+
+ // Do not flatten offscreen inner frames during frame flattening.
+ return absoluteBoundingBoxRect().intersects(IntRect(IntPoint(0, 0), view->contentsSize()));
+}
+
+void RenderIFrame::layout()
+{
+ ASSERT(needsLayout());
+
+ RenderPart::calcWidth();
+ RenderPart::calcHeight();
+
+ if (flattenFrame()) {
+ layoutWithFlattening(style()->width().isFixed(), style()->height().isFixed());
+ return;
+ }
+
+ RenderPart::layout();
+
+ m_overflow.clear();
+ addShadowOverflow();
+
+ setNeedsLayout(false);
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+bool RenderIFrame::requiresLayer() const
+{
+ if (RenderPart::requiresLayer())
+ return true;
+
+ return requiresAcceleratedCompositing();
+}
+
+bool RenderIFrame::requiresAcceleratedCompositing() const
+{
+ if (!node() || !node()->hasTagName(iframeTag))
+ return false;
+
+ // If the contents of the iframe are composited, then we have to be as well.
+ HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(node());
+ if (Document* contentDocument = element->contentDocument()) {
+ if (RenderView* view = contentDocument->renderView())
+ return view->usesCompositing();
+ }
+
+ return false;
+}
+#endif
+
+}
diff --git a/WebCore/rendering/RenderIFrame.h b/WebCore/rendering/RenderIFrame.h
new file mode 100644
index 0000000..ab659a4
--- /dev/null
+++ b/WebCore/rendering/RenderIFrame.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderIFrame_h
+#define RenderIFrame_h
+
+#include "RenderFrameBase.h"
+
+namespace WebCore {
+
+class RenderIFrame : public RenderFrameBase {
+public:
+ RenderIFrame(Element*);
+
+#if USE(ACCELERATED_COMPOSITING)
+ bool requiresAcceleratedCompositing() const;
+#endif
+
+private:
+ virtual void calcHeight();
+ virtual void calcWidth();
+
+ virtual void layout();
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual bool requiresLayer() const;
+#endif
+ virtual bool isRenderIFrame() const { return true; }
+
+ virtual const char* renderName() const { return "RenderPartObject"; } // Lying for now to avoid breaking tests
+
+ bool flattenFrame();
+
+};
+
+inline RenderIFrame* toRenderIFrame(RenderObject* object)
+{
+ ASSERT(!object || object->isRenderIFrame());
+ return static_cast<RenderIFrame*>(object);
+}
+
+inline const RenderIFrame* toRenderIFrame(const RenderObject* object)
+{
+ ASSERT(!object || object->isRenderIFrame());
+ return static_cast<const RenderIFrame*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderIFrame(const RenderIFrame*);
+
+
+} // namespace WebCore
+
+#endif // RenderIFrame_h
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index 881d0b4..a2052fe 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -480,7 +480,7 @@ void RenderImage::paintFocusRings(PaintInfo& paintInfo, const RenderStyle* style
Vector<Path> focusRingPaths;
focusRingPaths.append(areaElement->getPath(this));
- paintInfo.context->drawFocusRing(focusRingPaths, style->outlineWidth(), style->outlineOffset(), style->outlineColor());
+ paintInfo.context->drawFocusRing(focusRingPaths, style->outlineWidth(), style->outlineOffset(), style->visitedDependentColor(CSSPropertyOutlineColor));
break;
}
}
diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp
index d254835..6d3f462 100644
--- a/WebCore/rendering/RenderInline.cpp
+++ b/WebCore/rendering/RenderInline.cpp
@@ -80,7 +80,7 @@ void RenderInline::destroy()
// not have a parent that means they are either already disconnected or
// root lines that can just be destroyed without disconnecting.
if (firstLineBox()->parent()) {
- for (InlineRunBox* box = firstLineBox(); box; box = box->nextLineBox())
+ for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox())
box->remove();
}
} else if (isInline() && parent())
@@ -410,7 +410,7 @@ void RenderInline::paint(PaintInfo& paintInfo, int tx, int ty)
void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
{
- if (InlineRunBox* curr = firstLineBox()) {
+ if (InlineFlowBox* curr = firstLineBox()) {
for (; curr; curr = curr->nextLineBox())
rects.append(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height()));
} else
@@ -429,7 +429,7 @@ void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
void RenderInline::absoluteQuads(Vector<FloatQuad>& quads)
{
- if (InlineRunBox* curr = firstLineBox()) {
+ if (InlineFlowBox* curr = firstLineBox()) {
for (; curr; curr = curr->nextLineBox()) {
FloatRect localRect(curr->x(), curr->y(), curr->width(), curr->height());
quads.append(localToAbsoluteQuad(localRect));
@@ -534,7 +534,7 @@ IntRect RenderInline::linesBoundingBox() const
// Return the width of the minimal left side and the maximal right side.
int leftSide = 0;
int rightSide = 0;
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
if (curr == firstLineBox() || curr->x() < leftSide)
leftSide = curr->x();
if (curr == firstLineBox() || curr->x() + curr->width() > rightSide)
@@ -557,7 +557,7 @@ IntRect RenderInline::linesVisibleOverflowBoundingBox() const
// Return the width of the minimal left side and the maximal right side.
int leftSide = numeric_limits<int>::max();
int rightSide = numeric_limits<int>::min();
- for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextFlowBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
leftSide = min(leftSide, curr->leftVisibleOverflow());
rightSide = max(rightSide, curr->rightVisibleOverflow());
}
@@ -599,11 +599,10 @@ IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repain
// cb->height() is inaccurate if we're in the middle of a layout of |cb|, so use the
// layer's size instead. Even if the layer's size is wrong, the layer itself will repaint
// anyway if its size does change.
- int x = r.x();
- int y = r.y();
+ IntRect repaintRect(r);
+ repaintRect.move(-cb->layer()->scrolledContentOffset()); // For overflow:auto/scroll/hidden.
+
IntRect boxRect(0, 0, cb->layer()->width(), cb->layer()->height());
- cb->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.
- IntRect repaintRect(x, y, r.width(), r.height());
r = intersection(repaintRect, boxRect);
}
@@ -928,7 +927,7 @@ void RenderInline::imageChanged(WrappedImagePtr, const IntRect*)
void RenderInline::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
{
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
RootInlineBox* root = curr->root();
int top = max(root->lineTop(), curr->y());
int bottom = min(root->lineBottom(), curr->y() + curr->height());
@@ -966,27 +965,26 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
if (!hasOutline())
return;
- if (style()->outlineStyleIsAuto() || hasOutlineAnnotation()) {
- int ow = style()->outlineWidth();
- Color oc = style()->outlineColor();
- if (!oc.isValid())
- oc = style()->color();
+ RenderStyle* styleToUse = style();
+ if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
+ int ow = styleToUse->outlineWidth();
+ Color oc = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
Vector<IntRect> focusRingRects;
addFocusRingRects(focusRingRects, tx, ty);
- if (style()->outlineStyleIsAuto())
- graphicsContext->drawFocusRing(focusRingRects, ow, style()->outlineOffset(), oc);
+ if (styleToUse->outlineStyleIsAuto())
+ graphicsContext->drawFocusRing(focusRingRects, ow, styleToUse->outlineOffset(), oc);
else
addPDFURLRect(graphicsContext, unionRect(focusRingRects));
}
- if (style()->outlineStyleIsAuto() || style()->outlineStyle() == BNONE)
+ if (styleToUse->outlineStyleIsAuto() || styleToUse->outlineStyle() == BNONE)
return;
Vector<IntRect> rects;
rects.append(IntRect());
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
RootInlineBox* root = curr->root();
int top = max(root->lineTop(), curr->y());
int bottom = min(root->lineBottom(), curr->y() + curr->height());
@@ -1001,11 +999,10 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx, int ty,
const IntRect& lastline, const IntRect& thisline, const IntRect& nextline)
{
- int ow = style()->outlineWidth();
- EBorderStyle os = style()->outlineStyle();
- Color oc = style()->outlineColor();
- if (!oc.isValid())
- oc = style()->color();
+ RenderStyle* styleToUse = style();
+ int ow = styleToUse->outlineWidth();
+ EBorderStyle os = styleToUse->outlineStyle();
+ Color oc = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
int offset = style()->outlineOffset();
@@ -1021,7 +1018,7 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
l,
b + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : 0),
BSLeft,
- oc, style()->color(), os,
+ oc, os,
(lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.right() - 1) <= thisline.x() ? ow : -ow),
(nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : -ow));
@@ -1032,7 +1029,7 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
r + ow,
b + (nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : 0),
BSRight,
- oc, style()->color(), os,
+ oc, os,
(lastline.isEmpty() || lastline.right() < thisline.right() || (thisline.right() - 1) <= lastline.x() ? ow : -ow),
(nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : -ow));
// upper edge
@@ -1042,7 +1039,7 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
t - ow,
min(r+ow, (lastline.isEmpty() ? 1000000 : tx + lastline.x())),
t ,
- BSTop, oc, style()->color(), os,
+ BSTop, oc, os,
ow,
(!lastline.isEmpty() && tx + lastline.x() + 1 < r + ow) ? -ow : ow);
@@ -1052,7 +1049,7 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
t - ow,
r + ow,
t ,
- BSTop, oc, style()->color(), os,
+ BSTop, oc, os,
(!lastline.isEmpty() && l - ow < tx + lastline.right()) ? -ow : ow,
ow);
@@ -1063,7 +1060,7 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
b,
min(r + ow, !nextline.isEmpty() ? tx + nextline.x() + 1 : 1000000),
b + ow,
- BSBottom, oc, style()->color(), os,
+ BSBottom, oc, os,
ow,
(!nextline.isEmpty() && tx + nextline.x() + 1 < r + ow) ? -ow : ow);
@@ -1073,7 +1070,7 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
b,
r + ow,
b + ow,
- BSBottom, oc, style()->color(), os,
+ BSBottom, oc, os,
(!nextline.isEmpty() && l - ow < tx + nextline.right()) ? -ow : ow,
ow);
}
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 03a1e75..7994325 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Portions are Copyright (C) 1998 Netscape Communications Corporation.
*
@@ -44,7 +44,6 @@
#include "config.h"
#include "RenderLayer.h"
-#include "CString.h"
#include "CSSPropertyNames.h"
#include "CSSStyleDeclaration.h"
#include "CSSStyleSelector.h"
@@ -83,6 +82,7 @@
#include "TransformationMatrix.h"
#include "TransformState.h"
#include "TranslateTransformOperation.h"
+#include <wtf/text/CString.h>
#include <wtf/StdLibExtras.h>
#include <wtf/UnusedParam.h>
@@ -245,7 +245,7 @@ bool RenderLayer::hasAcceleratedCompositing() const
#endif
}
-void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
+void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags, IntPoint* cachedOffset)
{
if (flags & DoFullRepaint) {
renderer()->repaint();
@@ -259,13 +259,49 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
#endif
}
+
updateLayerPosition(); // For relpositioned layers or non-positioned layers,
// we need to keep in sync, since we may have shifted relative
// to our parent layer.
+ IntPoint oldCachedOffset;
+ if (cachedOffset) {
+ // We can't cache our offset to the repaint container if the mapping is anything more complex than a simple translation
+ bool disableOffsetCache = renderer()->hasColumns() || renderer()->hasTransform() || isComposited();
+#if ENABLE(SVG)
+ disableOffsetCache = disableOffsetCache || renderer()->isSVGRoot();
+#endif
+ if (disableOffsetCache)
+ cachedOffset = 0; // If our cached offset is invalid make sure it's not passed to any of our children
+ else {
+ oldCachedOffset = *cachedOffset;
+ // Frequently our parent layer's renderer will be the same as our renderer's containing block. In that case,
+ // we just update the cache using our offset to our parent (which is m_x / m_y). Otherwise, regenerated cached
+ // offsets to the root from the render tree.
+ if (!m_parent || m_parent->renderer() == renderer()->containingBlock())
+ cachedOffset->move(m_x, m_y); // Fast case
+ else {
+ int x = 0;
+ int y = 0;
+ convertToLayerCoords(root(), x, y);
+ *cachedOffset = IntPoint(x, y);
+ }
+ }
+ }
int x = 0;
int y = 0;
- convertToLayerCoords(root(), x, y);
+ if (cachedOffset) {
+ x += cachedOffset->x();
+ y += cachedOffset->y();
+#ifndef NDEBUG
+ int nonCachedX = 0;
+ int nonCachedY = 0;
+ convertToLayerCoords(root(), nonCachedX, nonCachedY);
+ ASSERT(x == nonCachedX);
+ ASSERT(y == nonCachedY);
+#endif
+ } else
+ convertToLayerCoords(root(), x, y);
positionOverflowControls(x, y);
updateVisibilityStatus();
@@ -281,7 +317,9 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
IntRect newRect = renderer()->clippedOverflowRectForRepaint(repaintContainer);
- IntRect newOutlineBox = renderer()->outlineBoundsForRepaint(repaintContainer);
+ IntRect newOutlineBox = renderer()->outlineBoundsForRepaint(repaintContainer, cachedOffset);
+ // FIXME: Should ASSERT that value calculated for newOutlineBox using the cached offset is the same
+ // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
if (flags & CheckForRepaint) {
if (view && !view->printing()) {
if (m_needsFullRepaint) {
@@ -289,7 +327,7 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
if (newRect != m_repaintRect)
renderer()->repaintUsingContainer(repaintContainer, newRect);
} else
- renderer()->repaintAfterLayoutIfNeeded(repaintContainer, m_repaintRect, m_outlineBox);
+ renderer()->repaintAfterLayoutIfNeeded(repaintContainer, m_repaintRect, m_outlineBox, &newRect, &newOutlineBox);
}
}
m_repaintRect = newRect;
@@ -313,7 +351,7 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
#endif
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
- child->updateLayerPositions(flags);
+ child->updateLayerPositions(flags, cachedOffset);
#if USE(ACCELERATED_COMPOSITING)
if ((flags & UpdateCompositingLayers) && isComposited())
@@ -323,6 +361,9 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
// With all our children positioned, now update our marquee if we need to.
if (m_marquee)
m_marquee->updateMarqueePosition();
+
+ if (cachedOffset)
+ *cachedOffset = oldCachedOffset;
}
void RenderLayer::computeRepaintRects()
@@ -332,6 +373,22 @@ void RenderLayer::computeRepaintRects()
m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer);
}
+void RenderLayer::updateRepaintRectsAfterScroll(bool fixed)
+{
+ if (fixed || renderer()->style()->position() == FixedPosition) {
+ computeRepaintRects();
+ fixed = true;
+ } else if (renderer()->hasTransform()) {
+ // Transforms act as fixed position containers, so nothing inside a
+ // transformed element can be fixed relative to the viewport if the
+ // transformed element is not fixed itself or child of a fixed element.
+ return;
+ }
+
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+ child->updateRepaintRectsAfterScroll(fixed);
+}
+
void RenderLayer::updateTransform()
{
// hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
@@ -571,15 +628,20 @@ void RenderLayer::updateLayerPosition()
RenderLayer* positionedParent = enclosingPositionedAncestor();
// For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
- positionedParent->subtractScrolledContentOffset(x, y);
+ IntSize offset = positionedParent->scrolledContentOffset();
+ x -= offset.width();
+ y -= offset.height();
if (renderer()->isPositioned() && positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) {
IntSize offset = toRenderInline(positionedParent->renderer())->relativePositionedInlineOffset(toRenderBox(renderer()));
x += offset.width();
y += offset.height();
}
- } else if (parent())
- parent()->subtractScrolledContentOffset(x, y);
+ } else if (parent()) {
+ IntSize offset = parent()->scrolledContentOffset();
+ x -= offset.width();
+ y -= offset.height();
+ }
// FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
@@ -714,6 +776,11 @@ RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const
RenderLayer* RenderLayer::clippingRoot() const
{
+#if USE(ACCELERATED_COMPOSITING)
+ if (isComposited())
+ return const_cast<RenderLayer*>(this);
+#endif
+
const RenderLayer* current = this;
while (current) {
if (current->renderer()->isRenderView())
@@ -1175,21 +1242,6 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
}
}
-
-void
-RenderLayer::addScrolledContentOffset(int& x, int& y) const
-{
- x += scrollXOffset() + m_scrollLeftOverflow;
- y += scrollYOffset();
-}
-
-void
-RenderLayer::subtractScrolledContentOffset(int& x, int& y) const
-{
- x -= scrollXOffset() + m_scrollLeftOverflow;
- y -= scrollYOffset();
-}
-
void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repaint)
{
RenderBox* box = renderBox();
@@ -1250,15 +1302,24 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
view->updateWidgetPositions();
}
- // The caret rect needs to be invalidated after scrolling
+ RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
+ IntRect rectForRepaint = renderer()->clippedOverflowRectForRepaint(repaintContainer);
+
Frame* frame = renderer()->document()->frame();
- if (frame)
+ if (frame) {
+ // The caret rect needs to be invalidated after scrolling
frame->selection()->setNeedsLayout();
+ FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint);
+ if (repaintContainer)
+ quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
+ frame->eventHandler()->dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
+ }
+
// Just schedule a full repaint of our object.
- if (repaint)
- renderer()->repaint();
-
+ if (view && repaint)
+ renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
+
if (updateScrollbars) {
if (m_hBar)
m_hBar->setValue(scrollXOffset());
@@ -2876,17 +2937,19 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa
// If we establish a clip at all, then go ahead and make sure our background
// rect is intersected with our layer's bounds.
- if (ShadowData* boxShadow = renderer()->style()->boxShadow()) {
+ // FIXME: This could be changed to just use generic visual overflow.
+ // See https://bugs.webkit.org/show_bug.cgi?id=37467 for more information.
+ if (const ShadowData* boxShadow = renderer()->style()->boxShadow()) {
IntRect overflow = layerBounds;
do {
- if (boxShadow->style == Normal) {
+ if (boxShadow->style() == Normal) {
IntRect shadowRect = layerBounds;
- shadowRect.move(boxShadow->x, boxShadow->y);
- shadowRect.inflate(boxShadow->blur + boxShadow->spread);
+ shadowRect.move(boxShadow->x(), boxShadow->y());
+ shadowRect.inflate(boxShadow->blur() + boxShadow->spread());
overflow.unite(shadowRect);
}
- boxShadow = boxShadow->next;
+ boxShadow = boxShadow->next();
} while (boxShadow);
backgroundRect.intersect(overflow);
} else
@@ -2987,7 +3050,7 @@ IntRect RenderLayer::localBoundingBox() const
int top = firstBox->topVisibleOverflow();
int bottom = inlineFlow->lastLineBox()->bottomVisibleOverflow();
int left = firstBox->x();
- for (InlineRunBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
left = min(left, curr->x());
result = IntRect(left, top, width(), bottom - top);
} else if (renderer()->isTableRow()) {
@@ -3160,22 +3223,33 @@ void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestR
// Locate the common ancestor render object for the two renderers.
RenderObject* ancestor = commonAncestor(oldHoverObj, newHoverObj);
+ Vector<RefPtr<Node>, 32> nodesToRemoveFromChain;
+ Vector<RefPtr<Node>, 32> nodesToAddToChain;
+
if (oldHoverObj != newHoverObj) {
// The old hover path only needs to be cleared up to (and not including) the common ancestor;
for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
- if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain())) {
- curr->node()->setActive(false);
- curr->node()->setHovered(false);
- }
+ if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain()))
+ nodesToRemoveFromChain.append(curr->node());
}
}
// Now set the hover state for our new object up to the root.
for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) {
- if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain())) {
- curr->node()->setActive(request.active());
- curr->node()->setHovered(true);
- }
+ if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain()))
+ nodesToAddToChain.append(curr->node());
+ }
+
+ size_t removeCount = nodesToRemoveFromChain.size();
+ for (size_t i = 0; i < removeCount; ++i) {
+ nodesToRemoveFromChain[i]->setActive(false);
+ nodesToRemoveFromChain[i]->setHovered(false);
+ }
+
+ size_t addCount = nodesToAddToChain.size();
+ for (size_t i = 0; i < addCount; ++i) {
+ nodesToAddToChain[i]->setActive(request.active());
+ nodesToAddToChain[i]->setHovered(true);
}
}
@@ -3519,7 +3593,7 @@ void showLayerTree(const WebCore::RenderLayer* layer)
return;
if (WebCore::Frame* frame = layer->renderer()->document()->frame()) {
- WebCore::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers);
+ WebCore::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses);
fprintf(stderr, "%s\n", output.utf8().data());
}
}
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index 2c8d184..746c6fa 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -227,6 +227,8 @@ public:
int width() const { return m_width; }
int height() const { return m_height; }
+ IntSize size() const { return IntSize(m_width, m_height); }
+
void setWidth(int w) { m_width = w; }
void setHeight(int h) { m_height = h; }
@@ -237,8 +239,7 @@ public:
// Scrolling methods for layers that can scroll their overflow.
void scrollByRecursively(int xDelta, int yDelta);
- void addScrolledContentOffset(int& x, int& y) const;
- void subtractScrolledContentOffset(int& x, int& y) const;
+
IntSize scrolledContentOffset() const { return IntSize(scrollXOffset() + m_scrollLeftOverflow, scrollYOffset()); }
int scrollXOffset() const { return m_scrollX + m_scrollOriginX; }
@@ -304,7 +305,7 @@ public:
UpdateCompositingLayers = 1 << 3,
};
typedef unsigned UpdateLayerPositionsFlags;
- void updateLayerPositions(UpdateLayerPositionsFlags = DoFullRepaint | IsCompositingUpdateRoot | UpdateCompositingLayers);
+ void updateLayerPositions(UpdateLayerPositionsFlags = DoFullRepaint | IsCompositingUpdateRoot | UpdateCompositingLayers, IntPoint* cachedOffset = 0);
void updateTransform();
@@ -402,6 +403,7 @@ public:
// Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint.
IntRect repaintRect() const { return m_repaintRect; }
void computeRepaintRects();
+ void updateRepaintRectsAfterScroll(bool fixed = false);
void setNeedsFullRepaint(bool f = true) { m_needsFullRepaint = f; }
int staticX() const { return m_staticX; }
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index f637e3c..b5f74c6 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -424,7 +424,7 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs
if (needsDescendantClip) {
if (!m_clippingLayer) {
- m_clippingLayer = GraphicsLayer::create(0);
+ m_clippingLayer = GraphicsLayer::create(this);
#ifndef NDEBUG
m_clippingLayer->setName("Child clipping Layer");
#endif
diff --git a/WebCore/rendering/RenderLayerBacking.h b/WebCore/rendering/RenderLayerBacking.h
index 7aea926..a6907e7 100644
--- a/WebCore/rendering/RenderLayerBacking.h
+++ b/WebCore/rendering/RenderLayerBacking.h
@@ -46,7 +46,7 @@ class RenderLayerCompositor;
//
// There is one RenderLayerBacking for each RenderLayer that is composited.
-class RenderLayerBacking : public GraphicsLayerClient {
+class RenderLayerBacking : public GraphicsLayerClient, public Noncopyable {
public:
RenderLayerBacking(RenderLayer*);
~RenderLayerBacking();
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index 22118fe..480abb7 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,8 +37,13 @@
#include "GraphicsLayer.h"
#include "HitTestResult.h"
#include "HTMLCanvasElement.h"
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "HTMLMediaElement.h"
+#include "HTMLNames.h"
+#endif
#include "Page.h"
#include "RenderEmbeddedObject.h"
+#include "RenderIFrame.h"
#include "RenderLayerBacking.h"
#include "RenderReplica.h"
#include "RenderVideo.h"
@@ -50,7 +55,6 @@
#endif
#ifndef NDEBUG
-#include "CString.h"
#include "RenderTreeAsText.h"
#endif
@@ -119,6 +123,8 @@ void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
ensureRootPlatformLayer();
else
destroyRootPlatformLayer();
+
+ m_renderView->compositingStateChanged(m_compositing);
}
}
@@ -134,6 +140,15 @@ void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
showRepaintCounter = settings->showRepaintCounter();
}
+ // We allow the chrome to override the settings, in case the page is rendered
+ // on a chrome that doesn't allow accelerated compositing.
+ if (hasAcceleratedCompositing) {
+ Frame* frame = m_renderView->frameView()->frame();
+ Page* page = frame ? frame->page() : 0;
+ if (page)
+ hasAcceleratedCompositing = page->chrome()->client()->allowsAcceleratedCompositing();
+ }
+
if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter)
setCompositingLayersNeedRebuild();
@@ -215,8 +230,13 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
rebuildCompositingLayerTree(updateRoot, compState, childList);
// Host the document layer in the RenderView's root layer.
- if (updateRoot == rootRenderLayer() && !childList.isEmpty())
- m_rootPlatformLayer->setChildren(childList);
+ if (updateRoot == rootRenderLayer()) {
+ if (childList.isEmpty()) {
+ willMoveOffscreen();
+ m_rootPlatformLayer = 0;
+ } else
+ m_rootPlatformLayer->setChildren(childList);
+ }
} else if (needGeometryUpdate) {
// We just need to do a geometry update. This is only used for position:fixed scrolling;
// most of the time, geometry is updated via RenderLayer::styleChanged().
@@ -326,7 +346,7 @@ void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
// RenderLayers that are rendered by the composited RenderLayer.
IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
{
- if (!layer->isSelfPaintingLayer())
+ if (!canBeComposited(layer))
return IntRect();
IntRect boundingBoxRect, unionBounds;
@@ -444,6 +464,9 @@ void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer*
if (!boundsComputed) {
layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
+ // Empty rects never intersect, but we need them to for the purposes of overlap testing.
+ if (layerBounds.isEmpty())
+ layerBounds.setSize(IntSize(1, 1));
boundsComputed = true;
}
@@ -487,6 +510,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (overlapMap && !overlapMap->isEmpty()) {
// If we're testing for overlap, we only need to composite if we overlap something that is already composited.
absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
+ // Empty rects never intersect, but we need them to for the purposes of overlap testing.
+ if (absBounds.isEmpty())
+ absBounds.setSize(IntSize(1, 1));
haveComputedBounds = true;
mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
}
@@ -501,6 +527,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
++childState.m_depth;
#endif
+<<<<<<< HEAD
const bool willBeComposited = needsToBeComposited(layer);
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
@@ -513,6 +540,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (willBeComposited || compositingState.m_fixedSibling) {
#else
+=======
+ bool willBeComposited = needsToBeComposited(layer);
+>>>>>>> webkit.org at r58033
if (willBeComposited) {
#endif
// Tell the parent it has compositing descendants.
@@ -599,28 +629,44 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
// 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.
- if (!willBeComposited && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
+ if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
layer->setMustOverlapCompositedLayers(true);
if (overlapMap)
addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
+ willBeComposited = true;
}
+ ASSERT(willBeComposited == needsToBeComposited(layer));
if (layer->reflectionLayer())
- layer->reflectionLayer()->setMustOverlapCompositedLayers(needsToBeComposited(layer));
+ layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
// Subsequent layers in the parent stacking context also need to composite.
if (childState.m_subtreeIsCompositing)
compositingState.m_subtreeIsCompositing = true;
- // If the layer is going into compositing mode, repaint its old location.
- if (!layer->isComposited() && needsToBeComposited(layer))
- repaintOnCompositingChange(layer);
-
// Set the flag to say that this SC has compositing children.
- // this can affect the answer to needsToBeComposited() when clipping,
- // but that's ok here.
layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
+ // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
+ // so test that again.
+ if (!willBeComposited && canBeComposited(layer) && clipsCompositingDescendants(layer)) {
+ if (overlapMap)
+ addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
+ willBeComposited = true;
+ }
+
+ // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
+ // to be composited, then we can drop out of compositing mode altogether.
+ if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer)) {
+ m_compositing = false;
+ willBeComposited = false;
+ }
+
+ // If the layer is going into compositing mode, repaint its old location.
+ ASSERT(willBeComposited == needsToBeComposited(layer));
+ if (!layer->isComposited() && willBeComposited)
+ repaintOnCompositingChange(layer);
+
// Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
if (updateBacking(layer, CompositingChangeRepaintNow))
layersChanged = true;
@@ -967,9 +1013,10 @@ bool RenderLayerCompositor::has3DContent() const
bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
{
- if (!m_hasAcceleratedCompositing || !layer->isSelfPaintingLayer())
+ if (!canBeComposited(layer))
return false;
+<<<<<<< HEAD
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
// if an ancestor is fixed positioned, we need to be composited...
const RenderLayer* currLayer = layer;
@@ -980,6 +1027,9 @@ bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
#endif
return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers();
+=======
+ return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
+>>>>>>> webkit.org at r58033
}
#if PLATFORM(ANDROID)
@@ -1032,6 +1082,7 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c
layer = toRenderBoxModelObject(renderer)->layer();
}
// The root layer always has a compositing layer, but it may not have backing.
+<<<<<<< HEAD
return (inCompositingMode() && layer->isRootLayer()) ||
#if PLATFORM(ANDROID)
requiresCompositingForMobileSites(layer) ||
@@ -1044,6 +1095,21 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c
#endif
renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden ||
clipsCompositingDescendants(layer);
+=======
+ return requiresCompositingForTransform(renderer)
+ || requiresCompositingForVideo(renderer)
+ || requiresCompositingForCanvas(renderer)
+ || requiresCompositingForPlugin(renderer)
+ || requiresCompositingForIFrame(renderer)
+ || renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden
+ || clipsCompositingDescendants(layer)
+ || requiresCompositingForAnimation(renderer);
+}
+
+bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
+{
+ return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer();
+>>>>>>> webkit.org at r58033
}
// Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
@@ -1106,6 +1172,19 @@ bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer)
RenderVideo* video = toRenderVideo(renderer);
return canAccelerateVideoRendering(video);
}
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ else if (renderer->isRenderPart()) {
+ if (!m_hasAcceleratedCompositing)
+ return false;
+
+ Node* node = renderer->node();
+ if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag)))
+ return false;
+
+ HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node);
+ return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false;
+ }
+#endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
#else
UNUSED_PARAM(renderer);
#endif
@@ -1130,6 +1209,11 @@ bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer)
return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
}
+bool RenderLayerCompositor::requiresCompositingForIFrame(RenderObject* renderer) const
+{
+ return renderer->isRenderIFrame() && toRenderIFrame(renderer)->requiresAcceleratedCompositing();
+}
+
bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
{
if (AnimationController* animController = renderer->animation()) {
diff --git a/WebCore/rendering/RenderLayerCompositor.h b/WebCore/rendering/RenderLayerCompositor.h
index eeacdf7..43b8a17 100644
--- a/WebCore/rendering/RenderLayerCompositor.h
+++ b/WebCore/rendering/RenderLayerCompositor.h
@@ -142,6 +142,8 @@ private:
bool needsToBeComposited(const RenderLayer*) const;
// Whether the layer has an intrinsic need for compositing layer.
bool requiresCompositingLayer(const RenderLayer*) const;
+ // Whether the layer could ever be composited.
+ bool canBeComposited(const RenderLayer*) const;
// Make or destroy the backing for this layer; returns true if backing changed.
bool updateBacking(RenderLayer*, CompositingChangeRepaint shouldRepaint);
@@ -179,6 +181,7 @@ private:
bool requiresCompositingForVideo(RenderObject*) const;
bool requiresCompositingForCanvas(RenderObject*) const;
bool requiresCompositingForPlugin(RenderObject*) const;
+ bool requiresCompositingForIFrame(RenderObject*) const;
bool requiresCompositingWhenDescendantsAreCompositing(RenderObject*) const;
#if PLATFORM(ANDROID)
diff --git a/WebCore/rendering/RenderLineBoxList.cpp b/WebCore/rendering/RenderLineBoxList.cpp
index 57bc26c..9736874 100644
--- a/WebCore/rendering/RenderLineBoxList.cpp
+++ b/WebCore/rendering/RenderLineBoxList.cpp
@@ -67,7 +67,7 @@ void RenderLineBoxList::deleteLineBoxTree(RenderArena* arena)
InlineFlowBox* line = m_firstLineBox;
InlineFlowBox* nextLine;
while (line) {
- nextLine = line->nextFlowBox();
+ nextLine = line->nextLineBox();
line->deleteLine(arena);
line = nextLine;
}
@@ -78,13 +78,13 @@ void RenderLineBoxList::extractLineBox(InlineFlowBox* box)
{
checkConsistency();
- m_lastLineBox = box->prevFlowBox();
+ m_lastLineBox = box->prevLineBox();
if (box == m_firstLineBox)
m_firstLineBox = 0;
if (box->prevLineBox())
box->prevLineBox()->setNextLineBox(0);
box->setPreviousLineBox(0);
- for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = box; curr; curr = curr->nextLineBox())
curr->setExtracted();
checkConsistency();
@@ -100,7 +100,7 @@ void RenderLineBoxList::attachLineBox(InlineFlowBox* box)
} else
m_firstLineBox = box;
InlineFlowBox* last = box;
- for (InlineFlowBox* curr = box; curr; curr = curr->nextFlowBox()) {
+ for (InlineFlowBox* curr = box; curr; curr = curr->nextLineBox()) {
curr->setExtracted(false);
last = curr;
}
@@ -114,9 +114,9 @@ void RenderLineBoxList::removeLineBox(InlineFlowBox* box)
checkConsistency();
if (box == m_firstLineBox)
- m_firstLineBox = box->nextFlowBox();
+ m_firstLineBox = box->nextLineBox();
if (box == m_lastLineBox)
- m_lastLineBox = box->prevFlowBox();
+ m_lastLineBox = box->prevLineBox();
if (box->nextLineBox())
box->nextLineBox()->setPreviousLineBox(box->prevLineBox());
if (box->prevLineBox())
@@ -128,8 +128,8 @@ void RenderLineBoxList::removeLineBox(InlineFlowBox* box)
void RenderLineBoxList::deleteLineBoxes(RenderArena* arena)
{
if (m_firstLineBox) {
- InlineRunBox* next;
- for (InlineRunBox* curr = m_firstLineBox; curr; curr = next) {
+ InlineFlowBox* next;
+ for (InlineFlowBox* curr = m_firstLineBox; curr; curr = next) {
next = curr->nextLineBox();
curr->destroy(arena);
}
@@ -140,7 +140,7 @@ void RenderLineBoxList::deleteLineBoxes(RenderArena* arena)
void RenderLineBoxList::dirtyLineBoxes()
{
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
curr->dirtyLineBoxes();
}
@@ -177,7 +177,7 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::Pain
// based off positions of our first line box or our last line box.
RenderView* v = renderer->view();
bool usePrintRect = !v->printRect().isEmpty();
- for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextFlowBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
if (usePrintRect) {
// FIXME: This is a feeble effort to avoid splitting a line across two pages.
// It is utterly inadequate, and this should not be done at paint time at all.
@@ -236,7 +236,7 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq
// See if our root lines contain the point. If so, then we hit test
// them further. Note that boxes can easily overlap, so we can't make any assumptions
// based off positions of our first line box or our last line box.
- for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevFlowBox()) {
+ for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) {
if (y >= ty + curr->root()->topVisibleOverflow() && y < ty + curr->root()->bottomVisibleOverflow()) {
bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty);
if (inside) {
@@ -281,9 +281,9 @@ void RenderLineBoxList::dirtyLinesFromChangedChild(RenderObject* container, Rend
if (textBox)
box = textBox->root();
} else if (curr->isRenderInline()) {
- InlineRunBox* runBox = toRenderInline(curr)->lastLineBox();
- if (runBox)
- box = runBox->root();
+ InlineFlowBox* flowBox = toRenderInline(curr)->lastLineBox();
+ if (flowBox)
+ box = flowBox->root();
}
if (box)
@@ -321,8 +321,8 @@ void RenderLineBoxList::checkConsistency() const
{
#ifdef CHECK_CONSISTENCY
const InlineFlowBox* prev = 0;
- for (const InlineFlowBox* child = m_firstLineBox; child != 0; child = child->nextFlowBox()) {
- ASSERT(child->prevFlowBox() == prev);
+ for (const InlineFlowBox* child = m_firstLineBox; child != 0; child = child->nextLineBox()) {
+ ASSERT(child->prevLineBox() == prev);
prev = child;
}
ASSERT(prev == m_lastLineBox);
diff --git a/WebCore/rendering/RenderListItem.cpp b/WebCore/rendering/RenderListItem.cpp
index 54a7dd2..f861467 100644
--- a/WebCore/rendering/RenderListItem.cpp
+++ b/WebCore/rendering/RenderListItem.cpp
@@ -80,33 +80,24 @@ static bool isList(Node* node)
return (node->hasTagName(ulTag) || node->hasTagName(olTag));
}
-static Node* enclosingList(Node* node)
+static Node* enclosingList(const RenderListItem* listItem)
{
- Node* parent = node->parentNode();
- for (Node* n = parent; n; n = n->parentNode())
- if (isList(n))
- return n;
- // If there's no actual <ul> or <ol> list element, then our parent acts as
- // our list for purposes of determining what other list items should be
- // numbered as part of the same list.
- return parent;
-}
-
-static Node* enclosingList(const RenderObject* renderer)
-{
- Node* node = renderer->node();
- if (node)
- return enclosingList(node);
-
- renderer = renderer->parent();
- while (renderer && !renderer->node())
- renderer = renderer->parent();
-
- node = renderer->node();
- if (isList(node))
- return node;
+ Node* firstNode = 0;
+
+ for (const RenderObject* renderer = listItem->parent(); renderer; renderer = renderer->parent()) {
+ Node* node = renderer->node();
+ if (node) {
+ if (isList(node))
+ return node;
+ if (!firstNode)
+ firstNode = node;
+ }
+ }
- return enclosingList(node);
+ // If there's no actual <ul> or <ol> list element, then the first found
+ // node acts as our list for purposes of determining what other list items
+ // should be numbered as part of the same list.
+ return firstNode;
}
static RenderListItem* previousListItem(Node* list, const RenderListItem* item)
@@ -114,7 +105,7 @@ static RenderListItem* previousListItem(Node* list, const RenderListItem* item)
for (RenderObject* renderer = item->previousInPreOrder(); renderer != list->renderer(); renderer = renderer->previousInPreOrder()) {
if (!renderer->isListItem())
continue;
- Node* otherList = enclosingList(renderer);
+ Node* otherList = enclosingList(toRenderListItem(renderer));
// This item is part of our current list, so it's what we're looking for.
if (list == otherList)
return toRenderListItem(renderer);
@@ -326,7 +317,7 @@ void RenderListItem::explicitValueChanged()
{
if (m_marker)
m_marker->setNeedsLayoutAndPrefWidthsRecalc();
- Node* listNode = enclosingList(node());
+ Node* listNode = enclosingList(this);
RenderObject* listRenderer = 0;
if (listNode)
listRenderer = listNode->renderer();
@@ -364,4 +355,38 @@ void RenderListItem::clearExplicitValue()
explicitValueChanged();
}
+void RenderListItem::updateListMarkerNumbers()
+{
+ Node* listNode = enclosingList(this);
+ ASSERT(listNode && listNode->renderer());
+ if (!listNode || !listNode->renderer())
+ return;
+
+ RenderObject* list = listNode->renderer();
+ RenderObject* child = nextInPreOrder(list);
+ while (child) {
+ if (child->node() && isList(child->node())) {
+ // We've found a nested, independent list: nothing to do here.
+ child = child->nextInPreOrderAfterChildren(list);
+ continue;
+ }
+
+ if (child->isListItem()) {
+ RenderListItem* item = toRenderListItem(child);
+
+ if (!item->m_isValueUpToDate) {
+ // If an item has been marked for update before, we can safely
+ // assume that all the following ones have too.
+ // This gives us the opportunity to stop here and avoid
+ // marking the same nodes again.
+ break;
+ }
+
+ item->updateValue();
+ }
+
+ child = child->nextInPreOrder(list);
+ }
+}
+
} // namespace WebCore
diff --git a/WebCore/rendering/RenderListItem.h b/WebCore/rendering/RenderListItem.h
index c4c41dc..2ad9a41 100644
--- a/WebCore/rendering/RenderListItem.h
+++ b/WebCore/rendering/RenderListItem.h
@@ -46,6 +46,8 @@ public:
const String& markerText() const;
+ void updateListMarkerNumbers();
+
private:
virtual const char* renderName() const { return "RenderListItem"; }
diff --git a/WebCore/rendering/RenderMenuList.cpp b/WebCore/rendering/RenderMenuList.cpp
index 05a9873..518925a 100644
--- a/WebCore/rendering/RenderMenuList.cpp
+++ b/WebCore/rendering/RenderMenuList.cpp
@@ -1,6 +1,7 @@
/*
* This file is part of the select element renderer in WebCore.
*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
@@ -25,6 +26,7 @@
#include "RenderMenuList.h"
#include "AXObjectCache.h"
+#include "AccessibilityObject.h"
#include "CSSStyleSelector.h"
#include "Frame.h"
#include "FrameView.h"
@@ -308,6 +310,20 @@ void RenderMenuList::valueChanged(unsigned listIndex, bool fireOnChange)
select->setSelectedIndexByUser(select->listToOptionIndex(listIndex), true, fireOnChange);
}
+#if ENABLE(NO_LISTBOX_RENDERING)
+void RenderMenuList::listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow)
+{
+ SelectElement* select = toSelectElement(static_cast<Element*>(node()));
+ select->listBoxSelectItem(select->listToOptionIndex(listIndex), allowMultiplySelections, shift, fireOnChangeNow);
+}
+
+bool RenderMenuList::multiple()
+{
+ SelectElement* select = toSelectElement(static_cast<Element*>(node()));
+ return select->multiple();
+}
+#endif
+
void RenderMenuList::didSetSelectedIndex()
{
int index = selectedIndex();
@@ -334,6 +350,17 @@ String RenderMenuList::itemText(unsigned listIndex) const
return String();
}
+String RenderMenuList::itemAccessibilityText(unsigned listIndex) const
+{
+ // Allow the accessible name be changed if necessary.
+ SelectElement* select = toSelectElement(static_cast<Element*>(node()));
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size())
+ return String();
+
+ return AccessibilityObject::getAttribute(listItems[listIndex], aria_labelAttr);
+}
+
String RenderMenuList::itemToolTip(unsigned listIndex) const
{
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
diff --git a/WebCore/rendering/RenderMenuList.h b/WebCore/rendering/RenderMenuList.h
index a5aa041..aeb6205 100644
--- a/WebCore/rendering/RenderMenuList.h
+++ b/WebCore/rendering/RenderMenuList.h
@@ -1,6 +1,7 @@
/*
* This file is part of the select element renderer in WebCore.
*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -37,7 +38,12 @@ namespace WebCore {
class PopupMenu;
class RenderText;
+#if ENABLE(NO_LISTBOX_RENDERING)
+class RenderMenuList : public RenderFlexibleBox, private ListPopupMenuClient {
+#else
class RenderMenuList : public RenderFlexibleBox, private PopupMenuClient {
+#endif
+
public:
RenderMenuList(Element*);
virtual ~RenderMenuList();
@@ -75,6 +81,7 @@ private:
// PopupMenuClient methods
virtual String itemText(unsigned listIndex) const;
virtual String itemToolTip(unsigned listIndex) const;
+ virtual String itemAccessibilityText(unsigned listIndex) const;
virtual bool itemIsEnabled(unsigned listIndex) const;
virtual PopupMenuStyle itemStyle(unsigned listIndex) const;
virtual PopupMenuStyle menuStyle() const;
@@ -96,6 +103,11 @@ private:
virtual HostWindow* hostWindow() const;
virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize);
+#if ENABLE(NO_LISTBOX_RENDERING)
+ virtual void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
+ virtual bool multiple();
+#endif
+
virtual bool hasLineIfEmpty() const { return true; }
Color itemBackgroundColor(unsigned listIndex) const;
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index e70de96..d63997a 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -119,12 +119,12 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
if (node->hasTagName(rubyTag)) {
if (style->display() == INLINE)
return new (arena) RenderRubyAsInline(node);
- else
+ else if (style->display() == BLOCK)
return new (arena) RenderRubyAsBlock(node);
}
// treat <rt> as ruby text ONLY if it still has its default treatment of block
if (node->hasTagName(rtTag) && style->display() == BLOCK)
- return new (arena) RenderRubyText(node);
+ return new (arena) RenderRubyText(node);
#endif
switch (style->display()) {
@@ -260,14 +260,6 @@ bool RenderObject::isHTMLMarquee() const
return node() && node()->renderer() == this && node()->hasTagName(marqueeTag);
}
-static void updateListMarkerNumbers(RenderObject* child)
-{
- for (RenderObject* sibling = child; sibling; sibling = sibling->nextSibling()) {
- if (sibling->isListItem())
- toRenderListItem(sibling)->updateValue();
- }
-}
-
void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
RenderObjectChildList* children = virtualChildren();
@@ -277,9 +269,7 @@ void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
bool needsTable = false;
- if (newChild->isListItem())
- updateListMarkerNumbers(beforeChild ? beforeChild : children->lastChild());
- else if (newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
+ if (newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
needsTable = !isTable();
else if (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
needsTable = !isTable();
@@ -701,7 +691,7 @@ bool RenderObject::mustRepaintBackgroundOrBorder() const
}
void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
- BoxSide s, Color c, const Color& textcolor, EBorderStyle style,
+ BoxSide s, Color c, EBorderStyle style,
int adjbw1, int adjbw2)
{
int width = (s == BSTop || s == BSBottom ? y2 - y1 : x2 - x1);
@@ -709,13 +699,6 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
if (style == DOUBLE && width < 3)
style = SOLID;
- if (!c.isValid()) {
- if (style == INSET || style == OUTSET || style == RIDGE || style == GROOVE)
- c.setRGB(238, 238, 238);
- else
- c = textcolor;
- }
-
switch (style) {
case BNONE:
case BHIDDEN:
@@ -767,34 +750,34 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
case BSTop:
drawLineForBoxSide(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
y1, x2 - max((-adjbw2 * 2 + 1) / 3, 0), y1 + third,
- s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
+ s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
drawLineForBoxSide(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
y2 - third, x2 - max((adjbw2 * 2 + 1) / 3, 0), y2,
- s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
+ s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
break;
case BSLeft:
drawLineForBoxSide(graphicsContext, x1, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
x1 + third, y2 - max((-adjbw2 * 2 + 1) / 3, 0),
- s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
+ s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((adjbw1 * 2 + 1) / 3, 0),
x2, y2 - max((adjbw2 * 2 + 1) / 3, 0),
- s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
+ s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
break;
case BSBottom:
drawLineForBoxSide(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
y1, x2 - max((adjbw2 * 2 + 1) / 3, 0), y1 + third,
- s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
+ s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
drawLineForBoxSide(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
y2 - third, x2 - max((-adjbw2 * 2 + 1) / 3, 0), y2,
- s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
+ s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
break;
case BSRight:
drawLineForBoxSide(graphicsContext, x1, y1 + max((adjbw1 * 2 + 1) / 3, 0),
x1 + third, y2 - max((adjbw2 * 2 + 1) / 3, 0),
- s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
+ s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
x2, y2 - max((-adjbw2 * 2 + 1) / 3, 0),
- s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
+ s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
break;
default:
break;
@@ -821,27 +804,27 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
switch (s) {
case BSTop:
drawLineForBoxSide(graphicsContext, x1 + max(-adjbw1, 0) / 2, y1, x2 - max(-adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
- s, c, textcolor, s1, adjbw1bighalf, adjbw2bighalf);
+ s, c, s1, adjbw1bighalf, adjbw2bighalf);
drawLineForBoxSide(graphicsContext, x1 + max(adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(adjbw2 + 1, 0) / 2, y2,
- s, c, textcolor, s2, adjbw1 / 2, adjbw2 / 2);
+ s, c, s2, adjbw1 / 2, adjbw2 / 2);
break;
case BSLeft:
drawLineForBoxSide(graphicsContext, x1, y1 + max(-adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(-adjbw2, 0) / 2,
- s, c, textcolor, s1, adjbw1bighalf, adjbw2bighalf);
+ s, c, s1, adjbw1bighalf, adjbw2bighalf);
drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(adjbw1 + 1, 0) / 2, x2, y2 - max(adjbw2 + 1, 0) / 2,
- s, c, textcolor, s2, adjbw1 / 2, adjbw2 / 2);
+ s, c, s2, adjbw1 / 2, adjbw2 / 2);
break;
case BSBottom:
drawLineForBoxSide(graphicsContext, x1 + max(adjbw1, 0) / 2, y1, x2 - max(adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
- s, c, textcolor, s2, adjbw1bighalf, adjbw2bighalf);
+ s, c, s2, adjbw1bighalf, adjbw2bighalf);
drawLineForBoxSide(graphicsContext, x1 + max(-adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(-adjbw2 + 1, 0) / 2, y2,
- s, c, textcolor, s1, adjbw1/2, adjbw2/2);
+ s, c, s1, adjbw1 / 2, adjbw2 / 2);
break;
case BSRight:
drawLineForBoxSide(graphicsContext, x1, y1 + max(adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(adjbw2, 0) / 2,
- s, c, textcolor, s2, adjbw1bighalf, adjbw2bighalf);
+ s, c, s2, adjbw1bighalf, adjbw2bighalf);
drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(-adjbw1 + 1, 0) / 2, x2, y2 - max(-adjbw2 + 1, 0) / 2,
- s, c, textcolor, s1, adjbw1/2, adjbw2/2);
+ s, c, s1, adjbw1 / 2, adjbw2 / 2);
break;
}
break;
@@ -897,19 +880,12 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
}
void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, int y, float thickness, IntSize radius,
- int angleStart, int angleSpan, BoxSide s, Color c, const Color& textColor,
+ int angleStart, int angleSpan, BoxSide s, Color c,
EBorderStyle style, bool firstCorner)
{
if ((style == DOUBLE && thickness / 2 < 3) || ((style == RIDGE || style == GROOVE) && thickness / 2 < 2))
style = SOLID;
- if (!c.isValid()) {
- if (style == INSET || style == OUTSET || style == RIDGE || style == GROOVE)
- c.setRGB(238, 238, 238);
- else
- c = textColor;
- }
-
switch (style) {
case BNONE:
case BHIDDEN:
@@ -997,33 +973,32 @@ void RenderObject::addPDFURLRect(GraphicsContext* context, const IntRect& rect)
context->setURLForRect(n->document()->completeURL(href), rect);
}
-void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style)
+void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty, int w, int h)
{
if (!hasOutline())
return;
- int ow = style->outlineWidth();
- EBorderStyle os = style->outlineStyle();
+ RenderStyle* styleToUse = style();
+ int ow = styleToUse->outlineWidth();
+ EBorderStyle os = styleToUse->outlineStyle();
- Color oc = style->outlineColor();
- if (!oc.isValid())
- oc = style->color();
+ Color oc = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
- int offset = style->outlineOffset();
+ int offset = styleToUse->outlineOffset();
- if (style->outlineStyleIsAuto() || hasOutlineAnnotation()) {
- if (!theme()->supportsFocusRing(style)) {
+ if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
+ if (!theme()->supportsFocusRing(styleToUse)) {
// Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
Vector<IntRect> focusRingRects;
addFocusRingRects(focusRingRects, tx, ty);
- if (style->outlineStyleIsAuto())
+ if (styleToUse->outlineStyleIsAuto())
graphicsContext->drawFocusRing(focusRingRects, ow, offset, oc);
else
addPDFURLRect(graphicsContext, unionRect(focusRingRects));
}
}
- if (style->outlineStyleIsAuto() || style->outlineStyle() == BNONE)
+ if (styleToUse->outlineStyleIsAuto() || styleToUse->outlineStyle() == BNONE)
return;
tx -= offset;
@@ -1034,17 +1009,10 @@ void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
if (h < 0 || w < 0)
return;
- drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx, ty + h + ow,
- BSLeft, Color(oc), style->color(), os, ow, ow);
-
- drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx + w + ow, ty,
- BSTop, Color(oc), style->color(), os, ow, ow);
-
- drawLineForBoxSide(graphicsContext, tx + w, ty - ow, tx + w + ow, ty + h + ow,
- BSRight, Color(oc), style->color(), os, ow, ow);
-
- drawLineForBoxSide(graphicsContext, tx - ow, ty + h, tx + w + ow, ty + h + ow,
- BSBottom, Color(oc), style->color(), os, ow, ow);
+ drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx, ty + h + ow, BSLeft, oc, os, ow, ow);
+ drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx + w + ow, ty, BSTop, oc, os, ow, ow);
+ drawLineForBoxSide(graphicsContext, tx + w, ty - ow, tx + w + ow, ty + h + ow, BSRight, oc, os, ow, ow);
+ drawLineForBoxSide(graphicsContext, tx - ow, ty + h, tx + w + ow, ty + h + ow, BSBottom, oc, os, ow, ow);
}
IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms)
@@ -1182,13 +1150,14 @@ void RenderObject::repaintRectangle(const IntRect& r, bool immediate)
repaintUsingContainer(repaintContainer ? repaintContainer : view, dirtyRect, immediate);
}
-bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox)
+bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox, const IntRect* newBoundsPtr, const IntRect* newOutlineBoxRectPtr)
{
RenderView* v = view();
if (v->printing())
return false; // Don't repaint if we're printing.
- IntRect newBounds = clippedOverflowRectForRepaint(repaintContainer);
+ ASSERT(!newBoundsPtr || *newBoundsPtr == clippedOverflowRectForRepaint(repaintContainer));
+ IntRect newBounds = newBoundsPtr ? *newBoundsPtr : clippedOverflowRectForRepaint(repaintContainer);
IntRect newOutlineBox;
bool fullRepaint = selfNeedsLayout();
@@ -1196,7 +1165,8 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta
if (!fullRepaint && style()->borderFit() == BorderFitLines)
fullRepaint = true;
if (!fullRepaint) {
- newOutlineBox = outlineBoundsForRepaint(repaintContainer);
+ ASSERT(!newOutlineBoxRectPtr || *newOutlineBoxRectPtr == outlineBoundsForRepaint(repaintContainer));
+ newOutlineBox = newOutlineBoxRectPtr ? *newOutlineBoxRectPtr : outlineBoundsForRepaint(repaintContainer);
if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox)))
fullRepaint = true;
}
@@ -1331,11 +1301,10 @@ void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer,
// anyway if its size does change.
RenderBox* boxParent = toRenderBox(o);
+ IntRect repaintRect(rect);
+ repaintRect.move(-boxParent->layer()->scrolledContentOffset()); // For overflow:auto/scroll/hidden.
+
IntRect boxRect(0, 0, boxParent->layer()->width(), boxParent->layer()->height());
- int x = rect.x();
- int y = rect.y();
- boxParent->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.
- IntRect repaintRect(x, y, rect.width(), rect.height());
rect = intersection(repaintRect, boxRect);
if (rect.isEmpty())
return;
@@ -1667,9 +1636,10 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
#endif
bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition
- || (!shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage()));
+ || (!shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage()));
bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition
- || (!shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage()));
+ || (!shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage()));
+
if (oldStyleSlowScroll != newStyleSlowScroll) {
if (oldStyleSlowScroll)
view()->frameView()->removeSlowRepaintObject();
@@ -2210,21 +2180,17 @@ PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(PseudoId pseudo, Re
return result.release();
}
-static Color decorationColor(RenderStyle* style)
+static Color decorationColor(RenderObject* renderer)
{
Color result;
- if (style->textStrokeWidth() > 0) {
+ if (renderer->style()->textStrokeWidth() > 0) {
// Prefer stroke color if possible but not if it's fully transparent.
- result = style->textStrokeColor();
- if (!result.isValid())
- result = style->color();
+ result = renderer->style()->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
if (result.alpha())
return result;
}
- result = style->textFillColor();
- if (!result.isValid())
- result = style->color();
+ result = renderer->style()->visitedDependentColor(CSSPropertyWebkitTextFillColor);
return result;
}
@@ -2237,15 +2203,15 @@ void RenderObject::getTextDecorationColors(int decorations, Color& underline, Co
if (currDecs) {
if (currDecs & UNDERLINE) {
decorations &= ~UNDERLINE;
- underline = decorationColor(curr->style());
+ underline = decorationColor(curr);
}
if (currDecs & OVERLINE) {
decorations &= ~OVERLINE;
- overline = decorationColor(curr->style());
+ overline = decorationColor(curr);
}
if (currDecs & LINE_THROUGH) {
decorations &= ~LINE_THROUGH;
- linethrough = decorationColor(curr->style());
+ linethrough = decorationColor(curr);
}
}
curr = curr->parent();
@@ -2257,11 +2223,11 @@ void RenderObject::getTextDecorationColors(int decorations, Color& underline, Co
// If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
if (decorations && curr) {
if (decorations & UNDERLINE)
- underline = decorationColor(curr->style());
+ underline = decorationColor(curr);
if (decorations & OVERLINE)
- overline = decorationColor(curr->style());
+ overline = decorationColor(curr);
if (decorations & LINE_THROUGH)
- linethrough = decorationColor(curr->style());
+ linethrough = decorationColor(curr);
}
}
@@ -2381,21 +2347,21 @@ int RenderObject::nextOffset(int current) const
void RenderObject::adjustRectForOutlineAndShadow(IntRect& rect) const
{
int outlineSize = outlineStyleForRepaint()->outlineSize();
- if (ShadowData* boxShadow = style()->boxShadow()) {
+ if (const ShadowData* boxShadow = style()->boxShadow()) {
int shadowLeft = 0;
int shadowRight = 0;
int shadowTop = 0;
int shadowBottom = 0;
do {
- if (boxShadow->style == Normal) {
- shadowLeft = min(boxShadow->x - boxShadow->blur - boxShadow->spread - outlineSize, shadowLeft);
- shadowRight = max(boxShadow->x + boxShadow->blur + boxShadow->spread + outlineSize, shadowRight);
- shadowTop = min(boxShadow->y - boxShadow->blur - boxShadow->spread - outlineSize, shadowTop);
- shadowBottom = max(boxShadow->y + boxShadow->blur + boxShadow->spread + outlineSize, shadowBottom);
+ if (boxShadow->style() == Normal) {
+ shadowLeft = min(boxShadow->x() - boxShadow->blur() - boxShadow->spread() - outlineSize, shadowLeft);
+ shadowRight = max(boxShadow->x() + boxShadow->blur() + boxShadow->spread() + outlineSize, shadowRight);
+ shadowTop = min(boxShadow->y() - boxShadow->blur() - boxShadow->spread() - outlineSize, shadowTop);
+ shadowBottom = max(boxShadow->y() + boxShadow->blur() + boxShadow->spread() + outlineSize, shadowBottom);
}
- boxShadow = boxShadow->next;
+ boxShadow = boxShadow->next();
} while (boxShadow);
rect.move(shadowLeft, shadowTop);
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 791d4d0..ae12758 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -277,8 +277,12 @@ public:
virtual bool isListMarker() const { return false; }
virtual bool isMedia() const { return false; }
virtual bool isMenuList() const { return false; }
+#if ENABLE(PROGRESS_TAG)
+ virtual bool isProgress() const { return false; }
+#endif
virtual bool isRenderBlock() const { return false; }
virtual bool isRenderButton() const { return false; }
+ virtual bool isRenderIFrame() const { return false; }
virtual bool isRenderImage() const { return false; }
virtual bool isRenderInline() const { return false; }
virtual bool isRenderPart() const { return false; }
@@ -334,10 +338,17 @@ public:
virtual bool isSVGImage() const { return false; }
virtual bool isSVGForeignObject() const { return false; }
virtual bool isSVGResource() const { return false; }
+ virtual bool isSVGShadowTreeRootContainer() const { return false; }
virtual const SVGRenderBase* toSVGRenderBase() const;
virtual RenderSVGResource* toRenderSVGResource();
+ // 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
+ // to inherit from RenderSVGObject -> RenderObject (some need RenderBlock inheritance for instance)
+ virtual void setNeedsTransformUpdate() { }
+ virtual void setNeedsBoundariesUpdate() { }
+
// Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects, opacity and stroke-width.
// This is used for all computation of objectBoundingBox relative units and by SVGLocateable::getBBox().
// NOTE: Markers are not specifically ignored here by SVG 1.1 spec, but we ignore them
@@ -350,7 +361,6 @@ public:
// respecting clipping, masking, filters, opacity, stroke-width and markers
virtual FloatRect repaintRectInLocalCoordinates() const;
- // FIXME: This accessor is deprecated and mostly around for SVGRenderTreeAsText.
// This only returns the transform="" value from the element
// most callsites want localToParentTransform() instead.
virtual AffineTransform localTransform() const;
@@ -405,9 +415,9 @@ public:
bool hasMask() const { return style() && style()->hasMask(); }
void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide,
- Color, const Color& textcolor, EBorderStyle, int adjbw1, int adjbw2);
+ Color, EBorderStyle, int adjbw1, int adjbw2);
void drawArcForBoxSide(GraphicsContext*, int x, int y, float thickness, IntSize radius, int angleStart,
- int angleSpan, BoxSide, Color, const Color& textcolor, EBorderStyle, bool firstCorner);
+ int angleSpan, BoxSide, Color, EBorderStyle, bool firstCorner);
public:
// The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect
@@ -512,10 +522,6 @@ public:
/* This function performs a layout only if one is needed. */
void layoutIfNeeded() { if (needsLayout()) layout(); }
-
- // Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted
- // that just updates the object's position. If the size does change, the object remains dirty.
- virtual void tryLayoutDoingPositionedMovementOnly() { }
// used for element state updates that cannot be fixed with a
// repaint and do not need a relayout
@@ -616,8 +622,8 @@ public:
// Repaint a specific subrectangle within a given object. The rect |r| is in the object's coordinate space.
void repaintRectangle(const IntRect&, bool immediate = false);
- // Repaint only if our old bounds and new bounds are different.
- bool repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox);
+ // Repaint only if our old bounds and new bounds are different. The caller may pass in newBounds and newOutlineBox if they are known.
+ bool repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox, const IntRect* newBoundsPtr = 0, const IntRect* newOutlineBoxPtr = 0);
// Repaint only if the object moved.
virtual void repaintDuringLayoutIfMoved(const IntRect& rect);
@@ -782,7 +788,7 @@ protected:
// Overrides should call the superclass at the start
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- void paintOutline(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*);
+ void paintOutline(GraphicsContext*, int tx, int ty, int w, int h);
void addPDFURLRect(GraphicsContext*, const IntRect&);
virtual IntRect viewRect() const;
@@ -791,7 +797,7 @@ protected:
void arenaDelete(RenderArena*, void* objectBase);
- virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const { return IntRect(); }
+ virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/, IntPoint* /*cachedOffsetToRepaintContainer*/ = 0) const { return IntRect(); }
class LayoutRepainter {
public:
diff --git a/WebCore/rendering/RenderObjectChildList.cpp b/WebCore/rendering/RenderObjectChildList.cpp
index d56a015..6d76f34 100644
--- a/WebCore/rendering/RenderObjectChildList.cpp
+++ b/WebCore/rendering/RenderObjectChildList.cpp
@@ -39,14 +39,6 @@
namespace WebCore {
-static void updateListMarkerNumbers(RenderObject* child)
-{
- for (RenderObject* sibling = child; sibling; sibling = sibling->nextSibling()) {
- if (sibling->isListItem())
- toRenderListItem(sibling)->updateValue();
- }
-}
-
void RenderObjectChildList::destroyLeftoverChildren()
{
while (firstChild()) {
@@ -91,11 +83,10 @@ RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, Render
layer = owner->enclosingLayer();
oldChild->removeLayers(layer);
}
-
- // renumber ordered lists
+
if (oldChild->isListItem())
- updateListMarkerNumbers(oldChild->nextSibling());
-
+ toRenderListItem(oldChild)->updateListMarkerNumbers();
+
if (oldChild->isPositioned() && owner->childrenInline())
owner->dirtyLinesFromChangedChild(oldChild);
}
@@ -161,7 +152,10 @@ void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* n
if (layer)
layer->setHasVisibleContent(true);
}
-
+
+ if (newChild->isListItem())
+ toRenderListItem(newChild)->updateListMarkerNumbers();
+
if (!newChild->isFloatingOrPositioned() && owner->childrenInline())
owner->dirtyLinesFromChangedChild(newChild);
}
@@ -218,7 +212,9 @@ void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* c
layer->setHasVisibleContent(true);
}
-
+ if (child->isListItem())
+ toRenderListItem(child)->updateListMarkerNumbers();
+
if (!child->isFloating() && owner->childrenInline())
owner->dirtyLinesFromChangedChild(child);
}
@@ -234,17 +230,42 @@ void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* c
static RenderObject* beforeAfterContainer(RenderObject* container, PseudoId type)
{
if (type == BEFORE) {
+ // An anonymous (generated) inline run-in that has PseudoId BEFORE must come from a grandparent.
+ // Therefore we should skip these generated run-ins when checking our immediate children.
+ // If we don't find our :before child immediately, then we should check if we own a
+ // generated inline run-in in the next level of children.
RenderObject* first = container;
do {
- // Skip list markers.
+ // Skip list markers and generated run-ins
first = first->firstChild();
- while (first && first->isListMarker())
+ while (first && (first->isListMarker() || (first->isRenderInline() && first->isRunIn() && first->isAnonymous())))
first = first->nextSibling();
} while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);
- if (first && first->style()->styleType() != type)
+
+ if (!first)
+ return 0;
+
+ if (first->style()->styleType() == type)
+ return first;
+
+ // Check for a possible generated run-in, using run-in positioning rules.
+ // Skip inlines and floating / positioned blocks, and place as the first child.
+ first = container->firstChild();
+ if (!first->isRenderBlock())
return 0;
- return first;
+ while (first && first->isFloatingOrPositioned())
+ first = first->nextSibling();
+ if (first) {
+ first = first->firstChild();
+ // We still need to skip any list markers that could exist before the run-in.
+ while (first && first->isListMarker())
+ first = first->nextSibling();
+ if (first && first->style()->styleType() == type && first->isRenderInline() && first->isRunIn() && first->isAnonymous())
+ return first;
+ }
+ return 0;
}
+
if (type == AFTER) {
RenderObject* last = container;
do {
@@ -314,7 +335,7 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
// Whether or not we currently have generated content attached.
bool oldContentPresent = child;
- // Whether or not we now want generated content.
+ // Whether or not we now want generated content.
bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;
// For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate
@@ -330,9 +351,9 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
// If we don't want generated content any longer, or if we have generated content, but it's no longer
// identical to the new content data we want to build render objects for, then we nuke all
// of the old generated content.
- if (!newContentWanted || (oldContentPresent && Node::diff(child->style(), pseudoElementStyle) == Node::Detach)) {
+ if (oldContentPresent && (!newContentWanted || Node::diff(child->style(), pseudoElementStyle) == Node::Detach)) {
// Nuke the child.
- if (child && child->style()->styleType() == type) {
+ if (child->style()->styleType() == type) {
oldContentPresent = false;
child->destroy();
child = (type == BEFORE) ? owner->virtualChildren()->firstChild() : owner->virtualChildren()->lastChild();
diff --git a/WebCore/rendering/RenderPart.cpp b/WebCore/rendering/RenderPart.cpp
index 5c4a6ec..3262961 100644
--- a/WebCore/rendering/RenderPart.cpp
+++ b/WebCore/rendering/RenderPart.cpp
@@ -24,16 +24,16 @@
#include "config.h"
#include "RenderPart.h"
+#include "RenderView.h"
#include "Frame.h"
#include "FrameView.h"
+#include "HTMLFrameElementBase.h"
namespace WebCore {
RenderPart::RenderPart(Element* node)
: RenderWidget(node)
- , m_hasFallbackContent(false)
{
- // init RenderObject attributes
setInline(false);
}
diff --git a/WebCore/rendering/RenderPart.h b/WebCore/rendering/RenderPart.h
index 8303543..18f2346 100644
--- a/WebCore/rendering/RenderPart.h
+++ b/WebCore/rendering/RenderPart.h
@@ -27,23 +27,15 @@
namespace WebCore {
-// Renderer for frames via RenderPartObject, and plug-ins via RenderEmbeddedObject.
-
-// FIXME: This class is subclassed in RenderPartObject for iframes, which is in turn
-// subclassed in RenderEmbeddedObject for object and embed. This class itself could be removed.
+// Renderer for frames via RenderFrameBase, and plug-ins via RenderEmbeddedObject.
class RenderPart : public RenderWidget {
public:
RenderPart(Element*);
virtual ~RenderPart();
-
- bool hasFallbackContent() const { return m_hasFallbackContent; }
virtual void setWidget(PassRefPtr<Widget>);
virtual void viewCleared();
-protected:
- bool m_hasFallbackContent;
-
private:
virtual bool isRenderPart() const { return true; }
virtual const char* renderName() const { return "RenderPart"; }
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index bcedd38..b1e2a8f 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -31,10 +31,11 @@
#include "GraphicsContext.h"
#include "PointerEventsHitRules.h"
#include "RenderSVGContainer.h"
+#include "RenderSVGResourceFilter.h"
+#include "RenderSVGResourceMarker.h"
#include "StrokeStyleApplier.h"
#include "SVGPaintServer.h"
#include "SVGRenderSupport.h"
-#include "SVGResourceMarker.h"
#include "SVGStyledTransformableElement.h"
#include "SVGTransformList.h"
#include "SVGURIReference.h"
@@ -64,19 +65,12 @@ 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_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
{
}
-const AffineTransform& RenderPath::localToParentTransform() const
-{
- return m_localTransform;
-}
-
-AffineTransform RenderPath::localTransform() const
-{
- return m_localTransform;
-}
-
bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill) const
{
if (m_path.isEmpty())
@@ -171,22 +165,34 @@ FloatRect RenderPath::repaintRectInLocalCoordinates() const
return m_cachedLocalRepaintRect;
}
-void RenderPath::setPath(const Path& newPath)
-{
- m_path = newPath;
- m_cachedLocalRepaintRect = FloatRect();
- m_cachedLocalStrokeBBox = FloatRect();
- m_cachedLocalFillBBox = FloatRect();
- m_cachedLocalMarkerBBox = FloatRect();
-}
-
void RenderPath::layout()
{
LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
-
SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
- m_localTransform = element->animatedLocalTransform();
- setPath(element->toPathData());
+
+ // 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;
+
+ if (m_needsBoundariesUpdate)
+ m_needsBoundariesUpdate = false;
+
+ if (m_needsPathUpdate) {
+ m_path = element->toPathData();
+ m_needsPathUpdate = false;
+ }
+
+ if (m_needsTransformUpdate) {
+ m_localTransform = element->animatedLocalTransform();
+ m_needsTransformUpdate = false;
+ }
+
+ if (needsUpdate)
+ invalidateCachedBoundaries();
repainter.repaintAfterLayout();
setNeedsLayout(false);
@@ -223,29 +229,32 @@ void RenderPath::paint(PaintInfo& paintInfo, int, int)
return;
PaintInfo childPaintInfo(paintInfo);
- childPaintInfo.context->save();
- applyTransformToPaintInfo(childPaintInfo, m_localTransform);
- SVGResourceFilter* filter = 0;
-
- if (childPaintInfo.phase == PaintPhaseForeground) {
- PaintInfo savedInfo(childPaintInfo);
-
- if (prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter)) {
- if (style()->svgStyle()->shapeRendering() == SR_CRISPEDGES)
- childPaintInfo.context->setShouldAntialias(false);
- fillAndStrokePath(m_path, childPaintInfo.context, style(), this);
-
- if (static_cast<SVGStyledElement*>(node())->supportsMarkers())
- m_markerLayoutInfo.drawMarkers(childPaintInfo);
+ bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
+ if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
+ childPaintInfo.context->save();
+ applyTransformToPaintInfo(childPaintInfo, m_localTransform);
+ RenderSVGResourceFilter* filter = 0;
+
+ if (childPaintInfo.phase == PaintPhaseForeground) {
+ PaintInfo savedInfo(childPaintInfo);
+
+ if (prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter)) {
+ if (style()->svgStyle()->shapeRendering() == SR_CRISPEDGES)
+ childPaintInfo.context->setShouldAntialias(false);
+ fillAndStrokePath(m_path, childPaintInfo.context, style(), this);
+
+ if (static_cast<SVGStyledElement*>(node())->supportsMarkers())
+ m_markerLayoutInfo.drawMarkers(childPaintInfo);
+ }
+ finishRenderSVGContent(this, childPaintInfo, filter, savedInfo.context);
}
- finishRenderSVGContent(this, childPaintInfo, filter, savedInfo.context);
- }
- if ((childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
- paintOutline(childPaintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()),
- static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height()), style());
-
- childPaintInfo.context->restore();
+ if (drawsOutline)
+ paintOutline(childPaintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()),
+ static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height()));
+
+ childPaintInfo.context->restore();
+ }
}
// This method is called from inside paintOutline() since we call paintOutline()
@@ -293,28 +302,28 @@ void RenderPath::calculateMarkerBoundsIfNeeded() const
return;
const SVGRenderStyle* svgStyle = style()->svgStyle();
- AtomicString startMarkerId(svgStyle->startMarker());
- AtomicString midMarkerId(svgStyle->midMarker());
- AtomicString endMarkerId(svgStyle->endMarker());
+ AtomicString startMarkerId(svgStyle->markerStartResource());
+ AtomicString midMarkerId(svgStyle->markerMidResource());
+ AtomicString endMarkerId(svgStyle->markerEndResource());
- SVGResourceMarker* startMarker = getMarkerById(doc, startMarkerId, this);
- SVGResourceMarker* midMarker = getMarkerById(doc, midMarkerId, this);
- SVGResourceMarker* endMarker = getMarkerById(doc, endMarkerId, this);
+ RenderSVGResourceMarker* startMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, startMarkerId);
+ RenderSVGResourceMarker* midMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, midMarkerId);
+ RenderSVGResourceMarker* endMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, endMarkerId);
if (!startMarker && !startMarkerId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(startMarkerId, styledElement);
else if (startMarker)
- startMarker->addClient(styledElement);
+ startMarker->addClient(this);
if (!midMarker && !midMarkerId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(midMarkerId, styledElement);
else if (midMarker)
- midMarker->addClient(styledElement);
+ midMarker->addClient(this);
if (!endMarker && !endMarkerId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(endMarkerId, styledElement);
else if (endMarker)
- endMarker->addClient(styledElement);
+ endMarker->addClient(this);
if (!startMarker && !midMarker && !endMarker)
return;
@@ -323,6 +332,20 @@ void RenderPath::calculateMarkerBoundsIfNeeded() const
m_cachedLocalMarkerBBox = m_markerLayoutInfo.calculateBoundaries(startMarker, midMarker, endMarker, strokeWidth, m_path);
}
+void RenderPath::invalidateCachedBoundaries()
+{
+ m_cachedLocalRepaintRect = FloatRect();
+ m_cachedLocalStrokeBBox = FloatRect();
+ m_cachedLocalFillBBox = FloatRect();
+ m_cachedLocalMarkerBBox = FloatRect();
+}
+
+void RenderPath::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+{
+ invalidateCachedBoundaries();
+ RenderSVGModelObject::styleWillChange(diff, newStyle);
+}
+
}
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/RenderPath.h b/WebCore/rendering/RenderPath.h
index d530f3c..ea4de40 100644
--- a/WebCore/rendering/RenderPath.h
+++ b/WebCore/rendering/RenderPath.h
@@ -41,6 +41,9 @@ public:
RenderPath(SVGStyledTransformableElement*);
const Path& path() const { return m_path; }
+ void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
+ void setNeedsPathUpdate() { m_needsPathUpdate = true; }
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
private:
// Hit-detection seperated for the fill and the stroke
@@ -52,9 +55,7 @@ private:
virtual FloatRect markerBoundingBox() const;
virtual FloatRect repaintRectInLocalCoordinates() const;
- virtual const AffineTransform& localToParentTransform() const;
-
- void setPath(const Path&);
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
virtual bool isRenderPath() const { return true; }
virtual const char* renderName() const { return "RenderPath"; }
@@ -64,11 +65,17 @@ private:
virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
+ virtual void styleWillChange(StyleDifference, const RenderStyle*);
void calculateMarkerBoundsIfNeeded() const;
+ void invalidateCachedBoundaries();
private:
- virtual AffineTransform localTransform() const;
+ virtual AffineTransform localTransform() const { return m_localTransform; }
+
+ bool m_needsBoundariesUpdate : 1;
+ bool m_needsPathUpdate : 1;
+ bool m_needsTransformUpdate : 1;
mutable Path m_path;
mutable FloatRect m_cachedLocalFillBBox;
diff --git a/WebCore/rendering/RenderProgress.cpp b/WebCore/rendering/RenderProgress.cpp
new file mode 100644
index 0000000..a9dbfe8
--- /dev/null
+++ b/WebCore/rendering/RenderProgress.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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(PROGRESS_TAG)
+
+#include "RenderProgress.h"
+
+#include "HTMLProgressElement.h"
+#include "RenderTheme.h"
+#include <wtf/CurrentTime.h>
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+RenderProgress::RenderProgress(HTMLProgressElement* element)
+ : RenderBlock(element)
+ , m_position(-1)
+ , m_animationStartTime(0)
+ , m_animationRepeatInterval(0)
+ , m_animationDuration(0)
+ , m_animating(false)
+ , m_animationTimer(this, &RenderProgress::animationTimerFired)
+{
+}
+
+void RenderProgress::layout()
+{
+ ASSERT(needsLayout());
+
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+
+ calcWidth();
+ calcHeight();
+
+ m_overflow.clear();
+
+ updateAnimationState();
+
+ repainter.repaintAfterLayout();
+
+ setNeedsLayout(false);
+}
+
+void RenderProgress::updateFromElement()
+{
+ HTMLProgressElement* element = progressElement();
+ if (m_position == element->position())
+ return;
+ m_position = element->position();
+
+ updateAnimationState();
+
+ repaint();
+}
+
+double RenderProgress::animationProgress()
+{
+ return m_animating ? (fmod((currentTime() - m_animationStartTime), m_animationDuration) / m_animationDuration) : 0;
+}
+
+void RenderProgress::animationTimerFired(Timer<RenderProgress>*)
+{
+ repaint();
+}
+
+void RenderProgress::paint(PaintInfo& paintInfo, int tx, int ty)
+{
+ if (paintInfo.phase == PaintPhaseBlockBackground) {
+ if (!m_animationTimer.isActive() && m_animating)
+ m_animationTimer.startOneShot(m_animationRepeatInterval);
+ }
+
+ RenderBlock::paint(paintInfo, tx, ty);
+}
+
+void RenderProgress::updateAnimationState()
+{
+ m_animationDuration = theme()->animationDurationForProgressBar(this);
+ m_animationRepeatInterval = theme()->animationRepeatIntervalForProgressBar(this);
+
+ bool animating = m_animationDuration > 0;
+ if (animating == m_animating)
+ return;
+
+ m_animating = animating;
+ if (m_animating) {
+ m_animationStartTime = currentTime();
+ m_animationTimer.startOneShot(m_animationRepeatInterval);
+ } else
+ m_animationTimer.stop();
+}
+
+HTMLProgressElement* RenderProgress::progressElement() const
+{
+ return static_cast<HTMLProgressElement*>(node());
+}
+
+} // namespace WebCore
+#endif
diff --git a/WebCore/rendering/RenderProgress.h b/WebCore/rendering/RenderProgress.h
new file mode 100644
index 0000000..d6f5078
--- /dev/null
+++ b/WebCore/rendering/RenderProgress.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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 RenderProgress_h
+#define RenderProgress_h
+
+#if ENABLE(PROGRESS_TAG)
+#include "RenderBlock.h"
+
+namespace WebCore {
+
+class HTMLProgressElement;
+
+class RenderProgress : public RenderBlock {
+public:
+ RenderProgress(HTMLProgressElement*);
+ double position() { return m_position; }
+ double animationProgress();
+
+ HTMLProgressElement* progressElement() const;
+
+private:
+ virtual const char* renderName() const { return "RenderProgress"; }
+ virtual bool isProgress() const { return true; }
+ virtual void layout();
+ virtual void updateFromElement();
+ virtual void paint(PaintInfo&, int tx, int ty);
+
+ void animationTimerFired(Timer<RenderProgress>*);
+ void updateAnimationState();
+
+ double m_position;
+ double m_animationStartTime;
+ double m_animationRepeatInterval;
+ double m_animationDuration;
+ bool m_animating;
+ Timer<RenderProgress> m_animationTimer;
+};
+
+inline RenderProgress* toRenderProgress(RenderObject* object)
+{
+ ASSERT(!object || object->isProgress());
+ return static_cast<RenderProgress*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderProgress(const RenderProgress*);
+
+} // namespace WebCore
+
+#endif
+
+#endif // RenderProgress_h
+
diff --git a/WebCore/rendering/RenderReplaced.cpp b/WebCore/rendering/RenderReplaced.cpp
index ba579df..0ba99f5 100644
--- a/WebCore/rendering/RenderReplaced.cpp
+++ b/WebCore/rendering/RenderReplaced.cpp
@@ -109,7 +109,7 @@ void RenderReplaced::paint(PaintInfo& paintInfo, int tx, int ty)
}
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
- paintOutline(paintInfo.context, tx, ty, width(), height(), style());
+ paintOutline(paintInfo.context, tx, ty, width(), height());
if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
return;
diff --git a/WebCore/rendering/RenderReplaced.h b/WebCore/rendering/RenderReplaced.h
index bcf565d..b5c6179 100644
--- a/WebCore/rendering/RenderReplaced.h
+++ b/WebCore/rendering/RenderReplaced.h
@@ -48,7 +48,6 @@ protected:
virtual void paint(PaintInfo&, int tx, int ty);
bool shouldPaint(PaintInfo&, int& tx, int& ty);
- void adjustOverflowForBoxShadowAndReflect();
IntRect localSelectionRect(bool checkWhetherSelected = true) const;
private:
diff --git a/WebCore/rendering/RenderSVGContainer.cpp b/WebCore/rendering/RenderSVGContainer.cpp
index 6d1b965..56846a9 100644
--- a/WebCore/rendering/RenderSVGContainer.cpp
+++ b/WebCore/rendering/RenderSVGContainer.cpp
@@ -27,9 +27,9 @@
#include "RenderSVGContainer.h"
#include "GraphicsContext.h"
+#include "RenderSVGResourceFilter.h"
#include "RenderView.h"
#include "SVGRenderSupport.h"
-#include "SVGResourceFilter.h"
#include "SVGStyledElement.h"
namespace WebCore {
@@ -70,7 +70,7 @@ bool RenderSVGContainer::selfWillPaint() const
{
#if ENABLE(FILTERS)
const SVGRenderStyle* svgStyle = style()->svgStyle();
- SVGResourceFilter* filter = getFilterById(document(), svgStyle->filter(), this);
+ RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document(), svgStyle->filterResource());
if (filter)
return true;
#endif
@@ -95,7 +95,7 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int)
applyTransformToPaintInfo(childPaintInfo, localToParentTransform());
- SVGResourceFilter* filter = 0;
+ RenderSVGResourceFilter* filter = 0;
FloatRect boundingBox = repaintRectInLocalCoordinates();
bool continueRendering = true;
@@ -120,7 +120,7 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int)
// We should instead disable our clip during PaintPhaseOutline
IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRectInLocalCoordinates()));
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
- paintOutline(paintInfo.context, paintRectInParent.x(), paintRectInParent.y(), paintRectInParent.width(), paintRectInParent.height(), style());
+ paintOutline(paintInfo.context, paintRectInParent.x(), paintRectInParent.y(), paintRectInParent.width(), paintRectInParent.height());
}
// addFocusRingRects is called from paintOutline and needs to be in the same coordinates as the paintOuline call
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index 6fb9501..1fb7c0f 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -42,6 +42,7 @@ namespace WebCore {
RenderSVGImage::RenderSVGImage(SVGImageElement* impl)
: RenderImage(impl)
+ , m_needsTransformUpdate(true)
{
}
@@ -50,10 +51,13 @@ void RenderSVGImage::layout()
ASSERT(needsLayout());
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
-
SVGImageElement* image = static_cast<SVGImageElement*>(node());
- m_localTransform = image->animatedLocalTransform();
-
+
+ if (m_needsTransformUpdate) {
+ m_localTransform = image->animatedLocalTransform();
+ m_needsTransformUpdate = false;
+ }
+
// minimum height
setHeight(errorOccurred() ? intrinsicSize().height() : 0);
@@ -77,7 +81,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
paintInfo.context->concatCTM(localToParentTransform());
if (paintInfo.phase == PaintPhaseForeground) {
- SVGResourceFilter* filter = 0;
+ RenderSVGResourceFilter* filter = 0;
PaintInfo savedInfo(paintInfo);
@@ -95,14 +99,14 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
}
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
- paintOutline(paintInfo.context, 0, 0, width(), height(), style());
+ paintOutline(paintInfo.context, 0, 0, width(), height());
paintInfo.context->restore();
}
void RenderSVGImage::destroy()
{
- SVGRenderBase::deregisterFromResources(this);
+ deregisterFromResources(this);
RenderImage::destroy();
}
diff --git a/WebCore/rendering/RenderSVGImage.h b/WebCore/rendering/RenderSVGImage.h
index f48b9dd..120ac72 100644
--- a/WebCore/rendering/RenderSVGImage.h
+++ b/WebCore/rendering/RenderSVGImage.h
@@ -38,6 +38,8 @@ class RenderSVGImage : public RenderImage, protected SVGRenderBase {
public:
RenderSVGImage(SVGImageElement*);
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+
private:
virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
virtual const char* renderName() const { return "RenderSVGImage"; }
@@ -72,6 +74,7 @@ private:
virtual AffineTransform localTransform() const { return m_localTransform; }
+ bool m_needsTransformUpdate : 1;
AffineTransform m_localTransform;
FloatRect m_localBounds;
mutable FloatRect m_cachedLocalRepaintRect;
diff --git a/WebCore/rendering/RenderSVGInline.cpp b/WebCore/rendering/RenderSVGInline.cpp
index cf97b52..33459ce 100644
--- a/WebCore/rendering/RenderSVGInline.cpp
+++ b/WebCore/rendering/RenderSVGInline.cpp
@@ -48,9 +48,9 @@ InlineFlowBox* RenderSVGInline::createInlineFlowBox()
void RenderSVGInline::absoluteRects(Vector<IntRect>& rects, int, int)
{
- InlineRunBox* firstBox = firstLineBox();
+ InlineFlowBox* firstBox = firstLineBox();
- SVGRootInlineBox* rootBox = firstBox ? static_cast<SVGInlineTextBox*>(firstBox)->svgRootInlineBox() : 0;
+ RootInlineBox* rootBox = firstBox ? firstBox->root() : 0;
RenderBox* object = rootBox ? rootBox->block() : 0;
if (!object)
@@ -59,17 +59,45 @@ void RenderSVGInline::absoluteRects(Vector<IntRect>& rects, int, int)
int xRef = object->x();
int yRef = object->y();
- for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
FloatRect rect(xRef + curr->x(), yRef + curr->y(), curr->width(), curr->height());
rects.append(enclosingIntRect(localToAbsoluteQuad(rect).boundingBox()));
}
}
+FloatRect RenderSVGInline::objectBoundingBox() const
+{
+ if (const RenderObject* object = findTextRootObject(this))
+ return object->objectBoundingBox();
+
+ return FloatRect();
+}
+
+FloatRect RenderSVGInline::strokeBoundingBox() const
+{
+ const RenderObject* object = findTextRootObject(this);
+ ASSERT(object);
+
+ const SVGRenderBase* renderer = object->toSVGRenderBase();
+ if (!renderer)
+ return FloatRect();
+
+ return renderer->strokeBoundingBox();
+}
+
+FloatRect RenderSVGInline::repaintRectInLocalCoordinates() const
+{
+ if (const RenderObject* object = findTextRootObject(this))
+ return object->repaintRectInLocalCoordinates();
+
+ return FloatRect();
+}
+
void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads)
{
- InlineRunBox* firstBox = firstLineBox();
+ InlineFlowBox* firstBox = firstLineBox();
- SVGRootInlineBox* rootBox = firstBox ? static_cast<SVGInlineTextBox*>(firstBox)->svgRootInlineBox() : 0;
+ RootInlineBox* rootBox = firstBox ? firstBox->root() : 0;
RenderBox* object = rootBox ? rootBox->block() : 0;
if (!object)
@@ -78,7 +106,7 @@ void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads)
int xRef = object->x();
int yRef = object->y();
- for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
FloatRect rect(xRef + curr->x(), yRef + curr->y(), curr->width(), curr->height());
quads.append(localToAbsoluteQuad(rect));
}
diff --git a/WebCore/rendering/RenderSVGInline.h b/WebCore/rendering/RenderSVGInline.h
index 53fd4b7..e57b936 100644
--- a/WebCore/rendering/RenderSVGInline.h
+++ b/WebCore/rendering/RenderSVGInline.h
@@ -31,9 +31,12 @@
namespace WebCore {
-class RenderSVGInline : public RenderInline {
+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; }
@@ -41,8 +44,14 @@ public:
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
- virtual FloatRect objectBoundingBox() const { return FloatRect(); }
- virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
+ // Chapter 10.4 of the SVG Specification say that we should use the
+ // object bounding box of the parent text element.
+ // We search for the root text element and take it's bounding box.
+ // It is also necessary to take the stroke and repaint rect of
+ // this element, since we need it for filters.
+ virtual FloatRect objectBoundingBox() const;
+ virtual FloatRect strokeBoundingBox() const;
+ virtual FloatRect repaintRectInLocalCoordinates() const;
private:
virtual InlineFlowBox* createInlineFlowBox();
diff --git a/WebCore/rendering/RenderSVGModelObject.cpp b/WebCore/rendering/RenderSVGModelObject.cpp
index c163dc6..837b36a 100644
--- a/WebCore/rendering/RenderSVGModelObject.cpp
+++ b/WebCore/rendering/RenderSVGModelObject.cpp
@@ -63,7 +63,7 @@ void RenderSVGModelObject::mapLocalToContainer(RenderBoxModelObject* repaintCont
// Copied from RenderBox, this method likely requires further refactoring to work easily for both SVG and CSS Box Model content.
// FIXME: This may also need to move into SVGRenderBase as the RenderBox version depends
// on borderBoundingBox() which SVG RenderBox subclases (like SVGRenderBlock) do not implement.
-IntRect RenderSVGModelObject::outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer) const
+IntRect RenderSVGModelObject::outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer, IntPoint*) const
{
IntRect box = enclosingIntRect(repaintRectInLocalCoordinates());
adjustRectForOutlineAndShadow(box);
diff --git a/WebCore/rendering/RenderSVGModelObject.h b/WebCore/rendering/RenderSVGModelObject.h
index c04c590..760e79a 100644
--- a/WebCore/rendering/RenderSVGModelObject.h
+++ b/WebCore/rendering/RenderSVGModelObject.h
@@ -55,7 +55,7 @@ public:
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
- virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer) const;
+ virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer, IntPoint*) const;
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
diff --git a/WebCore/rendering/RenderSVGResource.h b/WebCore/rendering/RenderSVGResource.h
index 38c6c09..1665404 100644
--- a/WebCore/rendering/RenderSVGResource.h
+++ b/WebCore/rendering/RenderSVGResource.h
@@ -28,12 +28,58 @@
namespace WebCore {
enum RenderSVGResourceType {
- MaskerResourceType
+ MaskerResourceType,
+ MarkerResourceType,
+ FilterResourceType,
+ ClipperResourceType
};
class RenderSVGResource : public RenderSVGHiddenContainer {
public:
- RenderSVGResource(SVGStyledElement* node) : RenderSVGHiddenContainer(node) { }
+ 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);
+
+ 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);
+ }
template<class Renderer>
Renderer* cast()
@@ -51,10 +97,14 @@ public:
virtual void invalidateClients() = 0;
virtual void invalidateClient(RenderObject*) = 0;
- virtual bool applyResource(RenderObject*, GraphicsContext*) = 0;
+ virtual bool applyResource(RenderObject*, GraphicsContext*&) = 0;
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&) { }
virtual FloatRect resourceBoundingBox(const FloatRect&) const = 0;
virtual RenderSVGResourceType resourceType() const = 0;
+
+private:
+ AtomicString m_id;
};
template<typename Renderer>
@@ -63,19 +113,10 @@ Renderer* getRenderSVGResourceById(Document* document, const AtomicString& id)
if (id.isEmpty())
return 0;
- Element* element = document->getElementById(id);
- if (!element || !element->isSVGElement())
- return 0;
-
- RenderObject* renderer = element->renderer();
- if (!renderer)
- return 0;
-
- RenderSVGResource* renderResource = renderer->toRenderSVGResource();
- if (!renderResource)
- return 0;
+ if (RenderSVGResource* renderResource = document->accessSVGExtensions()->resourceById(id))
+ return renderResource->cast<Renderer>();
- return renderResource->cast<Renderer>();
+ return 0;
}
}
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
new file mode 100644
index 0000000..ccb7397
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
+ * 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org>
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderSVGResourceClipper.h"
+
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "IntRect.h"
+#include "RenderObject.h"
+#include "RenderStyle.h"
+#include "RenderSVGResource.h"
+#include "SVGClipPathElement.h"
+#include "SVGElement.h"
+#include "SVGRenderSupport.h"
+#include "SVGStyledElement.h"
+#include "SVGStyledTransformableElement.h"
+#include "SVGUnitTypes.h"
+#include "SVGUseElement.h"
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourceClipper::s_resourceType = ClipperResourceType;
+
+RenderSVGResourceClipper::RenderSVGResourceClipper(SVGStyledElement* node)
+ : RenderSVGResource(node)
+{
+}
+
+RenderSVGResourceClipper::~RenderSVGResourceClipper()
+{
+ deleteAllValues(m_clipper);
+ m_clipper.clear();
+}
+
+void RenderSVGResourceClipper::invalidateClients()
+{
+ HashMap<RenderObject*, ClipperData*>::const_iterator end = m_clipper.end();
+ for (HashMap<RenderObject*, ClipperData*>::const_iterator it = m_clipper.begin(); it != end; ++it) {
+ RenderObject* renderer = it->first;
+ renderer->setNeedsBoundariesUpdate();
+ renderer->setNeedsLayout(true);
+ }
+ deleteAllValues(m_clipper);
+ m_clipper.clear();
+}
+
+void RenderSVGResourceClipper::invalidateClient(RenderObject* object)
+{
+ ASSERT(object);
+
+ // FIXME: The HashSet 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_clipper.contains(object))
+ return;
+
+ delete m_clipper.take(object);
+}
+
+bool RenderSVGResourceClipper::applyResource(RenderObject* object, GraphicsContext*& context)
+{
+ applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
+ return true;
+}
+
+bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const FloatRect& objectBoundingBox)
+{
+ // If the current clip-path gets clipped itself, we have to fallback to masking.
+ if (!style()->svgStyle()->clipperResource().isEmpty())
+ return false;
+ WindRule clipRule = RULE_NONZERO;
+ Path clipPath = Path();
+
+ // If clip-path only contains one visible shape or path, we can use path-based clipping. Invisible
+ // shapes don't affect the clipping and can be ignored. If clip-path contains more than one
+ // visible shape, the additive clipping may not work, caused by the clipRule. EvenOdd
+ // as well as NonZero can cause self-clipping of the elements.
+ // See also http://www.w3.org/TR/SVG/painting.html#FillRuleProperty
+ for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
+ RenderObject* renderer = childNode->renderer();
+ if (!renderer)
+ continue;
+ // Only shapes or paths are supported for direct clipping. We need to fallback to masking for texts.
+ if (renderer->isSVGText())
+ return false;
+ if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyledTransformable())
+ continue;
+ SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(childNode);
+ RenderStyle* style = renderer->style();
+ if (!style || style->display() == NONE || style->visibility() != VISIBLE)
+ continue;
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+ // Current shape in clip-path gets clipped too. Fallback to masking.
+ if (!svgStyle->clipperResource().isEmpty())
+ return false;
+ // Fallback to masking, if there is more than one clipping path.
+ if (clipPath.isEmpty()) {
+ clipPath = styled->toClipPath();
+ clipRule = svgStyle->clipRule();
+ } else
+ return false;
+ }
+ // Only one visible shape/path was found. Directly continue clipping and transform the content to userspace if necessary.
+ if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ AffineTransform transform;
+ transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ clipPath.transform(transform);
+ }
+ // The SVG specification wants us to clip everything, if clip-path doesn't have a child.
+ if (clipPath.isEmpty())
+ clipPath.addRect(FloatRect());
+ context->beginPath();
+ context->addPath(clipPath);
+ context->clipPath(clipRule);
+ return true;
+}
+
+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);
+
+ ClipperData* clipperData = m_clipper.get(object);
+ if (!clipperData->clipMaskImage) {
+ if (pathOnlyClipping(context, objectBoundingBox))
+ return true;
+ createClipData(clipperData, objectBoundingBox, repaintRect);
+ }
+
+ if (!clipperData->clipMaskImage)
+ return false;
+
+ context->clipToImageBuffer(repaintRect, clipperData->clipMaskImage.get());
+ return true;
+}
+
+bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData, const FloatRect& objectBoundingBox, const FloatRect& repaintRect)
+{
+ IntRect clipMaskRect = enclosingIntRect(repaintRect);
+ clipperData->clipMaskImage = ImageBuffer::create(clipMaskRect.size());
+ if (!clipperData->clipMaskImage)
+ return false;
+
+ GraphicsContext* maskContext = clipperData->clipMaskImage->context();
+ ASSERT(maskContext);
+
+ maskContext->save();
+ maskContext->translate(-repaintRect.x(), -repaintRect.y());
+
+ // clipPath can also be clipped by another clipPath.
+ bool clipperGetsClipped = false;
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(this->document(), style()->svgStyle()->clipperResource())) {
+ clipperGetsClipped = true;
+ if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) {
+ maskContext->restore();
+ return false;
+ }
+ }
+
+ SVGClipPathElement* clipPath = static_cast<SVGClipPathElement*>(node());
+ if (clipPath->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ maskContext->translate(objectBoundingBox.x(), objectBoundingBox.y());
+ maskContext->scale(objectBoundingBox.size());
+ }
+
+ // Draw all clipPath children into a global mask.
+ for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
+ RenderObject* renderer = childNode->renderer();
+ if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
+ continue;
+ RenderStyle* style = renderer->style();
+ if (!style || style->display() == NONE || style->visibility() != VISIBLE)
+ continue;
+
+ WindRule newClipRule = style->svgStyle()->clipRule();
+ bool isUseElement = renderer->isSVGShadowTreeRootContainer();
+ if (isUseElement) {
+ SVGUseElement* useElement = static_cast<SVGUseElement*>(childNode);
+ renderer = useElement->rendererClipChild();
+ if (!renderer)
+ continue;
+ if (!useElement->hasAttribute(SVGNames::clip_ruleAttr))
+ newClipRule = renderer->style()->svgStyle()->clipRule();
+ }
+
+ // Only shapes, paths and texts are allowed for clipping.
+ if (!renderer->isRenderPath() && !renderer->isSVGText())
+ continue;
+
+ // Save the old RenderStyle of the current object for restoring after drawing
+ // it to the MaskImage. The new intermediate RenderStyle needs to inherit from
+ // the old one.
+ RefPtr<RenderStyle> oldRenderStyle = renderer->style();
+ RefPtr<RenderStyle> newRenderStyle = RenderStyle::clone(oldRenderStyle.get());
+ SVGRenderStyle* svgStyle = newRenderStyle.get()->accessSVGStyle();
+ svgStyle->setFillPaint(SVGPaint::defaultFill());
+ svgStyle->setStrokePaint(SVGPaint::defaultStroke());
+ svgStyle->setFillRule(newClipRule);
+ newRenderStyle.get()->setOpacity(1.0f);
+ svgStyle->setFillOpacity(1.0f);
+ svgStyle->setStrokeOpacity(1.0f);
+ svgStyle->setFilterResource(String());
+ svgStyle->setMaskerResource(String());
+ renderer->setStyle(newRenderStyle.release());
+
+ // Get the renderer of the element, that is referenced by the <use>-element.
+ if (isUseElement)
+ renderer = childNode->renderer();
+
+ renderSubtreeToImage(clipperData->clipMaskImage.get(), renderer);
+
+ renderer->setStyle(oldRenderStyle.release());
+ }
+
+ maskContext->restore();
+
+ return true;
+}
+
+FloatRect RenderSVGResourceClipper::resourceBoundingBox(const FloatRect& objectBoundingBox) const
+{
+ // This is a rough heuristic to appraise the clip size and doesn't consider clip on clip.
+ FloatRect clipRect;
+ for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
+ RenderObject* renderer = childNode->renderer();
+ if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
+ continue;
+ if (!renderer->isRenderPath() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer())
+ continue;
+ clipRect.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
+ }
+
+ if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ AffineTransform transform;
+ transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ return transform.mapRect(clipRect);
+ }
+
+ return clipRect;
+}
+
+}
diff --git a/WebCore/rendering/RenderSVGResourceClipper.h b/WebCore/rendering/RenderSVGResourceClipper.h
new file mode 100644
index 0000000..8de17d4
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceClipper.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderSVGResourceClipper_h
+#define RenderSVGResourceClipper_h
+
+#if ENABLE(SVG)
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "IntSize.h"
+#include "Path.h"
+#include "RenderSVGResource.h"
+#include "SVGClipPathElement.h"
+#include "SVGUnitTypes.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+struct ClipperData {
+ OwnPtr<ImageBuffer> clipMaskImage;
+};
+
+class RenderSVGResourceClipper : public RenderSVGResource {
+
+public:
+ RenderSVGResourceClipper(SVGStyledElement*);
+ virtual ~RenderSVGResourceClipper();
+
+ virtual const char* renderName() const { return "RenderSVGResourceClipper"; }
+
+ virtual void invalidateClients();
+ virtual void invalidateClient(RenderObject*);
+
+ virtual bool applyResource(RenderObject*, GraphicsContext*&);
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const;
+
+ virtual RenderSVGResourceType resourceType() const { return ClipperResourceType; }
+
+ SVGUnitTypes::SVGUnitType clipPathUnits() const { return toUnitType(static_cast<SVGClipPathElement*>(node())->clipPathUnits()); }
+
+ static RenderSVGResourceType s_resourceType;
+private:
+ // clipPath can be clipped too, but don't have a boundingBox or repaintRect. So we can't call
+ // applyResource directly and use the rects from the object, since they are empty for RenderSVGResources
+ bool applyClippingToContext(RenderObject*, const FloatRect&, const FloatRect&, GraphicsContext*);
+ bool pathOnlyClipping(GraphicsContext*, const FloatRect&);
+ bool createClipData(ClipperData*, const FloatRect&, const FloatRect&);
+
+ HashMap<RenderObject*, ClipperData*> m_clipper;
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp
new file mode 100644
index 0000000..cbedfe3
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceFilter.cpp
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * 2004, 2005 Rob Buis <buis@kde.org>
+ * 2005 Eric Seidel <eric@webkit.org>
+ * 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
+ * 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) && ENABLE(FILTERS)
+#include "RenderSVGResourceFilter.h"
+
+#include "AffineTransform.h"
+#include "FloatPoint.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "IntRect.h"
+#include "RenderSVGResource.h"
+#include "SVGElement.h"
+#include "SVGFilter.h"
+#include "SVGFilterElement.h"
+#include "SVGFilterPrimitiveStandardAttributes.h"
+#include "SVGStyledElement.h"
+#include "SVGUnitTypes.h"
+#include <wtf/Vector.h>
+
+static const float kMaxFilterSize = 5000.0f;
+
+using namespace std;
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceType;
+
+RenderSVGResourceFilter::RenderSVGResourceFilter(SVGStyledElement* node)
+ : RenderSVGResource(node)
+ , m_savedContext(0)
+ , m_sourceGraphicBuffer(0)
+{
+}
+
+RenderSVGResourceFilter::~RenderSVGResourceFilter()
+{
+ deleteAllValues(m_filter);
+ m_filter.clear();
+}
+
+void RenderSVGResourceFilter::invalidateClients()
+{
+ HashMap<RenderObject*, FilterData*>::const_iterator end = m_filter.end();
+ for (HashMap<RenderObject*, FilterData*>::const_iterator it = m_filter.begin(); it != end; ++it) {
+ RenderObject* renderer = it->first;
+ renderer->setNeedsBoundariesUpdate();
+ renderer->setNeedsLayout(true);
+ }
+ deleteAllValues(m_filter);
+ m_filter.clear();
+}
+
+void RenderSVGResourceFilter::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_filter.contains(object))
+ return;
+
+ delete m_filter.take(object);
+}
+
+PassOwnPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives()
+{
+ SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
+ bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
+
+ // Add effects to the builder
+ OwnPtr<SVGFilterBuilder> builder(new SVGFilterBuilder);
+ builder->clearEffects();
+ for (Node* node = filterElement->firstChild(); node; node = node->nextSibling()) {
+ if (!node->isSVGElement())
+ continue;
+
+ SVGElement* element = static_cast<SVGElement*>(node);
+ if (!element->isFilterEffect())
+ continue;
+
+ SVGFilterPrimitiveStandardAttributes* effectElement = static_cast<SVGFilterPrimitiveStandardAttributes*>(element);
+ RefPtr<FilterEffect> effect = effectElement->build(builder.get());
+ if (!effect) {
+ builder->clearEffects();
+ return 0;
+ }
+ effectElement->setStandardAttributes(primitiveBoundingBoxMode, effect.get());
+ builder->add(effectElement->result(), effect);
+ }
+ return builder.release();
+}
+
+bool RenderSVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size, FloatSize& scale)
+{
+ bool matchesFilterSize = true;
+ if (size.width() > kMaxFilterSize) {
+ scale.setWidth(scale.width() * kMaxFilterSize / size.width());
+ matchesFilterSize = false;
+ }
+ if (size.height() > kMaxFilterSize) {
+ scale.setHeight(scale.height() * kMaxFilterSize / size.height());
+ matchesFilterSize = false;
+ }
+
+ return matchesFilterSize;
+}
+
+bool RenderSVGResourceFilter::applyResource(RenderObject* object, GraphicsContext*& context)
+{
+ ASSERT(object);
+ ASSERT(context);
+
+ // Returning false here, to avoid drawings onto the context. We just want to
+ // draw the stored filter output, not the unfiltered object as well.
+ if (m_filter.contains(object)) {
+ FilterData* filterData = m_filter.get(object);
+ if (filterData->builded)
+ return false;
+
+ delete m_filter.take(object); // Oops, have to rebuild, go through normal code path
+ }
+
+ OwnPtr<FilterData> filterData(new FilterData);
+ filterData->builder = buildPrimitives();
+ if (!filterData->builder)
+ return false;
+
+ const SVGRenderBase* renderer = object->toSVGRenderBase();
+ if (!renderer)
+ return false;
+
+ FloatRect paintRect = renderer->strokeBoundingBox();
+ paintRect.unite(renderer->markerBoundingBox());
+
+ // Calculate the scale factor for the use of filterRes.
+ // Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
+ SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
+ filterData->boundaries = filterElement->filterBoundingBox(object->objectBoundingBox());
+ if (filterData->boundaries.isEmpty())
+ return false;
+
+ FloatSize scale(1.0f, 1.0f);
+ if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
+ scale.setWidth(filterElement->filterResX() / filterData->boundaries.width());
+ scale.setHeight(filterElement->filterResY() / filterData->boundaries.height());
+ }
+
+ if (scale.isEmpty())
+ return false;
+
+ // clip sourceImage to filterRegion
+ FloatRect clippedSourceRect = paintRect;
+ clippedSourceRect.intersect(filterData->boundaries);
+
+ // scale filter size to filterRes
+ FloatRect tempSourceRect = clippedSourceRect;
+
+ // scale to big sourceImage size to kMaxFilterSize
+ tempSourceRect.scale(scale.width(), scale.height());
+ fitsInMaximumImageSize(tempSourceRect.size(), scale);
+
+ // prepare Filters
+ bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
+ filterData->filter = SVGFilter::create(paintRect, filterData->boundaries, primitiveBoundingBoxMode);
+ filterData->filter->setFilterResolution(scale);
+
+ FilterEffect* lastEffect = filterData->builder->lastEffect();
+ if (!lastEffect)
+ return false;
+
+ lastEffect->calculateEffectRect(filterData->filter.get());
+ // At least one FilterEffect has a too big image size,
+ // recalculate the effect sizes with new scale factors.
+ if (!fitsInMaximumImageSize(filterData->filter->maxImageSize(), scale)) {
+ filterData->filter->setFilterResolution(scale);
+ lastEffect->calculateEffectRect(filterData->filter.get());
+ }
+
+ clippedSourceRect.scale(scale.width(), scale.height());
+
+ // Draw the content of the current element and it's childs to a imageBuffer to get the SourceGraphic.
+ // The size of the SourceGraphic is clipped to the size of the filterRegion.
+ IntRect bufferRect = enclosingIntRect(clippedSourceRect);
+ OwnPtr<ImageBuffer> sourceGraphic(ImageBuffer::create(bufferRect.size(), LinearRGB));
+
+ if (!sourceGraphic.get())
+ return false;
+
+ GraphicsContext* sourceGraphicContext = sourceGraphic->context();
+ sourceGraphicContext->translate(-clippedSourceRect.x(), -clippedSourceRect.y());
+ sourceGraphicContext->scale(scale);
+ sourceGraphicContext->clearRect(FloatRect(FloatPoint(), paintRect.size()));
+ m_sourceGraphicBuffer.set(sourceGraphic.release());
+ m_savedContext = context;
+
+ context = sourceGraphicContext;
+ m_filter.set(object, filterData.release());
+
+ return true;
+}
+
+void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context)
+{
+ ASSERT(object);
+ ASSERT(context);
+
+ if (!m_filter.contains(object))
+ return;
+
+ FilterData* filterData = m_filter.get(object);
+ if (!filterData->builded) {
+ if (!m_savedContext) {
+ invalidateClient(object);
+ return;
+ }
+
+ context = m_savedContext;
+ m_savedContext = 0;
+#if !PLATFORM(CG)
+ m_sourceGraphicBuffer->transformColorSpace(DeviceRGB, LinearRGB);
+#endif
+ }
+
+ FilterEffect* lastEffect = filterData->builder->lastEffect();
+
+ if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->subRegion().isEmpty()) {
+ // This is the real filtering of the object. It just needs to be called on the
+ // initial filtering process. We just take the stored filter result on a
+ // second drawing.
+ if (!filterData->builded) {
+ filterData->filter->setSourceImage(m_sourceGraphicBuffer.release());
+ lastEffect->apply(filterData->filter.get());
+ filterData->builded = true;
+ }
+
+ ImageBuffer* resultImage = lastEffect->resultImage();
+ if (resultImage) {
+#if !PLATFORM(CG)
+ resultImage->transformColorSpace(LinearRGB, DeviceRGB);
+#endif
+ context->drawImage(resultImage->image(), object->style()->colorSpace(), lastEffect->subRegion());
+ }
+ }
+
+ m_sourceGraphicBuffer.clear();
+}
+
+FloatRect RenderSVGResourceFilter::resourceBoundingBox(const FloatRect& objectBoundingBox) const
+{
+ if (SVGFilterElement* element = static_cast<SVGFilterElement*>(node()))
+ return element->filterBoundingBox(objectBoundingBox);
+
+ return FloatRect();
+}
+
+}
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceFilter.h b/WebCore/rendering/RenderSVGResourceFilter.h
new file mode 100644
index 0000000..2cd4b6c
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceFilter.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * 2004, 2005 Rob Buis <buis@kde.org>
+ * 2005 Eric Seidel <eric@webkit.org>
+ * 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
+ * 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 RenderSVGResourceFilter_h
+#define RenderSVGResourceFilter_h
+
+#if ENABLE(SVG) && ENABLE(FILTERS)
+#include "FloatRect.h"
+#include "ImageBuffer.h"
+#include "RenderSVGResource.h"
+#include "SVGFilter.h"
+#include "SVGFilterBuilder.h"
+#include "SVGFilterElement.h"
+#include "SVGUnitTypes.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+struct FilterData {
+ FilterData()
+ : builded(false)
+ {
+ }
+
+ RefPtr<SVGFilter> filter;
+ OwnPtr<SVGFilterBuilder> builder;
+ FloatRect boundaries;
+ FloatSize scale;
+ bool builded;
+};
+
+class GraphicsContext;
+
+class RenderSVGResourceFilter : public RenderSVGResource {
+public:
+ RenderSVGResourceFilter(SVGStyledElement*);
+ virtual ~RenderSVGResourceFilter();
+
+ virtual const char* renderName() const { return "RenderSVGResourceFilter"; }
+
+ virtual void invalidateClients();
+ virtual void invalidateClient(RenderObject*);
+
+ virtual bool applyResource(RenderObject*, GraphicsContext*&);
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&);
+
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const;
+
+ PassOwnPtr<SVGFilterBuilder> buildPrimitives();
+
+ SVGUnitTypes::SVGUnitType filterUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->filterUnits()); }
+ SVGUnitTypes::SVGUnitType primitiveUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->primitiveUnits()); }
+
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
+
+private:
+ bool fitsInMaximumImageSize(const FloatSize&, FloatSize&);
+
+ // Intermediate storage during
+ GraphicsContext* m_savedContext;
+ OwnPtr<ImageBuffer> m_sourceGraphicBuffer;
+
+ HashMap<RenderObject*, FilterData*> m_filter;
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceMarker.cpp b/WebCore/rendering/RenderSVGResourceMarker.cpp
new file mode 100644
index 0000000..c526962
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceMarker.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
+ * 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org>
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderSVGResourceMarker.h"
+
+#include "GraphicsContext.h"
+#include "RenderSVGContainer.h"
+#include "SVGElement.h"
+#include "SVGMarkerElement.h"
+#include "SVGRenderSupport.h"
+#include "SVGStyledElement.h"
+#include "SVGStyledTransformableElement.h"
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourceMarker::s_resourceType = MarkerResourceType;
+
+RenderSVGResourceMarker::RenderSVGResourceMarker(SVGStyledElement* node)
+ : RenderSVGResource(node)
+{
+}
+
+RenderSVGResourceMarker::~RenderSVGResourceMarker()
+{
+ m_marker.clear();
+}
+
+void RenderSVGResourceMarker::layout()
+{
+ // RenderSVGHiddenContainer overwrites layout(). We need the
+ // layouting of RenderSVGContainer for calculating local
+ // transformations and repaint.
+ RenderSVGContainer::layout();
+}
+
+void RenderSVGResourceMarker::addClient(const RenderObject* object)
+{
+ m_marker.add(object);
+}
+
+void RenderSVGResourceMarker::invalidateClients()
+{
+ const HashSet<const RenderObject*>::const_iterator end = m_marker.end();
+ for (HashSet<const RenderObject*>::const_iterator it = m_marker.begin(); it != end; ++it) {
+ RenderObject* renderer = const_cast<RenderObject*>(*it);
+ renderer->setNeedsBoundariesUpdate();
+ renderer->setNeedsLayout(true);
+ }
+
+ m_marker.clear();
+}
+
+void RenderSVGResourceMarker::invalidateClient(RenderObject* object)
+{
+ ASSERT(object);
+
+ // FIXME: The HashSet 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_marker.contains(object))
+ return;
+
+ m_marker.remove(object);
+}
+
+void RenderSVGResourceMarker::applyViewportClip(PaintInfo& paintInfo)
+{
+ if (SVGRenderBase::isOverflowHidden(this))
+ paintInfo.context->clip(m_viewport);
+}
+
+FloatRect RenderSVGResourceMarker::markerBoundaries(const AffineTransform& markerTransformation) const
+{
+ FloatRect coordinates = RenderSVGContainer::repaintRectInLocalCoordinates();
+
+ // Map repaint rect into parent coordinate space, in which the marker boundaries have to be evaluated
+ coordinates = localToParentTransform().mapRect(coordinates);
+
+ return markerTransformation.mapRect(coordinates);
+}
+
+const AffineTransform& RenderSVGResourceMarker::localToParentTransform() const
+{
+ AffineTransform viewportTranslation(viewportTransform());
+ m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
+ return m_localToParentTransform;
+ // If this class were ever given a localTransform(), then the above would read:
+ // return viewportTransform() * localTransform() * viewportTranslation;
+}
+
+FloatPoint RenderSVGResourceMarker::referencePoint() const
+{
+ SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ ASSERT(marker);
+
+ return FloatPoint(marker->refX().value(marker), marker->refY().value(marker));
+}
+
+float RenderSVGResourceMarker::angle() const
+{
+ SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ ASSERT(marker);
+
+ float angle = -1;
+ if (marker->orientType() == SVGMarkerElement::SVG_MARKER_ORIENT_ANGLE)
+ angle = marker->orientAngle().value();
+
+ return angle;
+}
+
+AffineTransform RenderSVGResourceMarker::markerTransformation(const FloatPoint& origin, float autoAngle, float strokeWidth) const
+{
+ SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ ASSERT(marker);
+
+ float markerAngle = angle();
+ bool useStrokeWidth = (marker->markerUnits() == SVGMarkerElement::SVG_MARKERUNITS_STROKEWIDTH);
+
+ AffineTransform transform;
+ transform.translate(origin.x(), origin.y());
+ transform.rotate(markerAngle == -1 ? autoAngle : markerAngle);
+ transform = markerContentTransformation(transform, referencePoint(), useStrokeWidth ? strokeWidth : -1);
+ return transform;
+}
+
+void RenderSVGResourceMarker::draw(RenderObject::PaintInfo& paintInfo, const AffineTransform& transform)
+{
+ DEFINE_STATIC_LOCAL(HashSet<RenderSVGResourceMarker*>, currentlyDrawingMarkers, ());
+
+ // avoid drawing circular marker references
+ if (currentlyDrawingMarkers.contains(this))
+ return;
+
+ currentlyDrawingMarkers.add(this);
+ RenderObject::PaintInfo info(paintInfo);
+ info.context->save();
+ applyTransformToPaintInfo(info, transform);
+ RenderSVGContainer::paint(info, 0, 0);
+ info.context->restore();
+
+ currentlyDrawingMarkers.remove(this);
+}
+
+AffineTransform RenderSVGResourceMarker::markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth) const
+{
+ // The 'origin' coordinate maps to SVGs refX/refY, given in coordinates relative to the viewport established by the marker
+ FloatPoint mappedOrigin = viewportTransform().mapPoint(origin);
+
+ AffineTransform transformation = contentTransformation;
+ if (strokeWidth != -1)
+ transformation.scaleNonUniform(strokeWidth, strokeWidth);
+
+ transformation.translate(-mappedOrigin.x(), -mappedOrigin.y());
+ return transformation;
+}
+
+AffineTransform RenderSVGResourceMarker::viewportTransform() const
+{
+ SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ ASSERT(marker);
+
+ return marker->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
+}
+
+void RenderSVGResourceMarker::calcViewport()
+{
+ if (!selfNeedsLayout())
+ return;
+
+ SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ ASSERT(marker);
+
+ float w = marker->markerWidth().value(marker);
+ float h = marker->markerHeight().value(marker);
+ m_viewport = FloatRect(0, 0, w, h);
+}
+
+}
diff --git a/WebCore/rendering/RenderSVGResourceMarker.h b/WebCore/rendering/RenderSVGResourceMarker.h
new file mode 100644
index 0000000..9e39b99
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceMarker.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderSVGResourceMarker_h
+#define RenderSVGResourceMarker_h
+
+#if ENABLE(SVG)
+#include "FloatRect.h"
+#include "RenderObject.h"
+#include "RenderSVGResource.h"
+#include "SVGMarkerElement.h"
+#include "SVGStyledElement.h"
+
+#include <wtf/HashSet.h>
+
+namespace WebCore {
+
+class AffineTransform;
+
+class RenderSVGResourceMarker : public RenderSVGResource {
+
+public:
+ RenderSVGResourceMarker(SVGStyledElement*);
+ virtual ~RenderSVGResourceMarker();
+
+ virtual const char* renderName() const { return "RenderSVGResourceMarker"; }
+
+ void addClient(const RenderObject*);
+ virtual void invalidateClients();
+ virtual void invalidateClient(RenderObject*);
+
+ void draw(RenderObject::PaintInfo&, const AffineTransform&);
+
+ // Calculates marker boundaries, mapped to the target element's coordinate space
+ FloatRect markerBoundaries(const AffineTransform& markerTransformation) const;
+
+ virtual void applyViewportClip(PaintInfo&);
+ virtual void layout();
+ virtual void calcViewport();
+
+ virtual const AffineTransform& localToParentTransform() const;
+ AffineTransform markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const;
+
+ virtual bool applyResource(RenderObject*, GraphicsContext*&) { return false; }
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const { return FloatRect(); }
+
+ FloatPoint referencePoint() const;
+ float angle() const;
+ SVGMarkerElement::SVGMarkerUnitsType markerUnits() const { return static_cast<SVGMarkerElement::SVGMarkerUnitsType>(static_cast<SVGMarkerElement*>(node())->markerUnits()); }
+
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
+
+private:
+ // Generates a transformation matrix usable to render marker content. Handles scaling the marker content
+ // acording to SVGs markerUnits="strokeWidth" concept, when a strokeWidth value != -1 is passed in.
+ AffineTransform markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth = -1) const;
+
+ AffineTransform viewportTransform() const;
+
+ // Save objects using this marker for invalidation.
+ HashSet<const RenderObject*> m_marker;
+
+ mutable AffineTransform m_localToParentTransform;
+ FloatRect m_viewport;
+};
+
+}
+#endif
+
+#endif
diff --git a/WebCore/rendering/RenderSVGResourceMasker.cpp b/WebCore/rendering/RenderSVGResourceMasker.cpp
index 2923c6e..8bb16de 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -31,6 +31,7 @@
#include "ImageBuffer.h"
#include "ImageData.h"
#include "IntRect.h"
+#include "RenderSVGResource.h"
#include "SVGElement.h"
#include "SVGMaskElement.h"
#include "SVGStyledElement.h"
@@ -55,8 +56,12 @@ RenderSVGResourceMasker::~RenderSVGResourceMasker()
void RenderSVGResourceMasker::invalidateClients()
{
HashMap<RenderObject*, MaskerData*>::const_iterator end = m_masker.end();
- for (HashMap<RenderObject*, MaskerData*>::const_iterator it = m_masker.begin(); it != end; ++it)
- it->first->setNeedsLayout(true);
+ for (HashMap<RenderObject*, MaskerData*>::const_iterator it = m_masker.begin(); it != end; ++it) {
+ RenderObject* renderer = it->first;
+ renderer->setNeedsBoundariesUpdate();
+ renderer->setNeedsLayout(true);
+ }
+
deleteAllValues(m_masker);
m_masker.clear();
}
@@ -75,7 +80,7 @@ void RenderSVGResourceMasker::invalidateClient(RenderObject* object)
delete m_masker.take(object);
}
-bool RenderSVGResourceMasker::applyResource(RenderObject* object, GraphicsContext* context)
+bool RenderSVGResourceMasker::applyResource(RenderObject* object, GraphicsContext*& context)
{
ASSERT(object);
ASSERT(context);
diff --git a/WebCore/rendering/RenderSVGResourceMasker.h b/WebCore/rendering/RenderSVGResourceMasker.h
index 6c73c84..3127e3c 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.h
+++ b/WebCore/rendering/RenderSVGResourceMasker.h
@@ -58,7 +58,7 @@ public:
virtual void invalidateClients();
virtual void invalidateClient(RenderObject*);
- virtual bool applyResource(RenderObject*, GraphicsContext*);
+ virtual bool applyResource(RenderObject*, GraphicsContext*&);
virtual FloatRect resourceBoundingBox(const FloatRect&) const;
SVGUnitTypes::SVGUnitType maskUnits() const { return toUnitType(static_cast<SVGMaskElement*>(node())->maskUnits()); }
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index 51bf3e7..5ed0871 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -35,7 +35,7 @@
#include "TransformState.h"
#if ENABLE(FILTERS)
-#include "SVGResourceFilter.h"
+#include "RenderSVGResourceFilter.h"
#endif
using namespace std;
@@ -129,7 +129,7 @@ bool RenderSVGRoot::selfWillPaint() const
{
#if ENABLE(FILTERS)
const SVGRenderStyle* svgStyle = style()->svgStyle();
- SVGResourceFilter* filter = getFilterById(document(), svgStyle->filter(), this);
+ RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document(), svgStyle->filterResource());
if (filter)
return true;
#endif
@@ -166,7 +166,7 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
// Transform from our paint container's coordinate system to our local coords.
applyTransformToPaintInfo(childPaintInfo, localToRepaintContainerTransform(parentOriginInContainer));
- SVGResourceFilter* filter = 0;
+ RenderSVGResourceFilter* filter = 0;
FloatRect boundingBox = repaintRectInLocalCoordinates();
bool continueRendering = true;
@@ -182,7 +182,7 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
childPaintInfo.context->restore();
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
- paintOutline(paintInfo.context, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y(), width(), height(), style());
+ paintOutline(paintInfo.context, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y(), width(), height());
}
void RenderSVGRoot::destroy()
diff --git a/WebCore/rendering/RenderSVGShadowTreeRootContainer.h b/WebCore/rendering/RenderSVGShadowTreeRootContainer.h
index 01cd427..81ae44b 100644
--- a/WebCore/rendering/RenderSVGShadowTreeRootContainer.h
+++ b/WebCore/rendering/RenderSVGShadowTreeRootContainer.h
@@ -33,6 +33,8 @@ public:
RenderSVGShadowTreeRootContainer(SVGUseElement*);
virtual ~RenderSVGShadowTreeRootContainer();
+ virtual bool isSVGShadowTreeRootContainer() const { return true; }
+
void markShadowTreeForRecreation() { m_recreateTree = true; }
void updateStyle(Node::StyleChange);
virtual void updateFromElement();
diff --git a/WebCore/rendering/RenderSVGTSpan.h b/WebCore/rendering/RenderSVGTSpan.h
index 652c5e3..931bd8c 100644
--- a/WebCore/rendering/RenderSVGTSpan.h
+++ b/WebCore/rendering/RenderSVGTSpan.h
@@ -31,12 +31,6 @@ class RenderSVGTSpan : public RenderSVGInline {
public:
RenderSVGTSpan(Node*);
virtual const char* renderName() const { return "RenderSVGTSpan"; }
-
- // FIXME: These are incorrect, but have always behaved this way.
- // These empty implementations prevent us from hitting RenderObject ASSERTS.
- // tspan.getBBox() will be wrong, and repainting for tspans may not work correctly!
- virtual FloatRect objectBoundingBox() const { return FloatRect(); }
- virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
};
}
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp
index b8b9553..c0c4650 100644
--- a/WebCore/rendering/RenderSVGText.cpp
+++ b/WebCore/rendering/RenderSVGText.cpp
@@ -38,7 +38,6 @@
#include "RenderSVGRoot.h"
#include "SVGLengthList.h"
#include "SVGRenderSupport.h"
-#include "SVGResourceFilter.h"
#include "SVGRootInlineBox.h"
#include "SVGTextElement.h"
#include "SVGTransformList.h"
@@ -49,6 +48,7 @@ namespace WebCore {
RenderSVGText::RenderSVGText(SVGTextElement* node)
: RenderSVGBlock(node)
+ , m_needsTransformUpdate(true)
{
}
@@ -78,7 +78,10 @@ void RenderSVGText::layout()
int yOffset = (int)(text->y()->getFirst().value(text));
setLocation(xOffset, yOffset);
- m_localTransform = text->animatedLocalTransform();
+ if (m_needsTransformUpdate) {
+ m_localTransform = text->animatedLocalTransform();
+ m_needsTransformUpdate = false;
+ }
RenderBlock::layout();
@@ -128,11 +131,8 @@ void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int)
// Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard
// to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
- for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
- ASSERT(runBox->isInlineFlowBox());
-
- InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
- for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
+ for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) {
+ for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine()) {
FloatRect boxRect(box->x(), box->y(), box->width(), box->height());
// FIXME: crawling up the parent chain to map each rect is very inefficient
// we should compute the absoluteTransform outside this loop first.
@@ -149,11 +149,8 @@ void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads)
// Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard
// to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
- for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
- ASSERT(runBox->isInlineFlowBox());
-
- InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
- for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
+ for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) {
+ for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine()) {
FloatRect boxRect(box->x(), box->y(), box->width(), box->height());
// FIXME: crawling up the parent chain to map each quad is very inefficient
// we should compute the absoluteTransform outside this loop first.
@@ -175,11 +172,8 @@ FloatRect RenderSVGText::objectBoundingBox() const
{
FloatRect boundingBox;
- for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
- ASSERT(runBox->isInlineFlowBox());
-
- InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
- for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine())
+ for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) {
+ for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine())
boundingBox.unite(FloatRect(box->x(), box->y(), box->width(), box->height()));
}
diff --git a/WebCore/rendering/RenderSVGText.h b/WebCore/rendering/RenderSVGText.h
index ab4b09b..fe53086 100644
--- a/WebCore/rendering/RenderSVGText.h
+++ b/WebCore/rendering/RenderSVGText.h
@@ -37,6 +37,8 @@ class RenderSVGText : public RenderSVGBlock {
public:
RenderSVGText(SVGTextElement* node);
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+
private:
virtual const char* renderName() const { return "RenderSVGText"; }
@@ -67,11 +69,11 @@ private:
virtual FloatRect strokeBoundingBox() const;
virtual FloatRect repaintRectInLocalCoordinates() const;
- // FIXME: This can be removed when localTransform() is removed from RenderObject
virtual AffineTransform localTransform() const { return m_localTransform; }
virtual RootInlineBox* createRootInlineBox();
+ bool m_needsTransformUpdate : 1;
AffineTransform m_localTransform;
};
diff --git a/WebCore/rendering/RenderSVGTransformableContainer.cpp b/WebCore/rendering/RenderSVGTransformableContainer.cpp
index 4bec7a7..94b9eea 100644
--- a/WebCore/rendering/RenderSVGTransformableContainer.cpp
+++ b/WebCore/rendering/RenderSVGTransformableContainer.cpp
@@ -31,29 +31,31 @@ namespace WebCore {
RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGStyledTransformableElement* node)
: RenderSVGContainer(node)
+ , m_needsTransformUpdate(true)
{
}
-const AffineTransform& RenderSVGTransformableContainer::localToParentTransform() const
+void RenderSVGTransformableContainer::calculateLocalTransform()
{
- return m_localTransform;
-}
+ SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
-AffineTransform RenderSVGTransformableContainer::localTransform() const
-{
- return m_localTransform;
-}
+ bool needsUpdate = m_needsTransformUpdate;
+ if (needsUpdate) {
+ m_localTransform = element->animatedLocalTransform();
+ m_needsTransformUpdate = false;
+ }
-void RenderSVGTransformableContainer::calculateLocalTransform()
-{
- m_localTransform = static_cast<SVGStyledTransformableElement*>(node())->animatedLocalTransform();
- if (!node()->hasTagName(SVGNames::gTag) || !static_cast<SVGGElement*>(node())->isShadowTreeContainerElement())
+ if (!element->hasTagName(SVGNames::gTag) || !static_cast<SVGGElement*>(element)->isShadowTreeContainerElement())
return;
- FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(node())->containerTranslation();
+ FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(element)->containerTranslation();
if (translation.width() == 0 && translation.height() == 0)
return;
+ // FIXME: Could optimize this case for use to avoid refetching the animatedLocalTransform() here, if only the containerTranslation() changed.
+ if (!needsUpdate)
+ m_localTransform = element->animatedLocalTransform();
+
m_localTransform.translate(translation.width(), translation.height());
}
diff --git a/WebCore/rendering/RenderSVGTransformableContainer.h b/WebCore/rendering/RenderSVGTransformableContainer.h
index 1de0b19..e6de054 100644
--- a/WebCore/rendering/RenderSVGTransformableContainer.h
+++ b/WebCore/rendering/RenderSVGTransformableContainer.h
@@ -31,13 +31,14 @@ namespace WebCore {
public:
RenderSVGTransformableContainer(SVGStyledTransformableElement*);
- virtual const AffineTransform& localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
private:
virtual void calculateLocalTransform();
- // FIXME: This can be made non-virtual once SVGRenderTreeAsText stops using localTransform()
- virtual AffineTransform localTransform() const;
+ virtual AffineTransform localTransform() const { return m_localTransform; }
+ bool m_needsTransformUpdate : 1;
AffineTransform m_localTransform;
};
}
diff --git a/WebCore/rendering/RenderSVGViewportContainer.cpp b/WebCore/rendering/RenderSVGViewportContainer.cpp
index 103d9d2..1587e7f 100644
--- a/WebCore/rendering/RenderSVGViewportContainer.cpp
+++ b/WebCore/rendering/RenderSVGViewportContainer.cpp
@@ -3,6 +3,7 @@
2004, 2005, 2007 Rob Buis <buis@kde.org>
2007 Eric Seidel <eric@webkit.org>
2009 Google, Inc.
+ Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -26,9 +27,7 @@
#include "RenderSVGViewportContainer.h"
#include "GraphicsContext.h"
-
#include "RenderView.h"
-#include "SVGMarkerElement.h"
#include "SVGSVGElement.h"
namespace WebCore {
@@ -38,29 +37,6 @@ RenderSVGViewportContainer::RenderSVGViewportContainer(SVGStyledElement* node)
{
}
-FloatRect RenderSVGViewportContainer::markerBoundaries(const AffineTransform& markerTransformation) const
-{
- FloatRect coordinates = repaintRectInLocalCoordinates();
-
- // Map repaint rect into parent coordinate space, in which the marker boundaries have to be evaluated
- coordinates = localToParentTransform().mapRect(coordinates);
-
- return markerTransformation.mapRect(coordinates);
-}
-
-AffineTransform RenderSVGViewportContainer::markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth) const
-{
- // The 'origin' coordinate maps to SVGs refX/refY, given in coordinates relative to the viewport established by the marker
- FloatPoint mappedOrigin = viewportTransform().mapPoint(origin);
-
- AffineTransform transformation = contentTransformation;
- if (strokeWidth != -1)
- transformation.scaleNonUniform(strokeWidth, strokeWidth);
-
- transformation.translate(-mappedOrigin.x(), -mappedOrigin.y());
- return transformation;
-}
-
void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
{
if (SVGRenderBase::isOverflowHidden(this))
@@ -81,14 +57,6 @@ void RenderSVGViewportContainer::calcViewport()
float w = svg->width().value(svg);
float h = svg->height().value(svg);
m_viewport = FloatRect(x, y, w, h);
- } else if (svgelem->hasTagName(SVGNames::markerTag)) {
- if (!selfNeedsLayout())
- return;
-
- SVGMarkerElement* svg = static_cast<SVGMarkerElement*>(node());
- float w = svg->markerWidth().value(svg);
- float h = svg->markerHeight().value(svg);
- m_viewport = FloatRect(0, 0, w, h);
}
}
@@ -97,9 +65,6 @@ AffineTransform RenderSVGViewportContainer::viewportTransform() const
if (node()->hasTagName(SVGNames::svgTag)) {
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
return svg->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
- } else if (node()->hasTagName(SVGNames::markerTag)) {
- SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
- return marker->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
}
return AffineTransform();
diff --git a/WebCore/rendering/RenderSVGViewportContainer.h b/WebCore/rendering/RenderSVGViewportContainer.h
index c4043ec..7b5702b 100644
--- a/WebCore/rendering/RenderSVGViewportContainer.h
+++ b/WebCore/rendering/RenderSVGViewportContainer.h
@@ -34,13 +34,6 @@ class RenderSVGViewportContainer : public RenderSVGContainer {
public:
RenderSVGViewportContainer(SVGStyledElement*);
- // Calculates marker boundaries, mapped to the target element's coordinate space
- FloatRect markerBoundaries(const AffineTransform& markerTransformation) const;
-
- // Generates a transformation matrix usable to render marker content. Handles scaling the marker content
- // acording to SVGs markerUnits="strokeWidth" concept, when a strokeWidth value != -1 is passed in.
- AffineTransform markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth = -1) const;
-
private:
virtual bool isSVGContainer() const { return true; }
virtual const char* renderName() const { return "RenderSVGViewportContainer"; }
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index 344f4ab..37b5e19 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -35,6 +35,7 @@
#include "RenderLayer.h"
#include "RenderTheme.h"
#include "RenderView.h"
+#include "StepRange.h"
#include <wtf/MathExtras.h>
#ifdef ANDROID_LAYOUT
@@ -49,80 +50,10 @@ using namespace HTMLNames;
static const int defaultTrackLength = 129;
-// FIXME: The SliderRange class and functions are entirely based on the DOM,
-// and could be put with HTMLInputElement (possibly with a new name) instead of here.
-struct SliderRange {
- bool hasStep;
- double step;
- double minimum;
- double maximum; // maximum must be >= minimum.
-
- explicit SliderRange(HTMLInputElement*);
- double clampValue(double value);
-
- // Map value into 0-1 range
- double proportionFromValue(double value)
- {
- if (minimum == maximum)
- return 0;
-
- return (value - minimum) / (maximum - minimum);
- }
-
- // Map from 0-1 range to value
- double valueFromProportion(double proportion)
- {
- return minimum + proportion * (maximum - minimum);
- }
-
- double valueFromElement(HTMLInputElement*, bool* wasClamped = 0);
-};
-
-SliderRange::SliderRange(HTMLInputElement* element)
-{
- if (element->hasAttribute(precisionAttr)) {
- step = 1.0;
- hasStep = !equalIgnoringCase(element->getAttribute(precisionAttr), "float");
- } else
- hasStep = element->getAllowedValueStep(&step);
-
- maximum = element->maximum();
- minimum = element->minimum();
-}
-
-double SliderRange::clampValue(double value)
-{
- double clampedValue = max(minimum, min(value, maximum));
- if (!hasStep)
- return clampedValue;
- // Rounds clampedValue to minimum + N * step.
- clampedValue = minimum + round((clampedValue - minimum) / step) * step;
- if (clampedValue > maximum)
- clampedValue -= step;
- ASSERT(clampedValue >= minimum);
- ASSERT(clampedValue <= maximum);
- return clampedValue;
-}
-
-double SliderRange::valueFromElement(HTMLInputElement* element, bool* wasClamped)
-{
- double oldValue;
- bool parseSuccess = HTMLInputElement::parseToDoubleForNumberType(element->value(), &oldValue);
- if (!parseSuccess)
- oldValue = (minimum + maximum) / 2;
- double newValue = clampValue(oldValue);
-
- if (wasClamped)
- *wasClamped = !parseSuccess || newValue != oldValue;
-
- return newValue;
-}
-
// Returns a value between 0 and 1.
-// As with SliderRange, this could be on HTMLInputElement instead of here.
static double sliderPosition(HTMLInputElement* element)
{
- SliderRange range(element);
+ StepRange range(element);
return range.proportionFromValue(range.valueFromElement(element));
}
@@ -376,15 +307,6 @@ void RenderSlider::layout()
void RenderSlider::updateFromElement()
{
- HTMLInputElement* element = static_cast<HTMLInputElement*>(node());
-
- // Send the value back to the element if the range changes it.
- SliderRange range(element);
- bool clamped;
- double value = range.valueFromElement(element, &clamped);
- if (clamped)
- element->setValueFromRenderer(HTMLInputElement::serializeForNumberType(value));
-
// Layout will take care of the thumb's size and position.
if (!m_thumb) {
m_thumb = new SliderThumbElement(document(), node());
@@ -434,7 +356,7 @@ void RenderSlider::setValueForPosition(int position)
HTMLInputElement* element = static_cast<HTMLInputElement*>(node());
// Calculate the new value based on the position, and send it to the element.
- SliderRange range(element);
+ StepRange range(element);
double fraction = static_cast<double>(position) / trackSize();
if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart)
fraction = 1 - fraction;
diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp
index 61e05ad..0a61a93 100644
--- a/WebCore/rendering/RenderTable.cpp
+++ b/WebCore/rendering/RenderTable.cpp
@@ -648,6 +648,25 @@ void RenderTable::appendColumn(int span)
setNeedsLayoutAndPrefWidthsRecalc();
}
+RenderTableCol* RenderTable::nextColElement(RenderTableCol* current) const
+{
+ RenderObject* next = current->firstChild();
+ if (!next)
+ next = current->nextSibling();
+ if (!next && current->parent()->isTableCol())
+ next = current->parent()->nextSibling();
+
+ while (next) {
+ if (next->isTableCol())
+ return toRenderTableCol(next);
+ if (next != m_caption)
+ return 0;
+ next = next->nextSibling();
+ }
+
+ return 0;
+}
+
RenderTableCol* RenderTable::colElement(int col, bool* startEdge, bool* endEdge) const
{
if (!m_hasColElements)
@@ -656,32 +675,31 @@ RenderTableCol* RenderTable::colElement(int col, bool* startEdge, bool* endEdge)
int cCol = 0;
while (child) {
- if (child->isTableCol()) {
- RenderTableCol* colElem = toRenderTableCol(child);
- int span = colElem->span();
- if (!colElem->firstChild()) {
- int startCol = cCol;
- int endCol = cCol + span - 1;
- cCol += span;
- if (cCol > col) {
- if (startEdge)
- *startEdge = startCol == col;
- if (endEdge)
- *endEdge = endCol == col;
- return colElem;
- }
- }
-
- RenderObject* next = child->firstChild();
- if (!next)
- next = child->nextSibling();
- if (!next && child->parent()->isTableCol())
- next = child->parent()->nextSibling();
- child = next;
- } else if (child == m_caption)
- child = child->nextSibling();
- else
+ if (child->isTableCol())
break;
+ if (child != m_caption)
+ return 0;
+ child = child->nextSibling();
+ }
+ if (!child)
+ return 0;
+
+ RenderTableCol* colElem = toRenderTableCol(child);
+ while (colElem) {
+ int span = colElem->span();
+ if (!colElem->firstChild()) {
+ int startCol = cCol;
+ int endCol = cCol + span - 1;
+ cCol += span;
+ if (cCol > col) {
+ if (startEdge)
+ *startEdge = startCol == col;
+ if (endEdge)
+ *endEdge = endCol == col;
+ return colElem;
+ }
+ }
+ colElem = nextColElement(colElem);
}
return 0;
@@ -773,7 +791,7 @@ int RenderTable::calcBorderLeft() const
if (tb.style() == BHIDDEN)
return 0;
if (tb.style() > BHIDDEN)
- borderWidth = tb.width;
+ borderWidth = tb.width();
int leftmostColumn = style()->direction() == RTL ? numEffCols() - 1 : 0;
RenderTableCol* colGroup = colElement(leftmostColumn);
@@ -782,7 +800,7 @@ int RenderTable::calcBorderLeft() const
if (gb.style() == BHIDDEN)
return 0;
if (gb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<unsigned>(gb.width));
+ borderWidth = max(borderWidth, static_cast<unsigned>(gb.width()));
}
RenderTableSection* firstNonEmptySection = m_head ? m_head : (m_firstBody ? m_firstBody : m_foot);
@@ -795,7 +813,7 @@ int RenderTable::calcBorderLeft() const
return 0;
if (sb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<unsigned>(sb.width));
+ borderWidth = max(borderWidth, static_cast<unsigned>(sb.width()));
const RenderTableSection::CellStruct& cs = firstNonEmptySection->cellAt(0, leftmostColumn);
@@ -809,9 +827,9 @@ int RenderTable::calcBorderLeft() const
return 0;
if (cb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<unsigned>(cb.width));
+ borderWidth = max(borderWidth, static_cast<unsigned>(cb.width()));
if (rb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<unsigned>(rb.width));
+ borderWidth = max(borderWidth, static_cast<unsigned>(rb.width()));
}
}
return borderWidth / 2;
@@ -832,7 +850,7 @@ int RenderTable::calcBorderRight() const
if (tb.style() == BHIDDEN)
return 0;
if (tb.style() > BHIDDEN)
- borderWidth = tb.width;
+ borderWidth = tb.width();
int rightmostColumn = style()->direction() == RTL ? 0 : numEffCols() - 1;
RenderTableCol* colGroup = colElement(rightmostColumn);
@@ -841,7 +859,7 @@ int RenderTable::calcBorderRight() const
if (gb.style() == BHIDDEN)
return 0;
if (gb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<unsigned>(gb.width));
+ borderWidth = max(borderWidth, static_cast<unsigned>(gb.width()));
}
RenderTableSection* firstNonEmptySection = m_head ? m_head : (m_firstBody ? m_firstBody : m_foot);
@@ -854,7 +872,7 @@ int RenderTable::calcBorderRight() const
return 0;
if (sb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<unsigned>(sb.width));
+ borderWidth = max(borderWidth, static_cast<unsigned>(sb.width()));
const RenderTableSection::CellStruct& cs = firstNonEmptySection->cellAt(0, rightmostColumn);
@@ -868,9 +886,9 @@ int RenderTable::calcBorderRight() const
return 0;
if (cb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<unsigned>(cb.width));
+ borderWidth = max(borderWidth, static_cast<unsigned>(cb.width()));
if (rb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<unsigned>(rb.width));
+ borderWidth = max(borderWidth, static_cast<unsigned>(rb.width()));
}
}
return (borderWidth + 1) / 2;
@@ -921,7 +939,7 @@ int RenderTable::outerBorderTop() const
if (tb.style() == BHIDDEN)
return 0;
if (tb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<int>(tb.width / 2));
+ borderWidth = max(borderWidth, static_cast<int>(tb.width() / 2));
return borderWidth;
}
@@ -947,7 +965,7 @@ int RenderTable::outerBorderBottom() const
if (tb.style() == BHIDDEN)
return 0;
if (tb.style() > BHIDDEN)
- borderWidth = max(borderWidth, static_cast<int>((tb.width + 1) / 2));
+ borderWidth = max(borderWidth, static_cast<int>((tb.width() + 1) / 2));
return borderWidth;
}
@@ -962,7 +980,7 @@ int RenderTable::outerBorderLeft() const
if (tb.style() == BHIDDEN)
return 0;
if (tb.style() > BHIDDEN)
- borderWidth = tb.width / 2;
+ borderWidth = tb.width() / 2;
bool allHidden = true;
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
@@ -992,7 +1010,7 @@ int RenderTable::outerBorderRight() const
if (tb.style() == BHIDDEN)
return 0;
if (tb.style() > BHIDDEN)
- borderWidth = (tb.width + 1) / 2;
+ borderWidth = (tb.width() + 1) / 2;
bool allHidden = true;
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
diff --git a/WebCore/rendering/RenderTable.h b/WebCore/rendering/RenderTable.h
index d07a727..ea81d64 100644
--- a/WebCore/rendering/RenderTable.h
+++ b/WebCore/rendering/RenderTable.h
@@ -113,6 +113,7 @@ public:
}
RenderTableCol* colElement(int col, bool* startEdge = 0, bool* endEdge = 0) const;
+ RenderTableCol* nextColElement(RenderTableCol* current) const;
bool needsSectionRecalc() const { return m_needsSectionRecalc; }
void setNeedsSectionRecalc()
diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp
index de71796..4506e77 100644
--- a/WebCore/rendering/RenderTableCell.cpp
+++ b/WebCore/rendering/RenderTableCell.cpp
@@ -88,18 +88,42 @@ void RenderTableCell::updateFromElement()
Length RenderTableCell::styleOrColWidth() const
{
Length w = style()->width();
- if (colSpan() > 1 || !w.isAuto())
+ if (!w.isAuto())
return w;
+
RenderTableCol* tableCol = table()->colElement(col());
+
if (tableCol) {
- w = tableCol->style()->width();
-
+ int colSpanCount = colSpan();
+
+ Length colWidthSum = Length(0, Fixed);
+ for (int i = 1; i <= colSpanCount; i++) {
+ Length colWidth = tableCol->style()->width();
+
+ // Percentage value should be returned only for colSpan == 1.
+ // Otherwise we return original width for the cell.
+ if (!colWidth.isFixed()) {
+ if (colSpanCount > 1)
+ return w;
+ return colWidth;
+ }
+
+ colWidthSum = Length(colWidthSum.value() + colWidth.value(), Fixed);
+
+ tableCol = table()->nextColElement(tableCol);
+ // If no next <col> tag found for the span we just return what we have for now.
+ if (!tableCol)
+ break;
+ }
+
// Column widths specified on <col> apply to the border box of the cell.
// 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 (w.isFixed() && w.value() > 0)
- w = Length(max(0, w.value() - borderLeft() - borderRight() - paddingLeft() - paddingRight()), Fixed);
+ if (colWidthSum.isFixed() && colWidthSum.value() > 0)
+ colWidthSum = Length(max(0, colWidthSum.value() - borderLeft() - borderRight() - paddingLeft() - paddingRight()), Fixed);
+ return colWidthSum;
}
+
return w;
}
@@ -312,7 +336,7 @@ static CollapsedBorderValue compareBorders(const CollapsedBorderValue& border1,
return border1.style() > border2.style() ? border1 : border2;
// The border have the same width and style. Rely on precedence (cell over row over row group, etc.)
- return border1.precedence >= border2.precedence ? border1 : border2;
+ return border1.precedence() >= border2.precedence() ? border1 : border2;
}
CollapsedBorderValue RenderTableCell::collapsedLeftBorder(bool rtl) const
@@ -328,22 +352,25 @@ CollapsedBorderValue RenderTableCell::collapsedLeftBorder(bool rtl) const
// For border left, we need to check, in order of precedence:
// (1) Our left border.
- CollapsedBorderValue result(&style()->borderLeft(), BCELL);
+ int left = CSSPropertyBorderLeftColor;
+ int right = CSSPropertyBorderRightColor;
+ CollapsedBorderValue result(&style()->borderLeft(), style()->visitedDependentColor(left), BCELL);
// (2) The right border of the cell to the left.
RenderTableCell* prevCell = rtl ? tableElt->cellAfter(this) : tableElt->cellBefore(this);
if (prevCell) {
- result = rtl ? compareBorders(result, CollapsedBorderValue(&prevCell->style()->borderRight(), BCELL)) : compareBorders(CollapsedBorderValue(&prevCell->style()->borderRight(), BCELL), result);
+ CollapsedBorderValue prevCellBorder = CollapsedBorderValue(&prevCell->style()->borderRight(), prevCell->style()->visitedDependentColor(right), BCELL);
+ result = rtl ? compareBorders(result, prevCellBorder) : compareBorders(prevCellBorder, result);
if (!result.exists())
return result;
} else if (leftmostColumn) {
// (3) Our row's left border.
- result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderLeft(), BROW));
+ result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderLeft(), parent()->style()->visitedDependentColor(left), BROW));
if (!result.exists())
return result;
// (4) Our row group's left border.
- result = compareBorders(result, CollapsedBorderValue(&section()->style()->borderLeft(), BROWGROUP));
+ result = compareBorders(result, CollapsedBorderValue(&section()->style()->borderLeft(), section()->style()->visitedDependentColor(left), BROWGROUP));
if (!result.exists())
return result;
}
@@ -353,11 +380,11 @@ CollapsedBorderValue RenderTableCell::collapsedLeftBorder(bool rtl) const
bool endColEdge;
RenderTableCol* colElt = tableElt->colElement(col() + (rtl ? colSpan() - 1 : 0), &startColEdge, &endColEdge);
if (colElt && (!rtl ? startColEdge : endColEdge)) {
- result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderLeft(), BCOL));
+ result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderLeft(), colElt->style()->visitedDependentColor(left), BCOL));
if (!result.exists())
return result;
if (colElt->parent()->isTableCol() && (!rtl ? !colElt->previousSibling() : !colElt->nextSibling())) {
- result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderLeft(), BCOLGROUP));
+ result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderLeft(), colElt->parent()->style()->visitedDependentColor(left), BCOLGROUP));
if (!result.exists())
return result;
}
@@ -367,13 +394,14 @@ CollapsedBorderValue RenderTableCell::collapsedLeftBorder(bool rtl) const
if (!leftmostColumn) {
colElt = tableElt->colElement(col() + (rtl ? colSpan() : -1), &startColEdge, &endColEdge);
if (colElt && (!rtl ? endColEdge : startColEdge)) {
- result = rtl ? compareBorders(result, CollapsedBorderValue(&colElt->style()->borderRight(), BCOL)) : compareBorders(CollapsedBorderValue(&colElt->style()->borderRight(), BCOL), result);
+ CollapsedBorderValue rightBorder = CollapsedBorderValue(&colElt->style()->borderRight(), colElt->style()->visitedDependentColor(right), BCOL);
+ result = rtl ? compareBorders(result, rightBorder) : compareBorders(rightBorder, result);
if (!result.exists())
return result;
}
} else {
// (7) The table's left border.
- result = compareBorders(result, CollapsedBorderValue(&tableElt->style()->borderLeft(), BTABLE));
+ result = compareBorders(result, CollapsedBorderValue(&tableElt->style()->borderLeft(), tableElt->style()->visitedDependentColor(left), BTABLE));
if (!result.exists())
return result;
}
@@ -394,24 +422,27 @@ CollapsedBorderValue RenderTableCell::collapsedRightBorder(bool rtl) const
// For border right, we need to check, in order of precedence:
// (1) Our right border.
- CollapsedBorderValue result = CollapsedBorderValue(&style()->borderRight(), BCELL);
+ int left = CSSPropertyBorderLeftColor;
+ int right = CSSPropertyBorderRightColor;
+ CollapsedBorderValue result = CollapsedBorderValue(&style()->borderRight(), style()->visitedDependentColor(right), BCELL);
// (2) The left border of the cell to the right.
if (!rightmostColumn) {
RenderTableCell* nextCell = rtl ? tableElt->cellBefore(this) : tableElt->cellAfter(this);
if (nextCell && nextCell->style()) {
- result = rtl ? compareBorders(CollapsedBorderValue(&nextCell->style()->borderLeft(), BCELL), result) : compareBorders(result, CollapsedBorderValue(&nextCell->style()->borderLeft(), BCELL));
+ CollapsedBorderValue leftBorder = CollapsedBorderValue(&nextCell->style()->borderLeft(), nextCell->style()->visitedDependentColor(left), BCELL);
+ result = rtl ? compareBorders(leftBorder, result) : compareBorders(result, leftBorder);
if (!result.exists())
return result;
}
} else {
// (3) Our row's right border.
- result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderRight(), BROW));
+ result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderRight(), parent()->style()->visitedDependentColor(right), BROW));
if (!result.exists())
return result;
// (4) Our row group's right border.
- result = compareBorders(result, CollapsedBorderValue(&section()->style()->borderRight(), BROWGROUP));
+ result = compareBorders(result, CollapsedBorderValue(&section()->style()->borderRight(), section()->style()->visitedDependentColor(right), BROWGROUP));
if (!result.exists())
return result;
}
@@ -421,11 +452,11 @@ CollapsedBorderValue RenderTableCell::collapsedRightBorder(bool rtl) const
bool endColEdge;
RenderTableCol* colElt = tableElt->colElement(col() + (rtl ? 0 : colSpan() - 1), &startColEdge, &endColEdge);
if (colElt && (!rtl ? endColEdge : startColEdge)) {
- result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderRight(), BCOL));
+ result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderRight(), colElt->style()->visitedDependentColor(right), BCOL));
if (!result.exists())
return result;
if (colElt->parent()->isTableCol() && (!rtl ? !colElt->nextSibling() : !colElt->previousSibling())) {
- result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderRight(), BCOLGROUP));
+ result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderRight(), colElt->parent()->style()->visitedDependentColor(right), BCOLGROUP));
if (!result.exists())
return result;
}
@@ -435,13 +466,14 @@ CollapsedBorderValue RenderTableCell::collapsedRightBorder(bool rtl) const
if (!rightmostColumn) {
colElt = tableElt->colElement(col() + (rtl ? -1 : colSpan()), &startColEdge, &endColEdge);
if (colElt && (!rtl ? startColEdge : endColEdge)) {
- result = rtl ? compareBorders(CollapsedBorderValue(&colElt->style()->borderLeft(), BCOL), result) : compareBorders(result, CollapsedBorderValue(&colElt->style()->borderLeft(), BCOL));
+ CollapsedBorderValue leftBorder = CollapsedBorderValue(&colElt->style()->borderLeft(), colElt->style()->visitedDependentColor(left), BCOL);
+ result = rtl ? compareBorders(leftBorder, result) : compareBorders(result, leftBorder);
if (!result.exists())
return result;
}
} else {
// (7) The table's right border.
- result = compareBorders(result, CollapsedBorderValue(&tableElt->style()->borderRight(), BTABLE));
+ result = compareBorders(result, CollapsedBorderValue(&tableElt->style()->borderRight(), tableElt->style()->visitedDependentColor(right), BTABLE));
if (!result.exists())
return result;
}
@@ -453,18 +485,20 @@ CollapsedBorderValue RenderTableCell::collapsedTopBorder() const
{
// For border top, we need to check, in order of precedence:
// (1) Our top border.
- CollapsedBorderValue result = CollapsedBorderValue(&style()->borderTop(), BCELL);
+ int top = CSSPropertyBorderTopColor;
+ int bottom = CSSPropertyBorderBottomColor;
+ CollapsedBorderValue result = CollapsedBorderValue(&style()->borderTop(), style()->visitedDependentColor(top), BCELL);
RenderTableCell* prevCell = table()->cellAbove(this);
if (prevCell) {
// (2) A previous cell's bottom border.
- result = compareBorders(CollapsedBorderValue(&prevCell->style()->borderBottom(), BCELL), result);
+ result = compareBorders(CollapsedBorderValue(&prevCell->style()->borderBottom(), prevCell->style()->visitedDependentColor(bottom), BCELL), result);
if (!result.exists())
return result;
}
// (3) Our row's top border.
- result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderTop(), BROW));
+ result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderTop(), parent()->style()->visitedDependentColor(top), BROW));
if (!result.exists())
return result;
@@ -477,7 +511,7 @@ CollapsedBorderValue RenderTableCell::collapsedTopBorder() const
prevRow = prevCell->section()->lastChild();
if (prevRow) {
- result = compareBorders(CollapsedBorderValue(&prevRow->style()->borderBottom(), BROW), result);
+ result = compareBorders(CollapsedBorderValue(&prevRow->style()->borderBottom(), prevRow->style()->visitedDependentColor(bottom), BROW), result);
if (!result.exists())
return result;
}
@@ -487,14 +521,14 @@ CollapsedBorderValue RenderTableCell::collapsedTopBorder() const
RenderTableSection* currSection = section();
if (!row()) {
// (5) Our row group's top border.
- result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderTop(), BROWGROUP));
+ result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderTop(), currSection->style()->visitedDependentColor(top), BROWGROUP));
if (!result.exists())
return result;
// (6) Previous row group's bottom border.
currSection = table()->sectionAbove(currSection);
if (currSection) {
- result = compareBorders(CollapsedBorderValue(&currSection->style()->borderBottom(), BROWGROUP), result);
+ result = compareBorders(CollapsedBorderValue(&currSection->style()->borderBottom(), currSection->style()->visitedDependentColor(bottom), BROWGROUP), result);
if (!result.exists())
return result;
}
@@ -504,18 +538,19 @@ CollapsedBorderValue RenderTableCell::collapsedTopBorder() const
// (8) Our column and column group's top borders.
RenderTableCol* colElt = table()->colElement(col());
if (colElt) {
- result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderTop(), BCOL));
+ result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderTop(), colElt->style()->visitedDependentColor(top), BCOL));
if (!result.exists())
return result;
if (colElt->parent()->isTableCol()) {
- result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderTop(), BCOLGROUP));
+ result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderTop(), colElt->parent()->style()->visitedDependentColor(top), BCOLGROUP));
if (!result.exists())
return result;
}
}
// (9) The table's top border.
- result = compareBorders(result, CollapsedBorderValue(&table()->style()->borderTop(), BTABLE));
+ RenderTable* enclosingTable = table();
+ result = compareBorders(result, CollapsedBorderValue(&enclosingTable->style()->borderTop(), enclosingTable->style()->visitedDependentColor(top), BTABLE));
if (!result.exists())
return result;
}
@@ -527,24 +562,26 @@ CollapsedBorderValue RenderTableCell::collapsedBottomBorder() const
{
// For border top, we need to check, in order of precedence:
// (1) Our bottom border.
- CollapsedBorderValue result = CollapsedBorderValue(&style()->borderBottom(), BCELL);
+ int top = CSSPropertyBorderTopColor;
+ int bottom = CSSPropertyBorderBottomColor;
+ CollapsedBorderValue result = CollapsedBorderValue(&style()->borderBottom(), style()->visitedDependentColor(bottom), BCELL);
RenderTableCell* nextCell = table()->cellBelow(this);
if (nextCell) {
// (2) A following cell's top border.
- result = compareBorders(result, CollapsedBorderValue(&nextCell->style()->borderTop(), BCELL));
+ result = compareBorders(result, CollapsedBorderValue(&nextCell->style()->borderTop(), nextCell->style()->visitedDependentColor(top), BCELL));
if (!result.exists())
return result;
}
// (3) Our row's bottom border. (FIXME: Deal with rowspan!)
- result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderBottom(), BROW));
+ result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderBottom(), parent()->style()->visitedDependentColor(bottom), BROW));
if (!result.exists())
return result;
// (4) The next row's top border.
if (nextCell) {
- result = compareBorders(result, CollapsedBorderValue(&nextCell->parent()->style()->borderTop(), BROW));
+ result = compareBorders(result, CollapsedBorderValue(&nextCell->parent()->style()->borderTop(), nextCell->parent()->style()->visitedDependentColor(top), BROW));
if (!result.exists())
return result;
}
@@ -553,14 +590,14 @@ CollapsedBorderValue RenderTableCell::collapsedBottomBorder() const
RenderTableSection* currSection = section();
if (row() + rowSpan() >= currSection->numRows()) {
// (5) Our row group's bottom border.
- result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderBottom(), BROWGROUP));
+ result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderBottom(), currSection->style()->visitedDependentColor(bottom), BROWGROUP));
if (!result.exists())
return result;
// (6) Following row group's top border.
currSection = table()->sectionBelow(currSection);
if (currSection) {
- result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderTop(), BROWGROUP));
+ result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderTop(), currSection->style()->visitedDependentColor(top), BROWGROUP));
if (!result.exists())
return result;
}
@@ -570,17 +607,18 @@ CollapsedBorderValue RenderTableCell::collapsedBottomBorder() const
// (8) Our column and column group's bottom borders.
RenderTableCol* colElt = table()->colElement(col());
if (colElt) {
- result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderBottom(), BCOL));
+ result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderBottom(), colElt->style()->visitedDependentColor(bottom), BCOL));
if (!result.exists()) return result;
if (colElt->parent()->isTableCol()) {
- result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderBottom(), BCOLGROUP));
+ result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderBottom(), colElt->parent()->style()->visitedDependentColor(bottom), BCOLGROUP));
if (!result.exists())
return result;
}
}
// (9) The table's bottom border.
- result = compareBorders(result, CollapsedBorderValue(&table()->style()->borderBottom(), BTABLE));
+ RenderTable* enclosingTable = table();
+ result = compareBorders(result, CollapsedBorderValue(&enclosingTable->style()->borderBottom(), enclosingTable->style()->visitedDependentColor(bottom), BTABLE));
if (!result.exists())
return result;
}
@@ -811,7 +849,7 @@ void RenderTableCell::paintCollapsedBorder(GraphicsContext* graphicsContext, int
for (CollapsedBorder* border = borders.nextBorder(); border; border = borders.nextBorder()) {
if (border->borderValue == *table()->currentBorderStyle())
drawLineForBoxSide(graphicsContext, border->x1, border->y1, border->x2, border->y2, border->side,
- border->borderValue.color(), style()->color(), border->style, 0, 0);
+ border->borderValue.color(), border->style, 0, 0);
}
}
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index a2457e1..e8ab4a4 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -807,13 +807,13 @@ int RenderTableSection::calcOuterBorderTop() const
if (sb.style() == BHIDDEN)
return -1;
if (sb.style() > BHIDDEN)
- borderWidth = sb.width;
+ borderWidth = sb.width();
const BorderValue& rb = firstChild()->style()->borderTop();
if (rb.style() == BHIDDEN)
return -1;
- if (rb.style() > BHIDDEN && rb.width > borderWidth)
- borderWidth = rb.width;
+ if (rb.style() > BHIDDEN && rb.width() > borderWidth)
+ borderWidth = rb.width();
bool allHidden = true;
for (int c = 0; c < totalCols; c++) {
@@ -829,17 +829,17 @@ int RenderTableSection::calcOuterBorderTop() const
continue;
else
allHidden = false;
- if (gb.style() > BHIDDEN && gb.width > borderWidth)
- borderWidth = gb.width;
- if (cb.style() > BHIDDEN && cb.width > borderWidth)
- borderWidth = cb.width;
+ if (gb.style() > BHIDDEN && gb.width() > borderWidth)
+ borderWidth = gb.width();
+ if (cb.style() > BHIDDEN && cb.width() > borderWidth)
+ borderWidth = cb.width();
} else {
if (cb.style() == BHIDDEN)
continue;
else
allHidden = false;
- if (cb.style() > BHIDDEN && cb.width > borderWidth)
- borderWidth = cb.width;
+ if (cb.style() > BHIDDEN && cb.width() > borderWidth)
+ borderWidth = cb.width();
}
}
if (allHidden)
@@ -860,13 +860,13 @@ int RenderTableSection::calcOuterBorderBottom() const
if (sb.style() == BHIDDEN)
return -1;
if (sb.style() > BHIDDEN)
- borderWidth = sb.width;
+ borderWidth = sb.width();
const BorderValue& rb = lastChild()->style()->borderBottom();
if (rb.style() == BHIDDEN)
return -1;
- if (rb.style() > BHIDDEN && rb.width > borderWidth)
- borderWidth = rb.width;
+ if (rb.style() > BHIDDEN && rb.width() > borderWidth)
+ borderWidth = rb.width();
bool allHidden = true;
for (int c = 0; c < totalCols; c++) {
@@ -882,17 +882,17 @@ int RenderTableSection::calcOuterBorderBottom() const
continue;
else
allHidden = false;
- if (gb.style() > BHIDDEN && gb.width > borderWidth)
- borderWidth = gb.width;
- if (cb.style() > BHIDDEN && cb.width > borderWidth)
- borderWidth = cb.width;
+ if (gb.style() > BHIDDEN && gb.width() > borderWidth)
+ borderWidth = gb.width();
+ if (cb.style() > BHIDDEN && cb.width() > borderWidth)
+ borderWidth = cb.width();
} else {
if (cb.style() == BHIDDEN)
continue;
else
allHidden = false;
- if (cb.style() > BHIDDEN && cb.width > borderWidth)
- borderWidth = cb.width;
+ if (cb.style() > BHIDDEN && cb.width() > borderWidth)
+ borderWidth = cb.width();
}
}
if (allHidden)
@@ -913,7 +913,7 @@ int RenderTableSection::calcOuterBorderLeft(bool rtl) const
if (sb.style() == BHIDDEN)
return -1;
if (sb.style() > BHIDDEN)
- borderWidth = sb.width;
+ borderWidth = sb.width();
int leftmostColumn = rtl ? totalCols - 1 : 0;
RenderTableCol* colGroup = table()->colElement(leftmostColumn);
@@ -921,8 +921,8 @@ int RenderTableSection::calcOuterBorderLeft(bool rtl) const
const BorderValue& gb = colGroup->style()->borderLeft();
if (gb.style() == BHIDDEN)
return -1;
- if (gb.style() > BHIDDEN && gb.width > borderWidth)
- borderWidth = gb.width;
+ if (gb.style() > BHIDDEN && gb.width() > borderWidth)
+ borderWidth = gb.width();
}
bool allHidden = true;
@@ -937,10 +937,10 @@ int RenderTableSection::calcOuterBorderLeft(bool rtl) const
continue;
else
allHidden = false;
- if (cb.style() > BHIDDEN && cb.width > borderWidth)
- borderWidth = cb.width;
- if (rb.style() > BHIDDEN && rb.width > borderWidth)
- borderWidth = rb.width;
+ if (cb.style() > BHIDDEN && cb.width() > borderWidth)
+ borderWidth = cb.width();
+ if (rb.style() > BHIDDEN && rb.width() > borderWidth)
+ borderWidth = rb.width();
}
if (allHidden)
return -1;
@@ -960,7 +960,7 @@ int RenderTableSection::calcOuterBorderRight(bool rtl) const
if (sb.style() == BHIDDEN)
return -1;
if (sb.style() > BHIDDEN)
- borderWidth = sb.width;
+ borderWidth = sb.width();
int rightmostColumn = rtl ? 0 : totalCols - 1;
RenderTableCol* colGroup = table()->colElement(rightmostColumn);
@@ -968,8 +968,8 @@ int RenderTableSection::calcOuterBorderRight(bool rtl) const
const BorderValue& gb = colGroup->style()->borderRight();
if (gb.style() == BHIDDEN)
return -1;
- if (gb.style() > BHIDDEN && gb.width > borderWidth)
- borderWidth = gb.width;
+ if (gb.style() > BHIDDEN && gb.width() > borderWidth)
+ borderWidth = gb.width();
}
bool allHidden = true;
@@ -984,10 +984,10 @@ int RenderTableSection::calcOuterBorderRight(bool rtl) const
continue;
else
allHidden = false;
- if (cb.style() > BHIDDEN && cb.width > borderWidth)
- borderWidth = cb.width;
- if (rb.style() > BHIDDEN && rb.width > borderWidth)
- borderWidth = rb.width;
+ if (cb.style() > BHIDDEN && cb.width() > borderWidth)
+ borderWidth = cb.width();
+ if (rb.style() > BHIDDEN && rb.width() > borderWidth)
+ borderWidth = rb.width();
}
if (allHidden)
return -1;
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index 4653273..90ad6d8 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -36,8 +36,10 @@
#include "RenderBlock.h"
#include "RenderLayer.h"
#include "RenderView.h"
+#include "StringBuffer.h"
#include "Text.h"
#include "TextBreakIterator.h"
+#include "TextResourceDecoder.h"
#include "VisiblePosition.h"
#include "break_lines.h"
#include <wtf/AlwaysInline.h>
@@ -48,16 +50,46 @@ using namespace Unicode;
namespace WebCore {
-// FIXME: Move to StringImpl.h eventually.
-static inline bool charactersAreAllASCII(StringImpl* text)
+static void makeCapitalized(String* string, UChar previous)
{
- return charactersAreAllASCII(text->characters(), text->length());
+ if (string->isNull())
+ return;
+
+ unsigned length = string->length();
+ const UChar* characters = string->characters();
+
+ StringBuffer stringWithPrevious(length + 1);
+ stringWithPrevious[0] = previous == noBreakSpace ? ' ' : previous;
+ for (unsigned i = 1; i < length + 1; i++) {
+ // Replace &nbsp with a real space since ICU no longer treats &nbsp as a word separator.
+ if (characters[i - 1] == noBreakSpace)
+ stringWithPrevious[i] = ' ';
+ else
+ stringWithPrevious[i] = characters[i - 1];
+ }
+
+ TextBreakIterator* boundary = wordBreakIterator(stringWithPrevious.characters(), length + 1);
+ if (!boundary)
+ return;
+
+ StringBuffer data(length);
+
+ int32_t endOfWord;
+ int32_t startOfWord = textBreakFirst(boundary);
+ for (endOfWord = textBreakNext(boundary); endOfWord != TextBreakDone; startOfWord = endOfWord, endOfWord = textBreakNext(boundary)) {
+ if (startOfWord != 0) // Ignore first char of previous string
+ data[startOfWord - 1] = characters[startOfWord - 1] == noBreakSpace ? noBreakSpace : toTitleCase(stringWithPrevious[startOfWord]);
+ for (int i = startOfWord + 1; i < endOfWord; i++)
+ data[i - 1] = characters[i - 1];
+ }
+
+ *string = String::adopt(data);
}
RenderText::RenderText(Node* node, PassRefPtr<StringImpl> str)
: RenderObject(node)
, m_minWidth(-1)
- , m_text(document()->displayStringModifiedByEncoding(str))
+ , m_text(str)
, m_firstTextBox(0)
, m_lastTextBox(0)
, m_maxWidth(-1)
@@ -66,8 +98,9 @@ RenderText::RenderText(Node* node, PassRefPtr<StringImpl> str)
, m_hasTab(false)
, m_linesDirty(false)
, m_containsReversedText(false)
- , m_isAllASCII(charactersAreAllASCII(m_text.get()))
- , m_knownNotToUseFallbackFonts(false)
+ , m_isAllASCII(m_text.containsOnlyASCII())
+ , m_knownToHaveNoOverflowAndNoFallbackFonts(false)
+ , m_needsTranscoding(false)
{
ASSERT(m_text);
@@ -104,6 +137,11 @@ bool RenderText::isWordBreak() const
return false;
}
+void RenderText::updateNeedsTranscoding()
+{
+ m_needsTranscoding = document()->decoder() && document()->decoder()->encoding().backslashAsCurrencySymbol() != '\\';
+}
+
void RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
// There is no need to ever schedule repaints from a style change of a text run, since
@@ -112,13 +150,18 @@ void RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl
// need to relayout.
if (diff == StyleDifferenceLayout) {
setNeedsLayoutAndPrefWidthsRecalc();
- m_knownNotToUseFallbackFonts = false;
+ m_knownToHaveNoOverflowAndNoFallbackFonts = false;
+ }
+
+ bool needsResetText = false;
+ if (!oldStyle) {
+ updateNeedsTranscoding();
+ needsResetText = m_needsTranscoding;
}
ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE;
ETextSecurity oldSecurity = oldStyle ? oldStyle->textSecurity() : TSNONE;
-
- if (oldTransform != style()->textTransform() || oldSecurity != style()->textSecurity()) {
+ if (needsResetText || oldTransform != style()->textTransform() || oldSecurity != style()->textSecurity()) {
if (RefPtr<StringImpl> textToTransform = originalText())
setText(textToTransform.release(), true);
}
@@ -150,9 +193,9 @@ void RenderText::extractTextBox(InlineTextBox* box)
if (box == m_firstTextBox)
m_firstTextBox = 0;
if (box->prevTextBox())
- box->prevTextBox()->setNextLineBox(0);
- box->setPreviousLineBox(0);
- for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())
+ box->prevTextBox()->setNextTextBox(0);
+ box->setPreviousTextBox(0);
+ for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox())
curr->setExtracted();
checkConsistency();
@@ -163,8 +206,8 @@ void RenderText::attachTextBox(InlineTextBox* box)
checkConsistency();
if (m_lastTextBox) {
- m_lastTextBox->setNextLineBox(box);
- box->setPreviousLineBox(m_lastTextBox);
+ m_lastTextBox->setNextTextBox(box);
+ box->setPreviousTextBox(m_lastTextBox);
} else
m_firstTextBox = box;
InlineTextBox* last = box;
@@ -186,9 +229,9 @@ void RenderText::removeTextBox(InlineTextBox* box)
if (box == m_lastTextBox)
m_lastTextBox = box->prevTextBox();
if (box->nextTextBox())
- box->nextTextBox()->setPreviousLineBox(box->prevTextBox());
+ box->nextTextBox()->setPreviousTextBox(box->prevTextBox());
if (box->prevTextBox())
- box->prevTextBox()->setNextLineBox(box->nextTextBox());
+ box->prevTextBox()->setNextTextBox(box->nextTextBox());
checkConsistency();
}
@@ -434,7 +477,7 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
return IntRect(left, top, caretWidth, height);
}
-ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts) const
+ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII) {
int monospaceCharacterWidth = f.spaceWidth();
@@ -442,8 +485,10 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len,
int w = 0;
bool isSpace;
bool previousCharWasSpace = true; // FIXME: Preserves historical behavior, but seems wrong for start > 0.
+ ASSERT(m_text);
+ StringImpl& text = *m_text.impl();
for (int i = start; i < start + len; i++) {
- char c = (*m_text)[i];
+ char c = text[i];
if (c <= ' ') {
if (c == ' ' || c == '\n') {
w += monospaceCharacterWidth;
@@ -464,7 +509,7 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len,
return w;
}
- return f.width(TextRun(text()->characters() + start, len, allowTabs(), xPos), fallbackFonts);
+ return f.width(TextRun(text()->characters() + start, len, allowTabs(), xPos), fallbackFonts, glyphOverflow);
}
void RenderText::trimmedPrefWidths(int leadWidth,
@@ -486,7 +531,7 @@ void RenderText::trimmedPrefWidths(int leadWidth,
int len = textLength();
- if (!len || (stripFrontSpaces && m_text->containsOnlyWhitespace())) {
+ if (!len || (stripFrontSpaces && text()->containsOnlyWhitespace())) {
beginMinW = 0;
endMinW = 0;
beginMaxW = 0;
@@ -506,7 +551,9 @@ void RenderText::trimmedPrefWidths(int leadWidth,
hasBreakableChar = m_hasBreakableChar;
hasBreak = m_hasBreak;
- if ((*m_text)[0] == ' ' || ((*m_text)[0] == '\n' && !style()->preserveNewline()) || (*m_text)[0] == '\t') {
+ ASSERT(m_text);
+ StringImpl& text = *m_text.impl();
+ if (text[0] == ' ' || (text[0] == '\n' && !style()->preserveNewline()) || text[0] == '\t') {
const Font& f = style()->font(); // FIXME: This ignores first-line.
if (stripFrontSpaces) {
const UChar space = ' ';
@@ -529,11 +576,11 @@ void RenderText::trimmedPrefWidths(int leadWidth,
endMaxW = maxW;
for (int i = 0; i < len; i++) {
int linelen = 0;
- while (i + linelen < len && (*m_text)[i + linelen] != '\n')
+ while (i + linelen < len && text[i + linelen] != '\n')
linelen++;
if (linelen) {
- endMaxW = widthFromCache(f, i, linelen, leadWidth + endMaxW, 0);
+ endMaxW = widthFromCache(f, i, linelen, leadWidth + endMaxW, 0, 0);
if (firstLine) {
firstLine = false;
leadWidth = 0;
@@ -578,14 +625,15 @@ int RenderText::maxPrefWidth() const
void RenderText::calcPrefWidths(int leadWidth)
{
HashSet<const SimpleFontData*> fallbackFonts;
- calcPrefWidths(leadWidth, fallbackFonts);
- if (fallbackFonts.isEmpty())
- m_knownNotToUseFallbackFonts = true;
+ GlyphOverflow glyphOverflow;
+ calcPrefWidths(leadWidth, fallbackFonts, glyphOverflow);
+ if (fallbackFonts.isEmpty() && !glyphOverflow.left && !glyphOverflow.right && !glyphOverflow.top && !glyphOverflow.bottom)
+ m_knownToHaveNoOverflowAndNoFallbackFonts = true;
}
-void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts)
+void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow)
{
- ASSERT(m_hasTab || prefWidthsDirty() || !m_knownNotToUseFallbackFonts);
+ ASSERT(m_hasTab || prefWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts);
m_minWidth = 0;
m_beginMinWidth = 0;
@@ -615,6 +663,8 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f
int nextBreakable = -1;
int lastWordBoundary = 0;
+ int firstGlyphLeftOverflow = -1;
+
bool breakNBSP = style()->autoWrap() && style()->nbspMode() == SPACE;
bool breakAll = (style()->wordBreak() == BreakAllWordBreak || style()->wordBreak() == BreakWordBreak) && style()->autoWrap();
@@ -657,7 +707,9 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f
lastWordBoundary++;
continue;
} else if (c == softHyphen) {
- currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts);
+ currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
+ if (firstGlyphLeftOverflow < 0)
+ firstGlyphLeftOverflow = glyphOverflow.left;
lastWordBoundary = i + 1;
continue;
}
@@ -680,13 +732,15 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f
int wordLen = j - i;
if (wordLen) {
- int w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts);
+ int w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
+ if (firstGlyphLeftOverflow < 0)
+ firstGlyphLeftOverflow = glyphOverflow.left;
currMinWidth += w;
if (betweenWords) {
if (lastWordBoundary == i)
currMaxWidth += w;
else
- currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts);
+ currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
lastWordBoundary = j;
}
@@ -739,6 +793,7 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f
currMaxWidth = 0;
} else {
currMaxWidth += f.width(TextRun(txt + i, 1, allowTabs(), leadWidth + currMaxWidth));
+ glyphOverflow.right = 0;
needsWordSpacing = isSpace && !previousCharacterIsSpace && i == len - 1;
}
ASSERT(lastWordBoundary == i);
@@ -746,6 +801,9 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f
}
}
+ if (firstGlyphLeftOverflow > 0)
+ glyphOverflow.left = firstGlyphLeftOverflow;
+
if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord))
currMaxWidth += wordSpacing;
@@ -777,9 +835,11 @@ bool RenderText::isAllCollapsibleWhitespace()
bool RenderText::containsOnlyWhitespace(unsigned from, unsigned len) const
{
+ ASSERT(m_text);
+ StringImpl& text = *m_text.impl();
unsigned currPos;
for (currPos = from;
- currPos < from + len && ((*m_text)[currPos] == '\n' || (*m_text)[currPos] == ' ' || (*m_text)[currPos] == '\t');
+ currPos < from + len && (text[currPos] == '\n' || text[currPos] == ' ' || text[currPos] == '\t');
currPos++) { }
return currPos >= (from + len);
}
@@ -912,7 +972,7 @@ void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset,
setText(text, force);
}
-static inline bool isInlineFlowOrEmptyText(RenderObject* o)
+static inline bool isInlineFlowOrEmptyText(const RenderObject* o)
{
if (o->isRenderInline())
return true;
@@ -924,10 +984,10 @@ static inline bool isInlineFlowOrEmptyText(RenderObject* o)
return !text->length();
}
-UChar RenderText::previousCharacter()
+UChar RenderText::previousCharacter() const
{
// find previous text renderer if one exists
- RenderObject* previousText = this;
+ const RenderObject* previousText = this;
while ((previousText = previousText->previousInPreOrder()))
if (!isInlineFlowOrEmptyText(previousText))
break;
@@ -938,10 +998,31 @@ UChar RenderText::previousCharacter()
return prev;
}
+void RenderText::transformText(String& text) const
+{
+ ASSERT(style());
+ switch (style()->textTransform()) {
+ case TTNONE:
+ break;
+ case CAPITALIZE:
+ makeCapitalized(&text, previousCharacter());
+ break;
+ case UPPERCASE:
+ text.makeUpper();
+ break;
+ case LOWERCASE:
+ text.makeLower();
+ break;
+ }
+}
+
void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
{
ASSERT(text);
- m_text = document()->displayStringModifiedByEncoding(text);
+ if (m_needsTranscoding)
+ m_text = document()->displayStringModifiedByEncoding(text);
+ else
+ m_text = text;
ASSERT(m_text);
#if ENABLE(SVG)
@@ -952,7 +1033,7 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
// characters into space characters. Then, it will draw all space characters, including
// leading, trailing and multiple contiguous space characters.
- m_text = m_text->replace('\n', ' ');
+ m_text.replace('\n', ' ');
// If xml:space="preserve" is set, white-space is set to "pre", which
// preserves leading, trailing & contiguous space character for us.
@@ -963,70 +1044,71 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
// Then, it will strip off all leading and trailing space characters.
// Then, all contiguous space characters will be consolidated.
- m_text = m_text->replace('\n', StringImpl::empty());
+ m_text.replace('\n', StringImpl::empty());
// If xml:space="default" is set, white-space is set to "nowrap", which handles
// leading, trailing & contiguous space character removal for us.
}
- m_text = m_text->replace('\t', ' ');
+ m_text.replace('\t', ' ');
}
#endif
if (style()) {
- switch (style()->textTransform()) {
- case TTNONE:
- break;
- case CAPITALIZE: {
- m_text = m_text->capitalize(previousCharacter());
- break;
- }
- case UPPERCASE:
- m_text = m_text->upper();
- break;
- case LOWERCASE:
- m_text = m_text->lower();
- break;
- }
+ transformText(m_text);
// We use the same characters here as for list markers.
// See the listMarkerText function in RenderListMarker.cpp.
switch (style()->textSecurity()) {
- case TSNONE:
- break;
- case TSCIRCLE:
- m_text = m_text->secure(whiteBullet);
- break;
- case TSDISC:
- m_text = m_text->secure(bullet);
- break;
- case TSSQUARE:
- m_text = m_text->secure(blackSquare);
+ case TSNONE:
+ break;
+ case TSCIRCLE:
+ m_text.makeSecure(whiteBullet);
+ break;
+ case TSDISC:
+ m_text.makeSecure(bullet);
+ break;
+ case TSSQUARE:
+ m_text.makeSecure(blackSquare);
}
}
ASSERT(m_text);
- ASSERT(!isBR() || (textLength() == 1 && (*m_text)[0] == '\n'));
+ ASSERT(!isBR() || (textLength() == 1 && m_text[0] == '\n'));
- m_isAllASCII = charactersAreAllASCII(m_text.get());
+ m_isAllASCII = m_text.containsOnlyASCII();
}
void RenderText::setText(PassRefPtr<StringImpl> text, bool force)
{
ASSERT(text);
- if (!force && equal(m_text.get(), text.get()))
+ if (!force && equal(m_text.impl(), text.get()))
return;
setTextInternal(text);
setNeedsLayoutAndPrefWidthsRecalc();
- m_knownNotToUseFallbackFonts = false;
+ m_knownToHaveNoOverflowAndNoFallbackFonts = false;
AXObjectCache* axObjectCache = document()->axObjectCache();
if (axObjectCache->accessibilityEnabled())
axObjectCache->contentChanged(this);
}
+String RenderText::textWithoutTranscoding() const
+{
+ // If m_text isn't transcoded or is secure, we can just return the modified text.
+ if (!m_needsTranscoding || style()->textSecurity() != TSNONE)
+ return text();
+
+ // Otherwise, we should use original text. If text-transform is
+ // specified, we should transform the text on the fly.
+ String text = originalText();
+ if (style())
+ transformText(text);
+ return text;
+}
+
int RenderText::lineHeight(bool firstLine, bool) const
{
// Always use the interior line height of the parent (e.g., if our parent is an inline block).
@@ -1055,8 +1137,8 @@ InlineTextBox* RenderText::createInlineTextBox()
if (!m_firstTextBox)
m_firstTextBox = m_lastTextBox = textBox;
else {
- m_lastTextBox->setNextLineBox(textBox);
- textBox->setPreviousLineBox(m_lastTextBox);
+ m_lastTextBox->setNextTextBox(textBox);
+ textBox->setPreviousTextBox(m_lastTextBox);
m_lastTextBox = textBox;
}
textBox->setIsText(true);
@@ -1074,11 +1156,11 @@ void RenderText::positionLineBox(InlineBox* box)
if (m_firstTextBox == s)
m_firstTextBox = s->nextTextBox();
else
- s->prevTextBox()->setNextLineBox(s->nextTextBox());
+ s->prevTextBox()->setNextTextBox(s->nextTextBox());
if (m_lastTextBox == s)
m_lastTextBox = s->prevTextBox();
else
- s->nextTextBox()->setPreviousLineBox(s->prevTextBox());
+ s->nextTextBox()->setPreviousTextBox(s->prevTextBox());
s->destroy(renderArena());
return;
}
@@ -1086,7 +1168,7 @@ void RenderText::positionLineBox(InlineBox* box)
m_containsReversedText |= s->direction() == RTL;
}
-unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts) const
+unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
if (from >= textLength())
return 0;
@@ -1094,10 +1176,10 @@ unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine
if (from + len > textLength())
len = textLength() - from;
- return width(from, len, style(firstLine)->font(), xPos, fallbackFonts);
+ return width(from, len, style(firstLine)->font(), xPos, fallbackFonts, glyphOverflow);
}
-unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos, HashSet<const SimpleFontData*>* fallbackFonts) const
+unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
ASSERT(from + len <= textLength());
if (!characters())
@@ -1107,18 +1189,19 @@ unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos,
if (&f == &style()->font()) {
if (!style()->preserveNewline() && !from && len == textLength()) {
if (fallbackFonts) {
- if (prefWidthsDirty() || !m_knownNotToUseFallbackFonts) {
- const_cast<RenderText*>(this)->calcPrefWidths(0, *fallbackFonts);
- if (fallbackFonts->isEmpty())
- m_knownNotToUseFallbackFonts = true;
+ ASSERT(glyphOverflow);
+ if (prefWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts) {
+ const_cast<RenderText*>(this)->calcPrefWidths(0, *fallbackFonts, *glyphOverflow);
+ if (fallbackFonts->isEmpty() && !glyphOverflow->left && !glyphOverflow->right && !glyphOverflow->top && !glyphOverflow->bottom)
+ m_knownToHaveNoOverflowAndNoFallbackFonts = true;
}
w = m_maxWidth;
} else
w = maxPrefWidth();
} else
- w = widthFromCache(f, from, len, xPos, fallbackFonts);
+ w = widthFromCache(f, from, len, xPos, fallbackFonts, glyphOverflow);
} else
- w = f.width(TextRun(text()->characters() + from, len, allowTabs(), xPos), fallbackFonts);
+ w = f.width(TextRun(text()->characters() + from, len, allowTabs(), xPos), fallbackFonts, glyphOverflow);
return w;
}
@@ -1150,6 +1233,11 @@ IntRect RenderText::linesBoundingBox() const
IntRect RenderText::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
RenderObject* cb = containingBlock();
+ // The containing block may be an ancestor of repaintContainer, but we need to do a repaintContainer-relative repaint.
+ if (repaintContainer && repaintContainer != cb) {
+ if (!cb->isDescendantOf(repaintContainer))
+ return repaintContainer->clippedOverflowRectForRepaint(repaintContainer);
+ }
return cb->clippedOverflowRectForRepaint(repaintContainer);
}
@@ -1245,7 +1333,7 @@ unsigned RenderText::caretMaxRenderedOffset() const
int RenderText::previousOffset(int current) const
{
- StringImpl* si = m_text.get();
+ StringImpl* si = m_text.impl();
TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());
if (!iterator)
return current - 1;
@@ -1293,14 +1381,16 @@ inline bool isHangulLVT(UChar32 character)
int RenderText::previousOffsetForBackwardDeletion(int current) const
{
#if PLATFORM(MAC)
+ ASSERT(m_text);
+ StringImpl& text = *m_text.impl();
UChar32 character;
while (current > 0) {
- if (U16_IS_TRAIL((*m_text)[--current]))
+ if (U16_IS_TRAIL(text[--current]))
--current;
if (current < 0)
break;
- UChar32 character = m_text->characterStartingAt(current);
+ UChar32 character = text.characterStartingAt(current);
// We don't combine characters in Armenian ... Limbu range for backward deletion.
if ((character >= 0x0530) && (character < 0x1950))
@@ -1314,7 +1404,7 @@ int RenderText::previousOffsetForBackwardDeletion(int current) const
return current;
// Hangul
- character = m_text->characterStartingAt(current);
+ character = text.characterStartingAt(current);
if (((character >= HANGUL_CHOSEONG_START) && (character <= HANGUL_JONGSEONG_END)) || ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))) {
HangulState state;
HangulState initialState;
@@ -1330,7 +1420,7 @@ int RenderText::previousOffsetForBackwardDeletion(int current) const
initialState = state;
- while (current > 0 && ((character = m_text->characterStartingAt(current - 1)) >= HANGUL_CHOSEONG_START) && (character <= HANGUL_SYLLABLE_END) && ((character <= HANGUL_JONGSEONG_END) || (character >= HANGUL_SYLLABLE_START))) {
+ while (current > 0 && ((character = text.characterStartingAt(current - 1)) >= HANGUL_CHOSEONG_START) && (character <= HANGUL_SYLLABLE_END) && ((character <= HANGUL_JONGSEONG_END) || (character >= HANGUL_SYLLABLE_START))) {
switch (state) {
case HangulStateV:
if (character <= HANGUL_CHOSEONG_END)
@@ -1368,7 +1458,7 @@ int RenderText::previousOffsetForBackwardDeletion(int current) const
int RenderText::nextOffset(int current) const
{
- StringImpl* si = m_text.get();
+ StringImpl* si = m_text.impl();
TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());
if (!iterator)
return current + 1;
diff --git a/WebCore/rendering/RenderText.h b/WebCore/rendering/RenderText.h
index d46bce9..92c82e1 100644
--- a/WebCore/rendering/RenderText.h
+++ b/WebCore/rendering/RenderText.h
@@ -50,7 +50,8 @@ public:
virtual void destroy();
- StringImpl* text() const { return m_text.get(); }
+ StringImpl* text() const { return m_text.impl(); }
+ String textWithoutTranscoding() const;
InlineTextBox* createInlineTextBox();
void dirtyLineBoxes(bool fullLayout);
@@ -63,12 +64,12 @@ public:
virtual VisiblePosition positionForPoint(const IntPoint&);
- const UChar* characters() const { return m_text->characters(); }
- unsigned textLength() const { return m_text->length(); } // non virtual implementation of length()
+ const UChar* characters() const { return m_text.characters(); }
+ unsigned textLength() const { return m_text.length(); } // non virtual implementation of length()
void positionLineBox(InlineBox*);
- virtual unsigned width(unsigned from, unsigned len, const Font&, int xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0) const;
- virtual unsigned width(unsigned from, unsigned len, int xPos, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0) const;
+ virtual unsigned width(unsigned from, unsigned len, const Font&, int xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+ virtual unsigned width(unsigned from, unsigned len, int xPos, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
@@ -128,12 +129,12 @@ protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void setTextInternal(PassRefPtr<StringImpl>);
- virtual UChar previousCharacter();
+ virtual UChar previousCharacter() const;
virtual InlineTextBox* createTextBox(); // Subclassed by SVG.
private:
- void calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts);
+ void calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow&);
// Make length() private so that callers that have a RenderText*
// will use the more efficient textLength() instead, while
@@ -146,12 +147,15 @@ private:
void deleteTextBoxes();
bool containsOnlyWhitespace(unsigned from, unsigned len) const;
- int widthFromCache(const Font&, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts) const;
+ int widthFromCache(const Font&, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const;
bool isAllASCII() const { return m_isAllASCII; }
+ void updateNeedsTranscoding();
+
+ inline void transformText(String&) const;
int m_minWidth; // here to minimize padding in 64-bit.
- RefPtr<StringImpl> m_text;
+ String m_text;
InlineTextBox* m_firstTextBox;
InlineTextBox* m_lastTextBox;
@@ -171,7 +175,8 @@ private:
// or removed).
bool m_containsReversedText : 1;
bool m_isAllASCII : 1;
- mutable bool m_knownNotToUseFallbackFonts : 1;
+ mutable bool m_knownToHaveNoOverflowAndNoFallbackFonts : 1;
+ bool m_needsTranscoding : 1;
};
inline RenderText* toRenderText(RenderObject* object)
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index d18940b..5e19362 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -167,15 +167,7 @@ void RenderTextControl::updateFromElement()
void RenderTextControl::setInnerTextValue(const String& innerTextValue)
{
- String value;
-
- if (innerTextValue.isNull())
- value = "";
- else {
- value = innerTextValue;
- value = document()->displayStringModifiedByEncoding(value);
- }
-
+ String value = innerTextValue;
if (value != text() || !m_innerText->hasChildNodes()) {
if (value != text()) {
if (Frame* frame = document()->frame()) {
@@ -266,11 +258,6 @@ void RenderTextControl::setSelectionRange(int start, int end)
if (Frame* frame = document()->frame())
frame->selection()->setSelection(newSelection);
-
- // FIXME: Granularity is stored separately on the frame, but also in the selection controller.
- // The granularity in the selection controller should be used, and then this line of code would not be needed.
- if (Frame* frame = document()->frame())
- frame->setSelectionGranularity(CharacterGranularity);
}
VisibleSelection RenderTextControl::selection(int start, int end) const
@@ -323,9 +310,6 @@ String RenderTextControl::finishText(Vector<UChar>& result) const
if (size && result[size - 1] == '\n')
result.shrink(--size);
- // Convert backslash to currency symbol.
- document()->displayBufferModifiedByEncoding(result.data(), result.size());
-
return String::adopt(result);
}
@@ -373,8 +357,6 @@ String RenderTextControl::textWithHardLineBreaks()
if (!firstChild)
return "";
- document()->updateLayout();
-
RenderObject* renderer = firstChild->renderer();
if (!renderer)
return "";
diff --git a/WebCore/rendering/RenderTextControlSingleLine.h b/WebCore/rendering/RenderTextControlSingleLine.h
index aa1f1e3..e1bcc84 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/WebCore/rendering/RenderTextControlSingleLine.h
@@ -101,6 +101,7 @@ private:
virtual void valueChanged(unsigned listIndex, bool fireEvents = true);
virtual String itemText(unsigned listIndex) const;
virtual String itemToolTip(unsigned) const { return String(); }
+ virtual String itemAccessibilityText(unsigned) const { return String(); }
virtual bool itemIsEnabled(unsigned listIndex) const;
virtual PopupMenuStyle itemStyle(unsigned listIndex) const;
virtual PopupMenuStyle menuStyle() const;
diff --git a/WebCore/rendering/RenderTextFragment.cpp b/WebCore/rendering/RenderTextFragment.cpp
index 9ff1106..2164ae1 100644
--- a/WebCore/rendering/RenderTextFragment.cpp
+++ b/WebCore/rendering/RenderTextFragment.cpp
@@ -69,10 +69,14 @@ void RenderTextFragment::setTextInternal(PassRefPtr<StringImpl> text)
m_firstLetter = 0;
m_start = 0;
m_end = textLength();
+ if (Node* t = node()) {
+ ASSERT(!t->renderer());
+ t->setRenderer(this);
+ }
}
}
-UChar RenderTextFragment::previousCharacter()
+UChar RenderTextFragment::previousCharacter() const
{
if (start()) {
Node* e = node();
diff --git a/WebCore/rendering/RenderTextFragment.h b/WebCore/rendering/RenderTextFragment.h
index 1fa509a..e351436 100644
--- a/WebCore/rendering/RenderTextFragment.h
+++ b/WebCore/rendering/RenderTextFragment.h
@@ -51,7 +51,7 @@ public:
private:
virtual void setTextInternal(PassRefPtr<StringImpl>);
- virtual UChar previousCharacter();
+ virtual UChar previousCharacter() const;
unsigned m_start;
unsigned m_end;
diff --git a/WebCore/rendering/RenderTheme.cpp b/WebCore/rendering/RenderTheme.cpp
index f1e564b..b3b7a1e 100644
--- a/WebCore/rendering/RenderTheme.cpp
+++ b/WebCore/rendering/RenderTheme.cpp
@@ -213,6 +213,10 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El
return adjustSearchFieldResultsDecorationStyle(selector, style, e);
case SearchFieldResultsButtonPart:
return adjustSearchFieldResultsButtonStyle(selector, style, e);
+#if ENABLE(PROGRESS_TAG)
+ case ProgressBarPart:
+ return adjustProgressBarStyle(selector, style, e);
+#endif
default:
break;
}
@@ -271,6 +275,10 @@ bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInf
#endif
case MenulistPart:
return paintMenuList(o, paintInfo, r);
+#if ENABLE(PROGRESS_TAG)
+ case ProgressBarPart:
+ return paintProgressBar(o, paintInfo, r);
+#endif
case SliderHorizontalPart:
case SliderVerticalPart:
return paintSliderTrack(o, paintInfo, r);
@@ -361,6 +369,9 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const RenderObject::PaintInfo
case DefaultButtonPart:
case ButtonPart:
case MenulistPart:
+#if ENABLE(PROGRESS_TAG)
+ case ProgressBarPart:
+#endif
case SliderHorizontalPart:
case SliderVerticalPart:
case SliderThumbHorizontalPart:
@@ -396,6 +407,9 @@ bool RenderTheme::paintDecorations(RenderObject* o, const RenderObject::PaintInf
case DefaultButtonPart:
case ButtonPart:
case MenulistPart:
+#if ENABLE(PROGRESS_TAG)
+ case ProgressBarPart:
+#endif
case SliderHorizontalPart:
case SliderVerticalPart:
case SliderThumbHorizontalPart:
@@ -829,6 +843,22 @@ void RenderTheme::adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*)
{
}
+#if ENABLE(PROGRESS_TAG)
+double RenderTheme::animationRepeatIntervalForProgressBar(RenderProgress*) const
+{
+ return 0;
+}
+
+double RenderTheme::animationDurationForProgressBar(RenderProgress*) const
+{
+ return 0;
+}
+
+void RenderTheme::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const
+{
+}
+#endif
+
void RenderTheme::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const
{
}
diff --git a/WebCore/rendering/RenderTheme.h b/WebCore/rendering/RenderTheme.h
index 32ae5e5..1526138 100644
--- a/WebCore/rendering/RenderTheme.h
+++ b/WebCore/rendering/RenderTheme.h
@@ -39,6 +39,9 @@ namespace WebCore {
class Element;
class PopupMenu;
class RenderMenuList;
+#if ENABLE(PROGRESS_TAG)
+class RenderProgress;
+#endif
class CSSStyleSheet;
class RenderTheme : public RefCounted<RenderTheme> {
@@ -169,6 +172,13 @@ public:
// Method for painting the caps lock indicator
virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return 0; };
+#if ENABLE(PROGRESS_TAG)
+ // Returns the repeat interval of the animation for the progress bar.
+ virtual double animationRepeatIntervalForProgressBar(RenderProgress*) const;
+ // Returns the duration of the animation for the progress bar.
+ virtual double animationDurationForProgressBar(RenderProgress*) const;
+#endif
+
#if ENABLE(VIDEO)
// Media controls
virtual bool hitTestMediaControlPart(RenderObject*, const IntPoint& absPoint);
@@ -230,6 +240,11 @@ protected:
virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
+#if ENABLE(PROGRESS_TAG)
+ virtual void adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual bool paintProgressBar(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
+#endif
+
virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
diff --git a/WebCore/rendering/RenderThemeChromiumSkia.cpp b/WebCore/rendering/RenderThemeChromiumSkia.cpp
index 7d3bcec..8b3b388 100644
--- a/WebCore/rendering/RenderThemeChromiumSkia.cpp
+++ b/WebCore/rendering/RenderThemeChromiumSkia.cpp
@@ -403,28 +403,41 @@ void RenderThemeChromiumSkia::adjustSearchFieldCancelButtonStyle(CSSStyleSelecto
style->setHeight(Length(cancelButtonSize, Fixed));
}
-bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+IntRect RenderThemeChromiumSkia::convertToPaintingRect(RenderObject* inputRenderer, const RenderObject* partRenderer, IntRect partRect, const IntRect& localOffset) const
{
- IntRect bounds = r;
- ASSERT(o->parent());
- if (!o->parent() || !o->parent()->isBox())
- return false;
-
- RenderBox* parentRenderBox = toRenderBox(o->parent());
+ // Compute an offset between the part renderer and the input renderer.
+ IntSize offsetFromInputRenderer = -(partRenderer->offsetFromAncestorContainer(inputRenderer));
+ // Move the rect into partRenderer's coords.
+ partRect.move(offsetFromInputRenderer);
+ // Account for the local drawing offset.
+ partRect.move(localOffset.x(), localOffset.y());
- IntRect parentBox = parentRenderBox->absoluteContentBox();
+ return partRect;
+}
- // Make sure the scaled button stays square and will fit in its parent's box
- bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height())));
- bounds.setWidth(bounds.height());
+bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* cancelButtonObject, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ // Get the renderer of <input> element.
+ Node* input = cancelButtonObject->node()->shadowAncestorNode();
+ if (!input->renderer()->isBox())
+ return false;
+ RenderBox* inputRenderBox = toRenderBox(input->renderer());
+ IntRect inputContentBox = inputRenderBox->contentBoxRect();
+ // Make sure the scaled button stays square and will fit in its parent's box.
+ int cancelButtonSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), r.height()));
+ // Calculate cancel button's coordinates relative to the input element.
// Center the button vertically. Round up though, so if it has to be one pixel off-center, it will
// be one pixel closer to the bottom of the field. This tends to look better with the text.
- bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
+ IntRect cancelButtonRect(cancelButtonObject->offsetFromAncestorContainer(inputRenderBox).width(),
+ inputContentBox.y() + (inputContentBox.height() - cancelButtonSize + 1) / 2,
+ cancelButtonSize, cancelButtonSize);
+ IntRect paintingRect = convertToPaintingRect(inputRenderBox, cancelButtonObject, cancelButtonRect, r);
static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef();
static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef();
- i.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, o->style()->colorSpace(), bounds);
+ paintInfo.context->drawImage(isPressed(cancelButtonObject) ? cancelPressedImage : cancelImage,
+ cancelButtonObject->style()->colorSpace(), paintingRect);
return false;
}
@@ -445,26 +458,27 @@ void RenderThemeChromiumSkia::adjustSearchFieldResultsDecorationStyle(CSSStyleSe
style->setHeight(Length(magnifierSize, Fixed));
}
-bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* magnifierObject, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- IntRect bounds = r;
- ASSERT(o->parent());
- if (!o->parent() || !o->parent()->isBox())
+ // Get the renderer of <input> element.
+ Node* input = magnifierObject->node()->shadowAncestorNode();
+ if (!input->renderer()->isBox())
return false;
+ RenderBox* inputRenderBox = toRenderBox(input->renderer());
+ IntRect inputContentBox = inputRenderBox->contentBoxRect();
- RenderBox* parentRenderBox = toRenderBox(o->parent());
- IntRect parentBox = parentRenderBox->absoluteContentBox();
-
- // Make sure the scaled decoration stays square and will fit in its parent's box
- bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height())));
- bounds.setWidth(bounds.height());
-
+ // Make sure the scaled decoration stays square and will fit in its parent's box.
+ int magnifierSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), r.height()));
+ // Calculate decoration's coordinates relative to the input element.
// Center the decoration vertically. Round up though, so if it has to be one pixel off-center, it will
// be one pixel closer to the bottom of the field. This tends to look better with the text.
- bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
+ IntRect magnifierRect(magnifierObject->offsetFromAncestorContainer(inputRenderBox).width(),
+ inputContentBox.y() + (inputContentBox.height() - magnifierSize + 1) / 2,
+ magnifierSize, magnifierSize);
+ IntRect paintingRect = convertToPaintingRect(inputRenderBox, magnifierObject, magnifierRect, r);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef();
- i.context->drawImage(magnifierImage, o->style()->colorSpace(), bounds);
+ paintInfo.context->drawImage(magnifierImage, magnifierObject->style()->colorSpace(), paintingRect);
return false;
}
@@ -479,28 +493,25 @@ void RenderThemeChromiumSkia::adjustSearchFieldResultsButtonStyle(CSSStyleSelect
style->setHeight(Length(magnifierHeight, Fixed));
}
-bool RenderThemeChromiumSkia::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+bool RenderThemeChromiumSkia::paintSearchFieldResultsButton(RenderObject* magnifierObject, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- IntRect bounds = r;
- ASSERT(o->parent());
- if (!o->parent())
- return false;
- if (!o->parent() || !o->parent()->isBox())
+ // Get the renderer of <input> element.
+ Node* input = magnifierObject->node()->shadowAncestorNode();
+ if (!input->renderer()->isBox())
return false;
+ RenderBox* inputRenderBox = toRenderBox(input->renderer());
+ IntRect inputContentBox = inputRenderBox->contentBoxRect();
- RenderBox* parentRenderBox = toRenderBox(o->parent());
- IntRect parentBox = parentRenderBox->absoluteContentBox();
-
- // Make sure the scaled decoration will fit in its parent's box
- bounds.setHeight(std::min(parentBox.height(), bounds.height()));
- bounds.setWidth(std::min(parentBox.width(), static_cast<int>(bounds.height() * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize)));
-
- // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will
- // be one pixel closer to the bottom of the field. This tends to look better with the text.
- bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
+ // Make sure the scaled decoration will fit in its parent's box.
+ int magnifierHeight = std::min(inputContentBox.height(), r.height());
+ int magnifierWidth = std::min(inputContentBox.width(), static_cast<int>(magnifierHeight * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize));
+ IntRect magnifierRect(magnifierObject->offsetFromAncestorContainer(inputRenderBox).width(),
+ inputContentBox.y() + (inputContentBox.height() - magnifierHeight + 1) / 2,
+ magnifierWidth, magnifierHeight);
+ IntRect paintingRect = convertToPaintingRect(inputRenderBox, magnifierObject, magnifierRect, r);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").releaseRef();
- i.context->drawImage(magnifierImage, o->style()->colorSpace(), bounds);
+ paintInfo.context->drawImage(magnifierImage, magnifierObject->style()->colorSpace(), paintingRect);
return false;
}
@@ -721,26 +732,6 @@ int RenderThemeChromiumSkia::popupInternalPaddingBottom(RenderStyle* style) cons
return menuListInternalPadding(style, BottomPadding);
}
-int RenderThemeChromiumSkia::buttonInternalPaddingLeft() const
-{
- return 3;
-}
-
-int RenderThemeChromiumSkia::buttonInternalPaddingRight() const
-{
- return 3;
-}
-
-int RenderThemeChromiumSkia::buttonInternalPaddingTop() const
-{
- return 1;
-}
-
-int RenderThemeChromiumSkia::buttonInternalPaddingBottom() const
-{
- return 1;
-}
-
#if ENABLE(VIDEO)
bool RenderThemeChromiumSkia::shouldRenderMediaControlPart(ControlPart part, Element* e)
{
diff --git a/WebCore/rendering/RenderThemeChromiumSkia.h b/WebCore/rendering/RenderThemeChromiumSkia.h
index 18fa859..dc920b1cf 100644
--- a/WebCore/rendering/RenderThemeChromiumSkia.h
+++ b/WebCore/rendering/RenderThemeChromiumSkia.h
@@ -123,11 +123,6 @@ namespace WebCore {
virtual int popupInternalPaddingTop(RenderStyle*) const;
virtual int popupInternalPaddingBottom(RenderStyle*) const;
- virtual int buttonInternalPaddingLeft() const;
- virtual int buttonInternalPaddingRight() const;
- virtual int buttonInternalPaddingTop() const;
- virtual int buttonInternalPaddingBottom() const;
-
#if ENABLE(VIDEO)
// Media controls
virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
@@ -153,6 +148,7 @@ namespace WebCore {
private:
int menuListInternalPadding(RenderStyle*, int paddingType) const;
bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*);
+ IntRect convertToPaintingRect(RenderObject* inputRenderer, const RenderObject* partRenderer, IntRect partRect, const IntRect& localOffset) const;
};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeChromiumWin.h b/WebCore/rendering/RenderThemeChromiumWin.h
index 3b86980..bbc54a7 100644
--- a/WebCore/rendering/RenderThemeChromiumWin.h
+++ b/WebCore/rendering/RenderThemeChromiumWin.h
@@ -59,7 +59,7 @@ namespace WebCore {
// System fonts.
virtual void systemFont(int propId, FontDescription&) const;
- virtual Color systemColor(int cssValueId) const;
+ virtual Color systemColor(int cssValueId) const;
virtual void adjustSliderThumbSize(RenderObject*) const;
diff --git a/WebCore/rendering/RenderThemeMac.h b/WebCore/rendering/RenderThemeMac.h
index 48c6c42..cba927f 100644
--- a/WebCore/rendering/RenderThemeMac.h
+++ b/WebCore/rendering/RenderThemeMac.h
@@ -27,6 +27,8 @@
#import <wtf/HashMap.h>
#import <wtf/RetainPtr.h>
+class RenderProgress;
+
#ifdef __OBJC__
@class WebCoreRenderThemeNotificationObserver;
#else
@@ -78,6 +80,13 @@ public:
virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+#if ENABLE(PROGRESS_TAG)
+ // Returns the repeat interval of the animation for the progress bar.
+ virtual double animationRepeatIntervalForProgressBar(RenderProgress*) const;
+ // Returns the duration of the animation for the progress bar.
+ virtual double animationDurationForProgressBar(RenderProgress*) const;
+#endif
+
virtual Color systemColor(int cssValueId) const;
protected:
@@ -95,6 +104,11 @@ protected:
virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+#if ENABLE(PROGRESS_TAG)
+ virtual void adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual bool paintProgressBar(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+#endif
+
virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
diff --git a/WebCore/rendering/RenderThemeMac.mm b/WebCore/rendering/RenderThemeMac.mm
index b6ce93d..c0d8020 100644
--- a/WebCore/rendering/RenderThemeMac.mm
+++ b/WebCore/rendering/RenderThemeMac.mm
@@ -32,6 +32,7 @@
#import "HTMLMediaElement.h"
#import "HTMLNames.h"
#import "Image.h"
+#import "ImageBuffer.h"
#import "LocalCurrentGraphicsContext.h"
#import "MediaControlElements.h"
#import "RenderMedia.h"
@@ -39,6 +40,7 @@
#import "RenderView.h"
#import "SharedBuffer.h"
#import "TimeRanges.h"
+#import "ThemeMac.h"
#import "WebCoreSystemInterface.h"
#import "UserAgentStyleSheets.h"
#import <Carbon/Carbon.h>
@@ -47,17 +49,26 @@
#import <wtf/StdLibExtras.h>
#import <math.h>
+#import "RenderProgress.h"
+
#ifdef BUILDING_ON_TIGER
typedef int NSInteger;
typedef unsigned NSUInteger;
#endif
-using std::min;
+using namespace std;
// 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.
+// We estimate the animation rate of a Mac OS X progress bar is 33 fps.
+// Hard code the value here because we haven't found API for it.
+const double progressAnimationFrameRate = 0.033;
+
+// Mac OS X progress bar animation seems to have 256 frames.
+const double progressAnimationNumFrames = 256;
+
@interface WebCoreRenderThemeNotificationObserver : NSObject
{
WebCore::RenderTheme *_theme;
@@ -735,6 +746,7 @@ const int* RenderThemeMac::popupButtonPadding(NSControlSize size) const
bool RenderThemeMac::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
+ LocalCurrentGraphicsContext localContext(paintInfo.context);
setPopupButtonCellState(o, r);
NSPopUpButtonCell* popupButton = this->popupButton();
@@ -764,13 +776,64 @@ bool RenderThemeMac::paintMenuList(RenderObject* o, const RenderObject::PaintInf
paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y());
}
- [popupButton drawWithFrame:inflatedRect inView:o->view()->frameView()->documentView()];
+ [popupButton drawWithFrame:inflatedRect inView:ThemeMac::ensuredView(o->view()->frameView())];
[popupButton setControlView:nil];
paintInfo.context->restore();
return false;
}
+
+#if ENABLE(PROGRESS_TAG)
+
+double RenderThemeMac::animationRepeatIntervalForProgressBar(RenderProgress*) const
+{
+ return progressAnimationFrameRate;
+}
+
+double RenderThemeMac::animationDurationForProgressBar(RenderProgress*) const
+{
+ return progressAnimationNumFrames * progressAnimationFrameRate;
+}
+
+void RenderThemeMac::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const
+{
+}
+
+bool RenderThemeMac::paintProgressBar(RenderObject* renderObject, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
+{
+ RenderProgress* renderProgress = toRenderProgress(renderObject);
+ HIThemeTrackDrawInfo trackInfo;
+ trackInfo.version = 0;
+ trackInfo.kind = renderProgress->position() < 0 ? kThemeLargeIndeterminateBar : kThemeLargeProgressBar;
+ trackInfo.bounds = IntRect(IntPoint(), rect.size());
+ trackInfo.min = 0;
+ trackInfo.max = numeric_limits<SInt32>::max();
+ trackInfo.value = lround(renderProgress->position() * nextafter(trackInfo.max, 0));
+ trackInfo.trackInfo.progress.phase = lround(renderProgress->animationProgress() * nextafter(progressAnimationNumFrames, 0));
+ trackInfo.attributes = kThemeTrackHorizontal;
+ trackInfo.enableState = isActive(renderObject) ? kThemeTrackActive : kThemeTrackInactive;
+ trackInfo.reserved = 0;
+ trackInfo.filler1 = 0;
+
+ OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(rect.size());
+ if (!imageBuffer)
+ return true;
+
+ HIThemeDrawTrack(&trackInfo, 0, imageBuffer->context()->platformContext(), kHIThemeOrientationNormal);
+
+ paintInfo.context->save();
+
+ if (renderProgress->style()->direction() == RTL) {
+ paintInfo.context->translate(2 * rect.x() + rect.width(), 0);
+ paintInfo.context->scale(FloatSize(-1, 1));
+ }
+ paintInfo.context->drawImage(imageBuffer->image(), DeviceColorSpace, rect.location());
+
+ paintInfo.context->restore();
+ return false;
+}
+#endif
const float baseFontSize = 11.0f;
const float baseArrowHeight = 4.0f;
@@ -1171,7 +1234,7 @@ bool RenderThemeMac::paintSliderThumb(RenderObject* o, const RenderObject::Paint
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
- [sliderThumbCell drawWithFrame:unzoomedRect inView:o->view()->frameView()->documentView()];
+ [sliderThumbCell drawWithFrame:unzoomedRect inView:ThemeMac::ensuredView(o->view()->frameView())];
[sliderThumbCell setControlView:nil];
paintInfo.context->restore();
@@ -1203,7 +1266,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:o->view()->frameView()->documentView()];
+ [search drawWithFrame:NSRect(unzoomedRect) inView:ThemeMac::ensuredView(o->view()->frameView())];
#ifdef BUILDING_ON_TIGER
if ([search showsFirstResponder])
wkDrawTextFieldCellFocusRing(search, NSRect(unzoomedRect));
@@ -1303,7 +1366,7 @@ bool RenderThemeMac::paintSearchFieldCancelButton(RenderObject* o, const RenderO
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
- [[search cancelButtonCell] drawWithFrame:unzoomedRect inView:o->view()->frameView()->documentView()];
+ [[search cancelButtonCell] drawWithFrame:unzoomedRect inView:ThemeMac::ensuredView(o->view()->frameView())];
[[search cancelButtonCell] setControlView:nil];
paintInfo.context->restore();
@@ -1368,7 +1431,7 @@ bool RenderThemeMac::paintSearchFieldResultsDecoration(RenderObject* o, const Re
FloatRect localBounds = [search searchButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())];
localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r);
- [[search searchButtonCell] drawWithFrame:localBounds inView:o->view()->frameView()->documentView()];
+ [[search searchButtonCell] drawWithFrame:localBounds inView:ThemeMac::ensuredView(o->view()->frameView())];
[[search searchButtonCell] setControlView:nil];
return false;
}
@@ -1411,7 +1474,7 @@ bool RenderThemeMac::paintSearchFieldResultsButton(RenderObject* o, const Render
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
- [[search searchButtonCell] drawWithFrame:unzoomedRect inView:o->view()->frameView()->documentView()];
+ [[search searchButtonCell] drawWithFrame:unzoomedRect inView:ThemeMac::ensuredView(o->view()->frameView())];
[[search searchButtonCell] setControlView:nil];
paintInfo.context->restore();
diff --git a/WebCore/rendering/RenderTreeAsText.cpp b/WebCore/rendering/RenderTreeAsText.cpp
index 164a656..75c35ba 100644
--- a/WebCore/rendering/RenderTreeAsText.cpp
+++ b/WebCore/rendering/RenderTreeAsText.cpp
@@ -28,7 +28,6 @@
#include "CSSMutableStyleDeclaration.h"
#include "CharacterNames.h"
-#include "CString.h"
#include "Document.h"
#include "Frame.h"
#include "FrameView.h"
@@ -38,6 +37,7 @@
#include "RenderBR.h"
#include "RenderFileUploadControl.h"
#include "RenderInline.h"
+#include "RenderListItem.h"
#include "RenderListMarker.h"
#include "RenderPart.h"
#include "RenderTableCell.h"
@@ -178,10 +178,13 @@ String quoteAndEscapeNonPrintables(const String& s)
return String::adopt(result);
}
-static TextStream &operator<<(TextStream& ts, const RenderObject& o)
+static void writeRenderObject(TextStream& ts, const RenderObject& o, RenderAsTextBehavior behavior)
{
ts << o.renderName();
+ if (behavior & RenderAsTextShowAddresses)
+ ts << " " << &o;
+
if (o.style() && o.style()->zIndex())
ts << " zI: " << o.style()->zIndex();
@@ -254,7 +257,7 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o)
ts << " [textStrokeWidth=" << o.style()->textStrokeWidth() << "]";
if (!o.isBoxModelObject())
- return ts;
+ return;
const RenderBoxModelObject& box = *toRenderBoxModelObject(&o);
if (box.borderTop() || box.borderRight() || box.borderBottom() || box.borderLeft()) {
@@ -367,8 +370,6 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o)
}
}
#endif
-
- return ts;
}
static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBox& run)
@@ -388,7 +389,7 @@ static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBo
<< "\n";
}
-void write(TextStream& ts, const RenderObject& o, int indent)
+void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavior behavior)
{
#if ENABLE(SVG)
if (o.isRenderPath()) {
@@ -422,7 +423,8 @@ void write(TextStream& ts, const RenderObject& o, int indent)
writeIndent(ts, indent);
- ts << o << "\n";
+ writeRenderObject(ts, o, behavior);
+ ts << "\n";
if (o.isText() && !o.isBR()) {
const RenderText& text = *toRenderText(&o);
@@ -435,7 +437,7 @@ void write(TextStream& ts, const RenderObject& o, int indent)
for (RenderObject* child = o.firstChild(); child; child = child->nextSibling()) {
if (child->hasLayer())
continue;
- write(ts, *child, indent + 1);
+ write(ts, *child, indent + 1, behavior);
}
if (o.isWidget()) {
@@ -447,7 +449,7 @@ void write(TextStream& ts, const RenderObject& o, int indent)
view->layout();
RenderLayer* l = root->layer();
if (l)
- writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), indent + 1);
+ writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), indent + 1, behavior);
}
}
}
@@ -465,7 +467,12 @@ static void write(TextStream& ts, RenderLayer& l,
{
writeIndent(ts, indent);
- ts << "layer " << layerBounds;
+ ts << "layer ";
+
+ if (behavior & RenderAsTextShowAddresses)
+ ts << &l << " ";
+
+ ts << layerBounds;
if (!layerBounds.isEmpty()) {
if (!backgroundClipRect.contains(layerBounds))
@@ -504,7 +511,7 @@ static void write(TextStream& ts, RenderLayer& l,
ts << "\n";
if (paintPhase != LayerPaintPhaseBackground)
- write(ts, *l.renderer(), indent + 1);
+ write(ts, *l.renderer(), indent + 1, behavior);
}
static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLayer* l,
@@ -654,4 +661,17 @@ String counterValueForElement(Element* element)
return stream.release();
}
+String markerTextForListItem(Element* element)
+{
+ // Make sure the element is not freed during the layout.
+ RefPtr<Element> elementRef(element);
+ element->document()->updateLayout();
+
+ RenderObject* renderer = element->renderer();
+ if (!renderer || !renderer->isListItem())
+ return String();
+
+ return toRenderListItem(renderer)->markerText();
+}
+
} // namespace WebCore
diff --git a/WebCore/rendering/RenderTreeAsText.h b/WebCore/rendering/RenderTreeAsText.h
index 13525e7..4da0bab 100644
--- a/WebCore/rendering/RenderTreeAsText.h
+++ b/WebCore/rendering/RenderTreeAsText.h
@@ -38,18 +38,21 @@ enum RenderAsTextBehaviorFlags {
RenderAsTextBehaviorNormal = 0,
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.
+ RenderAsTextShowCompositedLayers = 1 << 2, // Show which layers are composited.
+ RenderAsTextShowAddresses = 1 << 3 // Show layer and renderer addresses.
};
typedef unsigned RenderAsTextBehavior;
String externalRepresentation(Frame*, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
-void write(TextStream&, const RenderObject&, int indent = 0);
+void write(TextStream&, const RenderObject&, int indent = 0, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
// Helper function shared with SVGRenderTreeAsText
String quoteAndEscapeNonPrintables(const String&);
String counterValueForElement(Element*);
+String markerTextForListItem(Element*);
+
} // namespace WebCore
#endif // RenderTreeAsText_h
diff --git a/WebCore/rendering/RenderVideo.cpp b/WebCore/rendering/RenderVideo.cpp
index 13d6f60..ad25c22 100644
--- a/WebCore/rendering/RenderVideo.cpp
+++ b/WebCore/rendering/RenderVideo.cpp
@@ -47,9 +47,6 @@ namespace WebCore {
using namespace HTMLNames;
-static const int cDefaultWidth = 300;
-static const int cDefaultHeight = 150;
-
RenderVideo::RenderVideo(HTMLVideoElement* video)
: RenderMedia(video)
{
@@ -67,10 +64,10 @@ RenderVideo::RenderVideo(HTMLVideoElement* video)
// size since they also have audio thrown at them. By setting the intrinsic
// size to 300x1 the video will resize itself in these cases, and audio will
// have the correct height (it needs to be > 0 for controls to render properly).
- setIntrinsicSize(IntSize(cDefaultWidth, 1));
+ setIntrinsicSize(IntSize(defaultSize().width(), 1));
}
else
- setIntrinsicSize(IntSize(cDefaultWidth, cDefaultHeight));
+ setIntrinsicSize(defaultSize());
}
}
@@ -82,6 +79,15 @@ RenderVideo::~RenderVideo()
}
}
+IntSize RenderVideo::defaultSize()
+{
+ // These values are specified in the spec.
+ static const int cDefaultWidth = 300;
+ static const int cDefaultHeight = 150;
+
+ return IntSize(cDefaultWidth, cDefaultHeight);
+}
+
void RenderVideo::intrinsicSizeChanged()
{
if (videoElement()->shouldDisplayPosterImage())
diff --git a/WebCore/rendering/RenderVideo.h b/WebCore/rendering/RenderVideo.h
index 16c846d..bb2b05c 100644
--- a/WebCore/rendering/RenderVideo.h
+++ b/WebCore/rendering/RenderVideo.h
@@ -42,7 +42,9 @@ public:
void videoSizeChanged();
IntRect videoBox() const;
-
+
+ static IntSize defaultSize();
+
#if USE(ACCELERATED_COMPOSITING)
bool supportsAcceleratedRendering() const;
void acceleratedRenderingStateChanged();
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index 094abfd..a95ffdd 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -31,6 +31,7 @@
#include "RenderLayer.h"
#include "RenderSelectionInfo.h"
#include "RenderWidget.h"
+#include "RenderWidgetProtector.h"
#include "TransformState.h"
#if USE(ACCELERATED_COMPOSITING)
@@ -52,6 +53,10 @@ RenderView::RenderView(Node* node, FrameView* view)
, m_selectionEndPos(-1)
, m_printImages(true)
, m_maximalOutlineSize(0)
+ , m_bestTruncatedAt(0)
+ , m_truncatorWidth(0)
+ , m_minimumColumnHeight(0)
+ , m_forcedPageBreak(false)
, m_layoutState(0)
, m_layoutStateDisableCount(0)
{
@@ -577,9 +582,29 @@ bool RenderView::printing() const
void RenderView::updateWidgetPositions()
{
- RenderWidgetSet::iterator end = m_widgets.end();
- for (RenderWidgetSet::iterator it = m_widgets.begin(); it != end; ++it)
- (*it)->updateWidgetPosition();
+ // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
+ // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
+ // alive during enumeration.
+
+ size_t size = m_widgets.size();
+
+ Vector<RenderWidget*> renderWidgets;
+ renderWidgets.reserveCapacity(size);
+
+ RenderWidgetSet::const_iterator end = m_widgets.end();
+ for (RenderWidgetSet::const_iterator it = m_widgets.begin(); it != end; ++it) {
+ renderWidgets.uncheckedAppend(*it);
+ (*it)->ref();
+ }
+
+ for (size_t i = 0; i < size; ++i)
+ renderWidgets[i]->updateWidgetPosition();
+
+ for (size_t i = 0; i < size; ++i)
+ renderWidgets[i]->widgetPositionsUpdated();
+
+ for (size_t i = 0; i < size; ++i)
+ renderWidgets[i]->deref(renderArena());
}
void RenderView::addWidget(RenderWidget* o)
@@ -722,6 +747,16 @@ 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 faa2465..fb68da3 100644
--- a/WebCore/rendering/RenderView.h
+++ b/WebCore/rendering/RenderView.h
@@ -166,6 +166,7 @@ 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 f6f6da8..b03dcd6 100644
--- a/WebCore/rendering/RenderWidget.cpp
+++ b/WebCore/rendering/RenderWidget.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -151,13 +151,22 @@ RenderWidget::~RenderWidget()
bool RenderWidget::setWidgetGeometry(const IntRect& frame)
{
ASSERT(!widgetHierarchyUpdateSuspendCount);
- if (!node() || m_widget->frameRect() == frame)
+ if (!node())
return false;
+ IntRect clipRect = enclosingLayer()->childrenClipRect();
+ bool clipChanged = m_clipRect != clipRect;
+ bool boundsChanged = m_widget->frameRect() != frame;
+
+ if (!boundsChanged && !clipChanged)
+ return false;
+
+ m_clipRect = clipRect;
+
RenderWidgetProtector protector(this);
RefPtr<Node> protectedNode(node());
m_widget->setFrameRect(frame);
- return true;
+ return boundsChanged;
}
void RenderWidget::setWidget(PassRefPtr<Widget> widget)
@@ -304,7 +313,7 @@ void RenderWidget::deref(RenderArena *arena)
void RenderWidget::updateWidgetPosition()
{
- if (!m_widget)
+ if (!m_widget || !node()) // Check the node in case destroy() has been called.
return;
// FIXME: This doesn't work correctly with transforms.
@@ -327,6 +336,21 @@ void RenderWidget::updateWidgetPosition()
#endif
}
+void RenderWidget::widgetPositionsUpdated()
+{
+ if (!m_widget)
+ return;
+ m_widget->widgetPositionsUpdated();
+}
+
+IntRect RenderWidget::windowClipRect() const
+{
+ if (!m_frameView)
+ return IntRect();
+
+ return intersection(m_frameView->contentsToWindow(m_clipRect), m_frameView->windowClipRect());
+}
+
void RenderWidget::setSelectionState(SelectionState state)
{
if (selectionState() != state) {
diff --git a/WebCore/rendering/RenderWidget.h b/WebCore/rendering/RenderWidget.h
index 6cad04a..b85b951 100644
--- a/WebCore/rendering/RenderWidget.h
+++ b/WebCore/rendering/RenderWidget.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -39,12 +39,17 @@ public:
static RenderWidget* find(const Widget*);
void updateWidgetPosition();
+ void widgetPositionsUpdated();
+ IntRect windowClipRect() const;
void showSubstituteImage(PassRefPtr<Image>);
static void suspendWidgetHierarchyUpdates();
static void resumeWidgetHierarchyUpdates();
+ RenderArena* ref() { ++m_refCount; return renderArena(); }
+ void deref(RenderArena*);
+
protected:
RenderWidget(Node*);
@@ -54,11 +59,11 @@ protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void layout();
+ virtual void paint(PaintInfo&, int x, int y);
private:
virtual bool isWidget() const { return true; }
- virtual void paint(PaintInfo&, int x, int y);
virtual void destroy();
virtual void setSelectionState(SelectionState);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -66,13 +71,10 @@ private:
bool setWidgetGeometry(const IntRect&);
- friend class RenderWidgetProtector;
- RenderArena* ref() { ++m_refCount; return renderArena(); }
- void deref(RenderArena*);
-
RefPtr<Widget> m_widget;
RefPtr<Image> m_substituteImage;
FrameView* m_frameView;
+ IntRect m_clipRect; // The rectangle needs to remain correct after scrolling, so it is stored in content view coordinates, and not clipped to window.
int m_refCount;
};
diff --git a/WebCore/rendering/RootInlineBox.h b/WebCore/rendering/RootInlineBox.h
index 7fce1d3..fae0cba 100644
--- a/WebCore/rendering/RootInlineBox.h
+++ b/WebCore/rendering/RootInlineBox.h
@@ -49,8 +49,8 @@ public:
void detachEllipsisBox(RenderArena*);
- RootInlineBox* nextRootBox() const { return static_cast<RootInlineBox*>(m_nextLine); }
- RootInlineBox* prevRootBox() const { return static_cast<RootInlineBox*>(m_prevLine); }
+ RootInlineBox* nextRootBox() const { return static_cast<RootInlineBox*>(m_nextLineBox); }
+ RootInlineBox* prevRootBox() const { return static_cast<RootInlineBox*>(m_prevLineBox); }
virtual void adjustPosition(int dx, int dy);
diff --git a/WebCore/rendering/SVGInlineTextBox.cpp b/WebCore/rendering/SVGInlineTextBox.cpp
index 65aa5a1..bda512f 100644
--- a/WebCore/rendering/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/SVGInlineTextBox.cpp
@@ -405,12 +405,11 @@ void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int t
if (isGlyphPhase || isSelectionGlyphPhase) {
// Set a text shadow if we have one.
- // FIXME: Support multiple shadow effects. Need more from the CG API before
- // we can do this.
+ // FIXME: Support multiple shadow effects. See how it's done in InlineTextBox.cpp.
bool setShadow = false;
if (styleToUse->textShadow()) {
- paintInfo.context->setShadow(IntSize(styleToUse->textShadow()->x, styleToUse->textShadow()->y),
- styleToUse->textShadow()->blur, styleToUse->textShadow()->color,
+ paintInfo.context->setShadow(IntSize(styleToUse->textShadow()->x(), styleToUse->textShadow()->y()),
+ styleToUse->textShadow()->blur(), styleToUse->textShadow()->color(),
styleToUse->colorSpace());
setShadow = true;
}
diff --git a/WebCore/rendering/SVGMarkerData.h b/WebCore/rendering/SVGMarkerData.h
index 5ff2993..ba11e7e 100644
--- a/WebCore/rendering/SVGMarkerData.h
+++ b/WebCore/rendering/SVGMarkerData.h
@@ -27,7 +27,7 @@
namespace WebCore {
-class SVGResourceMarker;
+class RenderSVGResourceMarker;
class SVGMarkerData {
public:
@@ -38,14 +38,14 @@ public:
End
};
- SVGMarkerData(const Type& type = Unknown, SVGResourceMarker* marker = 0)
+ SVGMarkerData(const Type& type = Unknown, RenderSVGResourceMarker* marker = 0)
: m_type(type)
, m_marker(marker)
{
}
FloatPoint origin() const { return m_origin; }
- SVGResourceMarker* marker() const { return m_marker; }
+ RenderSVGResourceMarker* marker() const { return m_marker; }
float currentAngle() const
{
@@ -74,7 +74,7 @@ public:
return narrowPrecisionToFloat(angle);
}
- void updateTypeAndMarker(const Type& type, SVGResourceMarker* marker)
+ void updateTypeAndMarker(const Type& type, RenderSVGResourceMarker* marker)
{
m_type = type;
m_marker = marker;
@@ -121,7 +121,7 @@ private:
}
Type m_type;
- SVGResourceMarker* m_marker;
+ RenderSVGResourceMarker* m_marker;
FloatPoint m_origin;
FloatPoint m_subpathStart;
FloatPoint m_inslopePoints[2];
diff --git a/WebCore/rendering/SVGMarkerLayoutInfo.cpp b/WebCore/rendering/SVGMarkerLayoutInfo.cpp
index 3fe513f..b771cf8 100644
--- a/WebCore/rendering/SVGMarkerLayoutInfo.cpp
+++ b/WebCore/rendering/SVGMarkerLayoutInfo.cpp
@@ -26,8 +26,7 @@
#if ENABLE(SVG)
#include "SVGMarkerLayoutInfo.h"
-#include "RenderSVGViewportContainer.h"
-#include "SVGResourceMarker.h"
+#include "RenderSVGResourceMarker.h"
namespace WebCore {
@@ -52,7 +51,7 @@ static inline void processStartAndMidMarkers(void* infoPtr, const PathElement* e
markerData.updateOutslope(element->points[0]);
// Draw the marker for the previous element
- SVGResourceMarker* marker = markerData.marker();
+ RenderSVGResourceMarker* marker = markerData.marker();
if (elementIndex > 0 && marker)
info.addLayoutedMarker(marker, markerData.origin(), markerData.currentAngle());
@@ -66,7 +65,7 @@ static inline void processStartAndMidMarkers(void* infoPtr, const PathElement* e
++elementIndex;
}
-FloatRect SVGMarkerLayoutInfo::calculateBoundaries(SVGResourceMarker* startMarker, SVGResourceMarker* midMarker, SVGResourceMarker* endMarker, float strokeWidth, const Path& path)
+FloatRect SVGMarkerLayoutInfo::calculateBoundaries(RenderSVGResourceMarker* startMarker, RenderSVGResourceMarker* midMarker, RenderSVGResourceMarker* endMarker, float strokeWidth, const Path& path)
{
m_layout.clear();
m_midMarker = midMarker;
@@ -90,7 +89,7 @@ FloatRect SVGMarkerLayoutInfo::calculateBoundaries(SVGResourceMarker* startMarke
for (; it != end; ++it) {
MarkerLayout& layout = *it;
- RenderSVGViewportContainer* markerContent = layout.marker->renderer();
+ RenderSVGResourceMarker* markerContent = layout.marker;
ASSERT(markerContent);
bounds.unite(markerContent->markerBoundaries(layout.matrix));
@@ -113,7 +112,7 @@ void SVGMarkerLayoutInfo::drawMarkers(RenderObject::PaintInfo& paintInfo)
}
}
-void SVGMarkerLayoutInfo::addLayoutedMarker(SVGResourceMarker* marker, const FloatPoint& origin, float angle)
+void SVGMarkerLayoutInfo::addLayoutedMarker(RenderSVGResourceMarker* marker, const FloatPoint& origin, float angle)
{
ASSERT(marker);
m_layout.append(MarkerLayout(marker, marker->markerTransformation(origin, angle, m_strokeWidth)));
diff --git a/WebCore/rendering/SVGMarkerLayoutInfo.h b/WebCore/rendering/SVGMarkerLayoutInfo.h
index 517c993..6011a2d 100644
--- a/WebCore/rendering/SVGMarkerLayoutInfo.h
+++ b/WebCore/rendering/SVGMarkerLayoutInfo.h
@@ -28,17 +28,17 @@
namespace WebCore {
class Path;
-class SVGResourceMarker;
+class RenderSVGResourceMarker;
struct MarkerLayout {
- MarkerLayout(SVGResourceMarker* markerObj = 0, AffineTransform matrixObj = AffineTransform())
+ MarkerLayout(RenderSVGResourceMarker* markerObj = 0, AffineTransform matrixObj = AffineTransform())
: marker(markerObj)
, matrix(matrixObj)
{
ASSERT(marker);
}
- SVGResourceMarker* marker;
+ RenderSVGResourceMarker* marker;
AffineTransform matrix;
};
@@ -47,17 +47,17 @@ public:
SVGMarkerLayoutInfo();
~SVGMarkerLayoutInfo();
- FloatRect calculateBoundaries(SVGResourceMarker* startMarker, SVGResourceMarker* midMarker, SVGResourceMarker* endMarker, float strokeWidth, const Path&);
+ FloatRect calculateBoundaries(RenderSVGResourceMarker* startMarker, RenderSVGResourceMarker* midMarker, RenderSVGResourceMarker* endMarker, float strokeWidth, const Path&);
void drawMarkers(RenderObject::PaintInfo&);
// Used by static inline helper functions in SVGMarkerLayoutInfo.cpp
SVGMarkerData& markerData() { return m_markerData; }
- SVGResourceMarker* midMarker() const { return m_midMarker; }
+ RenderSVGResourceMarker* midMarker() const { return m_midMarker; }
int& elementIndex() { return m_elementIndex; }
- void addLayoutedMarker(SVGResourceMarker*, const FloatPoint& origin, float angle);
+ void addLayoutedMarker(RenderSVGResourceMarker*, const FloatPoint& origin, float angle);
private:
- SVGResourceMarker* m_midMarker;
+ RenderSVGResourceMarker* m_midMarker;
// Used while layouting markers
int m_elementIndex;
@@ -70,5 +70,5 @@ private:
}
-#endif // ENABLE(SVG)
-#endif // SVGMarkerLayoutInfo_h
+#endif
+#endif
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index dc1b3c1..dd67746 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -4,6 +4,7 @@
* (C) 2007 Eric Seidel <eric@webkit.org>
* (C) 2009 Google, Inc. All rights reserved.
* (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -33,10 +34,11 @@
#include "RenderObject.h"
#include "RenderSVGContainer.h"
#include "RenderSVGResource.h"
+#include "RenderSVGResourceClipper.h"
+#include "RenderSVGResourceFilter.h"
+#include "RenderSVGResourceMarker.h"
#include "RenderSVGResourceMasker.h"
#include "RenderView.h"
-#include "SVGResourceClipper.h"
-#include "SVGResourceFilter.h"
#include "SVGStyledElement.h"
#include "SVGURIReference.h"
#include "TransformState.h"
@@ -78,7 +80,7 @@ void SVGRenderBase::mapLocalToContainer(const RenderObject* object, RenderBoxMod
object->parent()->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
}
-bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& repaintRect, SVGResourceFilter*& filter, SVGResourceFilter* rootFilter)
+bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& repaintRect, RenderSVGResourceFilter*& filter, RenderSVGResourceFilter* rootFilter)
{
#if !ENABLE(FILTERS)
UNUSED_PARAM(filter);
@@ -103,23 +105,23 @@ bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
paintInfo.context->beginTransparencyLayer(opacity);
}
- if (ShadowData* shadow = svgStyle->shadow()) {
+ if (const ShadowData* shadow = svgStyle->shadow()) {
paintInfo.context->clip(repaintRect);
- paintInfo.context->setShadow(IntSize(shadow->x, shadow->y), shadow->blur, shadow->color, style->colorSpace());
+ paintInfo.context->setShadow(IntSize(shadow->x(), shadow->y()), shadow->blur(), shadow->color(), style->colorSpace());
paintInfo.context->beginTransparencyLayer(1.0f);
}
#if ENABLE(FILTERS)
- AtomicString filterId(svgStyle->filter());
+ AtomicString filterId(svgStyle->filterResource());
#endif
- AtomicString clipperId(svgStyle->clipPath());
- AtomicString maskerId(svgStyle->maskElement());
+ AtomicString clipperId(svgStyle->clipperResource());
+ AtomicString maskerId(svgStyle->maskerResource());
Document* document = object->document();
#if ENABLE(FILTERS)
- SVGResourceFilter* newFilter = getFilterById(document, filterId, object);
+ RenderSVGResourceFilter* newFilter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, filterId);
if (newFilter == rootFilter) {
// Catch <text filter="url(#foo)">Test<tspan filter="url(#foo)">123</tspan></text>.
// The filter is NOT meant to be applied twice in that case!
@@ -129,23 +131,20 @@ bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
filter = newFilter;
#endif
- // apply Masker
if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, maskerId)) {
if (!masker->applyResource(object, paintInfo.context))
return false;
} else if (!maskerId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
- if (SVGResourceClipper* clipper = getClipperById(document, clipperId, object)) {
- clipper->addClient(styledElement);
- clipper->applyClip(paintInfo.context, object->objectBoundingBox());
- } else if (!clipperId.isEmpty())
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, clipperId))
+ clipper->applyResource(object, paintInfo.context);
+ else if (!clipperId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);
#if ENABLE(FILTERS)
if (filter) {
- filter->addClient(styledElement);
- if (!filter->prepareFilter(paintInfo.context, object))
+ if (!filter->applyResource(object, paintInfo.context))
return false;
} else if (!filterId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
@@ -154,7 +153,7 @@ bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
return true;
}
-void SVGRenderBase::finishRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, SVGResourceFilter*& filter, GraphicsContext* savedContext)
+void SVGRenderBase::finishRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, RenderSVGResourceFilter*& filter, GraphicsContext* savedContext)
{
#if !ENABLE(FILTERS)
UNUSED_PARAM(filter);
@@ -168,7 +167,7 @@ void SVGRenderBase::finishRenderSVGContent(RenderObject* object, RenderObject::P
#if ENABLE(FILTERS)
if (filter) {
- filter->applyFilter(paintInfo.context, object);
+ filter->postApplyResource(object, paintInfo.context);
paintInfo.context = savedContext;
}
#endif
@@ -188,7 +187,14 @@ void renderSubtreeToImage(ImageBuffer* image, RenderObject* item)
ASSERT(item);
ASSERT(image);
ASSERT(image->context());
- RenderObject::PaintInfo info(image->context(), IntRect(), PaintPhaseForeground, 0, 0, 0);
+
+ // FIXME: This sets the rect to the viewable area of the current frame. This
+ // is used to support text drawings to the ImageBuffer. See bug 30399.
+ IntRect rect;
+ FrameView* frameView = item->document()->view();
+ if (frameView)
+ rect = IntRect(0, 0, frameView->visibleWidth(), frameView->visibleHeight());
+ RenderObject::PaintInfo info(image->context(), rect, PaintPhaseForeground, 0, 0, 0);
// FIXME: isSVGContainer returns true for RenderSVGViewportContainer, so if this is ever
// called with one of those, we will read from the wrong offset in an object due to a bad cast.
@@ -276,9 +282,8 @@ bool SVGRenderBase::isOverflowHidden(const RenderObject* object)
FloatRect SVGRenderBase::filterBoundingBoxForRenderer(const RenderObject* object) const
{
#if ENABLE(FILTERS)
- SVGResourceFilter* filter = getFilterById(object->document(), object->style()->svgStyle()->filter(), object);
- if (filter)
- return filter->filterBoundingBox(object->objectBoundingBox());
+ if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object->document(), object->style()->svgStyle()->filterResource()))
+ return filter->resourceBoundingBox(object->objectBoundingBox());
#else
UNUSED_PARAM(object);
#endif
@@ -287,26 +292,37 @@ FloatRect SVGRenderBase::filterBoundingBoxForRenderer(const RenderObject* object
FloatRect SVGRenderBase::clipperBoundingBoxForRenderer(const RenderObject* object) const
{
- SVGResourceClipper* clipper = getClipperById(object->document(), object->style()->svgStyle()->clipPath(), object);
- if (clipper)
- return clipper->clipperBoundingBox(object->objectBoundingBox());
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object->document(), object->style()->svgStyle()->clipperResource()))
+ return clipper->resourceBoundingBox(object->objectBoundingBox());
return FloatRect();
}
FloatRect SVGRenderBase::maskerBoundingBoxForRenderer(const RenderObject* object) const
{
- if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskElement()))
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskerResource()))
return masker->resourceBoundingBox(object->objectBoundingBox());
return FloatRect();
}
-void SVGRenderBase::deregisterFromResources(RenderObject* object)
+void deregisterFromResources(RenderObject* object)
{
- // We only have a renderer for masker at the moment.
- if (RenderSVGResourceMasker* resource = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskElement()))
- resource->invalidateClient(object);
+ // We only have the renderer for masker and clipper at the moment.
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskerResource()))
+ masker->invalidateClient(object);
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object->document(), object->style()->svgStyle()->clipperResource()))
+ clipper->invalidateClient(object);
+#if ENABLE(FILTERS)
+ if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object->document(), object->style()->svgStyle()->filterResource()))
+ filter->invalidateClient(object);
+#endif
+ if (RenderSVGResourceMarker* startMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(object->document(), object->style()->svgStyle()->markerStartResource()))
+ startMarker->invalidateClient(object);
+ if (RenderSVGResourceMarker* midMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(object->document(), object->style()->svgStyle()->markerMidResource()))
+ midMarker->invalidateClient(object);
+ if (RenderSVGResourceMarker* endMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(object->document(), object->style()->svgStyle()->markerEndResource()))
+ endMarker->invalidateClient(object);
}
void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const AffineTransform& localToAncestorTransform)
@@ -318,6 +334,16 @@ void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const AffineT
paintInfo.rect = localToAncestorTransform.inverse().mapRect(paintInfo.rect);
}
-} // namespace WebCore
+const RenderObject* findTextRootObject(const RenderObject* start)
+{
+ while (start && !start->isSVGText())
+ start = start->parent();
+ ASSERT(start);
+ ASSERT(start->isSVGText());
-#endif // ENABLE(SVG)
+ return start;
+}
+
+}
+
+#endif
diff --git a/WebCore/rendering/SVGRenderSupport.h b/WebCore/rendering/SVGRenderSupport.h
index 427ff1f..4b59b71 100644
--- a/WebCore/rendering/SVGRenderSupport.h
+++ b/WebCore/rendering/SVGRenderSupport.h
@@ -31,7 +31,7 @@
namespace WebCore {
-class SVGResourceFilter;
+class RenderSVGResourceFilter;
class ImageBuffer;
// SVGRendererBase is an abstract base class which all SVG renderers inherit
@@ -47,8 +47,8 @@ public:
// FIXME: These are only public for SVGRootInlineBox.
// It's unclear if these should be exposed or not. SVGRootInlineBox may
// pass the wrong RenderObject* and boundingBox to these functions.
- static bool prepareToRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, const FloatRect& boundingBox, SVGResourceFilter*&, SVGResourceFilter* rootFilter = 0);
- static void finishRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, SVGResourceFilter*&, GraphicsContext* savedContext);
+ static bool prepareToRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, const FloatRect& boundingBox, RenderSVGResourceFilter*&, RenderSVGResourceFilter* rootFilter = 0);
+ static void finishRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, RenderSVGResourceFilter*&, GraphicsContext* savedContext);
// Layout all children of the passed render object
static void layoutChildren(RenderObject*, bool selfNeedsLayout);
@@ -73,8 +73,6 @@ protected:
// Used to share the "walk all the children" logic between objectBoundingBox
// and repaintRectInLocalCoordinates in RenderSVGRoot and RenderSVGContainer
static FloatRect computeContainerBoundingBox(const RenderObject* container, bool includeAllPaintedContent);
-
- static void deregisterFromResources(RenderObject*);
};
// FIXME: This should move to RenderObject or PaintInfo
@@ -84,7 +82,10 @@ void applyTransformToPaintInfo(RenderObject::PaintInfo&, const AffineTransform&
// This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.
void renderSubtreeToImage(ImageBuffer*, RenderObject*);
+void deregisterFromResources(RenderObject*);
void clampImageBufferSizeToViewport(FrameView*, IntSize& imageBufferSize);
+
+const RenderObject* findTextRootObject(const RenderObject* start);
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index f892144..0f1f15d 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 2004, 2005, 2007, 2009 Apple Inc. All rights reserved.
* (C) 2005 Rob Buis <buis@kde.org>
* (C) 2006 Alexander Kellett <lypanov@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,10 +35,14 @@
#include "HTMLNames.h"
#include "InlineTextBox.h"
#include "NodeRenderStyle.h"
+#include "Path.h"
#include "RenderImage.h"
#include "RenderPath.h"
#include "RenderSVGContainer.h"
#include "RenderSVGInlineText.h"
+#include "RenderSVGResourceClipper.h"
+#include "RenderSVGResourceFilter.h"
+#include "RenderSVGResourceMarker.h"
#include "RenderSVGResourceMasker.h"
#include "RenderSVGRoot.h"
#include "RenderSVGText.h"
@@ -47,7 +52,6 @@
#include "SVGPaintServerGradient.h"
#include "SVGPaintServerPattern.h"
#include "SVGPaintServerSolid.h"
-#include "SVGResourceClipper.h"
#include "SVGRootInlineBox.h"
#include "SVGStyledElement.h"
#include <math.h>
@@ -196,6 +200,20 @@ TextStream& operator<<(TextStream& ts, const AffineTransform& transform)
return ts;
}
+static TextStream& operator<<(TextStream& ts, const WindRule rule)
+{
+ switch (rule) {
+ case RULE_NONZERO:
+ ts << "NON-ZERO";
+ break;
+ case RULE_EVENODD:
+ ts << "EVEN-ODD";
+ break;
+ }
+
+ return ts;
+}
+
static TextStream& operator<<(TextStream& ts, const SVGUnitTypes::SVGUnitType& unitType)
{
switch (unitType) {
@@ -213,6 +231,23 @@ static TextStream& operator<<(TextStream& ts, const SVGUnitTypes::SVGUnitType& u
return ts;
}
+static TextStream& operator<<(TextStream& ts, const SVGMarkerElement::SVGMarkerUnitsType& markerUnit)
+{
+ switch (markerUnit) {
+ case SVGMarkerElement::SVG_MARKERUNITS_UNKNOWN:
+ ts << "unknown";
+ break;
+ case SVGMarkerElement::SVG_MARKERUNITS_USERSPACEONUSE:
+ ts << "userSpaceOnUse";
+ break;
+ case SVGMarkerElement::SVG_MARKERUNITS_STROKEWIDTH:
+ ts << "strokeWidth";
+ break;
+ }
+
+ return ts;
+}
+
TextStream& operator<<(TextStream& ts, const Color& c)
{
return ts << c.name();
@@ -316,14 +351,12 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
writeIfNotDefault(ts, "fill rule", svgStyle->fillRule(), RULE_NONZERO);
ts << "}]";
}
+ writeIfNotDefault(ts, "clip rule", svgStyle->clipRule(), RULE_NONZERO);
}
- if (!svgStyle->clipPath().isEmpty())
- writeNameAndQuotedValue(ts, "clip path", svgStyle->clipPath());
- writeIfNotEmpty(ts, "start marker", svgStyle->startMarker());
- writeIfNotEmpty(ts, "middle marker", svgStyle->midMarker());
- writeIfNotEmpty(ts, "end marker", svgStyle->endMarker());
- writeIfNotEmpty(ts, "filter", svgStyle->filter());
+ writeIfNotEmpty(ts, "start marker", svgStyle->markerStartResource());
+ writeIfNotEmpty(ts, "middle marker", svgStyle->markerMidResource());
+ writeIfNotEmpty(ts, "end marker", svgStyle->markerEndResource());
}
static TextStream& writePositionAndStyle(TextStream& ts, const RenderObject& object)
@@ -496,9 +529,49 @@ void writeSVGResource(TextStream& ts, const RenderObject& object, int indent)
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()) {
+ ts << "\n";
+ const HashMap<AtomicString, RefPtr<FilterEffect> >& effects = builder->namedEffects();
+ HashMap<AtomicString, RefPtr<FilterEffect> >::const_iterator end = effects.end();
+ for (HashMap<AtomicString, RefPtr<FilterEffect> >::const_iterator it = effects.begin(); it != end; ++it) {
+ writeIndent(ts, indent);
+ ts << " [primitve=\"" << it->first << "\" ";
+ it->second->externalRepresentation(ts);
+ ts << "]\n";
+ }
+ writeIndent(ts, indent);
+ // FIXME: Some effects don't give a representation back. So we miss some more informations
+ // after '[last primitive' .
+ // We also just dump named effects and the last effect at the moment, more effects
+ // without a name might be in the pipe.
+ ts << " [last primitive ";
+ if (FilterEffect* lastEffect = builder->lastEffect())
+ lastEffect->externalRepresentation(ts);
+ ts << "]";
+ }
+#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=";
+ if (marker->angle() == -1)
+ ts << "auto" << "]";
+ else
+ ts << marker->angle() << "]";
}
- // FIXME: Handle other RenderSVGResource* classes here, after converting them from SVGResource*.
ts << "\n";
writeChildren(ts, object, indent);
}
@@ -558,17 +631,38 @@ void writeResources(TextStream& ts, const RenderObject& object, int indent)
const RenderStyle* style = object.style();
const SVGRenderStyle* svgStyle = style->svgStyle();
- if (!svgStyle->maskElement().isEmpty()) {
- if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskElement())) {
+ if (!svgStyle->maskerResource().isEmpty()) {
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskerResource())) {
writeIndent(ts, indent);
ts << " ";
- writeNameAndQuotedValue(ts, "masker", svgStyle->maskElement());
+ writeNameAndQuotedValue(ts, "masker", svgStyle->maskerResource());
ts << " ";
writeStandardPrefix(ts, *masker, 0);
ts << " " << masker->resourceBoundingBox(object.objectBoundingBox()) << "\n";
}
}
- // FIXME: Handle other RenderSVGResource* classes here, after converting them from SVGResource*.
+ if (!svgStyle->clipperResource().isEmpty()) {
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object.document(), svgStyle->clipperResource())) {
+ writeIndent(ts, indent);
+ ts << " ";
+ writeNameAndQuotedValue(ts, "clipPath", svgStyle->clipperResource());
+ ts << " ";
+ writeStandardPrefix(ts, *clipper, 0);
+ ts << " " << clipper->resourceBoundingBox(object.objectBoundingBox()) << "\n";
+ }
+ }
+#if ENABLE(FILTERS)
+ if (!svgStyle->filterResource().isEmpty()) {
+ if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object.document(), svgStyle->filterResource())) {
+ writeIndent(ts, indent);
+ ts << " ";
+ writeNameAndQuotedValue(ts, "filter", svgStyle->filterResource());
+ ts << " ";
+ writeStandardPrefix(ts, *filter, 0);
+ ts << " " << filter->resourceBoundingBox(object.objectBoundingBox()) << "\n";
+ }
+ }
+#endif
}
void writeRenderResources(TextStream& ts, Node* parent)
@@ -592,8 +686,7 @@ void writeRenderResources(TextStream& ts, Node* parent)
if (resource->isPaintServer()) {
RefPtr<SVGPaintServer> paintServer = WTF::static_pointer_cast<SVGPaintServer>(resource);
ts << "KRenderingPaintServer {id=\"" << elementId << "\" " << *paintServer << "}" << "\n";
- } else
- ts << "KCanvasResource {id=\"" << elementId << "\" " << *resource << "}" << "\n";
+ }
} while ((node = node->traverseNextNode(parent)));
}
diff --git a/WebCore/rendering/SVGRootInlineBox.cpp b/WebCore/rendering/SVGRootInlineBox.cpp
index 03b9db4..89b4375 100644
--- a/WebCore/rendering/SVGRootInlineBox.cpp
+++ b/WebCore/rendering/SVGRootInlineBox.cpp
@@ -28,9 +28,11 @@
#include "SVGRootInlineBox.h"
#include "Editor.h"
+#include "FloatConversion.h"
#include "Frame.h"
#include "GraphicsContext.h"
#include "RenderBlock.h"
+#include "RenderSVGResourceFilter.h"
#include "RenderSVGRoot.h"
#include "SVGInlineFlowBox.h"
#include "SVGInlineTextBox.h"
@@ -38,7 +40,6 @@
#include "SVGPaintServer.h"
#include "SVGRenderStyleDefs.h"
#include "SVGRenderSupport.h"
-#include "SVGResourceFilter.h"
#include "SVGTextPositioningElement.h"
#include "SVGURIReference.h"
#include "Text.h"
@@ -336,7 +337,7 @@ static float calculateKerning(RenderObject* item)
// Helper class for paint()
struct SVGRootInlineBoxPaintWalker {
- SVGRootInlineBoxPaintWalker(SVGRootInlineBox* rootBox, SVGResourceFilter* rootFilter, RenderObject::PaintInfo paintInfo, int tx, int ty)
+ SVGRootInlineBoxPaintWalker(SVGRootInlineBox* rootBox, RenderSVGResourceFilter* rootFilter, RenderObject::PaintInfo paintInfo, int tx, int ty)
: m_rootBox(rootBox)
, m_chunkStarted(false)
, m_paintInfo(paintInfo)
@@ -668,8 +669,8 @@ private:
RenderObject::PaintInfo m_savedInfo;
FloatRect m_boundingBox;
- SVGResourceFilter* m_filter;
- SVGResourceFilter* m_rootFilter;
+ RenderSVGResourceFilter* m_filter;
+ RenderSVGResourceFilter* m_rootFilter;
SVGPaintServer* m_fillPaintServer;
SVGPaintServer* m_strokePaintServer;
@@ -691,7 +692,7 @@ void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
RenderObject::PaintInfo savedInfo(paintInfo);
paintInfo.context->save();
- SVGResourceFilter* filter = 0;
+ RenderSVGResourceFilter* filter = 0;
FloatRect boundingBox(tx + x(), ty + y(), width(), height());
// Initialize text rendering
@@ -1413,7 +1414,7 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo&
}
}
- double kerning = 0.0;
+ float kerning = 0.0f;
#if ENABLE(SVG_FONTS)
SVGFontElement* svgFont = 0;
if (style->font().isSVGFont())
@@ -1422,25 +1423,26 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo&
if (lastGlyph.isValid && style->font().isSVGFont()) {
SVGHorizontalKerningPair kerningPair;
if (svgFont->getHorizontalKerningPairForStringsAndGlyphs(lastGlyph.unicode, lastGlyph.glyphName, unicodeStr, glyphName, kerningPair))
- kerning = kerningPair.kerning;
+ 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 -= (float)kerning;
+ svgChar.x -= kerning;
// Advance to new position
if (isVerticalText) {
svgChar.drawnSeperated = true;
info.cury += glyphAdvance + spacing;
} else
- info.curx += glyphAdvance + spacing - (float)kerning;
+ info.curx += glyphAdvance + spacing - kerning;
// Advance to next character group
for (int k = 0; k < charsConsumed; ++k) {
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index fc7f7f0..4cd55c5 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -63,18 +63,17 @@ bool RenderTextControlInnerBlock::nodeAtPoint(const HitTestRequest& request, Hit
VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& point)
{
- int contentsX = point.x();
- int contentsY = point.y();
+ IntPoint contentsPoint(point);
// Multiline text controls have the scroll on shadowAncestorNode, so we need to take that
// into account here.
if (m_multiLine) {
RenderTextControl* renderer = toRenderTextControl(node()->shadowAncestorNode()->renderer());
if (renderer->hasOverflowClip())
- renderer->layer()->addScrolledContentOffset(contentsX, contentsY);
+ contentsPoint += renderer->layer()->scrolledContentOffset();
}
- return RenderBlock::positionForPoint(IntPoint(contentsX, contentsY));
+ return RenderBlock::positionForPoint(contentsPoint);
}
TextControlInnerElement::TextControlInnerElement(Document* doc, Node* shadowParent)
diff --git a/WebCore/rendering/style/BorderData.h b/WebCore/rendering/style/BorderData.h
index 8ca0d65..96caf97 100644
--- a/WebCore/rendering/style/BorderData.h
+++ b/WebCore/rendering/style/BorderData.h
@@ -32,76 +32,90 @@
namespace WebCore {
class BorderData {
+friend class RenderStyle;
public:
- BorderValue left;
- BorderValue right;
- BorderValue top;
- BorderValue bottom;
-
- NinePieceImage image;
-
- IntSize topLeft;
- IntSize topRight;
- IntSize bottomLeft;
- IntSize bottomRight;
-
bool hasBorder() const
{
- bool haveImage = image.hasImage();
- return left.nonZero(!haveImage) || right.nonZero(!haveImage) || top.nonZero(!haveImage) || bottom.nonZero(!haveImage);
+ bool haveImage = m_image.hasImage();
+ return m_left.nonZero(!haveImage) || m_right.nonZero(!haveImage) || m_top.nonZero(!haveImage) || m_bottom.nonZero(!haveImage);
}
bool hasBorderRadius() const
{
- if (topLeft.width() > 0)
+ if (m_topLeft.width() > 0)
return true;
- if (topRight.width() > 0)
+ if (m_topRight.width() > 0)
return true;
- if (bottomLeft.width() > 0)
+ if (m_bottomLeft.width() > 0)
return true;
- if (bottomRight.width() > 0)
+ if (m_bottomRight.width() > 0)
return true;
return false;
}
unsigned short borderLeftWidth() const
{
- if (!image.hasImage() && (left.style() == BNONE || left.style() == BHIDDEN))
+ if (!m_image.hasImage() && (m_left.style() == BNONE || m_left.style() == BHIDDEN))
return 0;
- return left.width;
+ return m_left.width();
}
unsigned short borderRightWidth() const
{
- if (!image.hasImage() && (right.style() == BNONE || right.style() == BHIDDEN))
+ if (!m_image.hasImage() && (m_right.style() == BNONE || m_right.style() == BHIDDEN))
return 0;
- return right.width;
+ return m_right.width();
}
unsigned short borderTopWidth() const
{
- if (!image.hasImage() && (top.style() == BNONE || top.style() == BHIDDEN))
+ if (!m_image.hasImage() && (m_top.style() == BNONE || m_top.style() == BHIDDEN))
return 0;
- return top.width;
+ return m_top.width();
}
unsigned short borderBottomWidth() const
{
- if (!image.hasImage() && (bottom.style() == BNONE || bottom.style() == BHIDDEN))
+ if (!m_image.hasImage() && (m_bottom.style() == BNONE || m_bottom.style() == BHIDDEN))
return 0;
- return bottom.width;
+ return m_bottom.width();
}
bool operator==(const BorderData& o) const
{
- return left == o.left && right == o.right && top == o.top && bottom == o.bottom && image == o.image &&
- topLeft == o.topLeft && topRight == o.topRight && bottomLeft == o.bottomLeft && bottomRight == o.bottomRight;
+ return m_left == o.m_left && m_right == o.m_right && m_top == o.m_top && m_bottom == o.m_bottom && m_image == o.m_image
+ && m_topLeft == o.m_topLeft && m_topRight == o.m_topRight && m_bottomLeft == o.m_bottomLeft && m_bottomRight == o.m_bottomRight;
}
bool operator!=(const BorderData& o) const
{
return !(*this == o);
}
+
+ const BorderValue& left() const { return m_left; }
+ const BorderValue& right() const { return m_right; }
+ const BorderValue& top() const { return m_top; }
+ const BorderValue& bottom() const { return m_bottom; }
+
+ const NinePieceImage& image() const { return m_image; }
+
+ const IntSize& topLeft() const { return m_topLeft; }
+ const IntSize& topRight() const { return m_topRight; }
+ const IntSize& bottomLeft() const { return m_bottomLeft; }
+ const IntSize& bottomRight() const { return m_bottomRight; }
+
+private:
+ BorderValue m_left;
+ BorderValue m_right;
+ BorderValue m_top;
+ BorderValue m_bottom;
+
+ NinePieceImage m_image;
+
+ IntSize m_topLeft;
+ IntSize m_topRight;
+ IntSize m_bottomLeft;
+ IntSize m_bottomRight;
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/BorderValue.h b/WebCore/rendering/style/BorderValue.h
index e61e708..3e6fd5d 100644
--- a/WebCore/rendering/style/BorderValue.h
+++ b/WebCore/rendering/style/BorderValue.h
@@ -31,27 +31,22 @@
namespace WebCore {
class BorderValue {
+friend class RenderStyle;
public:
BorderValue()
- : width(3)
+ : m_width(3)
, m_style(BNONE)
{
}
- Color color;
- unsigned width : 12;
- unsigned m_style : 4; // EBorderStyle
-
- EBorderStyle style() const { return static_cast<EBorderStyle>(m_style); }
-
bool nonZero(bool checkStyle = true) const
{
- return width != 0 && (!checkStyle || m_style != BNONE);
+ return width() && (!checkStyle || m_style != BNONE);
}
bool isTransparent() const
{
- return color.isValid() && color.alpha() == 0;
+ return m_color.isValid() && !m_color.alpha();
}
bool isVisible(bool checkStyle = true) const
@@ -61,13 +56,22 @@ public:
bool operator==(const BorderValue& o) const
{
- return width == o.width && m_style == o.m_style && color == o.color;
+ return m_width == o.m_width && m_style == o.m_style && m_color == o.m_color;
}
bool operator!=(const BorderValue& o) const
{
return !(*this == o);
}
+
+ const Color& color() const { return m_color; }
+ unsigned short width() const { return m_width; }
+ EBorderStyle style() const { return static_cast<EBorderStyle>(m_style); }
+
+protected:
+ Color m_color;
+ unsigned m_width : 12;
+ unsigned m_style : 4; // EBorderStyle
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/CollapsedBorderValue.h b/WebCore/rendering/style/CollapsedBorderValue.h
index 805f474..6207231 100644
--- a/WebCore/rendering/style/CollapsedBorderValue.h
+++ b/WebCore/rendering/style/CollapsedBorderValue.h
@@ -29,36 +29,42 @@
namespace WebCore {
-struct CollapsedBorderValue {
+class CollapsedBorderValue {
+friend class RenderStyle;
+public:
CollapsedBorderValue()
- : border(0)
- , precedence(BOFF)
+ : m_border(0)
+ , m_precedence(BOFF)
{
}
- CollapsedBorderValue(const BorderValue* b, EBorderPrecedence p)
- : border(b)
- , precedence(p)
+ CollapsedBorderValue(const BorderValue* b, Color c, EBorderPrecedence p)
+ : m_border(b)
+ , m_borderColor(c)
+ , m_precedence(p)
{
}
- int width() const { return border && border->nonZero() ? border->width : 0; }
- EBorderStyle style() const { return border ? border->style() : BHIDDEN; }
- bool exists() const { return border; }
- Color color() const { return border ? border->color : Color(); }
- bool isTransparent() const { return border ? border->isTransparent() : true; }
-
+ int width() const { return m_border && m_border->nonZero() ? m_border->width() : 0; }
+ EBorderStyle style() const { return m_border ? m_border->style() : BHIDDEN; }
+ bool exists() const { return m_border; }
+ const Color& color() const { return m_borderColor; }
+ bool isTransparent() const { return m_border ? m_border->isTransparent() : true; }
+ EBorderPrecedence precedence() const { return m_precedence; }
+
bool operator==(const CollapsedBorderValue& o) const
{
- if (!border)
- return !o.border;
- if (!o.border)
+ if (!m_border)
+ return !o.m_border;
+ if (!o.m_border)
return false;
- return *border == *o.border && precedence == o.precedence;
+ return *m_border == *o.m_border && m_borderColor == o.m_borderColor && m_precedence == o.m_precedence;
}
-
- const BorderValue* border;
- EBorderPrecedence precedence;
+
+private:
+ const BorderValue* m_border;
+ Color m_borderColor;
+ EBorderPrecedence m_precedence;
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/CursorData.h b/WebCore/rendering/style/CursorData.h
index 7c6b31d..2341e71 100644
--- a/WebCore/rendering/style/CursorData.h
+++ b/WebCore/rendering/style/CursorData.h
@@ -31,15 +31,17 @@
namespace WebCore {
-struct CursorData {
- CursorData()
- : cursorImage(0)
+class CursorData {
+public:
+ CursorData(CachedImage* image, const IntPoint& hotSpot)
+ : m_image(image)
+ , m_hotSpot(hotSpot)
{
}
bool operator==(const CursorData& o) const
{
- return hotSpot == o.hotSpot && cursorImage == o.cursorImage;
+ return m_hotSpot == o.m_hotSpot && m_image == o.m_image;
}
bool operator!=(const CursorData& o) const
@@ -47,8 +49,12 @@ struct CursorData {
return !(*this == o);
}
- IntPoint hotSpot; // for CSS3 support
- CachedResourceHandle<CachedImage> cursorImage;
+ const CachedImage* image() const { return m_image.get(); }
+ const IntPoint& hotSpot() const { return m_hotSpot; }
+
+private:
+ CachedResourceHandle<CachedImage> m_image;
+ IntPoint m_hotSpot; // for CSS3 support
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/FillLayer.h b/WebCore/rendering/style/FillLayer.h
index cef6b19..eb21ec3 100644
--- a/WebCore/rendering/style/FillLayer.h
+++ b/WebCore/rendering/style/FillLayer.h
@@ -59,7 +59,7 @@ struct FillSize {
LengthSize size;
};
-struct FillLayer : FastAllocBase {
+class FillLayer : public FastAllocBase {
public:
FillLayer(EFillLayerType);
~FillLayer();
@@ -74,6 +74,7 @@ public:
EFillRepeat repeatY() const { return static_cast<EFillRepeat>(m_repeatY); }
CompositeOperator composite() const { return static_cast<CompositeOperator>(m_composite); }
LengthSize sizeLength() const { return m_sizeLength; }
+ EFillSizeType sizeType() const { return static_cast<EFillSizeType>(m_sizeType); }
FillSize size() const { return FillSize(static_cast<EFillSizeType>(m_sizeType), m_sizeLength); }
const FillLayer* next() const { return m_next; }
@@ -161,9 +162,10 @@ public:
static StyleImage* initialFillImage(EFillLayerType) { return 0; }
private:
+ friend class RenderStyle;
+
FillLayer() { }
-public:
RefPtr<StyleImage> m_image;
Length m_xPosition;
diff --git a/WebCore/rendering/style/NinePieceImage.h b/WebCore/rendering/style/NinePieceImage.h
index bf47ce6..c400551 100644
--- a/WebCore/rendering/style/NinePieceImage.h
+++ b/WebCore/rendering/style/NinePieceImage.h
@@ -55,10 +55,18 @@ public:
bool hasImage() const { return m_image != 0; }
StyleImage* image() const { return m_image.get(); }
+ void setImage(StyleImage* image) { m_image = image; }
+ const LengthBox& slices() const { return m_slices; }
+ void setSlices(const LengthBox& l) { m_slices = l; }
+
ENinePieceImageRule horizontalRule() const { return static_cast<ENinePieceImageRule>(m_horizontalRule); }
- ENinePieceImageRule verticalRule() const { return static_cast<ENinePieceImageRule>(m_verticalRule); }
+ void setHorizontalRule(ENinePieceImageRule rule) { m_horizontalRule = rule; }
+ ENinePieceImageRule verticalRule() const { return static_cast<ENinePieceImageRule>(m_verticalRule); }
+ void setVerticalRule(ENinePieceImageRule rule) { m_verticalRule = rule; }
+
+private:
RefPtr<StyleImage> m_image;
LengthBox m_slices;
unsigned m_horizontalRule : 2; // ENinePieceImageRule
diff --git a/WebCore/rendering/style/OutlineValue.h b/WebCore/rendering/style/OutlineValue.h
index 2628b7f..19c17a7 100644
--- a/WebCore/rendering/style/OutlineValue.h
+++ b/WebCore/rendering/style/OutlineValue.h
@@ -30,16 +30,17 @@
namespace WebCore {
class OutlineValue : public BorderValue {
+friend class RenderStyle;
public:
OutlineValue()
- : _offset(0)
- , _auto(false)
+ : m_offset(0)
+ , m_isAuto(false)
{
}
bool operator==(const OutlineValue& o) const
{
- return width == o.width && m_style == o.m_style && color == o.color && _offset == o._offset && _auto == o._auto;
+ return m_width == o.m_width && m_style == o.m_style && m_color == o.m_color && m_offset == o.m_offset && m_isAuto == o.m_isAuto;
}
bool operator!=(const OutlineValue& o) const
@@ -47,8 +48,12 @@ public:
return !(*this == o);
}
- int _offset;
- bool _auto;
+ int offset() const { return m_offset; }
+ bool isAuto() const { return m_isAuto; }
+
+private:
+ int m_offset;
+ bool m_isAuto;
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp
index 712344f..f1cf0bc 100644
--- a/WebCore/rendering/style/RenderStyle.cpp
+++ b/WebCore/rendering/style/RenderStyle.cpp
@@ -22,6 +22,7 @@
#include "config.h"
#include "RenderStyle.h"
+#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
#include "CachedImage.h"
#include "CounterContent.h"
@@ -58,8 +59,7 @@ PassRefPtr<RenderStyle> RenderStyle::clone(const RenderStyle* other)
}
RenderStyle::RenderStyle()
- : m_pseudoState(PseudoUnknown)
- , m_affectedByAttributeSelectors(false)
+ : m_affectedByAttributeSelectors(false)
, m_unique(false)
, m_affectedByEmpty(false)
, m_emptyState(false)
@@ -71,9 +71,9 @@ RenderStyle::RenderStyle()
, m_firstChildState(false)
, m_lastChildState(false)
, m_childIndex(0)
- , box(defaultStyle()->box)
+ , m_box(defaultStyle()->m_box)
, visual(defaultStyle()->visual)
- , background(defaultStyle()->background)
+ , m_background(defaultStyle()->m_background)
, surround(defaultStyle()->surround)
, rareNonInheritedData(defaultStyle()->rareNonInheritedData)
, rareInheritedData(defaultStyle()->rareInheritedData)
@@ -86,8 +86,7 @@ RenderStyle::RenderStyle()
}
RenderStyle::RenderStyle(bool)
- : m_pseudoState(PseudoUnknown)
- , m_affectedByAttributeSelectors(false)
+ : m_affectedByAttributeSelectors(false)
, m_unique(false)
, m_affectedByEmpty(false)
, m_emptyState(false)
@@ -102,9 +101,9 @@ RenderStyle::RenderStyle(bool)
{
setBitDefaults();
- box.init();
+ m_box.init();
visual.init();
- background.init();
+ m_background.init();
surround.init();
rareNonInheritedData.init();
rareNonInheritedData.access()->flexibleBox.init();
@@ -121,7 +120,6 @@ RenderStyle::RenderStyle(bool)
RenderStyle::RenderStyle(const RenderStyle& o)
: RefCounted<RenderStyle>()
- , m_pseudoState(o.m_pseudoState)
, m_affectedByAttributeSelectors(false)
, m_unique(false)
, m_affectedByEmpty(false)
@@ -134,9 +132,9 @@ RenderStyle::RenderStyle(const RenderStyle& o)
, m_firstChildState(false)
, m_lastChildState(false)
, m_childIndex(0)
- , box(o.box)
+ , m_box(o.m_box)
, visual(o.visual)
- , background(o.background)
+ , m_background(o.m_background)
, surround(o.surround)
, rareNonInheritedData(o.rareNonInheritedData)
, rareInheritedData(o.rareInheritedData)
@@ -169,9 +167,9 @@ bool RenderStyle::operator==(const RenderStyle& o) const
// compare everything except the pseudoStyle pointer
return inherited_flags == o.inherited_flags &&
noninherited_flags == o.noninherited_flags &&
- box == o.box &&
+ m_box == o.m_box &&
visual == o.visual &&
- background == o.background &&
+ m_background == o.m_background &&
surround == o.surround &&
rareNonInheritedData == o.rareNonInheritedData &&
rareInheritedData == o.rareInheritedData &&
@@ -213,28 +211,39 @@ void RenderStyle::setHasPseudoStyle(PseudoId pseudo)
RenderStyle* RenderStyle::getCachedPseudoStyle(PseudoId pid) const
{
- if (!m_cachedPseudoStyle || styleType() != NOPSEUDO)
+ ASSERT(styleType() != VISITED_LINK);
+
+ if (!m_cachedPseudoStyles || !m_cachedPseudoStyles->size())
+ return 0;
+
+ if (styleType() != NOPSEUDO) {
+ if (pid == VISITED_LINK)
+ return m_cachedPseudoStyles->at(0)->styleType() == VISITED_LINK ? m_cachedPseudoStyles->at(0).get() : 0;
return 0;
- RenderStyle* ps = m_cachedPseudoStyle.get();
- while (ps && ps->styleType() != pid)
- ps = ps->m_cachedPseudoStyle.get();
- return ps;
+ }
+
+ for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
+ RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
+ if (pseudoStyle->styleType() == pid)
+ return pseudoStyle;
+ }
+
+ return 0;
}
RenderStyle* RenderStyle::addCachedPseudoStyle(PassRefPtr<RenderStyle> pseudo)
{
if (!pseudo)
return 0;
- pseudo->m_cachedPseudoStyle = m_cachedPseudoStyle;
- m_cachedPseudoStyle = pseudo;
- return m_cachedPseudoStyle.get();
-}
+
+ RenderStyle* result = pseudo.get();
-void RenderStyle::getPseudoStyleCache(PseudoStyleCache& cache) const
-{
- ASSERT(cache.isEmpty());
- for (RenderStyle* pseudoStyle = m_cachedPseudoStyle.get(); pseudoStyle; pseudoStyle = pseudoStyle->m_cachedPseudoStyle.get())
- cache.append(pseudoStyle);
+ if (!m_cachedPseudoStyles)
+ m_cachedPseudoStyles.set(new PseudoStyleCache);
+
+ m_cachedPseudoStyles->append(pseudo);
+
+ return result;
}
bool RenderStyle::inheritedNotEqual(const RenderStyle* other) const
@@ -297,18 +306,18 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
return StyleDifferenceLayout;
#endif
- if (box->width != other->box->width ||
- box->min_width != other->box->min_width ||
- box->max_width != other->box->max_width ||
- box->height != other->box->height ||
- box->min_height != other->box->min_height ||
- box->max_height != other->box->max_height)
+ if (m_box->width() != other->m_box->width() ||
+ m_box->minWidth() != other->m_box->minWidth() ||
+ m_box->maxWidth() != other->m_box->maxWidth() ||
+ m_box->height() != other->m_box->height() ||
+ m_box->minHeight() != other->m_box->minHeight() ||
+ m_box->maxHeight() != other->m_box->maxHeight())
return StyleDifferenceLayout;
- if (box->vertical_align != other->box->vertical_align || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align)
+ if (m_box->verticalAlign() != other->m_box->verticalAlign() || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align)
return StyleDifferenceLayout;
- if (box->boxSizing != other->box->boxSizing)
+ if (m_box->boxSizing() != other->m_box->boxSizing())
return StyleDifferenceLayout;
if (surround->margin != other->surround->margin)
@@ -480,7 +489,7 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
// return RepaintLayer;
//else
return StyleDifferenceLayout;
- } else if (box->z_index != other->box->z_index || box->z_auto != other->box->z_auto ||
+ } else if (m_box->zIndex() != other->m_box->zIndex() || m_box->hasAutoZIndex() != other->m_box->hasAutoZIndex() ||
visual->clip != other->visual->clip || visual->hasClip != other->visual->hasClip)
return StyleDifferenceRepaintLayer;
}
@@ -502,8 +511,9 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
inherited_flags._visibility != other->inherited_flags._visibility ||
inherited_flags._text_decorations != other->inherited_flags._text_decorations ||
inherited_flags._force_backgrounds_to_white != other->inherited_flags._force_backgrounds_to_white ||
+ inherited_flags._insideLink != other->inherited_flags._insideLink ||
surround->border != other->surround->border ||
- *background.get() != *other->background.get() ||
+ *m_background.get() != *other->m_background.get() ||
visual->textDecoration != other->visual->textDecoration ||
rareInheritedData->userModify != other->rareInheritedData->userModify ||
rareInheritedData->userSelect != other->rareInheritedData->userSelect ||
@@ -543,12 +553,9 @@ void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)
void RenderStyle::addCursor(CachedImage* image, const IntPoint& hotSpot)
{
- CursorData data;
- data.cursorImage = image;
- data.hotSpot = hotSpot;
if (!inherited.access()->cursorData)
inherited.access()->cursorData = CursorList::create();
- inherited.access()->cursorData->append(data);
+ inherited.access()->cursorData->append(CursorData(image, hotSpot));
}
void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
@@ -707,7 +714,7 @@ void RenderStyle::addBindingURI(StringImpl* uri)
void RenderStyle::setTextShadow(ShadowData* val, bool add)
{
- ASSERT(!val || (!val->spread && val->style == Normal));
+ ASSERT(!val || (!val->spread() && val->style() == Normal));
StyleRareInheritedData* rareData = rareInheritedData.access();
if (!add) {
@@ -716,7 +723,7 @@ void RenderStyle::setTextShadow(ShadowData* val, bool add)
return;
}
- val->next = rareData->textShadow;
+ val->setNext(rareData->textShadow);
rareData->textShadow = val;
}
@@ -728,17 +735,17 @@ void RenderStyle::setBoxShadow(ShadowData* shadowData, bool add)
return;
}
- shadowData->next = rareData->m_boxShadow.release();
+ shadowData->setNext(rareData->m_boxShadow.release());
rareData->m_boxShadow.set(shadowData);
}
void RenderStyle::getBorderRadiiForRect(const IntRect& r, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight) const
{
- topLeft = surround->border.topLeft;
- topRight = surround->border.topRight;
+ topLeft = surround->border.topLeft();
+ topRight = surround->border.topRight();
- bottomLeft = surround->border.bottomLeft;
- bottomRight = surround->border.bottomRight;
+ bottomLeft = surround->border.bottomLeft();
+ bottomRight = surround->border.bottomRight();
// Constrain corner radii using CSS3 rules:
// http://www.w3.org/TR/css3-background/#the-border-radius
@@ -925,15 +932,15 @@ void RenderStyle::getBoxShadowExtent(int &top, int &right, int &bottom, int &lef
bottom = 0;
left = 0;
- for (ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
- if (boxShadow->style == Inset)
+ for (const ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next()) {
+ if (boxShadow->style() == Inset)
continue;
- int blurAndSpread = boxShadow->blur + boxShadow->spread;
+ int blurAndSpread = boxShadow->blur() + boxShadow->spread();
- top = min(top, boxShadow->y - blurAndSpread);
- right = max(right, boxShadow->x + blurAndSpread);
- bottom = max(bottom, boxShadow->y + blurAndSpread);
- left = min(left, boxShadow->x - blurAndSpread);
+ top = min(top, boxShadow->y() - blurAndSpread);
+ right = max(right, boxShadow->x() + blurAndSpread);
+ bottom = max(bottom, boxShadow->y() + blurAndSpread);
+ left = min(left, boxShadow->x() - blurAndSpread);
}
}
@@ -942,13 +949,13 @@ void RenderStyle::getBoxShadowHorizontalExtent(int &left, int &right) const
left = 0;
right = 0;
- for (ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
- if (boxShadow->style == Inset)
+ for (const ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next()) {
+ if (boxShadow->style() == Inset)
continue;
- int blurAndSpread = boxShadow->blur + boxShadow->spread;
+ int blurAndSpread = boxShadow->blur() + boxShadow->spread();
- left = min(left, boxShadow->x - blurAndSpread);
- right = max(right, boxShadow->x + blurAndSpread);
+ left = min(left, boxShadow->x() - blurAndSpread);
+ right = max(right, boxShadow->x() + blurAndSpread);
}
}
@@ -957,14 +964,108 @@ void RenderStyle::getBoxShadowVerticalExtent(int &top, int &bottom) const
top = 0;
bottom = 0;
- for (ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
- if (boxShadow->style == Inset)
+ for (const ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next()) {
+ if (boxShadow->style() == Inset)
continue;
- int blurAndSpread = boxShadow->blur + boxShadow->spread;
+ int blurAndSpread = boxShadow->blur() + boxShadow->spread();
- top = min(top, boxShadow->y - blurAndSpread);
- bottom = max(bottom, boxShadow->y + blurAndSpread);
+ top = min(top, boxShadow->y() - blurAndSpread);
+ bottom = max(bottom, boxShadow->y() + blurAndSpread);
}
}
+static EBorderStyle borderStyleForColorProperty(const RenderStyle* style, int colorProperty)
+{
+ EBorderStyle borderStyle;
+ switch (colorProperty) {
+ case CSSPropertyBorderLeftColor:
+ borderStyle = style->borderLeftStyle();
+ break;
+ case CSSPropertyBorderRightColor:
+ borderStyle = style->borderRightStyle();
+ break;
+ case CSSPropertyBorderTopColor:
+ borderStyle = style->borderTopStyle();
+ break;
+ case CSSPropertyBorderBottomColor:
+ borderStyle = style->borderBottomStyle();
+ break;
+ default:
+ borderStyle = BNONE;
+ break;
+ }
+ return borderStyle;
+}
+
+static Color colorIncludingFallback(const RenderStyle* style, int colorProperty, EBorderStyle borderStyle)
+{
+ Color result;
+ switch (colorProperty) {
+ case CSSPropertyBackgroundColor:
+ return style->backgroundColor(); // Background color doesn't fall back.
+ case CSSPropertyBorderLeftColor:
+ result = style->borderLeftColor();
+ borderStyle = style->borderLeftStyle();
+ break;
+ case CSSPropertyBorderRightColor:
+ result = style->borderRightColor();
+ borderStyle = style->borderRightStyle();
+ break;
+ case CSSPropertyBorderTopColor:
+ result = style->borderTopColor();
+ borderStyle = style->borderTopStyle();
+ break;
+ case CSSPropertyBorderBottomColor:
+ result = style->borderBottomColor();
+ borderStyle = style->borderBottomStyle();
+ break;
+ case CSSPropertyColor:
+ result = style->color();
+ break;
+ case CSSPropertyOutlineColor:
+ result = style->outlineColor();
+ break;
+ case CSSPropertyWebkitColumnRuleColor:
+ result = style->columnRuleColor();
+ break;
+ case CSSPropertyWebkitTextFillColor:
+ result = style->textFillColor();
+ break;
+ case CSSPropertyWebkitTextStrokeColor:
+ result = style->textStrokeColor();
+ break;
+ default:
+ // FIXME: Add SVG fill and stroke.
+ ASSERT_NOT_REACHED();
+ break;
+ }
+
+ if (!result.isValid()) {
+ if ((colorProperty == CSSPropertyBorderLeftColor || colorProperty == CSSPropertyBorderRightColor
+ || colorProperty == CSSPropertyBorderTopColor || colorProperty == CSSPropertyBorderBottomColor)
+ && (borderStyle == INSET || borderStyle == OUTSET || borderStyle == RIDGE || borderStyle == GROOVE))
+ result.setRGB(238, 238, 238);
+ else
+ result = style->color();
+ }
+
+ return result;
+}
+
+Color RenderStyle::visitedDependentColor(int colorProperty) const
+{
+ EBorderStyle borderStyle = borderStyleForColorProperty(this, colorProperty);
+ Color unvisitedColor = colorIncludingFallback(this, colorProperty, borderStyle);
+ if (insideLink() != InsideVisitedLink)
+ return unvisitedColor;
+
+ RenderStyle* visitedStyle = getCachedPseudoStyle(VISITED_LINK);
+ if (!visitedStyle)
+ return unvisitedColor;
+ Color visitedColor = colorIncludingFallback(visitedStyle, colorProperty, borderStyle);
+
+ // Take the alpha from the unvisited color, but get the RGB values from the visited color.
+ return Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), unvisitedColor.alpha());
+}
+
} // namespace WebCore
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index c7db254..fe42339 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -110,13 +110,14 @@ class Pair;
class StringImpl;
class StyleImage;
+typedef Vector<RefPtr<RenderStyle>, 4> PseudoStyleCache;
+
class RenderStyle: public RefCounted<RenderStyle> {
friend class CSSStyleSelector;
protected:
// The following bitfield is 32-bits long, which optimizes padding with the
// int refCount in the base class. Beware when adding more bits.
- unsigned m_pseudoState : 3; // PseudoState
bool m_affectedByAttributeSelectors : 1;
bool m_unique : 1;
@@ -133,12 +134,12 @@ protected:
bool m_childrenAffectedByBackwardPositionalRules : 1;
bool m_firstChildState : 1;
bool m_lastChildState : 1;
- unsigned m_childIndex : 18; // Plenty of bits to cache an index.
+ unsigned m_childIndex : 21; // Plenty of bits to cache an index.
// non-inherited attributes
- DataRef<StyleBoxData> box;
+ DataRef<StyleBoxData> m_box;
DataRef<StyleVisualData> visual;
- DataRef<StyleBackgroundData> background;
+ DataRef<StyleBackgroundData> m_background;
DataRef<StyleSurroundData> surround;
DataRef<StyleRareNonInheritedData> rareNonInheritedData;
@@ -147,7 +148,7 @@ protected:
DataRef<StyleInheritedData> inherited;
// list of associated pseudo styles
- RefPtr<RenderStyle> m_cachedPseudoStyle;
+ OwnPtr<PseudoStyleCache> m_cachedPseudoStyles;
#if ENABLE(SVG)
DataRef<SVGRenderStyle> m_svgStyle;
@@ -176,7 +177,8 @@ protected:
(_visuallyOrdered == other._visuallyOrdered) &&
(_htmlHacks == other._htmlHacks) &&
(_force_backgrounds_to_white == other._force_backgrounds_to_white) &&
- (_pointerEvents == other._pointerEvents);
+ (_pointerEvents == other._pointerEvents) &&
+ (_insideLink == other._insideLink);
}
bool operator!=(const InheritedFlags& other) const { return !(*this == other); }
@@ -201,7 +203,8 @@ protected:
bool _htmlHacks : 1;
bool _force_backgrounds_to_white : 1;
unsigned _pointerEvents : 4; // EPointerEvents
- // 41 bits
+ unsigned _insideLink : 2; // EInsideLink
+ // 43 bits
} inherited_flags;
// don't inherit
@@ -225,7 +228,8 @@ protected:
&& _affectedByActive == other._affectedByActive
&& _affectedByDrag == other._affectedByDrag
&& _pseudoBits == other._pseudoBits
- && _unicodeBidi == other._unicodeBidi;
+ && _unicodeBidi == other._unicodeBidi
+ && _isLink == other._isLink;
}
bool operator!=(const NonInheritedFlags& other) const { return !(*this == other); }
@@ -244,12 +248,13 @@ protected:
unsigned _page_break_after : 2; // EPageBreak
unsigned _page_break_inside : 2; // EPageBreak
- unsigned _styleType : 5; // PseudoId
+ unsigned _styleType : 6; // PseudoId
bool _affectedByHover : 1;
bool _affectedByActive : 1;
bool _affectedByDrag : 1;
unsigned _pseudoBits : 7;
unsigned _unicodeBidi : 2; // EUnicodeBidi
+ bool _isLink : 1;
// 50 bits
} noninherited_flags;
@@ -275,6 +280,7 @@ protected:
inherited_flags._box_direction = initialBoxDirection();
inherited_flags._force_backgrounds_to_white = false;
inherited_flags._pointerEvents = initialPointerEvents();
+ inherited_flags._insideLink = NotInsideLink;
noninherited_flags._effectiveDisplay = noninherited_flags._originalDisplay = initialDisplay();
noninherited_flags._overflowX = initialOverflowX();
@@ -293,6 +299,7 @@ protected:
noninherited_flags._affectedByDrag = false;
noninherited_flags._pseudoBits = 0;
noninherited_flags._unicodeBidi = initialUnicodeBidi();
+ noninherited_flags._isLink = false;
}
protected:
@@ -316,8 +323,7 @@ public:
RenderStyle* getCachedPseudoStyle(PseudoId) const;
RenderStyle* addCachedPseudoStyle(PassRefPtr<RenderStyle>);
- typedef Vector<RenderStyle*, 10> PseudoStyleCache;
- void getPseudoStyleCache(PseudoStyleCache&) const;
+ const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); }
bool affectedByHoverRules() const { return noninherited_flags._affectedByHover; }
bool affectedByActiveRules() const { return noninherited_flags._affectedByActive; }
@@ -339,10 +345,10 @@ public:
{
if (backgroundColor().isValid() && backgroundColor().alpha() > 0)
return true;
- return background->m_background.hasImage();
+ return m_background->background().hasImage();
}
- bool hasBackgroundImage() const { return background->m_background.hasImage(); }
- bool hasFixedBackgroundImage() const { return background->m_background.hasFixedImage(); }
+ bool hasBackgroundImage() const { return m_background->background().hasImage(); }
+ bool hasFixedBackgroundImage() const { return m_background->background().hasFixedImage(); }
bool hasAppearance() const { return appearance() != NoControlPart; }
bool visuallyOrdered() const { return inherited_flags._visuallyOrdered; }
@@ -372,62 +378,62 @@ public:
EPosition position() const { return static_cast<EPosition>(noninherited_flags._position); }
EFloat floating() const { return static_cast<EFloat>(noninherited_flags._floating); }
- Length width() const { return box->width; }
- Length height() const { return box->height; }
- Length minWidth() const { return box->min_width; }
- Length maxWidth() const { return box->max_width; }
- Length minHeight() const { return box->min_height; }
- Length maxHeight() const { return box->max_height; }
+ Length width() const { return m_box->width(); }
+ Length height() const { return m_box->height(); }
+ Length minWidth() const { return m_box->minWidth(); }
+ Length maxWidth() const { return m_box->maxWidth(); }
+ Length minHeight() const { return m_box->minHeight(); }
+ Length maxHeight() const { return m_box->maxHeight(); }
const BorderData& border() const { return surround->border; }
- const BorderValue& borderLeft() const { return surround->border.left; }
- const BorderValue& borderRight() const { return surround->border.right; }
- const BorderValue& borderTop() const { return surround->border.top; }
- const BorderValue& borderBottom() const { return surround->border.bottom; }
+ const BorderValue& borderLeft() const { return surround->border.left(); }
+ const BorderValue& borderRight() const { return surround->border.right(); }
+ const BorderValue& borderTop() const { return surround->border.top(); }
+ const BorderValue& borderBottom() const { return surround->border.bottom(); }
- const NinePieceImage& borderImage() const { return surround->border.image; }
+ const NinePieceImage& borderImage() const { return surround->border.image(); }
- const IntSize& borderTopLeftRadius() const { return surround->border.topLeft; }
- const IntSize& borderTopRightRadius() const { return surround->border.topRight; }
- const IntSize& borderBottomLeftRadius() const { return surround->border.bottomLeft; }
- const IntSize& borderBottomRightRadius() const { return surround->border.bottomRight; }
+ const IntSize& borderTopLeftRadius() const { return surround->border.topLeft(); }
+ const IntSize& borderTopRightRadius() const { return surround->border.topRight(); }
+ const IntSize& borderBottomLeftRadius() const { return surround->border.bottomLeft(); }
+ const IntSize& borderBottomRightRadius() const { return surround->border.bottomRight(); }
bool hasBorderRadius() const { return surround->border.hasBorderRadius(); }
unsigned short borderLeftWidth() const { return surround->border.borderLeftWidth(); }
- EBorderStyle borderLeftStyle() const { return surround->border.left.style(); }
- const Color& borderLeftColor() const { return surround->border.left.color; }
- bool borderLeftIsTransparent() const { return surround->border.left.isTransparent(); }
+ EBorderStyle borderLeftStyle() const { return surround->border.left().style(); }
+ const Color& borderLeftColor() const { return surround->border.left().color(); }
+ bool borderLeftIsTransparent() const { return surround->border.left().isTransparent(); }
unsigned short borderRightWidth() const { return surround->border.borderRightWidth(); }
- EBorderStyle borderRightStyle() const { return surround->border.right.style(); }
- const Color& borderRightColor() const { return surround->border.right.color; }
- bool borderRightIsTransparent() const { return surround->border.right.isTransparent(); }
+ EBorderStyle borderRightStyle() const { return surround->border.right().style(); }
+ const Color& borderRightColor() const { return surround->border.right().color(); }
+ bool borderRightIsTransparent() const { return surround->border.right().isTransparent(); }
unsigned short borderTopWidth() const { return surround->border.borderTopWidth(); }
- EBorderStyle borderTopStyle() const { return surround->border.top.style(); }
- const Color& borderTopColor() const { return surround->border.top.color; }
- bool borderTopIsTransparent() const { return surround->border.top.isTransparent(); }
+ EBorderStyle borderTopStyle() const { return surround->border.top().style(); }
+ const Color& borderTopColor() const { return surround->border.top().color(); }
+ bool borderTopIsTransparent() const { return surround->border.top().isTransparent(); }
unsigned short borderBottomWidth() const { return surround->border.borderBottomWidth(); }
- EBorderStyle borderBottomStyle() const { return surround->border.bottom.style(); }
- const Color& borderBottomColor() const { return surround->border.bottom.color; }
- bool borderBottomIsTransparent() const { return surround->border.bottom.isTransparent(); }
+ EBorderStyle borderBottomStyle() const { return surround->border.bottom().style(); }
+ const Color& borderBottomColor() const { return surround->border.bottom().color(); }
+ bool borderBottomIsTransparent() const { return surround->border.bottom().isTransparent(); }
unsigned short outlineSize() const { return max(0, outlineWidth() + outlineOffset()); }
unsigned short outlineWidth() const
{
- if (background->m_outline.style() == BNONE)
+ if (m_background->outline().style() == BNONE)
return 0;
- return background->m_outline.width;
+ return m_background->outline().width();
}
bool hasOutline() const { return outlineWidth() > 0 && outlineStyle() > BHIDDEN; }
- EBorderStyle outlineStyle() const { return background->m_outline.style(); }
- bool outlineStyleIsAuto() const { return background->m_outline._auto; }
- const Color& outlineColor() const { return background->m_outline.color; }
+ EBorderStyle outlineStyle() const { return m_background->outline().style(); }
+ bool outlineStyleIsAuto() const { return m_background->outline().isAuto(); }
+ const Color& outlineColor() const { return m_background->outline().color(); }
EOverflow overflowX() const { return static_cast<EOverflow>(noninherited_flags._overflowX); }
EOverflow overflowY() const { return static_cast<EOverflow>(noninherited_flags._overflowY); }
EVisibility visibility() const { return static_cast<EVisibility>(inherited_flags._visibility); }
EVerticalAlign verticalAlign() const { return static_cast<EVerticalAlign>(noninherited_flags._vertical_align); }
- Length verticalAlignLength() const { return box->vertical_align; }
+ Length verticalAlignLength() const { return m_box->verticalAlign(); }
Length clipLeft() const { return visual->clip.left(); }
Length clipRight() const { return visual->clip.right(); }
@@ -529,31 +535,32 @@ public:
return wordBreak() == BreakWordBreak || wordWrap() == BreakWordWrap;
}
- const Color& backgroundColor() const { return background->m_color; }
- StyleImage* backgroundImage() const { return background->m_background.m_image.get(); }
- EFillRepeat backgroundRepeatX() const { return static_cast<EFillRepeat>(background->m_background.m_repeatX); }
- EFillRepeat backgroundRepeatY() const { return static_cast<EFillRepeat>(background->m_background.m_repeatY); }
- CompositeOperator backgroundComposite() const { return static_cast<CompositeOperator>(background->m_background.m_composite); }
- EFillAttachment backgroundAttachment() const { return static_cast<EFillAttachment>(background->m_background.m_attachment); }
- EFillBox backgroundClip() const { return static_cast<EFillBox>(background->m_background.m_clip); }
- EFillBox backgroundOrigin() const { return static_cast<EFillBox>(background->m_background.m_origin); }
- Length backgroundXPosition() const { return background->m_background.m_xPosition; }
- Length backgroundYPosition() const { return background->m_background.m_yPosition; }
- EFillSizeType backgroundSizeType() const { return static_cast<EFillSizeType>(background->m_background.m_sizeType); }
- LengthSize backgroundSizeLength() const { return background->m_background.m_sizeLength; }
- FillLayer* accessBackgroundLayers() { return &(background.access()->m_background); }
- const FillLayer* backgroundLayers() const { return &(background->m_background); }
-
- StyleImage* maskImage() const { return rareNonInheritedData->m_mask.m_image.get(); }
- EFillRepeat maskRepeatX() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.m_repeatX); }
- EFillRepeat maskRepeatY() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.m_repeatY); }
- CompositeOperator maskComposite() const { return static_cast<CompositeOperator>(rareNonInheritedData->m_mask.m_composite); }
- EFillAttachment maskAttachment() const { return static_cast<EFillAttachment>(rareNonInheritedData->m_mask.m_attachment); }
- EFillBox maskClip() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.m_clip); }
- EFillBox maskOrigin() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.m_origin); }
- Length maskXPosition() const { return rareNonInheritedData->m_mask.m_xPosition; }
- Length maskYPosition() const { return rareNonInheritedData->m_mask.m_yPosition; }
- LengthSize maskSize() const { return rareNonInheritedData->m_mask.m_sizeLength; }
+ const Color& backgroundColor() const { return m_background->color(); }
+ StyleImage* backgroundImage() const { return m_background->background().image(); }
+ EFillRepeat backgroundRepeatX() const { return static_cast<EFillRepeat>(m_background->background().repeatX()); }
+ EFillRepeat backgroundRepeatY() const { return static_cast<EFillRepeat>(m_background->background().repeatY()); }
+ CompositeOperator backgroundComposite() const { return static_cast<CompositeOperator>(m_background->background().composite()); }
+ EFillAttachment backgroundAttachment() const { return static_cast<EFillAttachment>(m_background->background().attachment()); }
+ EFillBox backgroundClip() const { return static_cast<EFillBox>(m_background->background().clip()); }
+ EFillBox backgroundOrigin() const { return static_cast<EFillBox>(m_background->background().origin()); }
+ Length backgroundXPosition() const { return m_background->background().xPosition(); }
+ Length backgroundYPosition() const { return m_background->background().yPosition(); }
+ EFillSizeType backgroundSizeType() const { return m_background->background().sizeType(); }
+ LengthSize backgroundSizeLength() const { return m_background->background().sizeLength(); }
+ FillLayer* accessBackgroundLayers() { return &(m_background.access()->m_background); }
+ const FillLayer* backgroundLayers() const { return &(m_background->background()); }
+
+ StyleImage* maskImage() const { return rareNonInheritedData->m_mask.image(); }
+ EFillRepeat maskRepeatX() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.repeatX()); }
+ EFillRepeat maskRepeatY() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.repeatY()); }
+ CompositeOperator maskComposite() const { return static_cast<CompositeOperator>(rareNonInheritedData->m_mask.composite()); }
+ EFillAttachment maskAttachment() const { return static_cast<EFillAttachment>(rareNonInheritedData->m_mask.attachment()); }
+ EFillBox maskClip() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.clip()); }
+ EFillBox maskOrigin() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.origin()); }
+ Length maskXPosition() const { return rareNonInheritedData->m_mask.xPosition(); }
+ Length maskYPosition() const { return rareNonInheritedData->m_mask.yPosition(); }
+ EFillSizeType maskSizeType() const { return rareNonInheritedData->m_mask.sizeType(); }
+ LengthSize maskSizeLength() const { return rareNonInheritedData->m_mask.sizeLength(); }
FillLayer* accessMaskLayers() { return &(rareNonInheritedData.access()->m_mask); }
const FillLayer* maskLayers() const { return &(rareNonInheritedData->m_mask); }
const NinePieceImage& maskBoxImage() const { return rareNonInheritedData->m_maskBoxImage; }
@@ -587,6 +594,9 @@ public:
CursorList* cursors() const { return inherited->cursorData.get(); }
+ EInsideLink insideLink() const { return static_cast<EInsideLink>(inherited_flags._insideLink); }
+ bool isLink() const { return noninherited_flags._isLink; }
+
short widows() const { return inherited->widows; }
short orphans() const { return inherited->orphans; }
EPageBreak pageBreakInside() const { return static_cast<EPageBreak>(noninherited_flags._page_break_inside); }
@@ -600,12 +610,12 @@ public:
int outlineOffset() const
{
- if (background->m_outline.style() == BNONE)
+ if (m_background->outline().style() == BNONE)
return 0;
- return background->m_outline._offset;
+ return m_background->outline().offset();
}
- ShadowData* textShadow() const { return rareInheritedData->textShadow; }
+ const ShadowData* textShadow() const { return rareInheritedData->textShadow; }
const Color& textStrokeColor() const { return rareInheritedData->textStrokeColor; }
float textStrokeWidth() const { return rareInheritedData->textStrokeWidth; }
const Color& textFillColor() const { return rareInheritedData->textFillColor; }
@@ -621,13 +631,13 @@ public:
EBoxOrient boxOrient() const { return static_cast<EBoxOrient>(rareNonInheritedData->flexibleBox->orient); }
EBoxAlignment boxPack() const { return static_cast<EBoxAlignment>(rareNonInheritedData->flexibleBox->pack); }
- ShadowData* boxShadow() const { return rareNonInheritedData->m_boxShadow.get(); }
+ const ShadowData* boxShadow() const { return rareNonInheritedData->m_boxShadow.get(); }
void getBoxShadowExtent(int &top, int &right, int &bottom, int &left) const;
void getBoxShadowHorizontalExtent(int &left, int &right) const;
void getBoxShadowVerticalExtent(int &top, int &bottom) const;
StyleReflection* boxReflect() const { return rareNonInheritedData->m_boxReflect.get(); }
- EBoxSizing boxSizing() const { return static_cast<EBoxSizing>(box->boxSizing); }
+ EBoxSizing boxSizing() const { return m_box->boxSizing(); }
Length marqueeIncrement() const { return rareNonInheritedData->marquee->increment; }
int marqueeSpeed() const { return rareNonInheritedData->marquee->speed; }
int marqueeLoopCount() const { return rareNonInheritedData->marquee->loops; }
@@ -653,7 +663,7 @@ public:
bool hasAutoColumnCount() const { return rareNonInheritedData->m_multiCol->m_autoCount; }
float columnGap() const { return rareNonInheritedData->m_multiCol->m_gap; }
bool hasNormalColumnGap() const { return rareNonInheritedData->m_multiCol->m_normalGap; }
- const Color& columnRuleColor() const { return rareNonInheritedData->m_multiCol->m_rule.color; }
+ const Color& columnRuleColor() const { return rareNonInheritedData->m_multiCol->m_rule.color(); }
EBorderStyle columnRuleStyle() const { return rareNonInheritedData->m_multiCol->m_rule.style(); }
unsigned short columnRuleWidth() const { return rareNonInheritedData->m_multiCol->ruleWidth(); }
bool columnRuleIsTransparent() const { return rareNonInheritedData->m_multiCol->m_rule.isTransparent(); }
@@ -724,13 +734,13 @@ public:
void setTop(Length v) { SET_VAR(surround, offset.m_top, v) }
void setBottom(Length v) { SET_VAR(surround, offset.m_bottom, v) }
- void setWidth(Length v) { SET_VAR(box, width, v) }
- void setHeight(Length v) { SET_VAR(box, height, v) }
+ void setWidth(Length v) { SET_VAR(m_box, m_width, v) }
+ void setHeight(Length v) { SET_VAR(m_box, m_height, v) }
- void setMinWidth(Length v) { SET_VAR(box, min_width, v) }
- void setMaxWidth(Length v) { SET_VAR(box, max_width, v) }
- void setMinHeight(Length v) { SET_VAR(box, min_height, v) }
- void setMaxHeight(Length v) { SET_VAR(box, max_height, v) }
+ void setMinWidth(Length v) { SET_VAR(m_box, m_minWidth, v) }
+ void setMaxWidth(Length v) { SET_VAR(m_box, m_maxWidth, v) }
+ void setMinHeight(Length v) { SET_VAR(m_box, m_minHeight, v) }
+ void setMaxHeight(Length v) { SET_VAR(m_box, m_maxHeight, v) }
#if ENABLE(DASHBOARD_SUPPORT)
Vector<StyleDashboardRegion> dashboardRegions() const { return rareNonInheritedData->m_dashboardRegions; }
@@ -752,32 +762,32 @@ public:
#endif
void resetBorder() { resetBorderImage(); resetBorderTop(); resetBorderRight(); resetBorderBottom(); resetBorderLeft(); resetBorderRadius(); }
- void resetBorderTop() { SET_VAR(surround, border.top, BorderValue()) }
- void resetBorderRight() { SET_VAR(surround, border.right, BorderValue()) }
- void resetBorderBottom() { SET_VAR(surround, border.bottom, BorderValue()) }
- void resetBorderLeft() { SET_VAR(surround, border.left, BorderValue()) }
- void resetBorderImage() { SET_VAR(surround, border.image, NinePieceImage()) }
+ void resetBorderTop() { SET_VAR(surround, border.m_top, BorderValue()) }
+ void resetBorderRight() { SET_VAR(surround, border.m_right, BorderValue()) }
+ void resetBorderBottom() { SET_VAR(surround, border.m_bottom, BorderValue()) }
+ void resetBorderLeft() { SET_VAR(surround, border.m_left, BorderValue()) }
+ void resetBorderImage() { SET_VAR(surround, border.m_image, NinePieceImage()) }
void resetBorderRadius() { resetBorderTopLeftRadius(); resetBorderTopRightRadius(); resetBorderBottomLeftRadius(); resetBorderBottomRightRadius(); }
- void resetBorderTopLeftRadius() { SET_VAR(surround, border.topLeft, initialBorderRadius()) }
- void resetBorderTopRightRadius() { SET_VAR(surround, border.topRight, initialBorderRadius()) }
- void resetBorderBottomLeftRadius() { SET_VAR(surround, border.bottomLeft, initialBorderRadius()) }
- void resetBorderBottomRightRadius() { SET_VAR(surround, border.bottomRight, initialBorderRadius()) }
+ void resetBorderTopLeftRadius() { SET_VAR(surround, border.m_topLeft, initialBorderRadius()) }
+ void resetBorderTopRightRadius() { SET_VAR(surround, border.m_topRight, initialBorderRadius()) }
+ void resetBorderBottomLeftRadius() { SET_VAR(surround, border.m_bottomLeft, initialBorderRadius()) }
+ void resetBorderBottomRightRadius() { SET_VAR(surround, border.m_bottomRight, initialBorderRadius()) }
- void resetOutline() { SET_VAR(background, m_outline, OutlineValue()) }
+ void resetOutline() { SET_VAR(m_background, m_outline, OutlineValue()) }
- void setBackgroundColor(const Color& v) { SET_VAR(background, m_color, v) }
+ void setBackgroundColor(const Color& v) { SET_VAR(m_background, m_color, v) }
- void setBackgroundXPosition(Length l) { SET_VAR(background, m_background.m_xPosition, l) }
- void setBackgroundYPosition(Length l) { SET_VAR(background, m_background.m_yPosition, l) }
- void setBackgroundSize(EFillSizeType b) { SET_VAR(background, m_background.m_sizeType, b) }
- void setBackgroundSizeLength(LengthSize l) { SET_VAR(background, m_background.m_sizeLength, l) }
+ void setBackgroundXPosition(Length l) { SET_VAR(m_background, m_background.m_xPosition, l) }
+ void setBackgroundYPosition(Length l) { SET_VAR(m_background, m_background.m_yPosition, l) }
+ void setBackgroundSize(EFillSizeType b) { SET_VAR(m_background, m_background.m_sizeType, b) }
+ void setBackgroundSizeLength(LengthSize l) { SET_VAR(m_background, m_background.m_sizeLength, l) }
- void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.image, b) }
+ void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.m_image, b) }
- void setBorderTopLeftRadius(const IntSize& s) { SET_VAR(surround, border.topLeft, s) }
- void setBorderTopRightRadius(const IntSize& s) { SET_VAR(surround, border.topRight, s) }
- void setBorderBottomLeftRadius(const IntSize& s) { SET_VAR(surround, border.bottomLeft, s) }
- void setBorderBottomRightRadius(const IntSize& s) { SET_VAR(surround, border.bottomRight, s) }
+ void setBorderTopLeftRadius(const IntSize& s) { SET_VAR(surround, border.m_topLeft, s) }
+ void setBorderTopRightRadius(const IntSize& s) { SET_VAR(surround, border.m_topRight, s) }
+ void setBorderBottomLeftRadius(const IntSize& s) { SET_VAR(surround, border.m_bottomLeft, s) }
+ void setBorderBottomRightRadius(const IntSize& s) { SET_VAR(surround, border.m_bottomRight, s) }
void setBorderRadius(const IntSize& s)
{
@@ -789,33 +799,33 @@ public:
void getBorderRadiiForRect(const IntRect&, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight) const;
- void setBorderLeftWidth(unsigned short v) { SET_VAR(surround, border.left.width, v) }
- void setBorderLeftStyle(EBorderStyle v) { SET_VAR(surround, border.left.m_style, v) }
- void setBorderLeftColor(const Color& v) { SET_VAR(surround, border.left.color, v) }
- void setBorderRightWidth(unsigned short v) { SET_VAR(surround, border.right.width, v) }
- void setBorderRightStyle(EBorderStyle v) { SET_VAR(surround, border.right.m_style, v) }
- void setBorderRightColor(const Color& v) { SET_VAR(surround, border.right.color, v) }
- void setBorderTopWidth(unsigned short v) { SET_VAR(surround, border.top.width, v) }
- void setBorderTopStyle(EBorderStyle v) { SET_VAR(surround, border.top.m_style, v) }
- void setBorderTopColor(const Color& v) { SET_VAR(surround, border.top.color, v) }
- void setBorderBottomWidth(unsigned short v) { SET_VAR(surround, border.bottom.width, v) }
- void setBorderBottomStyle(EBorderStyle v) { SET_VAR(surround, border.bottom.m_style, v) }
- void setBorderBottomColor(const Color& v) { SET_VAR(surround, border.bottom.color, v) }
- void setOutlineWidth(unsigned short v) { SET_VAR(background, m_outline.width, v) }
+ void setBorderLeftWidth(unsigned short v) { SET_VAR(surround, border.m_left.m_width, v) }
+ void setBorderLeftStyle(EBorderStyle v) { SET_VAR(surround, border.m_left.m_style, v) }
+ void setBorderLeftColor(const Color& v) { SET_VAR(surround, border.m_left.m_color, v) }
+ void setBorderRightWidth(unsigned short v) { SET_VAR(surround, border.m_right.m_width, v) }
+ void setBorderRightStyle(EBorderStyle v) { SET_VAR(surround, border.m_right.m_style, v) }
+ void setBorderRightColor(const Color& v) { SET_VAR(surround, border.m_right.m_color, v) }
+ void setBorderTopWidth(unsigned short v) { SET_VAR(surround, border.m_top.m_width, v) }
+ void setBorderTopStyle(EBorderStyle v) { SET_VAR(surround, border.m_top.m_style, v) }
+ void setBorderTopColor(const Color& v) { SET_VAR(surround, border.m_top.m_color, v) }
+ void setBorderBottomWidth(unsigned short v) { SET_VAR(surround, border.m_bottom.m_width, v) }
+ void setBorderBottomStyle(EBorderStyle v) { SET_VAR(surround, border.m_bottom.m_style, v) }
+ void setBorderBottomColor(const Color& v) { SET_VAR(surround, border.m_bottom.m_color, v) }
+ void setOutlineWidth(unsigned short v) { SET_VAR(m_background, m_outline.m_width, v) }
void setOutlineStyle(EBorderStyle v, bool isAuto = false)
{
- SET_VAR(background, m_outline.m_style, v)
- SET_VAR(background, m_outline._auto, isAuto)
+ SET_VAR(m_background, m_outline.m_style, v)
+ SET_VAR(m_background, m_outline.m_isAuto, isAuto)
}
- void setOutlineColor(const Color& v) { SET_VAR(background, m_outline.color, v) }
+ void setOutlineColor(const Color& v) { SET_VAR(m_background, m_outline.m_color, v) }
void setOverflowX(EOverflow v) { noninherited_flags._overflowX = v; }
void setOverflowY(EOverflow v) { noninherited_flags._overflowY = v; }
void setVisibility(EVisibility v) { inherited_flags._visibility = v; }
void setVerticalAlign(EVerticalAlign v) { noninherited_flags._vertical_align = v; }
- void setVerticalAlignLength(Length l) { SET_VAR(box, vertical_align, l) }
+ void setVerticalAlignLength(Length l) { SET_VAR(m_box, m_verticalAlign, l) }
void setHasClip(bool b = true) { SET_VAR(visual, hasClip, b) }
void setClipLeft(Length v) { SET_VAR(visual, clip.m_left, v) }
@@ -858,8 +868,8 @@ public:
void setWordSpacing(int v) { inherited.access()->font.setWordSpacing(v); }
void setLetterSpacing(int v) { inherited.access()->font.setLetterSpacing(v); }
- void clearBackgroundLayers() { background.access()->m_background = FillLayer(BackgroundFillLayer); }
- void inheritBackgroundLayers(const FillLayer& parent) { background.access()->m_background = parent; }
+ void clearBackgroundLayers() { m_background.access()->m_background = FillLayer(BackgroundFillLayer); }
+ void inheritBackgroundLayers(const FillLayer& parent) { m_background.access()->m_background = parent; }
void adjustBackgroundLayers()
{
@@ -916,16 +926,19 @@ public:
void setCursorList(PassRefPtr<CursorList>);
void clearCursorList();
+ void setInsideLink(EInsideLink insideLink) { inherited_flags._insideLink = insideLink; }
+ void setIsLink(bool b) { noninherited_flags._isLink = b; }
+
bool forceBackgroundsToWhite() const { return inherited_flags._force_backgrounds_to_white; }
void setForceBackgroundsToWhite(bool b=true) { inherited_flags._force_backgrounds_to_white = b; }
bool htmlHacks() const { return inherited_flags._htmlHacks; }
void setHtmlHacks(bool b=true) { inherited_flags._htmlHacks = b; }
- bool hasAutoZIndex() const { return box->z_auto; }
- void setHasAutoZIndex() { SET_VAR(box, z_auto, true); SET_VAR(box, z_index, 0) }
- int zIndex() const { return box->z_index; }
- void setZIndex(int v) { SET_VAR(box, z_auto, false); SET_VAR(box, z_index, v) }
+ bool hasAutoZIndex() const { return m_box->hasAutoZIndex(); }
+ void setHasAutoZIndex() { SET_VAR(m_box, m_hasAutoZIndex, true); SET_VAR(m_box, m_zIndex, 0) }
+ int zIndex() const { return m_box->zIndex(); }
+ void setZIndex(int v) { SET_VAR(m_box, m_hasAutoZIndex, false); SET_VAR(m_box, m_zIndex, v) }
void setWidows(short w) { SET_VAR(inherited, widows, w); }
void setOrphans(short o) { SET_VAR(inherited, orphans, o); }
@@ -940,7 +953,7 @@ public:
void addBindingURI(StringImpl* uri);
#endif
- void setOutlineOffset(int v) { SET_VAR(background, m_outline._offset, v) }
+ void setOutlineOffset(int v) { SET_VAR(m_background, m_outline.m_offset, v) }
void setTextShadow(ShadowData* val, bool add=false);
void setTextStrokeColor(const Color& c) { SET_VAR(rareInheritedData, textStrokeColor, c) }
void setTextStrokeWidth(float w) { SET_VAR(rareInheritedData, textStrokeWidth, w) }
@@ -958,7 +971,7 @@ public:
void setBoxPack(EBoxAlignment p) { SET_VAR(rareNonInheritedData.access()->flexibleBox, pack, p); }
void setBoxShadow(ShadowData* val, bool add=false);
void setBoxReflect(PassRefPtr<StyleReflection> reflect) { if (rareNonInheritedData->m_boxReflect != reflect) rareNonInheritedData.access()->m_boxReflect = reflect; }
- void setBoxSizing(EBoxSizing s) { SET_VAR(box, boxSizing, s); }
+ void setBoxSizing(EBoxSizing s) { SET_VAR(m_box, m_boxSizing, s); }
void setMarqueeIncrement(const Length& f) { SET_VAR(rareNonInheritedData.access()->marquee, increment, f); }
void setMarqueeSpeed(int f) { SET_VAR(rareNonInheritedData.access()->marquee, speed, f); }
void setMarqueeDirection(EMarqueeDirection d) { SET_VAR(rareNonInheritedData.access()->marquee, direction, d); }
@@ -984,9 +997,9 @@ public:
void setHasAutoColumnCount() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoCount, true); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_count, 0); }
void setColumnGap(float f) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_normalGap, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_gap, f); }
void setHasNormalColumnGap() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_normalGap, true); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_gap, 0); }
- void setColumnRuleColor(const Color& c) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule.color, c); }
+ void setColumnRuleColor(const Color& c) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule.m_color, c); }
void setColumnRuleStyle(EBorderStyle b) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule.m_style, b); }
- void setColumnRuleWidth(unsigned short w) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule.width, w); }
+ void setColumnRuleWidth(unsigned short w) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule.m_width, w); }
void resetColumnRule() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule, BorderValue()) }
void setColumnBreakBefore(EPageBreak p) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakBefore, p); }
void setColumnBreakInside(EPageBreak p) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakInside, p); }
@@ -1077,10 +1090,6 @@ public:
originalDisplay() == INLINE_BOX || originalDisplay() == INLINE_TABLE;
}
- // To obtain at any time the pseudo state for a given link.
- PseudoState pseudoState() const { return static_cast<PseudoState>(m_pseudoState); }
- void setPseudoState(PseudoState s) { m_pseudoState = s; }
-
// To tell if this style matched attribute selectors. This makes it impossible to share.
bool affectedByAttributeSelectors() const { return m_affectedByAttributeSelectors; }
void setAffectedByAttributeSelectors() { m_affectedByAttributeSelectors = true; }
@@ -1110,6 +1119,8 @@ public:
unsigned childIndex() const { return m_childIndex; }
void setChildIndex(unsigned index) { m_childIndex = index; }
+ Color visitedDependentColor(int colorProperty) const;
+
// Initial values for all the properties
static bool initialBorderCollapse() { return false; }
static EBorderStyle initialBorderStyle() { return BNONE; }
diff --git a/WebCore/rendering/style/RenderStyleConstants.h b/WebCore/rendering/style/RenderStyleConstants.h
index 4abbc1c..b899d57 100644
--- a/WebCore/rendering/style/RenderStyleConstants.h
+++ b/WebCore/rendering/style/RenderStyleConstants.h
@@ -74,8 +74,9 @@ 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,
+ INPUT_LIST_BUTTON, INNER_SPIN_BUTTON, OUTER_SPIN_BUTTON, VISITED_LINK,
+ AFTER_LAST_INTERNAL_PSEUDOID,
FIRST_PUBLIC_PSEUDOID = FIRST_LINE,
FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON,
PUBLIC_PSEUDOID_MASK = ((1 << FIRST_INTERNAL_PSEUDOID) - 1) & ~((1 << FIRST_PUBLIC_PSEUDOID) - 1)
@@ -87,8 +88,6 @@ enum EBorderStyle { BNONE, BHIDDEN, INSET, GROOVE, RIDGE, OUTSET, DOTTED, DASHED
enum EBorderPrecedence { BOFF, BTABLE, BCOLGROUP, BCOL, BROWGROUP, BROW, BCELL };
-enum PseudoState { PseudoUnknown, PseudoNone, PseudoAnyLink, PseudoLink, PseudoVisited};
-
enum EPosition {
StaticPosition, RelativePosition, AbsolutePosition, FixedPosition
};
@@ -97,7 +96,6 @@ enum EFloat {
FNONE = 0, FLEFT, FRIGHT
};
-
enum EMarginCollapse { MCOLLAPSE, MSEPARATE, MDISCARD };
// Box attributes. Not inherited.
@@ -293,6 +291,8 @@ enum StyleContentType {
enum EBorderFit { BorderFitBorder, BorderFitLines };
+enum EAnimationFillMode { AnimationFillModeNone, AnimationFillModeForwards, AnimationFillModeBackwards, AnimationFillModeBoth };
+
enum EAnimPlayState {
AnimPlayStatePlaying = 0x0,
AnimPlayStatePaused = 0x1
@@ -386,6 +386,10 @@ enum EDisplay {
NONE
};
+enum EInsideLink {
+ NotInsideLink, InsideUnvisitedLink, InsideVisitedLink
+};
+
enum EPointerEvents {
PE_NONE, PE_AUTO, PE_STROKE, PE_FILL, PE_PAINTED, PE_VISIBLE,
PE_VISIBLE_STROKE, PE_VISIBLE_FILL, PE_VISIBLE_PAINTED, PE_ALL
diff --git a/WebCore/rendering/style/SVGRenderStyle.cpp b/WebCore/rendering/style/SVGRenderStyle.cpp
index 7958088..042b8f7 100644
--- a/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -1,6 +1,7 @@
/*
Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
Based on khtml code by:
Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
@@ -25,6 +26,7 @@
*/
#include "config.h"
+
#if ENABLE(SVG)
#include "SVGRenderStyle.h"
@@ -32,8 +34,6 @@
#include "CSSValueList.h"
#include "IntRect.h"
#include "NodeRenderStyle.h"
-#include "RenderObject.h"
-#include "RenderStyle.h"
#include "SVGStyledElement.h"
using namespace std;
@@ -48,11 +48,10 @@ SVGRenderStyle::SVGRenderStyle()
stroke = defaultStyle->stroke;
text = defaultStyle->text;
stops = defaultStyle->stops;
- clip = defaultStyle->clip;
- mask = defaultStyle->mask;
misc = defaultStyle->misc;
- markers = defaultStyle->markers;
shadowSVG = defaultStyle->shadowSVG;
+ inheritedResources = defaultStyle->inheritedResources;
+ resources = defaultStyle->resources;
setBitDefaults();
}
@@ -65,11 +64,10 @@ SVGRenderStyle::SVGRenderStyle(CreateDefaultType)
stroke.init();
text.init();
stops.init();
- clip.init();
- mask.init();
misc.init();
- markers.init();
shadowSVG.init();
+ inheritedResources.init();
+ resources.init();
}
SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
@@ -79,11 +77,10 @@ SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
stroke = other.stroke;
text = other.text;
stops = other.stops;
- clip = other.clip;
- mask = other.mask;
misc = other.misc;
- markers = other.markers;
shadowSVG = other.shadowSVG;
+ inheritedResources = other.inheritedResources;
+ resources = other.resources;
svg_inherited_flags = other.svg_inherited_flags;
svg_noninherited_flags = other.svg_noninherited_flags;
@@ -93,22 +90,27 @@ SVGRenderStyle::~SVGRenderStyle()
{
}
-bool SVGRenderStyle::operator==(const SVGRenderStyle& o) const
+bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const
{
- return (fill == o.fill && stroke == o.stroke && text == o.text &&
- stops == o.stops && clip == o.clip && mask == o.mask &&
- misc == o.misc && markers == o.markers && shadowSVG == o.shadowSVG &&
- svg_inherited_flags == o.svg_inherited_flags &&
- svg_noninherited_flags == o.svg_noninherited_flags);
+ return fill == other.fill
+ && stroke == other.stroke
+ && text == other.text
+ && stops == other.stops
+ && misc == other.misc
+ && shadowSVG == other.shadowSVG
+ && inheritedResources == other.inheritedResources
+ && resources == other.resources
+ && svg_inherited_flags == other.svg_inherited_flags
+ && svg_noninherited_flags == other.svg_noninherited_flags;
}
bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const
{
- return (fill != other->fill
- || stroke != other->stroke
- || markers != other->markers
- || text != other->text
- || svg_inherited_flags != other->svg_inherited_flags);
+ return fill != other->fill
+ || stroke != other->stroke
+ || text != other->text
+ || inheritedResources != other->inheritedResources
+ || svg_inherited_flags != other->svg_inherited_flags;
}
void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent)
@@ -118,8 +120,8 @@ void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent)
fill = svgInheritParent->fill;
stroke = svgInheritParent->stroke;
- markers = svgInheritParent->markers;
text = svgInheritParent->text;
+ inheritedResources = svgInheritParent->inheritedResources;
svg_inherited_flags = svgInheritParent->svg_inherited_flags;
}
@@ -144,7 +146,6 @@ float SVGRenderStyle::cssPrimitiveToLength(const RenderObject* item, CSSValue* v
return primitive->computeLengthFloat(const_cast<RenderStyle*>(item->style()), item->document()->documentElement()->renderStyle());
}
-
static void getSVGShadowExtent(ShadowData* shadow, int& top, int& right, int& bottom, int& left)
{
top = 0;
@@ -152,12 +153,12 @@ static void getSVGShadowExtent(ShadowData* shadow, int& top, int& right, int& bo
bottom = 0;
left = 0;
- int blurAndSpread = shadow->blur + shadow->spread;
+ int blurAndSpread = shadow->blur() + shadow->spread();
- top = min(top, shadow->y - blurAndSpread);
- right = max(right, shadow->x + blurAndSpread);
- bottom = max(bottom, shadow->y + blurAndSpread);
- left = min(left, shadow->x - blurAndSpread);
+ top = min(top, shadow->y() - blurAndSpread);
+ right = max(right, shadow->x() + blurAndSpread);
+ bottom = max(bottom, shadow->y() + blurAndSpread);
+ left = min(left, shadow->x() - blurAndSpread);
}
void SVGRenderStyle::inflateForShadow(IntRect& repaintRect) const
@@ -197,5 +198,3 @@ void SVGRenderStyle::inflateForShadow(FloatRect& repaintRect) const
}
#endif // ENABLE(SVG)
-
-// vim:ts=4:noet
diff --git a/WebCore/rendering/style/SVGRenderStyle.h b/WebCore/rendering/style/SVGRenderStyle.h
index c7f85db..c6d5022 100644
--- a/WebCore/rendering/style/SVGRenderStyle.h
+++ b/WebCore/rendering/style/SVGRenderStyle.h
@@ -2,6 +2,7 @@
Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
Copyright (C) 2005, 2006 Apple Computer, Inc.
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -26,11 +27,9 @@
#include "CSSValueList.h"
#include "DataRef.h"
#include "GraphicsTypes.h"
+#include "Path.h"
#include "SVGPaint.h"
#include "SVGRenderStyleDefs.h"
-#include "ShadowData.h"
-
-#include <wtf/Platform.h>
namespace WebCore {
@@ -91,13 +90,6 @@ public:
SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stops, opacity, StopOpacity, stopOpacity, 1.0f)
SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, stops, color, StopColor, stopColor, Color(0, 0, 0))
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, clip, clipPath, ClipPath, clipPath, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, mask, maskElement, MaskElement, maskElement, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, markers, startMarker, StartMarker, startMarker, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, markers, midMarker, MidMarker, midMarker, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, markers, endMarker, EndMarker, endMarker, String())
-
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, misc, filter, Filter, filter, String())
SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, misc, floodOpacity, FloodOpacity, floodOpacity, 1.0f)
SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, misc, floodColor, FloodColor, floodColor, Color(0, 0, 0))
SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, misc, lightingColor, LightingColor, lightingColor, Color(255, 255, 255))
@@ -105,6 +97,16 @@ public:
SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_OWNPTR(ShadowData, shadowSVG, shadow, Shadow, shadow, 0)
+ // Non-inherited resources
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, resources, clipper, ClipperResource, clipperResource, String())
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, resources, filter, FilterResource, filterResource, String())
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, resources, masker, MaskerResource, maskerResource, String())
+
+ // Inherited resources
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, inheritedResources, markerStart, MarkerStartResource, markerStartResource, String())
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, inheritedResources, markerMid, MarkerMidResource, markerMidResource, String())
+ 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); }
@@ -171,15 +173,14 @@ protected:
// inherited attributes
DataRef<StyleFillData> fill;
DataRef<StyleStrokeData> stroke;
- DataRef<StyleMarkerData> markers;
DataRef<StyleTextData> text;
+ DataRef<StyleInheritedResourceData> inheritedResources;
// non-inherited attributes
DataRef<StyleStopData> stops;
- DataRef<StyleClipData> clip;
- DataRef<StyleMaskData> mask;
DataRef<StyleMiscData> misc;
DataRef<StyleShadowSVGData> shadowSVG;
+ DataRef<StyleResourceData> resources;
private:
enum CreateDefaultType { CreateDefault };
@@ -215,5 +216,3 @@ private:
#endif // ENABLE(SVG)
#endif // SVGRenderStyle_h
-
-// vim:ts=4:noet
diff --git a/WebCore/rendering/style/SVGRenderStyleDefs.cpp b/WebCore/rendering/style/SVGRenderStyleDefs.cpp
index 093f1f1..bf7624f 100644
--- a/WebCore/rendering/style/SVGRenderStyleDefs.cpp
+++ b/WebCore/rendering/style/SVGRenderStyleDefs.cpp
@@ -1,6 +1,7 @@
/*
Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005, 2007 Rob Buis <buis@kde.org>
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
Based on khtml code by:
Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
@@ -25,28 +26,29 @@
*/
#include "config.h"
+
#if ENABLE(SVG)
#include "SVGRenderStyleDefs.h"
#include "RenderStyle.h"
#include "SVGRenderStyle.h"
-using namespace WebCore;
+namespace WebCore {
StyleFillData::StyleFillData()
+ : opacity(SVGRenderStyle::initialFillOpacity())
+ , paint(SVGRenderStyle::initialFillPaint())
{
- paint = SVGRenderStyle::initialFillPaint();
- opacity = SVGRenderStyle::initialFillOpacity();
}
StyleFillData::StyleFillData(const StyleFillData& other)
: RefCounted<StyleFillData>()
+ , opacity(other.opacity)
+ , paint(other.paint)
{
- paint = other.paint;
- opacity = other.opacity;
}
-bool StyleFillData::operator==(const StyleFillData &other) const
+bool StyleFillData::operator==(const StyleFillData& other) const
{
if (opacity != other.opacity)
return false;
@@ -67,64 +69,64 @@ bool StyleFillData::operator==(const StyleFillData &other) const
}
StyleStrokeData::StyleStrokeData()
+ : opacity(SVGRenderStyle::initialStrokeOpacity())
+ , miterLimit(SVGRenderStyle::initialStrokeMiterLimit())
+ , width(SVGRenderStyle::initialStrokeWidth())
+ , dashOffset(SVGRenderStyle::initialStrokeDashOffset())
+ , paint(SVGRenderStyle::initialStrokePaint())
+ , dashArray(SVGRenderStyle::initialStrokeDashArray())
{
- width = SVGRenderStyle::initialStrokeWidth();
- paint = SVGRenderStyle::initialStrokePaint();
- opacity = SVGRenderStyle::initialStrokeOpacity();
- miterLimit = SVGRenderStyle::initialStrokeMiterLimit();
- dashOffset = SVGRenderStyle::initialStrokeDashOffset();
- dashArray = SVGRenderStyle::initialStrokeDashArray();
}
StyleStrokeData::StyleStrokeData(const StyleStrokeData& other)
: RefCounted<StyleStrokeData>()
+ , opacity(other.opacity)
+ , miterLimit(other.miterLimit)
+ , width(other.width)
+ , dashOffset(other.dashOffset)
+ , paint(other.paint)
+ , dashArray(other.dashArray)
{
- width = other.width;
- paint = other.paint;
- opacity = other.opacity;
- miterLimit = other.miterLimit;
- dashOffset = other.dashOffset;
- dashArray = other.dashArray;
}
-bool StyleStrokeData::operator==(const StyleStrokeData &other) const
+bool StyleStrokeData::operator==(const StyleStrokeData& other) const
{
- return (paint == other.paint) &&
- (width == other.width) &&
- (opacity == other.opacity) &&
- (miterLimit == other.miterLimit) &&
- (dashOffset == other.dashOffset) &&
- (dashArray == other.dashArray);
+ return paint == other.paint
+ && width == other.width
+ && opacity == other.opacity
+ && miterLimit == other.miterLimit
+ && dashOffset == other.dashOffset
+ && dashArray == other.dashArray;
}
StyleStopData::StyleStopData()
+ : opacity(SVGRenderStyle::initialStopOpacity())
+ , color(SVGRenderStyle::initialStopColor())
{
- color = SVGRenderStyle::initialStopColor();
- opacity = SVGRenderStyle::initialStopOpacity();
}
StyleStopData::StyleStopData(const StyleStopData& other)
: RefCounted<StyleStopData>()
+ , opacity(other.opacity)
+ , color(other.color)
{
- color = other.color;
- opacity = other.opacity;
}
-bool StyleStopData::operator==(const StyleStopData &other) const
+bool StyleStopData::operator==(const StyleStopData& other) const
{
- return (color == other.color) &&
- (opacity == other.opacity);
+ return color == other.color
+ && opacity == other.opacity;
}
StyleTextData::StyleTextData()
+ : kerning(SVGRenderStyle::initialKerning())
{
- kerning = SVGRenderStyle::initialKerning();
}
StyleTextData::StyleTextData(const StyleTextData& other)
: RefCounted<StyleTextData>()
+ , kerning(other.kerning)
{
- kerning = other.kerning;
}
bool StyleTextData::operator==(const StyleTextData& other) const
@@ -132,104 +134,94 @@ bool StyleTextData::operator==(const StyleTextData& other) const
return kerning == other.kerning;
}
-StyleClipData::StyleClipData()
-{
- clipPath = SVGRenderStyle::initialClipPath();
-}
-
-StyleClipData::StyleClipData(const StyleClipData& other)
- : RefCounted<StyleClipData>()
-{
- clipPath = other.clipPath;
-}
-
-bool StyleClipData::operator==(const StyleClipData &other) const
+StyleMiscData::StyleMiscData()
+ : floodColor(SVGRenderStyle::initialFloodColor())
+ , floodOpacity(SVGRenderStyle::initialFloodOpacity())
+ , lightingColor(SVGRenderStyle::initialLightingColor())
+ , baselineShiftValue(SVGRenderStyle::initialBaselineShiftValue())
{
- return (clipPath == other.clipPath);
}
-StyleMaskData::StyleMaskData()
+StyleMiscData::StyleMiscData(const StyleMiscData& other)
+ : RefCounted<StyleMiscData>()
+ , floodColor(other.floodColor)
+ , floodOpacity(other.floodOpacity)
+ , lightingColor(other.lightingColor)
+ , baselineShiftValue(other.baselineShiftValue)
{
- maskElement = SVGRenderStyle::initialMaskElement();
}
-StyleMaskData::StyleMaskData(const StyleMaskData& other)
- : RefCounted<StyleMaskData>()
+bool StyleMiscData::operator==(const StyleMiscData& other) const
{
- maskElement = other.maskElement;
+ return floodOpacity == other.floodOpacity
+ && floodColor == other.floodColor
+ && lightingColor == other.lightingColor
+ && baselineShiftValue == other.baselineShiftValue;
}
-bool StyleMaskData::operator==(const StyleMaskData &other) const
+StyleShadowSVGData::StyleShadowSVGData()
{
- return (maskElement == other.maskElement);
}
-StyleMarkerData::StyleMarkerData()
+StyleShadowSVGData::StyleShadowSVGData(const StyleShadowSVGData& other)
+ : RefCounted<StyleShadowSVGData>()
+ , shadow(other.shadow ? new ShadowData(*other.shadow) : 0)
{
- startMarker = SVGRenderStyle::initialStartMarker();
- midMarker = SVGRenderStyle::initialMidMarker();
- endMarker = SVGRenderStyle::initialEndMarker();
}
-StyleMarkerData::StyleMarkerData(const StyleMarkerData& other)
- : RefCounted<StyleMarkerData>()
+bool StyleShadowSVGData::operator==(const StyleShadowSVGData& other) const
{
- startMarker = other.startMarker;
- midMarker = other.midMarker;
- endMarker = other.endMarker;
+ if ((!shadow && other.shadow) || (shadow && !other.shadow))
+ return false;
+ if (shadow && other.shadow && (*shadow != *other.shadow))
+ return false;
+ return true;
}
-bool StyleMarkerData::operator==(const StyleMarkerData &other) const
+StyleResourceData::StyleResourceData()
+ : clipper(SVGRenderStyle::initialClipperResource())
+ , filter(SVGRenderStyle::initialFilterResource())
+ , masker(SVGRenderStyle::initialMaskerResource())
{
- return (startMarker == other.startMarker && midMarker == other.midMarker && endMarker == other.endMarker);
}
-StyleMiscData::StyleMiscData()
+StyleResourceData::StyleResourceData(const StyleResourceData& other)
+ : RefCounted<StyleResourceData>()
+ , clipper(other.clipper)
+ , filter(other.filter)
+ , masker(other.masker)
{
- floodColor = SVGRenderStyle::initialFloodColor();
- floodOpacity = SVGRenderStyle::initialFloodOpacity();
- lightingColor = SVGRenderStyle::initialLightingColor();
- baselineShiftValue = SVGRenderStyle::initialBaselineShiftValue();
}
-StyleMiscData::StyleMiscData(const StyleMiscData& other)
- : RefCounted<StyleMiscData>()
+bool StyleResourceData::operator==(const StyleResourceData& other) const
{
- filter = other.filter;
- floodColor = other.floodColor;
- floodOpacity = other.floodOpacity;
- lightingColor = other.lightingColor;
- baselineShiftValue = other.baselineShiftValue;
+ return clipper == other.clipper
+ && filter == other.filter
+ && masker == other.masker;
}
-bool StyleMiscData::operator==(const StyleMiscData &other) const
+StyleInheritedResourceData::StyleInheritedResourceData()
+ : markerStart(SVGRenderStyle::initialMarkerStartResource())
+ , markerMid(SVGRenderStyle::initialMarkerMidResource())
+ , markerEnd(SVGRenderStyle::initialMarkerEndResource())
{
- return filter == other.filter
- && floodOpacity == other.floodOpacity
- && floodColor == other.floodColor
- && lightingColor == other.lightingColor
- && baselineShiftValue == other.baselineShiftValue;
}
-StyleShadowSVGData::StyleShadowSVGData()
+StyleInheritedResourceData::StyleInheritedResourceData(const StyleInheritedResourceData& other)
+ : RefCounted<StyleInheritedResourceData>()
+ , markerStart(other.markerStart)
+ , markerMid(other.markerMid)
+ , markerEnd(other.markerEnd)
{
}
-StyleShadowSVGData::StyleShadowSVGData(const StyleShadowSVGData& other)
- : RefCounted<StyleShadowSVGData>()
- , shadow(other.shadow ? new ShadowData(*other.shadow) : 0)
+bool StyleInheritedResourceData::operator==(const StyleInheritedResourceData& other) const
{
+ return markerStart == other.markerStart
+ && markerMid == other.markerMid
+ && markerEnd == other.markerEnd;
}
-bool StyleShadowSVGData::operator==(const StyleShadowSVGData& other) const
-{
- if ((!shadow && other.shadow) || (shadow && !other.shadow))
- return false;
- if (shadow && other.shadow && (*shadow != *other.shadow))
- return false;
- return true;
}
#endif // ENABLE(SVG)
-
-// vim:ts=4:noet
diff --git a/WebCore/rendering/style/SVGRenderStyleDefs.h b/WebCore/rendering/style/SVGRenderStyleDefs.h
index 8f01d9f..e0354e6 100644
--- a/WebCore/rendering/style/SVGRenderStyleDefs.h
+++ b/WebCore/rendering/style/SVGRenderStyleDefs.h
@@ -1,6 +1,7 @@
/*
Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
Based on khtml code by:
Copyright (C) 2000-2003 Lars Knoll (knoll@kde.org)
@@ -29,11 +30,9 @@
#if ENABLE(SVG)
#include "Color.h"
-#include "Path.h"
#include "PlatformString.h"
#include "ShadowData.h"
#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -133,8 +132,8 @@ namespace WebCore {
static PassRefPtr<StyleFillData> create() { return adoptRef(new StyleFillData); }
PassRefPtr<StyleFillData> copy() const { return adoptRef(new StyleFillData(*this)); }
- bool operator==(const StyleFillData &other) const;
- bool operator!=(const StyleFillData &other) const
+ bool operator==(const StyleFillData&) const;
+ bool operator!=(const StyleFillData& other) const
{
return !(*this == other);
}
@@ -177,8 +176,8 @@ namespace WebCore {
static PassRefPtr<StyleStopData> create() { return adoptRef(new StyleStopData); }
PassRefPtr<StyleStopData> copy() const { return adoptRef(new StyleStopData(*this)); }
- bool operator==(const StyleStopData &other) const;
- bool operator!=(const StyleStopData &other) const
+ bool operator==(const StyleStopData&) const;
+ bool operator!=(const StyleStopData& other) const
{
return !(*this == other);
}
@@ -206,109 +205,94 @@ namespace WebCore {
private:
StyleTextData();
- StyleTextData(const StyleTextData& other);
+ StyleTextData(const StyleTextData&);
};
- class StyleClipData : public RefCounted<StyleClipData> {
+ // Note: the rule for this class is, *no inheritance* of these props
+ class StyleMiscData : public RefCounted<StyleMiscData> {
public:
- static PassRefPtr<StyleClipData> create() { return adoptRef(new StyleClipData); }
- PassRefPtr<StyleClipData> copy() const { return adoptRef(new StyleClipData(*this)); }
+ static PassRefPtr<StyleMiscData> create() { return adoptRef(new StyleMiscData); }
+ PassRefPtr<StyleMiscData> copy() const { return adoptRef(new StyleMiscData(*this)); }
- bool operator==(const StyleClipData &other) const;
- bool operator!=(const StyleClipData &other) const
+ bool operator==(const StyleMiscData&) const;
+ bool operator!=(const StyleMiscData& other) const
{
return !(*this == other);
}
- String clipPath;
-
- private:
- StyleClipData();
- StyleClipData(const StyleClipData&);
- };
-
- class StyleMaskData : public RefCounted<StyleMaskData> {
- public:
- static PassRefPtr<StyleMaskData> create() { return adoptRef(new StyleMaskData); }
- PassRefPtr<StyleMaskData> copy() const { return adoptRef(new StyleMaskData(*this)); }
-
- bool operator==(const StyleMaskData &other) const;
- bool operator!=(const StyleMaskData &other) const { return !(*this == other); }
+ Color floodColor;
+ float floodOpacity;
+ Color lightingColor;
- String maskElement;
+ // non-inherited text stuff lives here not in StyleTextData.
+ RefPtr<CSSValue> baselineShiftValue;
- private:
- StyleMaskData();
- StyleMaskData(const StyleMaskData&);
+ private:
+ StyleMiscData();
+ StyleMiscData(const StyleMiscData&);
};
- class StyleMarkerData : public RefCounted<StyleMarkerData> {
+ class StyleShadowSVGData : public RefCounted<StyleShadowSVGData> {
public:
- static PassRefPtr<StyleMarkerData> create() { return adoptRef(new StyleMarkerData); }
- PassRefPtr<StyleMarkerData> copy() const { return adoptRef(new StyleMarkerData(*this)); }
+ static PassRefPtr<StyleShadowSVGData> create() { return adoptRef(new StyleShadowSVGData); }
+ PassRefPtr<StyleShadowSVGData> copy() const { return adoptRef(new StyleShadowSVGData(*this)); }
- bool operator==(const StyleMarkerData &other) const;
- bool operator!=(const StyleMarkerData &other) const
+ bool operator==(const StyleShadowSVGData&) const;
+ bool operator!=(const StyleShadowSVGData& other) const
{
return !(*this == other);
}
- String startMarker;
- String midMarker;
- String endMarker;
+ OwnPtr<ShadowData> shadow;
private:
- StyleMarkerData();
- StyleMarkerData(const StyleMarkerData&);
+ StyleShadowSVGData();
+ StyleShadowSVGData(const StyleShadowSVGData&);
};
- // Note : the rule for this class is, *no inheritance* of these props
- class StyleMiscData : public RefCounted<StyleMiscData> {
+ // Non-inherited resources
+ class StyleResourceData : public RefCounted<StyleResourceData> {
public:
- static PassRefPtr<StyleMiscData> create() { return adoptRef(new StyleMiscData); }
- PassRefPtr<StyleMiscData> copy() const { return adoptRef(new StyleMiscData(*this)); }
+ static PassRefPtr<StyleResourceData> create() { return adoptRef(new StyleResourceData); }
+ PassRefPtr<StyleResourceData> copy() const { return adoptRef(new StyleResourceData(*this)); }
- bool operator==(const StyleMiscData &other) const;
- bool operator!=(const StyleMiscData &other) const
+ bool operator==(const StyleResourceData&) const;
+ bool operator!=(const StyleResourceData& other) const
{
return !(*this == other);
}
+ String clipper;
String filter;
- Color floodColor;
- float floodOpacity;
-
- Color lightingColor;
-
- // non-inherited text stuff lives here not in StyleTextData.
- RefPtr<CSSValue> baselineShiftValue;
+ String masker;
private:
- StyleMiscData();
- StyleMiscData(const StyleMiscData&);
+ StyleResourceData();
+ StyleResourceData(const StyleResourceData&);
};
-
- class StyleShadowSVGData : public RefCounted<StyleShadowSVGData> {
+
+ // Inherited resources
+ class StyleInheritedResourceData : public RefCounted<StyleInheritedResourceData> {
public:
- static PassRefPtr<StyleShadowSVGData> create() { return adoptRef(new StyleShadowSVGData); }
- PassRefPtr<StyleShadowSVGData> copy() const { return adoptRef(new StyleShadowSVGData(*this)); }
-
- bool operator==(const StyleShadowSVGData& other) const;
- bool operator!=(const StyleShadowSVGData& other) const
+ static PassRefPtr<StyleInheritedResourceData> create() { return adoptRef(new StyleInheritedResourceData); }
+ PassRefPtr<StyleInheritedResourceData> copy() const { return adoptRef(new StyleInheritedResourceData(*this)); }
+
+ bool operator==(const StyleInheritedResourceData&) const;
+ bool operator!=(const StyleInheritedResourceData& other) const
{
return !(*this == other);
}
- OwnPtr<ShadowData> shadow;
+ String markerStart;
+ String markerMid;
+ String markerEnd;
private:
- StyleShadowSVGData();
- StyleShadowSVGData(const StyleShadowSVGData& other);
+ StyleInheritedResourceData();
+ StyleInheritedResourceData(const StyleInheritedResourceData&);
};
} // namespace WebCore
#endif // ENABLE(SVG)
#endif // SVGRenderStyleDefs_h
-
-// vim:ts=4:noet
diff --git a/WebCore/rendering/style/ShadowData.cpp b/WebCore/rendering/style/ShadowData.cpp
index 1954224..d4569d0 100644
--- a/WebCore/rendering/style/ShadowData.cpp
+++ b/WebCore/rendering/style/ShadowData.cpp
@@ -25,23 +25,23 @@
namespace WebCore {
ShadowData::ShadowData(const ShadowData& o)
- : x(o.x)
- , y(o.y)
- , blur(o.blur)
- , spread(o.spread)
- , style(o.style)
- , color(o.color)
+ : m_x(o.m_x)
+ , m_y(o.m_y)
+ , m_blur(o.m_blur)
+ , m_spread(o.m_spread)
+ , m_style(o.m_style)
+ , m_color(o.m_color)
{
- next = o.next ? new ShadowData(*o.next) : 0;
+ m_next = o.m_next ? new ShadowData(*o.m_next) : 0;
}
bool ShadowData::operator==(const ShadowData& o) const
{
- if ((next && !o.next) || (!next && o.next) ||
- (next && o.next && *next != *o.next))
+ if ((m_next && !o.m_next) || (!m_next && o.m_next) ||
+ (m_next && o.m_next && *m_next != *o.m_next))
return false;
- return x == o.x && y == o.y && blur == o.blur && spread == o.spread && style == o.style && color == o.color;
+ return m_x == o.m_x && m_y == o.m_y && m_blur == o.m_blur && m_spread == o.m_spread && m_style == o.m_style && m_color == o.m_color;
}
} // namespace WebCore
diff --git a/WebCore/rendering/style/ShadowData.h b/WebCore/rendering/style/ShadowData.h
index 089cf77..9252e13 100644
--- a/WebCore/rendering/style/ShadowData.h
+++ b/WebCore/rendering/style/ShadowData.h
@@ -34,31 +34,31 @@ enum ShadowStyle { Normal, Inset };
// This struct holds information about shadows for the text-shadow and box-shadow properties.
-struct ShadowData : FastAllocBase {
+class ShadowData : public FastAllocBase {
+public:
ShadowData()
- : x(0)
- , y(0)
- , blur(0)
- , spread(0)
- , style(Normal)
- , next(0)
+ : m_x(0)
+ , m_y(0)
+ , m_blur(0)
+ , m_spread(0)
+ , m_style(Normal)
+ , m_next(0)
{
}
ShadowData(int x, int y, int blur, int spread, ShadowStyle style, const Color& color)
- : x(x)
- , y(y)
- , blur(blur)
- , spread(spread)
- , style(style)
- , color(color)
- , next(0)
+ : m_x(x)
+ , m_y(y)
+ , m_blur(blur)
+ , m_spread(spread)
+ , m_style(style)
+ , m_color(color)
+ , m_next(0)
{
}
ShadowData(const ShadowData& o);
-
- ~ShadowData() { delete next; }
+ ~ShadowData() { delete m_next; }
bool operator==(const ShadowData& o) const;
bool operator!=(const ShadowData& o) const
@@ -66,13 +66,24 @@ struct ShadowData : FastAllocBase {
return !(*this == o);
}
- int x;
- int y;
- int blur;
- int spread;
- ShadowStyle style;
- Color color;
- ShadowData* next;
+ int x() const { return m_x; }
+ int y() const { return m_y; }
+ int blur() const { return m_blur; }
+ int spread() const { return m_spread; }
+ ShadowStyle style() const { return m_style; }
+ const Color& color() const { return m_color; }
+
+ const ShadowData* next() const { return m_next; }
+ void setNext(ShadowData* shadow) { m_next = shadow; }
+
+private:
+ int m_x;
+ int m_y;
+ int m_blur;
+ int m_spread;
+ ShadowStyle m_style;
+ Color m_color;
+ ShadowData* m_next;
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/StyleBackgroundData.h b/WebCore/rendering/style/StyleBackgroundData.h
index 8f2da36..48a700e 100644
--- a/WebCore/rendering/style/StyleBackgroundData.h
+++ b/WebCore/rendering/style/StyleBackgroundData.h
@@ -45,13 +45,19 @@ public:
return !(*this == o);
}
- FillLayer m_background;
- Color m_color;
- OutlineValue m_outline;
+ const FillLayer& background() const { return m_background; }
+ const Color& color() const { return m_color; }
+ const OutlineValue& outline() const { return m_outline; }
private:
+ friend class RenderStyle;
+
StyleBackgroundData();
- StyleBackgroundData(const StyleBackgroundData&);
+ StyleBackgroundData(const StyleBackgroundData&);
+
+ FillLayer m_background;
+ Color m_color;
+ OutlineValue m_outline;
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/StyleBoxData.cpp b/WebCore/rendering/style/StyleBoxData.cpp
index d9734d1..2c523da 100644
--- a/WebCore/rendering/style/StyleBoxData.cpp
+++ b/WebCore/rendering/style/StyleBoxData.cpp
@@ -28,40 +28,41 @@
namespace WebCore {
StyleBoxData::StyleBoxData()
- : z_index(0)
- , z_auto(true)
- , boxSizing(CONTENT_BOX)
+ : m_minWidth(RenderStyle::initialMinSize())
+ , m_maxWidth(RenderStyle::initialMaxSize())
+ , m_minHeight(RenderStyle::initialMinSize())
+ , m_maxHeight(RenderStyle::initialMaxSize())
+ , m_zIndex(0)
+ , m_hasAutoZIndex(true)
+ , m_boxSizing(CONTENT_BOX)
{
- // Initialize our min/max widths/heights.
- min_width = min_height = RenderStyle::initialMinSize();
- max_width = max_height = RenderStyle::initialMaxSize();
}
StyleBoxData::StyleBoxData(const StyleBoxData& o)
: RefCounted<StyleBoxData>()
- , width(o.width)
- , height(o.height)
- , min_width(o.min_width)
- , max_width(o.max_width)
- , min_height(o.min_height)
- , max_height(o.max_height)
- , z_index(o.z_index)
- , z_auto(o.z_auto)
- , boxSizing(o.boxSizing)
+ , m_width(o.m_width)
+ , m_height(o.m_height)
+ , m_minWidth(o.m_minWidth)
+ , m_maxWidth(o.m_maxWidth)
+ , m_minHeight(o.m_minHeight)
+ , m_maxHeight(o.m_maxHeight)
+ , m_zIndex(o.m_zIndex)
+ , m_hasAutoZIndex(o.m_hasAutoZIndex)
+ , m_boxSizing(o.m_boxSizing)
{
}
bool StyleBoxData::operator==(const StyleBoxData& o) const
{
- return width == o.width &&
- height == o.height &&
- min_width == o.min_width &&
- max_width == o.max_width &&
- min_height == o.min_height &&
- max_height == o.max_height &&
- z_index == o.z_index &&
- z_auto == o.z_auto &&
- boxSizing == o.boxSizing;
+ return m_width == o.m_width
+ && m_height == o.m_height
+ && m_minWidth == o.m_minWidth
+ && m_maxWidth == o.m_maxWidth
+ && m_minHeight == o.m_minHeight
+ && m_maxHeight == o.m_maxHeight
+ && m_zIndex == o.m_zIndex
+ && m_hasAutoZIndex == o.m_hasAutoZIndex
+ && m_boxSizing == o.m_boxSizing;
}
} // namespace WebCore
diff --git a/WebCore/rendering/style/StyleBoxData.h b/WebCore/rendering/style/StyleBoxData.h
index a5bd2ff..00bce4e 100644
--- a/WebCore/rendering/style/StyleBoxData.h
+++ b/WebCore/rendering/style/StyleBoxData.h
@@ -26,6 +26,7 @@
#define StyleBoxData_h
#include "Length.h"
+#include "RenderStyleConstants.h"
#include <wtf/RefCounted.h>
#include <wtf/PassRefPtr.h>
@@ -42,24 +43,42 @@ public:
return !(*this == o);
}
- Length width;
- Length height;
-
- Length min_width;
- Length max_width;
-
- Length min_height;
- Length max_height;
-
- Length vertical_align;
-
- int z_index;
- bool z_auto : 1;
- unsigned boxSizing : 1; // EBoxSizing
+ Length width() const { return m_width; }
+ Length height() const { return m_height; }
+
+ Length minWidth() const { return m_minWidth; }
+ Length minHeight() const { return m_minHeight; }
+
+ Length maxWidth() const { return m_maxWidth; }
+ Length maxHeight() const { return m_maxHeight; }
+
+ Length verticalAlign() const { return m_verticalAlign; }
+
+ int zIndex() const { return m_zIndex; }
+ bool hasAutoZIndex() const { return m_hasAutoZIndex; }
+ EBoxSizing boxSizing() const { return static_cast<EBoxSizing>(m_boxSizing); }
+
private:
+ friend class RenderStyle;
+
StyleBoxData();
StyleBoxData(const StyleBoxData&);
+
+ Length m_width;
+ Length m_height;
+
+ Length m_minWidth;
+ Length m_maxWidth;
+
+ Length m_minHeight;
+ Length m_maxHeight;
+
+ Length m_verticalAlign;
+
+ int m_zIndex;
+ bool m_hasAutoZIndex : 1;
+ unsigned m_boxSizing : 1; // EBoxSizing
};
} // namespace WebCore
diff --git a/WebCore/rendering/style/StyleMultiColData.h b/WebCore/rendering/style/StyleMultiColData.h
index dec0a55..d3fe720 100644
--- a/WebCore/rendering/style/StyleMultiColData.h
+++ b/WebCore/rendering/style/StyleMultiColData.h
@@ -50,7 +50,7 @@ public:
{
if (m_rule.style() == BNONE || m_rule.style() == BHIDDEN)
return 0;
- return m_rule.width;
+ return m_rule.width();
}
float m_width;