summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/AutoTableLayout.h2
-rw-r--r--WebCore/rendering/CounterNode.cpp151
-rw-r--r--WebCore/rendering/CounterNode.h13
-rw-r--r--WebCore/rendering/EllipsisBox.cpp6
-rw-r--r--WebCore/rendering/EllipsisBox.h2
-rw-r--r--WebCore/rendering/FixedTableLayout.cpp2
-rw-r--r--WebCore/rendering/FixedTableLayout.h2
-rw-r--r--WebCore/rendering/HitTestRequest.h2
-rw-r--r--WebCore/rendering/HitTestResult.h2
-rw-r--r--WebCore/rendering/InlineFlowBox.cpp9
-rw-r--r--WebCore/rendering/InlineRunBox.h2
-rw-r--r--WebCore/rendering/InlineTextBox.cpp70
-rw-r--r--WebCore/rendering/InlineTextBox.h8
-rw-r--r--WebCore/rendering/MediaControlElements.cpp32
-rw-r--r--WebCore/rendering/MediaControlElements.h11
-rw-r--r--WebCore/rendering/PointerEventsHitRules.cpp2
-rw-r--r--WebCore/rendering/PointerEventsHitRules.h2
-rw-r--r--WebCore/rendering/RenderArena.h3
-rw-r--r--WebCore/rendering/RenderBR.cpp2
-rw-r--r--WebCore/rendering/RenderBR.h2
-rw-r--r--WebCore/rendering/RenderBlock.cpp138
-rw-r--r--WebCore/rendering/RenderBlock.h9
-rw-r--r--WebCore/rendering/RenderBlockLineLayout.cpp6
-rw-r--r--WebCore/rendering/RenderBox.cpp4
-rw-r--r--WebCore/rendering/RenderBoxModelObject.cpp39
-rw-r--r--WebCore/rendering/RenderButton.cpp2
-rw-r--r--WebCore/rendering/RenderButton.h2
-rw-r--r--WebCore/rendering/RenderCounter.cpp204
-rw-r--r--WebCore/rendering/RenderCounter.h6
-rw-r--r--WebCore/rendering/RenderFieldset.cpp2
-rw-r--r--WebCore/rendering/RenderFileUploadControl.cpp13
-rw-r--r--WebCore/rendering/RenderFileUploadControl.h12
-rw-r--r--WebCore/rendering/RenderFlexibleBox.cpp50
-rw-r--r--WebCore/rendering/RenderFrameSet.cpp16
-rw-r--r--WebCore/rendering/RenderImage.cpp12
-rw-r--r--WebCore/rendering/RenderInline.cpp11
-rw-r--r--WebCore/rendering/RenderLayer.cpp217
-rw-r--r--WebCore/rendering/RenderLayer.h27
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp62
-rw-r--r--WebCore/rendering/RenderLayerBacking.h5
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp130
-rw-r--r--WebCore/rendering/RenderLayerCompositor.h16
-rw-r--r--WebCore/rendering/RenderLineBoxList.cpp1
-rw-r--r--WebCore/rendering/RenderListBox.cpp6
-rw-r--r--WebCore/rendering/RenderListItem.cpp2
-rw-r--r--WebCore/rendering/RenderListMarker.cpp16
-rw-r--r--WebCore/rendering/RenderMarquee.h2
-rw-r--r--WebCore/rendering/RenderMedia.cpp16
-rw-r--r--WebCore/rendering/RenderMedia.h3
-rw-r--r--WebCore/rendering/RenderMediaControls.cpp9
-rw-r--r--WebCore/rendering/RenderMediaControlsChromium.cpp18
-rw-r--r--WebCore/rendering/RenderObject.cpp145
-rw-r--r--WebCore/rendering/RenderObject.h26
-rw-r--r--WebCore/rendering/RenderObjectChildList.cpp23
-rw-r--r--WebCore/rendering/RenderObjectChildList.h3
-rw-r--r--WebCore/rendering/RenderOverflow.h2
-rw-r--r--WebCore/rendering/RenderReplaced.cpp2
-rw-r--r--WebCore/rendering/RenderReplica.cpp2
-rw-r--r--WebCore/rendering/RenderRuby.cpp194
-rw-r--r--WebCore/rendering/RenderRuby.h83
-rw-r--r--WebCore/rendering/RenderRubyBase.cpp86
-rw-r--r--WebCore/rendering/RenderRubyBase.h55
-rw-r--r--WebCore/rendering/RenderRubyRun.cpp220
-rw-r--r--WebCore/rendering/RenderRubyRun.h80
-rw-r--r--WebCore/rendering/RenderRubyText.cpp50
-rw-r--r--WebCore/rendering/RenderRubyText.h52
-rw-r--r--WebCore/rendering/RenderSVGImage.cpp2
-rw-r--r--WebCore/rendering/RenderScrollbarTheme.cpp2
-rw-r--r--WebCore/rendering/RenderSelectionInfo.h2
-rw-r--r--WebCore/rendering/RenderSlider.cpp35
-rw-r--r--WebCore/rendering/RenderTableCell.cpp35
-rw-r--r--WebCore/rendering/RenderTableCell.h4
-rw-r--r--WebCore/rendering/RenderTableRow.cpp2
-rw-r--r--WebCore/rendering/RenderTableSection.cpp16
-rw-r--r--WebCore/rendering/RenderText.cpp15
-rw-r--r--WebCore/rendering/RenderText.h3
-rw-r--r--WebCore/rendering/RenderTextControl.cpp18
-rw-r--r--WebCore/rendering/RenderTextControl.h12
-rw-r--r--WebCore/rendering/RenderTextControlMultiLine.cpp4
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp4
-rw-r--r--WebCore/rendering/RenderTheme.cpp10
-rw-r--r--WebCore/rendering/RenderTheme.h1
-rw-r--r--WebCore/rendering/RenderThemeChromiumLinux.cpp12
-rw-r--r--WebCore/rendering/RenderThemeChromiumLinux.h11
-rw-r--r--WebCore/rendering/RenderThemeChromiumMac.mm6
-rw-r--r--WebCore/rendering/RenderThemeChromiumSkia.cpp25
-rw-r--r--WebCore/rendering/RenderThemeChromiumSkia.h2
-rw-r--r--WebCore/rendering/RenderThemeMac.h1
-rw-r--r--WebCore/rendering/RenderThemeMac.mm49
-rw-r--r--WebCore/rendering/RenderThemeSafari.cpp8
-rw-r--r--WebCore/rendering/RenderThemeWin.cpp29
-rw-r--r--WebCore/rendering/RenderThemeWin.h2
-rw-r--r--WebCore/rendering/RenderTreeAsText.cpp42
-rw-r--r--WebCore/rendering/RenderTreeAsText.h3
-rw-r--r--WebCore/rendering/RenderView.cpp18
-rw-r--r--WebCore/rendering/RenderView.h9
-rw-r--r--WebCore/rendering/RenderWidget.cpp152
-rw-r--r--WebCore/rendering/RenderWidget.h5
-rw-r--r--WebCore/rendering/RootInlineBox.h2
-rw-r--r--WebCore/rendering/SVGInlineTextBox.cpp7
-rw-r--r--WebCore/rendering/SVGInlineTextBox.h2
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp18
-rw-r--r--WebCore/rendering/TableLayout.h6
-rw-r--r--WebCore/rendering/break_lines.h2
-rw-r--r--WebCore/rendering/style/ContentData.h6
-rw-r--r--WebCore/rendering/style/CounterContent.h2
-rw-r--r--WebCore/rendering/style/FillLayer.h2
-rw-r--r--WebCore/rendering/style/LineClampValue.h69
-rw-r--r--WebCore/rendering/style/RenderStyle.cpp4
-rw-r--r--WebCore/rendering/style/RenderStyle.h11
-rw-r--r--WebCore/rendering/style/RenderStyleConstants.h9
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.cpp2
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.h2
-rw-r--r--WebCore/rendering/style/SVGRenderStyleDefs.cpp2
-rw-r--r--WebCore/rendering/style/SVGRenderStyleDefs.h2
-rw-r--r--WebCore/rendering/style/ShadowData.h3
-rw-r--r--WebCore/rendering/style/StyleBackgroundData.cpp2
-rw-r--r--WebCore/rendering/style/StyleRareInheritedData.cpp5
-rw-r--r--WebCore/rendering/style/StyleRareInheritedData.h1
-rw-r--r--WebCore/rendering/style/StyleRareNonInheritedData.h3
120 files changed, 2350 insertions, 755 deletions
diff --git a/WebCore/rendering/AutoTableLayout.h b/WebCore/rendering/AutoTableLayout.h
index 641a68b..f1ef768 100644
--- a/WebCore/rendering/AutoTableLayout.h
+++ b/WebCore/rendering/AutoTableLayout.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2002 Lars Knoll (knoll@kde.org)
* (C) 2002 Dirk Mueller (mueller@kde.org)
*
diff --git a/WebCore/rendering/CounterNode.cpp b/WebCore/rendering/CounterNode.cpp
index f546abb..95a3748 100644
--- a/WebCore/rendering/CounterNode.cpp
+++ b/WebCore/rendering/CounterNode.cpp
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
*
@@ -46,7 +44,58 @@ CounterNode::CounterNode(RenderObject* o, bool isReset, int value)
, m_nextSibling(0)
, m_firstChild(0)
, m_lastChild(0)
-{
+{
+}
+
+CounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWithin) const
+{
+ if (this == stayWithin)
+ return 0;
+
+ CounterNode* next = m_nextSibling;
+ if (next)
+ return next;
+ next = m_parent;
+ while (next && !next->m_nextSibling) {
+ if (next == stayWithin)
+ return 0;
+ next = next->m_parent;
+ }
+ if (next)
+ return next->m_nextSibling;
+ return 0;
+}
+
+CounterNode* CounterNode::nextInPreOrder(const CounterNode* stayWithin) const
+{
+ if (CounterNode* next = m_firstChild)
+ return next;
+
+ return nextInPreOrderAfterChildren(stayWithin);
+}
+
+CounterNode* CounterNode::lastDescendant() const
+{
+ CounterNode* last = m_lastChild;
+ if (!last)
+ return 0;
+
+ while (CounterNode* lastChild = last->m_lastChild)
+ last = lastChild;
+
+ return last;
+}
+
+CounterNode* CounterNode::previousInPreOrder() const
+{
+ CounterNode* previous = m_previousSibling;
+ if (!previous)
+ return m_parent;
+
+ while (CounterNode* lastChild = previous->m_lastChild)
+ previous = lastChild;
+
+ return previous;
}
int CounterNode::computeCountInParent() const
@@ -58,26 +107,37 @@ int CounterNode::computeCountInParent() const
return m_parent->m_value + increment;
}
-void CounterNode::recount()
+
+void CounterNode::resetRenderer(const AtomicString& identifier) const
+{
+ if (!m_renderer || m_renderer->documentBeingDestroyed())
+ return;
+ if (RenderObjectChildList* children = m_renderer->virtualChildren())
+ children->invalidateCounters(m_renderer, identifier);
+}
+
+void CounterNode::resetRenderers(const AtomicString& identifier) const
+{
+ const CounterNode* node = this;
+ do {
+ node->resetRenderer(identifier);
+ node = node->nextInPreOrder(this);
+ } while (node);
+}
+
+void CounterNode::recount(const AtomicString& identifier)
{
- for (CounterNode* c = this; c; c = c->m_nextSibling) {
- int oldCount = c->m_countInParent;
- int newCount = c->computeCountInParent();
+ for (CounterNode* node = this; node; node = node->m_nextSibling) {
+ int oldCount = node->m_countInParent;
+ int newCount = node->computeCountInParent();
if (oldCount == newCount)
break;
- c->m_countInParent = newCount;
- // m_renderer contains the parent of the render node
- // corresponding to a CounterNode. Let's find the counter
- // child and make this re-layout.
- for (RenderObject* o = c->m_renderer->firstChild(); o; o = o->nextSibling())
- if (!o->documentBeingDestroyed() && o->isCounter()) {
- o->setNeedsLayoutAndPrefWidthsRecalc();
- break;
- }
+ node->m_countInParent = newCount;
+ node->resetRenderers(identifier);
}
}
-void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild)
+void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, const AtomicString& identifier)
{
ASSERT(newChild);
ASSERT(!newChild->m_parent);
@@ -109,77 +169,56 @@ void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild)
newChild->m_countInParent = newChild->computeCountInParent();
if (next)
- next->recount();
+ next->recount(identifier);
}
-void CounterNode::removeChild(CounterNode* oldChild)
+void CounterNode::removeChild(CounterNode* oldChild, const AtomicString& identifier)
{
ASSERT(oldChild);
ASSERT(!oldChild->m_firstChild);
ASSERT(!oldChild->m_lastChild);
CounterNode* next = oldChild->m_nextSibling;
- CounterNode* prev = oldChild->m_previousSibling;
+ CounterNode* previous = oldChild->m_previousSibling;
oldChild->m_nextSibling = 0;
oldChild->m_previousSibling = 0;
oldChild->m_parent = 0;
- if (prev)
- prev->m_nextSibling = next;
+ if (previous)
+ previous->m_nextSibling = next;
else {
ASSERT(m_firstChild == oldChild);
m_firstChild = next;
}
-
+
if (next)
- next->m_previousSibling = prev;
+ next->m_previousSibling = previous;
else {
ASSERT(m_lastChild == oldChild);
- m_lastChild = prev;
+ m_lastChild = previous;
}
-
+
if (next)
- next->recount();
+ next->recount(identifier);
}
#ifndef NDEBUG
-static const CounterNode* nextInPreOrderAfterChildren(const CounterNode* node)
-{
- CounterNode* next = node->nextSibling();
- if (!next) {
- next = node->parent();
- while (next && !next->nextSibling())
- next = next->parent();
- if (next)
- next = next->nextSibling();
- }
- return next;
-}
-
-static const CounterNode* nextInPreOrder(const CounterNode* node)
-{
- if (CounterNode* child = node->firstChild())
- return child;
- return nextInPreOrderAfterChildren(node);
-}
-
static void showTreeAndMark(const CounterNode* node)
{
const CounterNode* root = node;
while (root->parent())
root = root->parent();
- for (const CounterNode* c = root; c; c = nextInPreOrder(c)) {
- if (c == node)
- fprintf(stderr, "*");
- for (const CounterNode* d = c; d && d != root; d = d->parent())
- fprintf(stderr, "\t");
- if (c->isReset())
- fprintf(stderr, "reset: %d %d\n", c->value(), c->countInParent());
- else
- fprintf(stderr, "increment: %d %d\n", c->value(), c->countInParent());
+ for (const CounterNode* current = root; current; current = current->nextInPreOrder()) {
+ fwrite((current == node) ? "*" : " ", 1, 1, stderr);
+ for (const CounterNode* parent = current; parent && parent != root; parent = parent->parent())
+ fwrite(" ", 1, 2, stderr);
+ fprintf(stderr, "%p %s: %d %d P:%p PS:%p NS:%p R:%p\n",
+ current, current->isReset() ? "reset____" : "increment", current->value(),
+ current->countInParent(), current->parent(), current->previousSibling(),
+ current->nextSibling(), current->renderer());
}
}
diff --git a/WebCore/rendering/CounterNode.h b/WebCore/rendering/CounterNode.h
index b432e1d..8081dc6 100644
--- a/WebCore/rendering/CounterNode.h
+++ b/WebCore/rendering/CounterNode.h
@@ -35,6 +35,7 @@
namespace WebCore {
+class AtomicString;
class RenderObject;
class CounterNode : public Noncopyable {
@@ -51,13 +52,19 @@ public:
CounterNode* nextSibling() const { return m_nextSibling; }
CounterNode* firstChild() const { return m_firstChild; }
CounterNode* lastChild() const { return m_lastChild; }
+ CounterNode* lastDescendant() const;
+ CounterNode* previousInPreOrder() const;
+ CounterNode* nextInPreOrder(const CounterNode* stayWithin = 0) const;
+ CounterNode* nextInPreOrderAfterChildren(const CounterNode* stayWithin = 0) const;
- void insertAfter(CounterNode* newChild, CounterNode* beforeChild);
- void removeChild(CounterNode*);
+ void insertAfter(CounterNode* newChild, CounterNode* beforeChild, const AtomicString& identifier);
+ void removeChild(CounterNode*, const AtomicString& identifier);
private:
int computeCountInParent() const;
- void recount();
+ void recount(const AtomicString& identifier);
+ void resetRenderer(const AtomicString& identifier) const;
+ void resetRenderers(const AtomicString& identifier) const;
bool m_isReset;
int m_value;
diff --git a/WebCore/rendering/EllipsisBox.cpp b/WebCore/rendering/EllipsisBox.cpp
index db9a101..bea9d73 100644
--- a/WebCore/rendering/EllipsisBox.cpp
+++ b/WebCore/rendering/EllipsisBox.cpp
@@ -1,6 +1,4 @@
/**
-* This file is part of the html renderer for KDE.
- *
* Copyright (C) 2003, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -34,11 +32,11 @@ void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
RenderStyle* style = m_renderer->style(m_firstLine);
Color textColor = style->color();
if (textColor != context->fillColor())
- context->setFillColor(textColor);
+ 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->textShadow()->blur, style->textShadow()->color, style->colorSpace());
setShadow = true;
}
diff --git a/WebCore/rendering/EllipsisBox.h b/WebCore/rendering/EllipsisBox.h
index 9dbd27f..a228d7a 100644
--- a/WebCore/rendering/EllipsisBox.h
+++ b/WebCore/rendering/EllipsisBox.h
@@ -1,6 +1,4 @@
/**
-* This file is part of the html renderer for KDE.
- *
* Copyright (C) 2003, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/rendering/FixedTableLayout.cpp b/WebCore/rendering/FixedTableLayout.cpp
index 4852708..09af518 100644
--- a/WebCore/rendering/FixedTableLayout.cpp
+++ b/WebCore/rendering/FixedTableLayout.cpp
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2002 Lars Knoll (knoll@kde.org)
* (C) 2002 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2003, 2006 Apple Computer, Inc.
diff --git a/WebCore/rendering/FixedTableLayout.h b/WebCore/rendering/FixedTableLayout.h
index ed7c089..758ddbb 100644
--- a/WebCore/rendering/FixedTableLayout.h
+++ b/WebCore/rendering/FixedTableLayout.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2002 Lars Knoll (knoll@kde.org)
* (C) 2002 Dirk Mueller (mueller@kde.org)
*
diff --git a/WebCore/rendering/HitTestRequest.h b/WebCore/rendering/HitTestRequest.h
index 46dd7b8..ca1445a 100644
--- a/WebCore/rendering/HitTestRequest.h
+++ b/WebCore/rendering/HitTestRequest.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
*
diff --git a/WebCore/rendering/HitTestResult.h b/WebCore/rendering/HitTestResult.h
index 25e1058..d1906ba 100644
--- a/WebCore/rendering/HitTestResult.h
+++ b/WebCore/rendering/HitTestResult.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index baea956..2bd1683 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -974,6 +974,7 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
setClip = true;
}
+ ColorSpace colorSpace = renderer()->style()->colorSpace();
bool setShadow = false;
do {
if (shadow) {
@@ -982,24 +983,24 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
ty -= extraOffset;
extraOffset = 0;
}
- context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color);
+ context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color, colorSpace);
setShadow = true;
shadow = shadow->next;
}
if (paintUnderline) {
- context->setStrokeColor(underline);
+ context->setStrokeColor(underline, colorSpace);
context->setStrokeStyle(SolidStroke);
// Leave one pixel of white between the baseline and the underline.
context->drawLineForText(IntPoint(tx, ty + baselinePos + 1), w, isPrinting);
}
if (paintOverline) {
- context->setStrokeColor(overline);
+ context->setStrokeColor(overline, colorSpace);
context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty), w, isPrinting);
}
if (paintLineThrough) {
- context->setStrokeColor(linethrough);
+ context->setStrokeColor(linethrough, colorSpace);
context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty + 2 * baselinePos / 3), w, isPrinting);
}
diff --git a/WebCore/rendering/InlineRunBox.h b/WebCore/rendering/InlineRunBox.h
index 0f7c29b..cbc82d5 100644
--- a/WebCore/rendering/InlineRunBox.h
+++ b/WebCore/rendering/InlineRunBox.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the line box implementation for KDE.
- *
* Copyright (C) 2003, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 751340d..31e6967 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -214,7 +214,7 @@ Color correctedTextColor(Color textColor, Color backgroundColor)
return textColor.light();
}
-void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, const Color& strokeColor, float strokeThickness)
+void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, const Color& strokeColor, float strokeThickness, ColorSpace colorSpace)
{
int mode = context->textDrawingMode();
if (strokeThickness > 0) {
@@ -225,12 +225,12 @@ void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, con
}
}
- if (mode & cTextFill && fillColor != context->fillColor())
- context->setFillColor(fillColor);
+ if (mode & cTextFill && (fillColor != context->fillColor() || colorSpace != context->fillColorSpace()))
+ context->setFillColor(fillColor, colorSpace);
if (mode & cTextStroke) {
if (strokeColor != context->strokeColor())
- context->setStrokeColor(strokeColor);
+ context->setStrokeColor(strokeColor, colorSpace);
if (strokeThickness != context->strokeThickness())
context->setStrokeThickness(strokeThickness);
}
@@ -257,9 +257,10 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in
static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, int startOffset, int endOffset, const IntPoint& textOrigin, int x, int y, int w, int h, ShadowData* shadow, bool stroked)
{
Color fillColor = context->fillColor();
+ ColorSpace fillColorSpace = context->fillColorSpace();
bool opaque = fillColor.alpha() == 255;
if (!opaque)
- context->setFillColor(Color::black);
+ context->setFillColor(Color::black, fillColorSpace);
do {
IntSize extraOffset;
@@ -279,9 +280,9 @@ static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
extraOffset = IntSize(0, 2 * h + max(0, shadowOffset.height()) + shadowBlur);
shadowOffset -= extraOffset;
}
- context->setShadow(shadowOffset, shadowBlur, shadowColor);
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, fillColorSpace);
} else if (!opaque)
- context->setFillColor(fillColor);
+ context->setFillColor(fillColor, fillColorSpace);
if (startOffset <= endOffset)
context->drawText(font, textRun, textOrigin + extraOffset, startOffset, endOffset);
@@ -465,7 +466,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
if (textStrokeWidth > 0)
context->save();
- updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth);
+ updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());
if (!paintSelectedTextSeparately || ePos <= sPos) {
// FIXME: Truncate right-to-left text correctly.
paintTextWithShadows(context, font, textRun, 0, m_truncation == cNoTruncation ? m_len : m_truncation, textOrigin, m_x + tx, m_y + ty, width(), height(), textShadow, textStrokeWidth > 0);
@@ -481,7 +482,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
if (selectionStrokeWidth > 0)
context->save();
- updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth);
+ updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth, styleToUse->colorSpace());
paintTextWithShadows(context, font, textRun, sPos, ePos, textOrigin, m_x + tx, m_y + ty, width(), height(), selectionShadow, selectionStrokeWidth > 0);
if (selectionStrokeWidth > 0)
@@ -490,7 +491,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());
+ context->setStrokeColor(styleToUse->color(), styleToUse->colorSpace());
paintDecoration(context, tx, ty, d, textShadow);
}
@@ -561,13 +562,13 @@ void InlineTextBox::paintSelection(GraphicsContext* context, int tx, int ty, Ren
c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
context->save();
- updateGraphicsContext(context, c, c, 0); // Don't draw text at all!
+ updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw text at all!
int y = selectionTop();
int h = selectionHeight();
context->clip(IntRect(m_x + tx, y + ty, m_width, h));
context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
direction() == RTL, m_dirOverride || style->visuallyOrdered()),
- IntPoint(m_x + tx, y + ty), h, c, sPos, ePos);
+ IntPoint(m_x + tx, y + ty), h, c, style->colorSpace(), sPos, ePos);
context->restore();
}
@@ -584,13 +585,13 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, int tx,
Color c = Color(225, 221, 85);
- updateGraphicsContext(context, c, c, 0); // Don't draw text at all!
+ updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw text at all!
int y = selectionTop();
int h = selectionHeight();
context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
direction() == RTL, m_dirOverride || style->visuallyOrdered()),
- IntPoint(m_x + tx, y + ty), h, c, sPos, ePos);
+ IntPoint(m_x + tx, y + ty), h, c, style->colorSpace(), sPos, ePos);
context->restore();
}
@@ -660,6 +661,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
setClip = true;
}
+ ColorSpace colorSpace = renderer()->style()->colorSpace();
bool setShadow = false;
do {
@@ -669,24 +671,24 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
ty -= extraOffset;
extraOffset = 0;
}
- context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color);
+ context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color, colorSpace);
setShadow = true;
shadow = shadow->next;
}
if (deco & UNDERLINE) {
- context->setStrokeColor(underline);
+ context->setStrokeColor(underline, colorSpace);
context->setStrokeStyle(SolidStroke);
// Leave one pixel of white between the baseline and the underline.
context->drawLineForText(IntPoint(tx, ty + baseline + 1), width, isPrinting);
}
if (deco & OVERLINE) {
- context->setStrokeColor(overline);
+ context->setStrokeColor(overline, colorSpace);
context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty), width, isPrinting);
}
if (deco & LINE_THROUGH) {
- context->setStrokeColor(linethrough);
+ context->setStrokeColor(linethrough, colorSpace);
context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty + 2 * baseline / 3), width, isPrinting);
}
@@ -698,7 +700,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
context->clearShadow();
}
-void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font, bool grammar)
+void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
{
// Never print spelling/grammar markers (5327887)
if (textRenderer()->document()->printing())
@@ -737,8 +739,11 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
// Store rendered rects for bad grammar markers, so we can hit-test against it elsewhere in order to
// display a toolTip. We don't do this for misspelling markers.
- if (grammar)
+ if (grammar) {
+ markerRect.move(-tx, -ty);
+ markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
+ }
}
// IMPORTANT: The misspelling underline is not considered when calculating the text bounds, so we have to
@@ -761,7 +766,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
pt->drawLineForMisspellingOrBadGrammar(IntPoint(tx + m_x + start, ty + m_y + underlineOffset), width, grammar);
}
-void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font)
+void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font)
{
// Use same y positioning and height as for selection, so that when the selection and this highlight are on
// the same word there are no pieces sticking out.
@@ -771,10 +776,10 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, Do
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
- IntPoint startPoint = IntPoint(m_x + tx, y + ty);
- // Always compute and store the rect associated with this marker
- IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
+ // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
+ IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, y), h, sPos, ePos));
+ markerRect = root()->block()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
// Optionally highlight the text
@@ -783,14 +788,14 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, Do
renderer()->theme()->platformActiveTextSearchHighlightColor() :
renderer()->theme()->platformInactiveTextSearchHighlightColor();
pt->save();
- updateGraphicsContext(pt, color, color, 0); // Don't draw text at all!
+ updateGraphicsContext(pt, color, color, 0, style->colorSpace()); // Don't draw text at all!
pt->clip(IntRect(tx + m_x, ty + y, m_width, h));
- pt->drawHighlightForText(font, run, startPoint, h, color, sPos, ePos);
+ pt->drawHighlightForText(font, run, IntPoint(m_x + tx, y + ty), h, color, style->colorSpace(), sPos, ePos);
pt->restore();
}
}
-void InlineTextBox::computeRectForReplacementMarker(int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font)
+void InlineTextBox::computeRectForReplacementMarker(int /*tx*/, int /*ty*/, const DocumentMarker& marker, RenderStyle* style, const Font& font)
{
// Replacement markers are not actually drawn, but their rects need to be computed for hit testing.
int y = selectionTop();
@@ -799,10 +804,11 @@ void InlineTextBox::computeRectForReplacementMarker(int tx, int ty, DocumentMark
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
- IntPoint startPoint = IntPoint(m_x + tx, y + ty);
+ IntPoint startPoint = IntPoint(m_x, y);
// Compute and store the rect associated with this marker.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
+ markerRect = root()->block()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
}
@@ -817,7 +823,7 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, Re
// Give any document markers that touch this run a chance to draw before the text has been drawn.
// Note end() points at the last char, not one past it like endOffset and ranges do.
for ( ; markerIt != markers.end(); markerIt++) {
- DocumentMarker marker = *markerIt;
+ const DocumentMarker& marker = *markerIt;
// Paint either the background markers or the foreground markers, but not both
switch (marker.type) {
@@ -911,7 +917,7 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, int tx, int
start += 1;
width -= 2;
- ctx->setStrokeColor(underline.color);
+ ctx->setStrokeColor(underline.color, renderer()->style()->colorSpace());
ctx->setStrokeThickness(lineThickness);
ctx->drawLineForText(IntPoint(tx + start, ty + height() - lineThickness), width, textRenderer()->document()->printing());
}
@@ -936,7 +942,7 @@ int InlineTextBox::textPos() const
if (x() == 0)
return 0;
- RenderBlock *blockElement = renderer()->containingBlock();
+ RenderBlock* blockElement = renderer()->containingBlock();
return direction() == RTL ? x() - blockElement->borderRight() - blockElement->paddingRight()
: x() - blockElement->borderLeft() - blockElement->paddingLeft();
}
@@ -947,7 +953,7 @@ int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const
return 0;
RenderText* text = toRenderText(renderer());
- RenderStyle *style = text->style(m_firstLine);
+ RenderStyle* style = text->style(m_firstLine);
const Font* f = &style->font();
return f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()),
_x - m_x, includePartialGlyphs);
diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h
index 3bbb453..80af2e3 100644
--- a/WebCore/rendering/InlineTextBox.h
+++ b/WebCore/rendering/InlineTextBox.h
@@ -34,7 +34,7 @@ const unsigned short cNoTruncation = USHRT_MAX;
const unsigned short cFullTruncation = USHRT_MAX - 1;
// Helper functions shared by InlineTextBox / SVGRootInlineBox
-void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, const Color& strokeColor, float strokeThickness);
+void updateGraphicsContext(GraphicsContext*, const Color& fillColor, const Color& strokeColor, float strokeThickness, ColorSpace);
Color correctedTextColor(Color textColor, Color backgroundColor);
class InlineTextBox : public InlineRunBox {
@@ -131,9 +131,9 @@ protected:
private:
void paintDecoration(GraphicsContext*, int tx, int ty, int decoration, ShadowData*);
void paintSelection(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&);
- void paintSpellingOrGrammarMarker(GraphicsContext*, int tx, int ty, DocumentMarker, RenderStyle*, const Font&, bool grammar);
- void paintTextMatchMarker(GraphicsContext*, int tx, int ty, DocumentMarker, RenderStyle*, const Font&);
- void computeRectForReplacementMarker(int tx, int ty, DocumentMarker, 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&);
+ void computeRectForReplacementMarker(int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&);
};
inline RenderText* InlineTextBox::textRenderer() const
diff --git a/WebCore/rendering/MediaControlElements.cpp b/WebCore/rendering/MediaControlElements.cpp
index 9611660..9c56756 100644
--- a/WebCore/rendering/MediaControlElements.cpp
+++ b/WebCore/rendering/MediaControlElements.cpp
@@ -38,6 +38,7 @@
#include "HTMLNames.h"
#include "LocalizedStrings.h"
#include "MouseEvent.h"
+#include "Page.h"
#include "RenderMedia.h"
#include "RenderSlider.h"
#include "RenderTheme.h"
@@ -347,6 +348,9 @@ MediaControlInputElement::MediaControlInputElement(Document* document, PseudoId
case MEDIA_CONTROLS_VOLUME_SLIDER:
m_displayType = MediaVolumeSlider;
break;
+ case MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON:
+ m_displayType = MediaShowClosedCaptionsButton;
+ break;
default:
ASSERT_NOT_REACHED();
break;
@@ -577,6 +581,29 @@ void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event
// ----------------------------
+MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document* doc, HTMLMediaElement* element)
+ : MediaControlInputElement(doc, MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON, "button", element)
+{
+}
+
+void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ m_mediaElement->setClosedCaptionsVisible(!m_mediaElement->closedCaptionsVisible());
+ setChecked(m_mediaElement->closedCaptionsVisible());
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
+{
+ setDisplayType(m_mediaElement->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
+}
+
+
+// ----------------------------
+
MediaControlTimelineElement::MediaControlTimelineElement(Document* document, HTMLMediaElement* element)
: MediaControlInputElement(document, MEDIA_CONTROLS_TIMELINE, "range", element)
{
@@ -649,10 +676,9 @@ void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
void MediaControlVolumeSliderElement::update()
{
float volume = m_mediaElement->volume();
- if (value().toFloat() != volume) {
+ if (value().toFloat() != volume)
setValue(String::number(volume));
- MediaControlInputElement::update();
- }
+ MediaControlInputElement::update();
}
// ----------------------------
diff --git a/WebCore/rendering/MediaControlElements.h b/WebCore/rendering/MediaControlElements.h
index 8b29773..0ba4aba 100644
--- a/WebCore/rendering/MediaControlElements.h
+++ b/WebCore/rendering/MediaControlElements.h
@@ -54,6 +54,8 @@ enum MediaControlElementType {
MediaSliderThumb,
MediaRewindButton,
MediaReturnToRealtimeButton,
+ MediaShowClosedCaptionsButton,
+ MediaHideClosedCaptionsButton,
MediaUnMuteButton,
MediaPauseButton,
MediaTimelineContainer,
@@ -221,6 +223,15 @@ public:
// ----------------------------
+class MediaControlToggleClosedCaptionsButtonElement : public MediaControlInputElement {
+public:
+ MediaControlToggleClosedCaptionsButtonElement(Document*, HTMLMediaElement*);
+ virtual void defaultEventHandler(Event*);
+ virtual void updateDisplayType();
+};
+
+// ----------------------------
+
class MediaControlTimelineElement : public MediaControlInputElement {
public:
MediaControlTimelineElement(Document*, HTMLMediaElement*);
diff --git a/WebCore/rendering/PointerEventsHitRules.cpp b/WebCore/rendering/PointerEventsHitRules.cpp
index 214fb09..ababcfd 100644
--- a/WebCore/rendering/PointerEventsHitRules.cpp
+++ b/WebCore/rendering/PointerEventsHitRules.cpp
@@ -1,8 +1,6 @@
/*
Copyright (C) 2007 Rob Buis <buis@kde.org>
- This file is part of the KDE project
-
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
diff --git a/WebCore/rendering/PointerEventsHitRules.h b/WebCore/rendering/PointerEventsHitRules.h
index 3d8939a..c17c19c 100644
--- a/WebCore/rendering/PointerEventsHitRules.h
+++ b/WebCore/rendering/PointerEventsHitRules.h
@@ -1,8 +1,6 @@
/*
Copyright (C) 2007 Rob Buis <buis@kde.org>
- This file is part of the KDE project
-
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
diff --git a/WebCore/rendering/RenderArena.h b/WebCore/rendering/RenderArena.h
index ca35361..edf052a 100644
--- a/WebCore/rendering/RenderArena.h
+++ b/WebCore/rendering/RenderArena.h
@@ -36,12 +36,13 @@
#define RenderArena_h
#include "Arena.h"
+#include <wtf/Noncopyable.h>
namespace WebCore {
static const size_t gMaxRecycledSize = 400;
-class RenderArena {
+class RenderArena : public Noncopyable {
public:
RenderArena(unsigned arenaSize = 4096);
~RenderArena();
diff --git a/WebCore/rendering/RenderBR.cpp b/WebCore/rendering/RenderBR.cpp
index e05c8b4..012a433 100644
--- a/WebCore/rendering/RenderBR.cpp
+++ b/WebCore/rendering/RenderBR.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* Copyright (C) 2006 Apple Computer, Inc.
*
diff --git a/WebCore/rendering/RenderBR.h b/WebCore/rendering/RenderBR.h
index 7eae8ea..8850d46 100644
--- a/WebCore/rendering/RenderBR.h
+++ b/WebCore/rendering/RenderBR.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 7040e06..204a0c3 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -44,6 +44,7 @@
#include "RenderView.h"
#include "SelectionController.h"
#include "Settings.h"
+#include "TransformState.h"
#include <wtf/StdLibExtras.h>
#ifdef ANDROID_LAYOUT
@@ -62,13 +63,7 @@ static const int verticalLineClickFudgeFactor = 3;
using namespace HTMLNames;
-static void moveChild(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* from, RenderObjectChildList* fromChildList, RenderObject* child)
-{
- ASSERT(from == child->parent());
- toChildList->appendChildNode(to, fromChildList->removeChildNode(from, child, false), false);
-}
-
-struct ColumnInfo {
+struct ColumnInfo : public Noncopyable {
ColumnInfo()
: m_desiredColumnWidth(0)
, m_desiredColumnCount(1)
@@ -167,6 +162,7 @@ RenderBlock::~RenderBlock()
void RenderBlock::destroy()
{
+<<<<<<< HEAD:WebCore/rendering/RenderBlock.cpp
// Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
// properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
children()->destroyLeftoverChildren();
@@ -178,7 +174,20 @@ void RenderBlock::destroy()
m_inlineContinuation->destroy();
m_inlineContinuation = 0;
}
+=======
+ // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
+ // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
+ children()->destroyLeftoverChildren();
+>>>>>>> webkit.org at r51976:WebCore/rendering/RenderBlock.cpp
+ // Destroy our continuation before anything other than anonymous children.
+ // The reason we don't destroy it before anonymous children is that they may
+ // have continuations of their own that are anonymous children of our continuation.
+ if (m_inlineContinuation) {
+ m_inlineContinuation->destroy();
+ m_inlineContinuation = 0;
+ }
+
if (!documentBeingDestroyed()) {
if (firstLineBox()) {
// We can't wait for RenderBox::destroy to clear the selection,
@@ -406,6 +415,19 @@ RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
m_lineBoxes.appendLineBox(rootBox);
return rootBox;
}
+
+void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child)
+{
+ ASSERT(this == child->parent());
+ toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false);
+}
+
+void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child)
+{
+ ASSERT(this == child->parent());
+ ASSERT(!beforeChild || to == beforeChild->parent());
+ toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false);
+}
void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
{
@@ -443,9 +465,9 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
RenderObject* no = o;
o = no->nextSibling();
- moveChild(block, block->children(), this, children(), no);
+ moveChildTo(block, block->children(), no);
}
- moveChild(block, block->children(), this, children(), inlineRunEnd);
+ moveChildTo(block, block->children(), inlineRunEnd);
}
#ifndef NDEBUG
@@ -520,7 +542,7 @@ void RenderBlock::removeChild(RenderObject* oldChild)
while (o) {
RenderObject* no = o;
o = no->nextSibling();
- moveChild(prevBlock, prevBlock->children(), nextBlock, nextBlock->children(), no);
+ nextBlock->moveChildTo(prevBlock, prevBlock->children(), no);
}
nextBlock->deleteLineBoxTree();
@@ -543,7 +565,7 @@ void RenderBlock::removeChild(RenderObject* oldChild)
while (o) {
RenderObject* no = o;
o = no->nextSibling();
- moveChild(this, children(), anonBlock, anonBlock->children(), no);
+ anonBlock->moveChildTo(this, children(), no);
}
// Delete the now-empty block's lines and nuke it.
@@ -613,15 +635,15 @@ void RenderBlock::finishDelayUpdateScrollInfo()
if (gDelayUpdateScrollInfo == 0) {
ASSERT(gDelayedUpdateScrollInfoSet);
- for (DelayedUpdateScrollInfoSet::iterator it = gDelayedUpdateScrollInfoSet->begin(); it != gDelayedUpdateScrollInfoSet->end(); ++it) {
+ OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
+ gDelayedUpdateScrollInfoSet = 0;
+
+ for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
RenderBlock* block = *it;
if (block->hasOverflowClip()) {
block->layer()->updateScrollInfoAfterLayout();
}
}
-
- delete gDelayedUpdateScrollInfoSet;
- gDelayedUpdateScrollInfoSet = 0;
}
}
@@ -876,7 +898,11 @@ void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marg
}
y += (collapsedTopPos - collapsedTopNeg) - marginTop;
}
- child->layer()->setStaticY(y);
+ RenderLayer* childLayer = child->layer();
+ if (childLayer->staticY() != y) {
+ child->layer()->setStaticY(y);
+ child->setChildNeedsLayout(true, false);
+ }
}
}
@@ -965,7 +991,7 @@ bool RenderBlock::handleRunInChild(RenderBox* child)
// Move the nodes from the old child to the new child, but skip any :before/:after content. It has already
// been regenerated by the new inline.
for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild; runInChild = runInChild->nextSibling()) {
- if (runInIsGenerated || runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER) {
+ if (runInIsGenerated || (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER)) {
blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
}
@@ -1535,7 +1561,7 @@ void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
// Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
// z-index. We paint after we painted the background/border, so that the scrollbars will
// sit above the background/border.
- if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground))
+ if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && shouldPaintWithinRoot(paintInfo))
layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
}
@@ -1919,23 +1945,28 @@ bool RenderBlock::isSelectionRoot() const
return false;
}
-GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* /*repaintContainer*/)
+GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
{
ASSERT(!needsLayout());
if (!shouldPaintSelectionGaps())
return GapRects();
- // FIXME: this is broken with transforms and a non-null repaintContainer
- FloatPoint absContentPoint = localToAbsolute(FloatPoint());
+ // 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();
+
if (hasOverflowClip())
- absContentPoint -= layer()->scrolledContentOffset();
+ layer()->subtractScrolledContentOffset(x, y);
int lastTop = 0;
int lastLeft = leftSelectionOffset(this, lastTop);
int lastRight = rightSelectionOffset(this, lastTop);
- return fillSelectionGaps(this, absContentPoint.x(), absContentPoint.y(), absContentPoint.x(), absContentPoint.y(), lastTop, lastLeft, lastRight);
+ return fillSelectionGaps(this, x, y, x, y, lastTop, lastLeft, lastRight);
}
void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
@@ -1945,7 +1976,14 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
int lastLeft = leftSelectionOffset(this, lastTop);
int lastRight = rightSelectionOffset(this, lastTop);
paintInfo.context->save();
- fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
+ IntRect gapRectsBounds = fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
+ if (!gapRectsBounds.isEmpty()) {
+ if (RenderLayer* layer = enclosingLayer()) {
+ IntSize offset = hasLayer() ? IntSize() : offsetFromAncestorContainer(layer->renderer());
+ gapRectsBounds.move(offset - IntSize(tx, ty));
+ layer->addBlockSelectionGapsBounds(gapRectsBounds);
+ }
+ }
paintInfo.context->restore();
}
}
@@ -2132,7 +2170,7 @@ IntRect RenderBlock::fillHorizontalSelectionGap(RenderObject* selObj, int xPos,
return IntRect();
IntRect gapRect(xPos, yPos, width, height);
if (paintInfo && selObj->style()->visibility() == VISIBLE)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -2153,7 +2191,7 @@ IntRect RenderBlock::fillVerticalSelectionGap(int lastTop, int lastLeft, int las
IntRect gapRect(left, top, width, height);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
return gapRect;
}
@@ -2169,7 +2207,7 @@ IntRect RenderBlock::fillLeftSelectionGap(RenderObject* selObj, int xPos, int yP
IntRect gapRect(left, top, width, height);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -2185,7 +2223,7 @@ IntRect RenderBlock::fillRightSelectionGap(RenderObject* selObj, int xPos, int y
IntRect gapRect(left, top, width, height);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -3418,7 +3456,7 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint&
RootInlineBox* firstRootBoxWithChildren = 0;
RootInlineBox* lastRootBoxWithChildren = 0;
for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
- if (!root->firstChild())
+ if (!root->firstLeafChild())
continue;
if (!firstRootBoxWithChildren)
firstRootBoxWithChildren = root;
@@ -3565,11 +3603,15 @@ void RenderBlock::calcColumnWidth()
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
} else if (colGap < availWidth) {
desiredColumnCount = availWidth / colGap;
+ if (desiredColumnCount < 1)
+ desiredColumnCount = 1;
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
}
} else if (style()->hasAutoColumnCount()) {
if (colWidth < availWidth) {
desiredColumnCount = (availWidth + colGap) / (colWidth + colGap);
+ if (desiredColumnCount < 1)
+ desiredColumnCount = 1;
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
}
} else {
@@ -3579,6 +3621,8 @@ void RenderBlock::calcColumnWidth()
desiredColumnWidth = colWidth;
} else if (colWidth < availWidth) {
desiredColumnCount = (availWidth + colGap) / (colWidth + colGap);
+ if (desiredColumnCount < 1)
+ desiredColumnCount = 1;
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
}
}
@@ -3629,7 +3673,7 @@ Vector<IntRect>* RenderBlock::columnRects() const
return &gColumnInfoMap->get(this)->m_columnRects;
}
-int RenderBlock::layoutColumns(int endOfContent)
+int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
{
// Don't do anything if we have no columns
if (!hasColumns())
@@ -3642,17 +3686,20 @@ int RenderBlock::layoutColumns(int endOfContent)
bool computeIntrinsicHeight = (endOfContent == -1);
- // Fill the columns in to the available height. Attempt to balance the height of the columns
- int availableHeight = contentHeight();
- int colHeight = computeIntrinsicHeight ? availableHeight / desiredColumnCount : availableHeight;
-
+ // Fill the columns in to the available height. Attempt to balance the height of the columns.
// Add in half our line-height to help with best-guess initial balancing.
int columnSlop = lineHeight(false) / 2;
int remainingSlopSpace = columnSlop * desiredColumnCount;
+ int availableHeight = contentHeight();
+ int colHeight;
+ if (computeIntrinsicHeight && requestedColumnHeight >= 0)
+ colHeight = requestedColumnHeight;
+ else if (computeIntrinsicHeight)
+ colHeight = availableHeight / desiredColumnCount + columnSlop;
+ else
+ colHeight = availableHeight;
+ int originalColHeight = colHeight;
- if (computeIntrinsicHeight)
- colHeight += columnSlop;
-
int colGap = columnGap();
// Compute a collection of column rects.
@@ -3668,7 +3715,8 @@ int RenderBlock::layoutColumns(int endOfContent)
int currY = top;
unsigned colCount = desiredColumnCount;
int maxColBottom = borderTop() + paddingTop();
- int contentBottom = top + availableHeight;
+ int contentBottom = top + availableHeight;
+ int minimumColumnHeight = -1;
for (unsigned i = 0; i < colCount; i++) {
// If we aren't constrained, then the last column can just get all the remaining space.
if (computeIntrinsicHeight && i == colCount - 1)
@@ -3688,6 +3736,11 @@ int RenderBlock::layoutColumns(int endOfContent)
paintObject(paintInfo, 0, 0);
setHasColumns(true);
+ if (computeIntrinsicHeight && v->minimumColumnHeight() > originalColHeight) {
+ // The initial column height was too small to contain one line of text.
+ minimumColumnHeight = max(minimumColumnHeight, v->minimumColumnHeight());
+ }
+
int adjustedBottom = v->bestTruncatedAt();
if (adjustedBottom <= currY)
adjustedBottom = currY + colHeight;
@@ -3724,6 +3777,11 @@ int RenderBlock::layoutColumns(int endOfContent)
colCount++;
}
+ if (minimumColumnHeight >= 0) {
+ // If originalColHeight was too small, we need to try to layout again.
+ return layoutColumns(endOfContent, minimumColumnHeight);
+ }
+
int overflowRight = max(width(), currX - colGap);
int overflowLeft = min(0, currX + desiredColumnWidth + colGap);
int overflowHeight = maxColBottom;
@@ -4208,6 +4266,10 @@ void RenderBlock::calcInlinePrefWidths()
} else
inlineMax += childMax;
}
+
+ // Ignore spaces after a list marker.
+ if (child->isListMarker())
+ stripFrontSpaces = true;
} else {
m_minPrefWidth = max(inlineMin, m_minPrefWidth);
m_maxPrefWidth = max(inlineMax, m_maxPrefWidth);
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 1628701..985074d 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -140,6 +140,9 @@ public:
RenderBlock* createAnonymousBlock(bool isFlexibleBox = false) const;
protected:
+ void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child);
+ void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child);
+
int maxTopPosMargin() const { return m_maxMargin ? m_maxMargin->m_topPos : MaxMargin::topPosDefault(this); }
int maxTopNegMargin() const { return m_maxMargin ? m_maxMargin->m_topNeg : MaxMargin::topNegDefault(this); }
int maxBottomPosMargin() const { return m_maxMargin ? m_maxMargin->m_bottomPos : MaxMargin::bottomPosDefault(this); }
@@ -377,13 +380,13 @@ private:
void offsetForContents(int& tx, int& ty) const;
void calcColumnWidth();
- int layoutColumns(int endOfContent = -1);
+ int layoutColumns(int endOfContent = -1, int requestedColumnHeight = -1);
bool expandsToEncloseOverhangingFloats() const;
void updateScrollInfoAfterLayout();
- struct FloatingObject {
+ struct FloatingObject : Noncopyable {
enum Type {
FloatLeft,
FloatRight
@@ -499,7 +502,7 @@ private:
RenderInline* m_inlineContinuation;
// Allocated only when some of these fields have non-default values
- struct MaxMargin {
+ struct MaxMargin : Noncopyable {
MaxMargin(const RenderBlock* o)
: m_topPos(topPosDefault(o))
, m_topNeg(topNegDefault(o))
diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp
index cf6514e..8517d6d 100644
--- a/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -1869,10 +1869,10 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
currentCharacterIsSpace = false;
currentCharacterIsWS = false;
trailingSpaceObject = 0;
-
+
// Optimize for a common case. If we can't find whitespace after the list
// item, then this is all moot. -dwh
- if (o->isListMarker() && !toRenderListMarker(o)->isInside()) {
+ if (o->isListMarker()) {
if (style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) {
// Like with inline flows, we start ignoring spaces to make sure that any
// additional spaces we see will be discarded.
@@ -1880,6 +1880,8 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
currentCharacterIsWS = true;
ignoringSpaces = true;
}
+ if (toRenderListMarker(o)->isInside())
+ tmpW += replacedBox->width() + replacedBox->marginLeft() + replacedBox->marginRight() + inlineWidth(o);
} else
tmpW += replacedBox->width() + replacedBox->marginLeft() + replacedBox->marginRight() + inlineWidth(o);
} else if (o->isText()) {
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 8e0f3b7..a7c2e63 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -1523,7 +1523,7 @@ void RenderBox::calcHeight()
// height since we don't set a height in RenderView when we're printing. So without this quirk, the
// height has nothing to be a percentage of, and it ends up being 0. That is bad.
bool printingNeedsBaseHeight = document()->printing() && h.isPercent()
- && (isRoot() || isBody() && document()->documentElement()->renderer()->style()->height().isPercent());
+ && (isRoot() || (isBody() && document()->documentElement()->renderer()->style()->height().isPercent()));
if (stretchesToViewHeight() || printingNeedsBaseHeight) {
int margins = collapsedMarginTop() + collapsedMarginBottom();
int visHeight = document()->printing() ? view()->frameView()->visibleHeight() : view()->viewHeight();
@@ -2747,7 +2747,7 @@ VisiblePosition RenderBox::positionForPoint(const IntPoint& point)
{
// no children...return this render object's element, if there is one, and offset 0
if (!firstChild())
- return createVisiblePosition(firstDeepEditingPositionForNode(node()));
+ return createVisiblePosition(node() ? firstDeepEditingPositionForNode(node()) : Position(0, 0));
int xPos = point.x();
int yPos = point.y();
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index 23dad2d..98960e0 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -441,14 +441,14 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
if (baseColor.alpha() > 0) {
context->save();
context->setCompositeOperation(CompositeCopy);
- context->fillRect(rect, baseColor);
+ context->fillRect(rect, baseColor, style()->colorSpace());
context->restore();
} else
context->clearRect(rect);
}
if (bgColor.isValid() && bgColor.alpha() > 0)
- context->fillRect(rect, bgColor);
+ context->fillRect(rect, bgColor, style()->colorSpace());
}
// no progressive loading of the background image
@@ -477,7 +477,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
clientForBackgroundImage = bodyRenderer;
}
}
- context->drawTiledImage(bg->image(clientForBackgroundImage, tileSize), destRect, phase, tileSize, compositeOp);
+ context->drawTiledImage(bg->image(clientForBackgroundImage, tileSize), style()->colorSpace(), destRect, phase, tileSize, compositeOp);
}
}
@@ -706,6 +706,7 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
(imageHeight - topSlice - bottomSlice) > 0 && (h - topWidth - bottomWidth) > 0;
Image* image = styleImage->image(this, imageSize);
+ ColorSpace colorSpace = style->colorSpace();
if (drawLeft) {
// Paint the top and bottom left corners.
@@ -713,18 +714,18 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// The top left corner rect is (tx, ty, leftWidth, topWidth)
// The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice)
if (drawTop)
- graphicsContext->drawImage(image, IntRect(tx, ty, leftWidth, topWidth),
+ graphicsContext->drawImage(image, colorSpace, IntRect(tx, ty, leftWidth, topWidth),
IntRect(0, 0, leftSlice, topSlice), op);
// The bottom left corner rect is (tx, ty + h - bottomWidth, leftWidth, bottomWidth)
// The rect to use from within the image is (0, imageHeight - bottomSlice, leftSlice, botomSlice)
if (drawBottom)
- graphicsContext->drawImage(image, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
+ graphicsContext->drawImage(image, colorSpace, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
IntRect(0, imageHeight - bottomSlice, leftSlice, bottomSlice), op);
// Paint the left edge.
// Have to scale and tile into the border rect.
- graphicsContext->drawTiledImage(image, IntRect(tx, ty + topWidth, leftWidth,
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx, ty + topWidth, leftWidth,
h - topWidth - bottomWidth),
IntRect(0, topSlice, leftSlice, imageHeight - topSlice - bottomSlice),
Image::StretchTile, (Image::TileRule)vRule, op);
@@ -735,17 +736,17 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// The top right corner rect is (tx + w - rightWidth, ty, rightWidth, topWidth)
// The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice)
if (drawTop)
- graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
+ graphicsContext->drawImage(image, colorSpace, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
IntRect(imageWidth - rightSlice, 0, rightSlice, topSlice), op);
// The bottom right corner rect is (tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth)
// The rect to use from within the image is (imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice)
if (drawBottom)
- graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
+ graphicsContext->drawImage(image, colorSpace, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
IntRect(imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice), op);
// Paint the right edge.
- graphicsContext->drawTiledImage(image, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
h - topWidth - bottomWidth),
IntRect(imageWidth - rightSlice, topSlice, rightSlice, imageHeight - topSlice - bottomSlice),
Image::StretchTile, (Image::TileRule)vRule, op);
@@ -753,20 +754,20 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// Paint the top edge.
if (drawTop)
- graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
IntRect(leftSlice, 0, imageWidth - rightSlice - leftSlice, topSlice),
(Image::TileRule)hRule, Image::StretchTile, op);
// Paint the bottom edge.
if (drawBottom)
- graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + h - bottomWidth,
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty + h - bottomWidth,
w - leftWidth - rightWidth, bottomWidth),
IntRect(leftSlice, imageHeight - bottomSlice, imageWidth - rightSlice - leftSlice, bottomSlice),
(Image::TileRule)hRule, Image::StretchTile, op);
// Paint the middle.
if (drawMiddle)
- graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
h - topWidth - bottomWidth),
IntRect(leftSlice, topSlice, imageWidth - rightSlice - leftSlice, imageHeight - topSlice - bottomSlice),
(Image::TileRule)hRule, (Image::TileRule)vRule, op);
@@ -1198,7 +1199,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
shadowOffset -= extraOffset;
fillRect.move(extraOffset);
- context->setShadow(shadowOffset, shadowBlur, shadowColor);
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
if (hasBorderRadius) {
IntRect rectToClipOut = rect;
IntSize topLeftToClipOut = topLeft;
@@ -1241,7 +1242,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
if (!rectToClipOut.isEmpty())
context->clipOutRoundedRect(rectToClipOut, topLeftToClipOut, topRightToClipOut, bottomLeftToClipOut, bottomRightToClipOut);
- context->fillRoundedRect(fillRect, topLeft, topRight, bottomLeft, bottomRight, Color::black);
+ context->fillRoundedRect(fillRect, topLeft, topRight, bottomLeft, bottomRight, Color::black, s->colorSpace());
} else {
IntRect rectToClipOut = rect;
@@ -1258,7 +1259,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
if (!rectToClipOut.isEmpty())
context->clipOut(rectToClipOut);
- context->fillRect(fillRect, Color::black);
+ context->fillRect(fillRect, Color::black, s->colorSpace());
}
context->restore();
@@ -1269,9 +1270,9 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
if (holeRect.isEmpty()) {
if (hasBorderRadius)
- context->fillRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, shadowColor);
+ context->fillRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, shadowColor, s->colorSpace());
else
- context->fillRect(rect, shadowColor);
+ context->fillRect(rect, shadowColor, s->colorSpace());
continue;
}
if (!begin) {
@@ -1320,8 +1321,8 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
context->addPath(Path::createRectangle(holeRect));
context->setFillRule(RULE_EVENODD);
- context->setFillColor(fillColor);
- context->setShadow(shadowOffset, shadowBlur, shadowColor);
+ context->setFillColor(fillColor, s->colorSpace());
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
context->fillPath();
context->restore();
diff --git a/WebCore/rendering/RenderButton.cpp b/WebCore/rendering/RenderButton.cpp
index f3ae558..3ecd382 100644
--- a/WebCore/rendering/RenderButton.cpp
+++ b/WebCore/rendering/RenderButton.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the html renderer for KDE.
- *
* Copyright (C) 2005 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/rendering/RenderButton.h b/WebCore/rendering/RenderButton.h
index 3a74589..7fd6ab0 100644
--- a/WebCore/rendering/RenderButton.h
+++ b/WebCore/rendering/RenderButton.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the html renderer for KDE.
- *
* Copyright (C) 2005 Apple Computer
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/rendering/RenderCounter.cpp b/WebCore/rendering/RenderCounter.cpp
index 17c6dad..b0aefc5 100644
--- a/WebCore/rendering/RenderCounter.cpp
+++ b/WebCore/rendering/RenderCounter.cpp
@@ -38,7 +38,7 @@ using namespace HTMLNames;
typedef HashMap<RefPtr<AtomicStringImpl>, CounterNode*> CounterMap;
typedef HashMap<const RenderObject*, CounterMap*> CounterMaps;
-static CounterNode* counter(RenderObject*, const AtomicString& counterName, bool alwaysCreateCounter);
+static CounterNode* makeCounterNode(RenderObject*, const AtomicString& counterName, bool alwaysCreateCounter);
static CounterMaps& counterMaps()
{
@@ -53,30 +53,6 @@ static inline RenderObject* previousSiblingOrParent(RenderObject* object)
return object->parent();
}
-static CounterNode* lastDescendant(CounterNode* node)
-{
- CounterNode* last = node->lastChild();
- if (!last)
- return 0;
-
- while (CounterNode* lastChild = last->lastChild())
- last = lastChild;
-
- return last;
-}
-
-static CounterNode* previousInPreOrder(CounterNode* node)
-{
- CounterNode* previous = node->previousSibling();
- if (!previous)
- return node->parent();
-
- while (CounterNode* lastChild = previous->lastChild())
- previous = lastChild;
-
- return previous;
-}
-
static bool planCounter(RenderObject* object, const AtomicString& counterName, bool& isReset, int& value)
{
ASSERT(object);
@@ -133,59 +109,124 @@ static bool planCounter(RenderObject* object, const AtomicString& counterName, b
return false;
}
-static bool findPlaceForCounter(RenderObject* object, const AtomicString& counterName,
- bool isReset, CounterNode*& parent, CounterNode*& previousSibling)
+// - Finds the insertion point for the counter described by counterOwner, isReset and
+// identifier in the CounterNode tree for identifier and sets parent and
+// previousSibling accordingly.
+// - The function returns true if the counter whose insertion point is searched is NOT
+// the root of the tree.
+// - The root of the tree is a counter reference that is not in the scope of any other
+// counter with the same identifier.
+// - All the counter references with the same identifier as this one that are in
+// children or subsequent siblings of the renderer that owns the root of the tree
+// form the rest of of the nodes of the tree.
+// - The root of the tree is always a reset type reference.
+// - A subtree rooted at any reset node in the tree is equivalent to all counter
+// references that are in the scope of the counter or nested counter defined by that
+// reset node.
+// - Non-reset CounterNodes cannot have descendants.
+
+static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString& identifier, bool isReset, CounterNode*& parent, CounterNode*& previousSibling)
{
- // Find the appropriate previous sibling for insertion into the parent node
- // by searching in render tree order for a child of the counter.
- parent = 0;
+ // We cannot stop searching for counters with the same identifier before we also
+ // check this renderer, because it may affect the positioning in the tree of our counter.
+ RenderObject* searchEndRenderer = previousSiblingOrParent(counterOwner);
+ // We check renderers in preOrder from the renderer that our counter is attached to
+ // towards the begining of the document for counters with the same identifier as the one
+ // we are trying to find a place for. This is the next renderer to be checked.
+ RenderObject* currentRenderer = counterOwner->previousInPreOrder();
previousSibling = 0;
- RenderObject* resetCandidate = isReset ? object->parent() : previousSiblingOrParent(object);
- RenderObject* prevCounterCandidate = object;
- CounterNode* candidateCounter = 0;
- // When a reset counter is chosen as candidateCounter, we'll
- // decide the new node should be a child of the reset node or a
- // sibling or the reset node. This flag controls it.
- bool createChildForReset = true;
- while ((prevCounterCandidate = prevCounterCandidate->previousInPreOrder())) {
- CounterNode* c = counter(prevCounterCandidate, counterName, false);
- if (prevCounterCandidate == resetCandidate) {
- if (!candidateCounter) {
- candidateCounter = c;
- createChildForReset = true;
- }
- if (candidateCounter) {
- if (createChildForReset && candidateCounter->isReset()) {
- parent = candidateCounter;
- previousSibling = 0;
- } else {
- parent = candidateCounter->parent();
- previousSibling = candidateCounter;
+ while (currentRenderer) {
+ CounterNode* currentCounter = makeCounterNode(currentRenderer, identifier, false);
+ if (searchEndRenderer == currentRenderer) {
+ // We may be at the end of our search.
+ if (currentCounter) {
+ // We have a suitable counter on the EndSearchRenderer.
+ if (previousSibling) { // But we already found another counter that we come after.
+ if (currentCounter->isReset()) {
+ // We found a reset counter that is on a renderer that is a sibling of ours or a parent.
+ if (isReset && currentRenderer->parent() == counterOwner->parent()) {
+ // We are also a reset counter and the previous reset was on a sibling renderer
+ // hence we are the next sibling of that counter if that reset is not a root or
+ // we are a root node if that reset is a root.
+ parent = currentCounter->parent();
+ previousSibling = parent ? currentCounter : 0;
+ return parent;
+ }
+ // We are not a reset node or the previous reset must be on an ancestor of our renderer
+ // hence we must be a child of that reset counter.
+ parent = currentCounter;
+ ASSERT(previousSibling->parent() == currentCounter);
+ return true;
+ }
+ // CurrentCounter, the counter at the EndSearchRenderer, is not reset.
+ if (!isReset || currentRenderer->parent() != counterOwner->parent()) {
+ // If the node we are placing is not reset or we have found a counter that is attached
+ // to an ancestor of the placed counter's renderer we know we are a sibling of that node.
+ ASSERT(currentCounter->parent() == previousSibling->parent());
+ parent = currentCounter->parent();
+ return true;
+ }
+ } else {
+ // We are at the potential end of the search, but we had no previous sibling candidate
+ // In this case we follow pretty much the same logic as above but no ASSERTs about
+ // previousSibling, and when we are a sibling of the end counter we must set previousSibling
+ // to currentCounter.
+ if (currentCounter->isReset()) {
+ if (isReset && currentRenderer->parent() == counterOwner->parent()) {
+ parent = currentCounter->parent();
+ previousSibling = currentCounter;
+ return parent;
+ }
+ parent = currentCounter;
+ return true;
+ }
+ if (!isReset || currentRenderer->parent() != counterOwner->parent()) {
+ parent = currentCounter->parent();
+ previousSibling = currentCounter;
+ return true;
+ }
+ previousSibling = currentCounter;
}
- return true;
}
- resetCandidate = previousSiblingOrParent(resetCandidate);
- } else if (c) {
- if (c->isReset()) {
- if (c->parent()) {
- // The new node may be the next sibling of this reset node.
- createChildForReset = false;
- candidateCounter = c;
- } else {
- createChildForReset = true;
- candidateCounter = 0;
- }
- } else if (!candidateCounter) {
- createChildForReset = true;
- candidateCounter = c;
+ // We come here if the previous sibling or parent of our renderer had no
+ // good counter, or we are a reset node and the counter on the previous sibling
+ // of our renderer was not a reset counter.
+ // Set a new goal for the end of the search.
+ searchEndRenderer = previousSiblingOrParent(currentRenderer);
+ } else {
+ // We are searching descendants of a previous sibling of the renderer that the
+ // counter being placed is attached to.
+ if (currentCounter) {
+ // We found a suitable counter.
+ if (previousSibling) {
+ // Since we had a suitable previous counter before, we should only consider this one as our
+ // previousSibling if it is a reset counter and hence the current previousSibling is its child.
+ if (currentCounter->isReset()) {
+ previousSibling = currentCounter;
+ // We are no longer interested in previous siblings of the currentRenderer or their children
+ // as counters they may have attached cannot be the previous sibling of the counter we are placing.
+ currentRenderer = currentRenderer->parent();
+ continue;
+ }
+ } else
+ previousSibling = currentCounter;
+ currentRenderer = previousSiblingOrParent(currentRenderer);
+ continue;
}
}
+ // This function is designed so that the same test is not done twice in an iteration, except for this one
+ // which may be done twice in some cases. Rearranging the decision points though, to accommodate this
+ // performance improvement would create more code duplication than is worthwhile in my oppinion and may further
+ // impede the readability of this already complex algorithm.
+ if (previousSibling)
+ currentRenderer = previousSiblingOrParent(currentRenderer);
+ else
+ currentRenderer = currentRenderer->previousInPreOrder();
}
-
return false;
}
-static CounterNode* counter(RenderObject* object, const AtomicString& counterName, bool alwaysCreateCounter)
+static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& counterName, bool alwaysCreateCounter)
{
ASSERT(object);
@@ -204,7 +245,7 @@ static CounterNode* counter(RenderObject* object, const AtomicString& counterNam
CounterNode* newNode;
if (findPlaceForCounter(object, counterName, isReset, newParent, newPreviousSibling)) {
newNode = new CounterNode(object, isReset, value);
- newParent->insertAfter(newNode, newPreviousSibling);
+ newParent->insertAfter(newNode, newPreviousSibling, counterName);
} else {
// Make a reset node for counters that aren't inside an existing reset node.
newNode = new CounterNode(object, true, value);
@@ -246,7 +287,7 @@ PassRefPtr<StringImpl> RenderCounter::originalText() const
return 0;
if (!m_counterNode)
- m_counterNode = counter(parent(), m_counter.identifier(), true);
+ m_counterNode = makeCounterNode(parent(), m_counter.identifier(), true);
CounterNode* child = m_counterNode;
int value = child->isReset() ? child->value() : child->countInParent();
@@ -272,24 +313,26 @@ void RenderCounter::calcPrefWidths(int lead)
RenderText::calcPrefWidths(lead);
}
-void RenderCounter::invalidate()
+void RenderCounter::invalidate(const AtomicString& identifier)
{
+ if (m_counter.identifier() != identifier)
+ return;
m_counterNode = 0;
setNeedsLayoutAndPrefWidthsRecalc();
}
-static void destroyCounterNodeChildren(AtomicStringImpl* identifier, CounterNode* node)
+static void destroyCounterNodeChildren(const AtomicString& identifier, CounterNode* node)
{
CounterNode* previous;
- for (CounterNode* child = lastDescendant(node); child && child != node; child = previous) {
- previous = previousInPreOrder(child);
- child->parent()->removeChild(child);
- ASSERT(counterMaps().get(child->renderer())->get(identifier) == child);
- counterMaps().get(child->renderer())->remove(identifier);
+ for (CounterNode* child = node->lastDescendant(); child && child != node; child = previous) {
+ previous = child->previousInPreOrder();
+ child->parent()->removeChild(child, identifier);
+ ASSERT(counterMaps().get(child->renderer())->get(identifier.impl()) == child);
+ counterMaps().get(child->renderer())->remove(identifier.impl());
if (!child->renderer()->documentBeingDestroyed()) {
RenderObjectChildList* children = child->renderer()->virtualChildren();
if (children)
- children->invalidateCounters(child->renderer());
+ children->invalidateCounters(child->renderer(), identifier);
}
delete child;
}
@@ -306,9 +349,10 @@ void RenderCounter::destroyCounterNodes(RenderObject* object)
CounterMap::const_iterator end = map->end();
for (CounterMap::const_iterator it = map->begin(); it != end; ++it) {
CounterNode* node = it->second;
- destroyCounterNodeChildren(it->first.get(), node);
+ AtomicString identifier(it->first.get());
+ destroyCounterNodeChildren(identifier, node);
if (CounterNode* parent = node->parent())
- parent->removeChild(node);
+ parent->removeChild(node, identifier);
delete node;
}
diff --git a/WebCore/rendering/RenderCounter.h b/WebCore/rendering/RenderCounter.h
index 961968e..356f1bd 100644
--- a/WebCore/rendering/RenderCounter.h
+++ b/WebCore/rendering/RenderCounter.h
@@ -33,7 +33,11 @@ class RenderCounter : public RenderText {
public:
RenderCounter(Document*, const CounterContent&);
- void invalidate();
+ // Removes the reference to the CounterNode associated with this renderer
+ // if its identifier matches the argument.
+ // This is used to cause a counter display update when the CounterNode
+ // tree for identifier changes.
+ void invalidate(const AtomicString& identifier);
static void destroyCounterNodes(RenderObject*);
diff --git a/WebCore/rendering/RenderFieldset.cpp b/WebCore/rendering/RenderFieldset.cpp
index 8618d11..1f2b371 100644
--- a/WebCore/rendering/RenderFieldset.cpp
+++ b/WebCore/rendering/RenderFieldset.cpp
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
diff --git a/WebCore/rendering/RenderFileUploadControl.cpp b/WebCore/rendering/RenderFileUploadControl.cpp
index 72623f7..37ee8fb 100644
--- a/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/WebCore/rendering/RenderFileUploadControl.cpp
@@ -63,8 +63,13 @@ private:
RenderFileUploadControl::RenderFileUploadControl(HTMLInputElement* input)
: RenderBlock(input)
, m_button(0)
- , m_fileChooser(FileChooser::create(this, input->value()))
{
+ FileList* list = input->files();
+ Vector<String> filenames;
+ unsigned length = list ? list->length() : 0;
+ for (unsigned i = 0; i < length; ++i)
+ filenames.append(list->item(i)->path());
+ m_fileChooser = FileChooser::create(this, filenames);
}
RenderFileUploadControl::~RenderFileUploadControl()
@@ -184,7 +189,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
}
if (paintInfo.phase == PaintPhaseForeground) {
- const String& displayedFilename = m_fileChooser->basenameForWidth(style()->font(), maxFilenameWidth());
+ const String& displayedFilename = fileTextValue();
unsigned length = displayedFilename.length();
const UChar* string = displayedFilename.characters();
TextRun textRun(string, length, false, 0, 0, style()->direction() == RTL, style()->unicodeBidi() == Override);
@@ -204,7 +209,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
+ buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
+ buttonRenderer->baselinePosition(true, false);
- paintInfo.context->setFillColor(style()->color());
+ paintInfo.context->setFillColor(style()->color(), style()->colorSpace());
// Draw the filename
paintInfo.context->drawBidiText(style()->font(), textRun, IntPoint(textX, textY));
@@ -284,7 +289,7 @@ String RenderFileUploadControl::buttonValue()
return m_button->value();
}
-String RenderFileUploadControl::fileTextValue()
+String RenderFileUploadControl::fileTextValue() const
{
return m_fileChooser->basenameForWidth(style()->font(), maxFilenameWidth());
}
diff --git a/WebCore/rendering/RenderFileUploadControl.h b/WebCore/rendering/RenderFileUploadControl.h
index bd7d62a..72ba308 100644
--- a/WebCore/rendering/RenderFileUploadControl.h
+++ b/WebCore/rendering/RenderFileUploadControl.h
@@ -37,6 +37,8 @@ public:
RenderFileUploadControl(HTMLInputElement*);
virtual ~RenderFileUploadControl();
+ virtual bool isFileUploadControl() const { return true; }
+
void click();
void valueChanged();
@@ -44,7 +46,7 @@ public:
void receiveDroppedFiles(const Vector<String>&);
String buttonValue();
- String fileTextValue();
+ String fileTextValue() const;
bool allowsMultipleFiles();
@@ -66,10 +68,16 @@ private:
inline RenderFileUploadControl* toRenderFileUploadControl(RenderObject* object)
{
- ASSERT(!object || !strcmp(object->renderName(), "RenderFileUploadControl"));
+ ASSERT(!object || object->isFileUploadControl());
return static_cast<RenderFileUploadControl*>(object);
}
+inline const RenderFileUploadControl* toRenderFileUploadControl(const RenderObject* object)
+{
+ ASSERT(!object || object->isFileUploadControl());
+ return static_cast<const RenderFileUploadControl*>(object);
+}
+
// This will catch anyone doing an unnecessary cast.
void toRenderFileUploadControl(const RenderFileUploadControl*);
diff --git a/WebCore/rendering/RenderFlexibleBox.cpp b/WebCore/rendering/RenderFlexibleBox.cpp
index f32e6e3..6882097 100644
--- a/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/WebCore/rendering/RenderFlexibleBox.cpp
@@ -426,8 +426,13 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
child->layer()->setStaticX(xPos);
else child->layer()->setStaticX(width() - xPos);
}
- if (child->style()->hasStaticY())
- child->layer()->setStaticY(yPos);
+ if (child->style()->hasStaticY()) {
+ RenderLayer* childLayer = child->layer();
+ if (childLayer->staticY() != yPos) {
+ child->layer()->setStaticY(yPos);
+ child->setChildNeedsLayout(true, false);
+ }
+ }
child = iterator.next();
continue;
}
@@ -656,7 +661,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
// We confine the line clamp ugliness to vertical flexible boxes (thus keeping it out of
// mainstream block layout); this is not really part of the XUL box model.
- bool haveLineClamp = style()->lineClamp() >= 0 && style()->lineClamp() <= 100;
+ bool haveLineClamp = !style()->lineClamp().isNone();
if (haveLineClamp) {
int maxLineCount = 0;
child = iterator.first();
@@ -681,7 +686,8 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
// Get the # of lines and then alter all block flow children with auto height to use the
// specified height. We always try to leave room for at least one line.
- int numVisibleLines = max(1, static_cast<int>((maxLineCount + 1) * style()->lineClamp() / 100.0));
+ LineClampValue lineClamp = style()->lineClamp();
+ int numVisibleLines = lineClamp.isPercentage() ? max(1, (maxLineCount + 1) * lineClamp.value() / 100) : lineClamp.value();
if (numVisibleLines < maxLineCount) {
for (child = iterator.first(); child; child = iterator.next()) {
if (child->isPositioned() || !child->style()->height().isAuto() || !child->isBlockFlow())
@@ -712,28 +718,25 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (!lastLine)
continue;
- // See if the last item is an anchor
- InlineBox* anchorBox = lastLine->lastChild();
- if (!anchorBox)
- continue;
- if (!anchorBox->renderer()->node())
- continue;
- if (!anchorBox->renderer()->node()->isLink())
- continue;
-
RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines-1);
if (!lastVisibleLine)
continue;
const UChar ellipsisAndSpace[2] = { horizontalEllipsis, ' ' };
DEFINE_STATIC_LOCAL(AtomicString, ellipsisAndSpaceStr, (ellipsisAndSpace, 2));
-
+ DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1));
const Font& font = style(numVisibleLines == 1)->font();
- int ellipsisAndSpaceWidth = font.width(TextRun(ellipsisAndSpace, 2));
- // Get ellipsis width + " " + anchor width
- int totalWidth = ellipsisAndSpaceWidth + anchorBox->width();
-
+ // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too
+ int totalWidth;
+ InlineBox* anchorBox = lastLine->lastChild();
+ if (anchorBox && anchorBox->renderer()->node() && anchorBox->renderer()->node()->isLink())
+ totalWidth = anchorBox->width() + font.width(TextRun(ellipsisAndSpace, 2));
+ else {
+ anchorBox = 0;
+ totalWidth = font.width(TextRun(&horizontalEllipsis, 1));
+ }
+
// See if this width can be accommodated on the last visible line
RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer());
RenderBlock* srcBlock = toRenderBlock(lastLine->renderer());
@@ -755,7 +758,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
continue;
// Let the truncation code kick in.
- lastVisibleLine->placeEllipsis(ellipsisAndSpaceStr, ltr, blockLeftEdge, blockRightEdge, totalWidth, anchorBox);
+ lastVisibleLine->placeEllipsis(anchorBox ? ellipsisAndSpaceStr : ellipsisStr, ltr, blockLeftEdge, blockRightEdge, totalWidth, anchorBox);
destBlock->setHasMarkupTruncation(true);
}
}
@@ -785,8 +788,13 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
else
child->layer()->setStaticX(borderRight()+paddingRight());
}
- if (child->style()->hasStaticY())
- child->layer()->setStaticY(height());
+ if (child->style()->hasStaticY()) {
+ RenderLayer* childLayer = child->layer();
+ if (childLayer->staticY() != height()) {
+ child->layer()->setStaticY(height());
+ child->setChildNeedsLayout(true, false);
+ }
+ }
child = iterator.next();
continue;
}
diff --git a/WebCore/rendering/RenderFrameSet.cpp b/WebCore/rendering/RenderFrameSet.cpp
index a855a08..09ad11f 100644
--- a/WebCore/rendering/RenderFrameSet.cpp
+++ b/WebCore/rendering/RenderFrameSet.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the KDE project.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 2000 Simon Hausmann <hausmann@kde.org>
* (C) 2000 Stefan Schimanski (1Stein@gmx.de)
@@ -90,13 +88,14 @@ void RenderFrameSet::paintColumnBorder(const PaintInfo& paintInfo, const IntRect
// Fill first.
GraphicsContext* context = paintInfo.context;
- context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor());
+ ColorSpace colorSpace = style()->colorSpace();
+ context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor(), colorSpace);
// Now stroke the edges but only if we have enough room to paint both edges with a little
// bit of the fill color showing through.
if (borderRect.width() >= 3) {
- context->fillRect(IntRect(borderRect.topLeft(), IntSize(1, height())), borderStartEdgeColor());
- context->fillRect(IntRect(borderRect.topRight(), IntSize(1, height())), borderEndEdgeColor());
+ context->fillRect(IntRect(borderRect.topLeft(), IntSize(1, height())), borderStartEdgeColor(), colorSpace);
+ context->fillRect(IntRect(borderRect.topRight(), IntSize(1, height())), borderEndEdgeColor(), colorSpace);
}
}
@@ -109,13 +108,14 @@ void RenderFrameSet::paintRowBorder(const PaintInfo& paintInfo, const IntRect& b
// Fill first.
GraphicsContext* context = paintInfo.context;
- context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor());
+ ColorSpace colorSpace = style()->colorSpace();
+ context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor(), colorSpace);
// Now stroke the edges but only if we have enough room to paint both edges with a little
// bit of the fill color showing through.
if (borderRect.height() >= 3) {
- context->fillRect(IntRect(borderRect.topLeft(), IntSize(width(), 1)), borderStartEdgeColor());
- context->fillRect(IntRect(borderRect.bottomLeft(), IntSize(width(), 1)), borderEndEdgeColor());
+ context->fillRect(IntRect(borderRect.topLeft(), IntSize(width(), 1)), borderStartEdgeColor(), colorSpace);
+ context->fillRect(IntRect(borderRect.bottomLeft(), IntSize(width(), 1)), borderEndEdgeColor(), colorSpace);
}
}
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index ff7c9c9..d06ca1f 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -53,7 +53,7 @@ namespace WebCore {
static const double cInterpolationCutoff = 800. * 800.;
static const double cLowQualityTimeThreshold = 0.050; // 50 ms
-class RenderImageScaleData {
+class RenderImageScaleData : public Noncopyable {
public:
RenderImageScaleData(RenderImage* image, const IntSize& size, double time, bool lowQualityScale)
: m_size(size)
@@ -371,8 +371,8 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
context->save();
#endif
context->setStrokeStyle(SolidStroke);
- context->setStrokeColor(Color::lightGray);
- context->setFillColor(Color::transparent);
+ context->setStrokeColor(Color::lightGray, style()->colorSpace());
+ context->setFillColor(Color::transparent, style()->colorSpace());
context->drawRect(IntRect(tx + leftBorder + leftPad, ty + topBorder + topPad, cWidth, cHeight));
#ifdef ANDROID_FIX // see http://b/issue?id=2052757
context->restore();
@@ -396,13 +396,13 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
centerY = 0;
imageX = leftBorder + leftPad + centerX + 1;
imageY = topBorder + topPad + centerY + 1;
- context->drawImage(image(), IntPoint(tx + imageX, ty + imageY));
+ context->drawImage(image(), style()->colorSpace(), IntPoint(tx + imageX, ty + imageY));
errorPictureDrawn = true;
}
if (!m_altText.isEmpty()) {
String text = document()->displayStringModifiedByEncoding(m_altText);
- context->setFillColor(style()->color());
+ context->setFillColor(style()->color(), style()->colorSpace());
int ax = tx + leftBorder + leftPad;
int ay = ty + topBorder + topPad;
const Font& font = style()->font();
@@ -434,7 +434,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
IntRect rect(IntPoint(tx + leftBorder + leftPad, ty + topBorder + topPad), contentSize);
HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
- context->drawImage(image(cWidth, cHeight), rect, compositeOperator, useLowQualityScaling);
+ context->drawImage(image(cWidth, cHeight), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
}
}
diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp
index 8b0c3c7..6df5ffe 100644
--- a/WebCore/rendering/RenderInline.cpp
+++ b/WebCore/rendering/RenderInline.cpp
@@ -56,6 +56,7 @@ void RenderInline::destroy()
// properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
children()->destroyLeftoverChildren();
+<<<<<<< HEAD:WebCore/rendering/RenderInline.cpp
// Destroy our continuation before anything other than anonymous children.
// The reason we don't destroy it before anonymous children is that they may
// have continuations of their own that are anonymous children of our continuation.
@@ -64,6 +65,16 @@ void RenderInline::destroy()
m_continuation = 0;
}
+=======
+ // Destroy our continuation before anything other than anonymous children.
+ // The reason we don't destroy it before anonymous children is that they may
+ // have continuations of their own that are anonymous children of our continuation.
+ if (m_continuation) {
+ m_continuation->destroy();
+ m_continuation = 0;
+ }
+
+>>>>>>> webkit.org at r51976:WebCore/rendering/RenderInline.cpp
if (!documentBeingDestroyed()) {
if (firstLineBox()) {
// We can't wait for RenderBoxModelObject::destroy to clear the selection,
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 8f2805a..ee7814c 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -243,14 +243,6 @@ bool RenderLayer::hasAcceleratedCompositing() const
#endif
}
-void RenderLayer::setStaticY(int staticY)
-{
- if (m_staticY == staticY)
- return;
- m_staticY = staticY;
- renderer()->setChildNeedsLayout(true, false);
-}
-
void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
{
if (flags & DoFullRepaint) {
@@ -383,6 +375,20 @@ TransformationMatrix RenderLayer::currentTransform() const
return *m_transform;
}
+TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
+{
+ if (!m_transform)
+ return TransformationMatrix();
+
+ if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
+ TransformationMatrix matrix = *m_transform;
+ makeMatrixRenderable(matrix, false /* flatten 3d */);
+ return matrix;
+ }
+
+ return *m_transform;
+}
+
void RenderLayer::setHasVisibleContent(bool b)
{
if (m_hasVisibleContent == b && !m_visibleContentStatusDirty)
@@ -689,6 +695,27 @@ RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const
}
#endif
+RenderLayer* RenderLayer::clippingRoot() const
+{
+ const RenderLayer* current = this;
+ while (current) {
+ if (current->renderer()->isRenderView())
+ return const_cast<RenderLayer*>(current);
+
+ current = compositingContainer(current);
+ ASSERT(current);
+ if (current->transform()
+#if USE(ACCELERATED_COMPOSITING)
+ || current->isComposited()
+#endif
+ )
+ return const_cast<RenderLayer*>(current);
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
IntPoint RenderLayer::absoluteToContents(const IntPoint& absolutePoint) const
{
// We don't use convertToLayerCoords because it doesn't know about transforms
@@ -727,46 +754,18 @@ RenderLayer* RenderLayer::transparentPaintingAncestor()
return 0;
}
-static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransform, const RenderLayer* l, const RenderLayer* rootLayer)
-{
- // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
- // paintDirtyRect, and that should cut down on the amount we have to paint. Still it
- // would be better to respect clips.
-
- if (rootLayer != l && l->paintsWithTransform()) {
- // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
- // the transformed layer and all of its children.
- int x = 0;
- int y = 0;
- l->convertToLayerCoords(rootLayer, x, y);
-
- TransformationMatrix transform;
- transform.translate(x, y);
- transform = *l->transform() * transform;
- transform = transform * enclosingTransform;
+static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior);
- // We now have a transform that will produce a rectangle in our view's space.
- IntRect clipRect = transform.mapRect(l->boundingBox(l));
-
- // Now shift the root layer to be us and pass down the new enclosing transform.
- for (RenderLayer* curr = l->firstChild(); curr; curr = curr->nextSibling()) {
- if (!l->reflection() || l->reflectionLayer() != curr)
- clipRect.unite(transparencyClipBox(transform, curr, l));
- }
-
- return clipRect;
- }
-
- // Note: we don't have to walk z-order lists since transparent elements always establish
- // a stacking context. This means we can just walk the layer tree directly.
- IntRect clipRect = l->boundingBox(rootLayer);
-
+static void expandClipRectForDescendantsAndReflection(IntRect& clipRect, const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
+{
// If we have a mask, then the clip is limited to the border box area (and there is
// no need to examine child layers).
if (!l->renderer()->hasMask()) {
+ // Note: we don't have to walk z-order lists since transparent elements always establish
+ // a stacking context. This means we can just walk the layer tree directly.
for (RenderLayer* curr = l->firstChild(); curr; curr = curr->nextSibling()) {
if (!l->reflection() || l->reflectionLayer() != curr)
- clipRect.unite(transparencyClipBox(enclosingTransform, curr, rootLayer));
+ clipRect.unite(transparencyClipBox(curr, rootLayer, paintBehavior));
}
}
@@ -782,25 +781,54 @@ static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransfor
clipRect.unite(l->renderBox()->reflectedRect(clipRect));
clipRect.move(deltaX, deltaY);
}
+}
- // Now map the clipRect via the enclosing transform
- return enclosingTransform.mapRect(clipRect);
+static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
+{
+ // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
+ // paintDirtyRect, and that should cut down on the amount we have to paint. Still it
+ // would be better to respect clips.
+
+ if (rootLayer != l && l->paintsWithTransform(paintBehavior)) {
+ // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
+ // the transformed layer and all of its children.
+ int x = 0;
+ int y = 0;
+ l->convertToLayerCoords(rootLayer, x, y);
+
+ TransformationMatrix transform;
+ transform.translate(x, y);
+ transform = *l->transform() * transform;
+
+ IntRect clipRect = l->boundingBox(l);
+ expandClipRectForDescendantsAndReflection(clipRect, l, l, paintBehavior);
+ return transform.mapRect(clipRect);
+ }
+
+ IntRect clipRect = l->boundingBox(rootLayer);
+ expandClipRectForDescendantsAndReflection(clipRect, l, rootLayer, paintBehavior);
+ return clipRect;
}
-void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer* rootLayer)
+void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
{
- if (p->paintingDisabled() || (paintsWithTransparency() && m_usedTransparency))
+ if (p->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency))
return;
RenderLayer* ancestor = transparentPaintingAncestor();
if (ancestor)
- ancestor->beginTransparencyLayers(p, rootLayer);
+ ancestor->beginTransparencyLayers(p, rootLayer, paintBehavior);
- if (paintsWithTransparency()) {
+ if (paintsWithTransparency(paintBehavior)) {
m_usedTransparency = true;
p->save();
- p->clip(transparencyClipBox(TransformationMatrix(), this, rootLayer));
+ IntRect clipRect = transparencyClipBox(this, rootLayer, paintBehavior);
+ p->clip(clipRect);
p->beginTransparencyLayer(renderer()->opacity());
+#ifdef REVEAL_TRANSPARENCY_LAYERS
+ p->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
+ p->fillRect(clipRect);
+#endif
}
}
@@ -1061,7 +1089,7 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
bool restrictedByLineClamp = false;
if (renderer()->parent())
- restrictedByLineClamp = renderer()->parent()->style()->lineClamp() >= 0;
+ restrictedByLineClamp = !renderer()->parent()->style()->lineClamp().isNone();
if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
int newOffsetX = scrollXOffset() + xDelta;
@@ -1205,7 +1233,7 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor,
bool restrictedByLineClamp = false;
if (renderer()->parent()) {
parentLayer = renderer()->parent()->enclosingLayer();
- restrictedByLineClamp = renderer()->parent()->style()->lineClamp() >= 0;
+ restrictedByLineClamp = !renderer()->parent()->style()->lineClamp().isNone();
}
if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
@@ -1921,7 +1949,7 @@ void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, co
return;
}
- context->fillRect(absRect, Color::white);
+ context->fillRect(absRect, Color::white, box->style()->colorSpace());
}
void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
@@ -1950,7 +1978,7 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
// Paint the resizer control.
DEFINE_STATIC_LOCAL(RefPtr<Image>, resizeCornerImage, (Image::loadPlatformResource("textAreaResizeCorner")));
IntPoint imagePoint(absRect.right() - resizeCornerImage->width(), absRect.bottom() - resizeCornerImage->height());
- context->drawImage(resizeCornerImage.get(), imagePoint);
+ context->drawImage(resizeCornerImage.get(), box->style()->colorSpace(), imagePoint);
// Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
// Clipping will exclude the right and bottom edges of this frame.
@@ -1959,9 +1987,9 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
context->clip(absRect);
IntRect largerCorner = absRect;
largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.height() + 1));
- context->setStrokeColor(Color(makeRGB(217, 217, 217)));
+ context->setStrokeColor(Color(makeRGB(217, 217, 217)), DeviceColorSpace);
context->setStrokeThickness(1.0f);
- context->setFillColor(Color::transparent);
+ context->setFillColor(Color::transparent, DeviceColorSpace);
context->drawRect(largerCorner);
context->restore();
}
@@ -2044,10 +2072,10 @@ bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularit
return (didHorizontalScroll || didVerticalScroll);
}
-void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintRestriction paintRestriction, RenderObject *paintingRoot)
+void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot)
{
RenderObject::OverlapTestRequestMap overlapTestRequests;
- paintLayer(this, p, damageRect, paintRestriction, paintingRoot, &overlapTestRequests);
+ paintLayer(this, p, damageRect, paintBehavior, paintingRoot, &overlapTestRequests);
RenderObject::OverlapTestRequestMap::iterator end = overlapTestRequests.end();
for (RenderObject::OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
it->first->setOverlapTestResult(false);
@@ -2091,7 +2119,7 @@ static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflect
#endif
void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
- const IntRect& paintDirtyRect, PaintRestriction paintRestriction,
+ const IntRect& paintDirtyRect, PaintBehavior paintBehavior,
RenderObject* paintingRoot, RenderObject::OverlapTestRequestMap* overlapTestRequests,
PaintLayerFlags paintFlags)
{
@@ -2099,7 +2127,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (isComposited()) {
// The updatingControlTints() painting pass goes through compositing layers,
// but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
- if (p->updatingControlTints())
+ if (p->updatingControlTints() || (paintBehavior & PaintBehaviorFlattenCompositingLayers))
paintFlags |= PaintLayerTemporaryClipRects;
else if (!backing()->paintingGoesToWindow() && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)) {
// If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer().
@@ -2118,19 +2146,20 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (!renderer()->opacity())
return;
- if (paintsWithTransparency())
+ if (paintsWithTransparency(paintBehavior))
paintFlags |= PaintLayerHaveTransparency;
// Apply a transform if we have one. A reflection is considered to be a transform, since it is a flip and a translate.
- if (paintsWithTransform() && !(paintFlags & PaintLayerAppliedTransform)) {
+ if (paintsWithTransform(paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) {
+ TransformationMatrix layerTransform = renderableTransform(paintBehavior);
// If the transform can't be inverted, then don't paint anything.
- if (!m_transform->isInvertible())
+ if (!layerTransform.isInvertible())
return;
// If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
// layer from the parent now.
if (paintFlags & PaintLayerHaveTransparency)
- parent()->beginTransparencyLayers(p, rootLayer);
+ parent()->beginTransparencyLayers(p, rootLayer, paintBehavior);
// Make sure the parent's clip rects have been calculated.
IntRect clipRect = paintDirtyRect;
@@ -2153,15 +2182,19 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
#else
TransformationMatrix transform;
transform.translate(x, y);
+<<<<<<< HEAD:WebCore/rendering/RenderLayer.cpp
transform = *m_transform * transform;
#endif
+=======
+ transform = layerTransform * transform;
+>>>>>>> webkit.org at r51976:WebCore/rendering/RenderLayer.cpp
// Apply the transform.
p->save();
p->concatCTM(transform);
// Now do a paint with the root layer shifted to be us.
- paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintRestriction, paintingRoot, overlapTestRequests, paintFlags | PaintLayerAppliedTransform);
+ paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, overlapTestRequests, paintFlags | PaintLayerAppliedTransform);
p->restore();
@@ -2178,7 +2211,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (m_reflection && !m_paintingInsideReflection) {
// Mark that we are now inside replica painting.
m_paintingInsideReflection = true;
- reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags | PaintLayerPaintingReflection);
+ reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags | PaintLayerPaintingReflection);
m_paintingInsideReflection = false;
}
@@ -2193,8 +2226,8 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Ensure our lists are up-to-date.
updateCompositingAndLayerListsIfNeeded();
- bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText;
- bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText;
+ bool forceBlackText = paintBehavior & PaintBehaviorForceBlackText;
+ bool selectionOnly = paintBehavior & PaintBehaviorSelectionOnly;
// If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
// is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
@@ -2212,7 +2245,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
// Begin transparency layers lazily now that we know we have to paint something.
if (haveTransparency)
- beginTransparencyLayers(p, rootLayer);
+ beginTransparencyLayers(p, rootLayer, paintBehavior);
// Paint our background first, before painting any child layers.
// Establish the clip used to paint our background.
@@ -2229,13 +2262,13 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Now walk the sorted list of children with negative z-indices.
if (m_negZOrderList)
for (Vector<RenderLayer*>::iterator it = m_negZOrderList->begin(); it != m_negZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags);
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
// Now establish the appropriate clip and paint our child RenderObjects.
if (shouldPaint && !clipRectToApply.isEmpty()) {
// Begin transparency layers lazily now that we know we have to paint something.
if (haveTransparency)
- beginTransparencyLayers(p, rootLayer);
+ beginTransparencyLayers(p, rootLayer, paintBehavior);
// Set up the clip used when painting our children.
setClip(p, paintDirtyRect, clipRectToApply);
@@ -2268,12 +2301,12 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Paint any child layers that have overflow.
if (m_normalFlowList)
for (Vector<RenderLayer*>::iterator it = m_normalFlowList->begin(); it != m_normalFlowList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags);
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
// Now walk the sorted list of children with positive z-indices.
if (m_posZOrderList)
for (Vector<RenderLayer*>::iterator it = m_posZOrderList->begin(); it != m_posZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags);
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
if (renderer()->hasMask() && shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
setClip(p, paintDirtyRect, damageRect);
@@ -2813,17 +2846,49 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa
IntRect RenderLayer::childrenClipRect() const
{
RenderLayer* rootLayer = renderer()->view()->layer();
+ RenderLayer* clippingRootLayer = clippingRoot();
IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
- calculateRects(rootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
- return foregroundRect;
+ calculateRects(clippingRootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
+ return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect)).enclosingBoundingBox();
}
IntRect RenderLayer::selfClipRect() const
{
RenderLayer* rootLayer = renderer()->view()->layer();
+ RenderLayer* clippingRootLayer = clippingRoot();
IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
- calculateRects(rootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
- return backgroundRect;
+ calculateRects(clippingRootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
+ return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect)).enclosingBoundingBox();
+}
+
+void RenderLayer::addBlockSelectionGapsBounds(const IntRect& bounds)
+{
+ m_blockSelectionGapsBounds.unite(bounds);
+}
+
+void RenderLayer::clearBlockSelectionGapsBounds()
+{
+ m_blockSelectionGapsBounds = IntRect();
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+ child->clearBlockSelectionGapsBounds();
+}
+
+void RenderLayer::repaintBlockSelectionGaps()
+{
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+ child->repaintBlockSelectionGaps();
+
+ if (m_blockSelectionGapsBounds.isEmpty())
+ return;
+
+ IntRect rect = m_blockSelectionGapsBounds;
+ rect.move(-scrolledContentOffset());
+ if (renderer()->hasOverflowClip())
+ rect.intersect(toRenderBox(renderer())->overflowClipRect(0, 0));
+ if (renderer()->hasClip())
+ rect.intersect(toRenderBox(renderer())->clipRect(0, 0));
+ if (!rect.isEmpty())
+ renderer()->repaintRectangle(rect);
}
bool RenderLayer::intersectsDamageRect(const IntRect& layerBounds, const IntRect& damageRect, const RenderLayer* rootLayer) const
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index a274638..af64fc4 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -202,7 +202,7 @@ public:
bool isTransparent() const;
RenderLayer* transparentPaintingAncestor();
- void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer);
+ void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, PaintBehavior);
bool hasReflection() const { return renderer()->hasReflection(); }
RenderReplica* reflection() const { return m_reflection; }
@@ -312,6 +312,10 @@ public:
void clearClipRectsIncludingDescendants();
void clearClipRects();
+ void addBlockSelectionGapsBounds(const IntRect&);
+ void clearBlockSelectionGapsBounds();
+ void repaintBlockSelectionGaps();
+
// Get the enclosing stacking context for this layer. A stacking context is a layer
// that has a non-auto z-index.
RenderLayer* stackingContext() const;
@@ -336,6 +340,9 @@ public:
// the <html> layer and the root layer).
RenderLayer* enclosingPositionedAncestor() const;
+ // The layer relative to which clipping rects for this layer are computed.
+ RenderLayer* clippingRoot() const;
+
#if USE(ACCELERATED_COMPOSITING)
// Enclosing compositing layer; if includeSelf is true, may return this.
RenderLayer* enclosingCompositingLayer(bool includeSelf = true) const;
@@ -352,7 +359,7 @@ public:
// paints the layers that intersect the damage rect from back to
// front. The hitTest method looks for mouse events by walking
// layers that intersect the point from front to back.
- void paint(GraphicsContext*, const IntRect& damageRect, PaintRestriction = PaintRestrictionNone, RenderObject* paintingRoot = 0);
+ void paint(GraphicsContext*, const IntRect& damageRect, PaintBehavior = PaintBehaviorNormal, RenderObject* paintingRoot = 0);
bool hitTest(const HitTestRequest&, HitTestResult&);
// This method figures out our layerBounds in coordinates relative to
@@ -390,7 +397,7 @@ public:
int staticX() const { return m_staticX; }
int staticY() const { return m_staticY; }
void setStaticX(int staticX) { m_staticX = staticX; }
- void setStaticY(int staticY);
+ void setStaticY(int staticY) { m_staticY = staticY; }
bool hasTransform() const { return renderer()->hasTransform(); }
// Note that this transform has the transform-origin baked in.
@@ -399,6 +406,7 @@ public:
// resulting transform has transform-origin baked in. If the layer does not have a transform,
// returns the identity matrix.
TransformationMatrix currentTransform() const;
+ TransformationMatrix renderableTransform(PaintBehavior) const;
// Get the perspective transform, which is applied to transformed sublayers.
// Returns true if the layer has a -webkit-perspective.
@@ -426,14 +434,14 @@ public:
bool hasCompositedMask() const { return false; }
#endif
- bool paintsWithTransparency() const
+ bool paintsWithTransparency(PaintBehavior paintBehavior) const
{
- return isTransparent() && !isComposited();
+ return isTransparent() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || !isComposited());
}
- bool paintsWithTransform() const
+ bool paintsWithTransform(PaintBehavior paintBehavior) const
{
- return transform() && !isComposited();
+ return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || !isComposited());
}
private:
@@ -465,7 +473,7 @@ private:
typedef unsigned PaintLayerFlags;
void paintLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect,
- PaintRestriction, RenderObject* paintingRoot, RenderObject::OverlapTestRequestMap* = 0,
+ PaintBehavior, RenderObject* paintingRoot, RenderObject::OverlapTestRequestMap* = 0,
PaintLayerFlags paintFlags = 0);
RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
@@ -644,6 +652,9 @@ protected:
RenderScrollbarPart* m_scrollCorner;
RenderScrollbarPart* m_resizer;
+private:
+ IntRect m_blockSelectionGapsBounds;
+
#if USE(ACCELERATED_COMPOSITING)
OwnPtr<RenderLayerBacking> m_backing;
#endif
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index d7248d4..a62c1be 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -28,7 +28,9 @@
#if USE(ACCELERATED_COMPOSITING)
#include "AnimationController.h"
-#include "CanvasRenderingContext3D.h"
+#if ENABLE(3D_CANVAS)
+#include "WebGLRenderingContext.h"
+#endif
#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
#include "FrameView.h"
@@ -37,11 +39,14 @@
#include "HTMLCanvasElement.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
+#include "InspectorTimelineAgent.h"
+#include "KeyframeList.h"
#include "RenderBox.h"
#include "RenderImage.h"
#include "RenderLayerCompositor.h"
#include "RenderVideo.h"
#include "RenderView.h"
+#include "Settings.h"
#include "RenderLayerBacking.h"
@@ -192,7 +197,7 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
else if (renderer()->isCanvas()) {
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
if (canvas->is3D()) {
- CanvasRenderingContext3D* context = static_cast<CanvasRenderingContext3D*>(canvas->renderingContext());
+ WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(canvas->renderingContext());
if (context->graphicsContext3D()->platformGraphicsContext3D())
m_graphicsLayer->setContentsToGraphicsContext3D(context->graphicsContext3D());
}
@@ -849,7 +854,7 @@ static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const
// Share this with RenderLayer::paintLayer, which would have to be educated about GraphicsLayerPaintingPhase?
void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* context,
const IntRect& paintDirtyRect, // in the coords of rootLayer
- PaintRestriction paintRestriction, GraphicsLayerPaintingPhase paintingPhase,
+ PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase,
RenderObject* paintingRoot)
{
if (paintingGoesToWindow()) {
@@ -863,7 +868,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
if (m_owningLayer->hasReflection()) {
// Mark that we are now inside replica painting.
m_owningLayer->setPaintingInsideReflection(true);
- m_owningLayer->reflectionLayer()->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot, 0, RenderLayer::PaintLayerPaintingReflection);
+ m_owningLayer->reflectionLayer()->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, RenderLayer::PaintLayerPaintingReflection);
m_owningLayer->setPaintingInsideReflection(false);
}
@@ -899,9 +904,9 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
int rw;
int rh;
- if (box->view()->frameView()) {
- rw = box->view()->frameView()->contentsWidth();
- rh = box->view()->frameView()->contentsHeight();
+ if (FrameView* frameView = box->view()->frameView()) {
+ rw = frameView->contentsWidth();
+ rh = frameView->contentsHeight();
} else {
rw = box->view()->width();
rh = box->view()->height();
@@ -930,8 +935,8 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
restoreClip(context, paintDirtyRect, damageRect);
}
- bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText;
- bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText;
+ bool forceBlackText = paintBehavior & PaintBehaviorForceBlackText;
+ bool selectionOnly = paintBehavior & PaintBehaviorSelectionOnly;
if (shouldPaint && (paintingPhase & GraphicsLayerPaintForeground)) {
// Now walk the sorted list of children with negative z-indices. Only RenderLayers without compositing layers will paint.
@@ -939,7 +944,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList();
if (negZOrderList) {
for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot);
+ it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot);
}
// Set up the clip used when painting our children.
@@ -975,14 +980,14 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList();
if (normalFlowList) {
for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it)
- it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot);
+ it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot);
}
// Now walk the sorted list of children with positive z-indices.
Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList();
if (posZOrderList) {
for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot);
+ it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot);
}
}
@@ -1002,9 +1007,25 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
ASSERT(!m_owningLayer->m_usedTransparency);
}
+static InspectorTimelineAgent* inspectorTimelineAgent(RenderObject* renderer)
+{
+ Frame* frame = renderer->document()->frame();
+ if (!frame)
+ return 0;
+ Page* page = frame->page();
+ if (!page)
+ return 0;
+ return page->inspectorTimelineAgent();
+}
+
// Up-call from compositing layer drawing callback.
void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
{
+#if ENABLE(INSPECTOR)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent(m_owningLayer->renderer()))
+ timelineAgent->willPaint(clip);
+#endif
+
// We have to use the same root as for hit testing, because both methods
// can compute and cache clipRects.
IntRect enclosingBBox = compositedBounds();
@@ -1021,7 +1042,22 @@ void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& co
IntRect dirtyRect = enclosingBBox;
dirtyRect.intersect(clipRect);
- paintIntoLayer(m_owningLayer, &context, dirtyRect, PaintRestrictionNone, paintingPhase, renderer());
+ paintIntoLayer(m_owningLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase, renderer());
+
+#if ENABLE(INSPECTOR)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent(m_owningLayer->renderer()))
+ timelineAgent->didPaint();
+#endif
+}
+
+bool RenderLayerBacking::showDebugBorders() const
+{
+ return compositor() ? compositor()->showDebugBorders() : false;
+}
+
+bool RenderLayerBacking::showRepaintCounter() const
+{
+ return compositor() ? compositor()->showRepaintCounter() : false;
}
bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes)
diff --git a/WebCore/rendering/RenderLayerBacking.h b/WebCore/rendering/RenderLayerBacking.h
index 17bcaf7..2bbb37f 100644
--- a/WebCore/rendering/RenderLayerBacking.h
+++ b/WebCore/rendering/RenderLayerBacking.h
@@ -119,6 +119,9 @@ public:
virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip);
+ virtual bool showDebugBorders() const;
+ virtual bool showRepaintCounter() const;
+
IntRect contentsBox() const;
private:
@@ -160,7 +163,7 @@ private:
bool hasNonCompositingContent() const;
void paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect,
- PaintRestriction paintRestriction, GraphicsLayerPaintingPhase, RenderObject* paintingRoot);
+ PaintBehavior paintBehavior, GraphicsLayerPaintingPhase, RenderObject* paintingRoot);
static int graphicsLayerToCSSProperty(AnimatedPropertyID);
static AnimatedPropertyID cssToGraphicsLayerProperty(int);
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index 5201287..2f5e267 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -79,6 +79,8 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
: m_renderView(renderView)
, m_rootPlatformLayer(0)
, m_hasAcceleratedCompositing(true)
+ , m_showDebugBorders(false)
+ , m_showRepaintCounter(false)
, m_compositingConsultsOverlap(true)
, m_compositing(false)
, m_rootLayerAttached(false)
@@ -109,16 +111,24 @@ void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
}
}
-void RenderLayerCompositor::cacheAcceleratedCompositingEnabledFlag()
+void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
{
bool hasAcceleratedCompositing = false;
- if (Settings* settings = m_renderView->document()->settings())
+ bool showDebugBorders = false;
+ bool showRepaintCounter = false;
+
+ if (Settings* settings = m_renderView->document()->settings()) {
hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
+ showDebugBorders = settings->showDebugBorders();
+ showRepaintCounter = settings->showRepaintCounter();
+ }
- if (hasAcceleratedCompositing != m_hasAcceleratedCompositing)
+ if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter)
setCompositingLayersNeedRebuild();
m_hasAcceleratedCompositing = hasAcceleratedCompositing;
+ m_showDebugBorders = showDebugBorders;
+ m_showRepaintCounter = showRepaintCounter;
}
void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
@@ -175,10 +185,18 @@ void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot)
needLayerRebuild |= layersChanged;
}
- // Now create and parent the compositing layers.
- {
+ if (needLayerRebuild) {
+ // Now updated and parent the compositing layers.
CompositingState compState(updateRoot);
- rebuildCompositingLayerTree(updateRoot, compState, needLayerRebuild);
+ Vector<GraphicsLayer*> childList;
+ rebuildCompositingLayerTree(updateRoot, compState, childList);
+
+ // Host the document layer in the RenderView's root layer.
+ if (updateRoot == rootRenderLayer() && !childList.isEmpty())
+ m_rootPlatformLayer->setChildren(childList);
+ } else {
+ // We just need to do a geometry update.
+ updateLayerTreeGeometry(updateRoot);
}
#if PROFILE_LAYER_REBUILD
@@ -328,7 +346,7 @@ IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* laye
}
}
- if (layer->paintsWithTransform()) {
+ if (layer->paintsWithTransform(PaintBehaviorNormal)) {
TransformationMatrix* affineTrans = layer->transform();
boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
unionBounds = affineTrans->mapRect(unionBounds);
@@ -476,7 +494,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
// If we have to make a layer for this child, make one now so we can have a contents layer
// (since we need to ensure that the -ve z-order child renders underneath our contents).
- if (childState.m_subtreeIsCompositing) {
+ if (!willBeComposited && childState.m_subtreeIsCompositing) {
// make layer compositing
layer->setMustOverlapCompositedLayers(true);
childState.m_compositingAncestor = layer;
@@ -509,7 +527,7 @@ 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 (childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
+ if (!willBeComposited && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
layer->setMustOverlapCompositedLayers(true);
if (overlapMap)
addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
@@ -586,11 +604,12 @@ bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
}
#endif
-void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, struct CompositingState& compositingState, bool updateHierarchy)
+void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer)
{
// Make the layer compositing if necessary, and set up clipping and content layers.
// Note that we can only do work here that is independent of whether the descendant layers
// have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
+
RenderLayerBacking* layerBacking = layer->backing();
if (layerBacking) {
// The compositing state of all our children has been updated already, so now
@@ -601,15 +620,12 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru
if (!layer->parent())
updateRootLayerPosition();
-
- // FIXME: make this more incremental
- if (updateHierarchy)
- layerBacking->parentForSublayers()->removeAllChildren();
}
- // host the document layer in the RenderView's root layer
- if (updateHierarchy && layer->isRootLayer() && layer->isComposited())
- parentInRootLayer(layer);
+ // If this layer has backing, then we are collecting its children, otherwise appending
+ // to the compositing child list of an enclosing layer.
+ Vector<GraphicsLayer*> layerChildren;
+ Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
CompositingState childState = compositingState;
if (layer->isComposited())
@@ -630,19 +646,13 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru
size_t listSize = negZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
- rebuildCompositingLayerTree(curLayer, childState, updateHierarchy);
- if (updateHierarchy && curLayer->isComposited())
- setCompositingParent(curLayer, childState.m_compositingAncestor);
+ rebuildCompositingLayerTree(curLayer, childState, childList);
}
}
- if (updateHierarchy && layerBacking && layerBacking->foregroundLayer()) {
- layerBacking->foregroundLayer()->removeFromParent();
-
- // The foreground layer has to be correctly sorted with child layers, so needs to become a child of the clipping layer.
- GraphicsLayer* hostingLayer = layerBacking->parentForSublayers();
- hostingLayer->addChild(layerBacking->foregroundLayer());
- }
+ // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
+ if (layerBacking && layerBacking->foregroundLayer())
+ childList.append(layerBacking->foregroundLayer());
}
ASSERT(!layer->m_normalFlowListDirty);
@@ -650,9 +660,7 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru
size_t listSize = normalFlowList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
- rebuildCompositingLayerTree(curLayer, childState, updateHierarchy);
- if (updateHierarchy && curLayer->isComposited())
- setCompositingParent(curLayer, childState.m_compositingAncestor);
+ rebuildCompositingLayerTree(curLayer, childState, childList);
}
}
@@ -661,14 +669,60 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru
size_t listSize = posZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
- rebuildCompositingLayerTree(curLayer, childState, updateHierarchy);
- if (updateHierarchy && curLayer->isComposited())
- setCompositingParent(curLayer, childState.m_compositingAncestor);
+ rebuildCompositingLayerTree(curLayer, childState, childList);
}
}
}
+
+ if (layerBacking) {
+ layerBacking->parentForSublayers()->setChildren(layerChildren);
+ childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
+ }
}
+// This just updates layer geometry without changing the hierarchy.
+void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
+{
+ if (RenderLayerBacking* layerBacking = layer->backing()) {
+ // The compositing state of all our children has been updated already, so now
+ // we can compute and cache the composited bounds for this layer.
+ layerBacking->updateCompositedBounds();
+
+ if (layer->reflectionLayer())
+ layer->reflectionLayer()->backing()->updateCompositedBounds();
+
+ layerBacking->updateGraphicsLayerConfiguration();
+ layerBacking->updateGraphicsLayerGeometry();
+
+ if (!layer->parent())
+ updateRootLayerPosition();
+ }
+
+ if (layer->isStackingContext()) {
+ ASSERT(!layer->m_zOrderListsDirty);
+
+ if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
+ size_t listSize = negZOrderList->size();
+ for (size_t i = 0; i < listSize; ++i)
+ updateLayerTreeGeometry(negZOrderList->at(i));
+ }
+ }
+
+ ASSERT(!layer->m_normalFlowListDirty);
+ if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
+ size_t listSize = normalFlowList->size();
+ for (size_t i = 0; i < listSize; ++i)
+ updateLayerTreeGeometry(normalFlowList->at(i));
+ }
+
+ if (layer->isStackingContext()) {
+ if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
+ size_t listSize = posZOrderList->size();
+ for (size_t i = 0; i < listSize; ++i)
+ updateLayerTreeGeometry(posZOrderList->at(i));
+ }
+ }
+}
// Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth)
@@ -716,6 +770,7 @@ void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& a
void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
{
+ // FIXME: This method does not work correctly with transforms.
if (layer->isComposited())
layer->setBackingNeedsRepaintInRect(rect);
@@ -724,7 +779,8 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const
size_t listSize = negZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
- int x = 0, y = 0;
+ int x = 0;
+ int y = 0;
curLayer->convertToLayerCoords(layer, x, y);
IntRect childRect(rect);
childRect.move(-x, -y);
@@ -736,7 +792,8 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const
size_t listSize = posZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
- int x = 0, y = 0;
+ int x = 0;
+ int y = 0;
curLayer->convertToLayerCoords(layer, x, y);
IntRect childRect(rect);
childRect.move(-x, -y);
@@ -748,7 +805,8 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const
size_t listSize = normalFlowList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
- int x = 0, y = 0;
+ int x = 0;
+ int y = 0;
curLayer->convertToLayerCoords(layer, x, y);
IntRect childRect(rect);
childRect.move(-x, -y);
diff --git a/WebCore/rendering/RenderLayerCompositor.h b/WebCore/rendering/RenderLayerCompositor.h
index a809a70..73683f3 100644
--- a/WebCore/rendering/RenderLayerCompositor.h
+++ b/WebCore/rendering/RenderLayerCompositor.h
@@ -61,8 +61,11 @@ public:
// Returns true if the accelerated compositing is enabled
bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; }
- // Copy the acceleratedCompositingEnabledFlag from Settings
- void cacheAcceleratedCompositingEnabledFlag();
+ bool showDebugBorders() const { return m_showDebugBorders; }
+ bool showRepaintCounter() const { return m_showRepaintCounter; }
+
+ // Copy the accelerated compositing related flags from Settings
+ void cacheAcceleratedCompositingFlags();
// Called when the layer hierarchy needs to be updated (compositing layers have been
// created, destroyed or re-parented).
@@ -147,8 +150,13 @@ private:
// Returns true if any layer's compositing changed
void computeCompositingRequirements(RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged);
- void rebuildCompositingLayerTree(RenderLayer* layer, struct CompositingState&, bool updateHierarchy);
+
+ // Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer.
+ void rebuildCompositingLayerTree(RenderLayer* layer, const struct CompositingState&, Vector<GraphicsLayer*>& childGraphicsLayersOfEnclosingLayer);
+ // Recurses down the tree, updating layer geometry only.
+ void updateLayerTreeGeometry(RenderLayer*);
+
// Hook compositing layers together
void setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer);
void removeCompositedChildren(RenderLayer*);
@@ -171,6 +179,8 @@ private:
RenderView* m_renderView;
OwnPtr<GraphicsLayer> m_rootPlatformLayer;
bool m_hasAcceleratedCompositing;
+ bool m_showDebugBorders;
+ bool m_showRepaintCounter;
bool m_compositingConsultsOverlap;
bool m_compositing;
bool m_rootLayerAttached;
diff --git a/WebCore/rendering/RenderLineBoxList.cpp b/WebCore/rendering/RenderLineBoxList.cpp
index 76a2e2f..57bc26c 100644
--- a/WebCore/rendering/RenderLineBoxList.cpp
+++ b/WebCore/rendering/RenderLineBoxList.cpp
@@ -199,6 +199,7 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::Pain
int bottom = curr->bottomVisibleOverflow() + renderer->maximalOutlineSize(info.phase);
h = bottom - top;
yPos = ty + top;
+ v->setMinimumColumnHeight(h);
if (yPos < info.rect.bottom() && yPos + h > info.rect.y())
curr->paint(info, tx, ty);
}
diff --git a/WebCore/rendering/RenderListBox.cpp b/WebCore/rendering/RenderListBox.cpp
index 0edfdef..15c652c 100644
--- a/WebCore/rendering/RenderListBox.cpp
+++ b/WebCore/rendering/RenderListBox.cpp
@@ -321,7 +321,8 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, in
textColor = theme()->inactiveListBoxSelectionForegroundColor();
}
- paintInfo.context->setFillColor(textColor);
+ ColorSpace colorSpace = itemStyle->colorSpace();
+ paintInfo.context->setFillColor(textColor, colorSpace);
Font itemFont = style()->font();
if (isOptionGroupElement(element)) {
@@ -358,9 +359,10 @@ void RenderListBox::paintItemBackground(PaintInfo& paintInfo, int tx, int ty, in
// Draw the background for this list box item
if (!element->renderStyle() || element->renderStyle()->visibility() != HIDDEN) {
+ ColorSpace colorSpace = element->renderStyle() ? element->renderStyle()->colorSpace() : style()->colorSpace();
IntRect itemRect = itemBoundingBoxRect(tx, ty, listIndex);
itemRect.intersect(controlClipRect(tx, ty));
- paintInfo.context->fillRect(itemRect, backColor);
+ paintInfo.context->fillRect(itemRect, backColor, colorSpace);
}
}
diff --git a/WebCore/rendering/RenderListItem.cpp b/WebCore/rendering/RenderListItem.cpp
index e487c60..539b8c7 100644
--- a/WebCore/rendering/RenderListItem.cpp
+++ b/WebCore/rendering/RenderListItem.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
diff --git a/WebCore/rendering/RenderListMarker.cpp b/WebCore/rendering/RenderListMarker.cpp
index 9627711..eab4404 100644
--- a/WebCore/rendering/RenderListMarker.cpp
+++ b/WebCore/rendering/RenderListMarker.cpp
@@ -48,7 +48,9 @@ static String toRoman(int number, bool upper)
if (number < 1 || number > 3999)
return String::number(number);
- const int lettersSize = 12; // big enough for three each of I, X, C, and M
+ // Big enough to store largest roman number less than 3999 which
+ // is 3888 (MMMDCCCLXXXVIII)
+ const int lettersSize = 15;
UChar letters[lettersSize];
int length = 0;
@@ -543,10 +545,10 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
if (style()->highlight() != nullAtom && !paintInfo.context->paintingDisabled())
paintCustomHighlight(tx, ty, style()->highlight(), true);
#endif
- context->drawImage(m_image->image(this, marker.size()), marker.location());
+ context->drawImage(m_image->image(this, marker.size()), style()->colorSpace(), marker.location());
if (selectionState() != SelectionNone) {
// FIXME: selectionRect() is in absolute, not painting coordinates.
- context->fillRect(selectionRect(), selectionBackgroundColor());
+ context->fillRect(selectionRect(), selectionBackgroundColor(), style()->colorSpace());
}
return;
}
@@ -559,21 +561,21 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
if (selectionState() != SelectionNone) {
// FIXME: selectionRect() is in absolute, not painting coordinates.
- context->fillRect(selectionRect(), selectionBackgroundColor());
+ context->fillRect(selectionRect(), selectionBackgroundColor(), style()->colorSpace());
}
const Color color(style()->color());
- context->setStrokeColor(color);
+ context->setStrokeColor(color, style()->colorSpace());
context->setStrokeStyle(SolidStroke);
context->setStrokeThickness(1.0f);
- context->setFillColor(color);
+ context->setFillColor(color, style()->colorSpace());
switch (style()->listStyleType()) {
case DISC:
context->drawEllipse(marker);
return;
case CIRCLE:
- context->setFillColor(Color::transparent);
+ context->setFillColor(Color::transparent, DeviceColorSpace);
context->drawEllipse(marker);
return;
case SQUARE:
diff --git a/WebCore/rendering/RenderMarquee.h b/WebCore/rendering/RenderMarquee.h
index 886c343..1651454 100644
--- a/WebCore/rendering/RenderMarquee.h
+++ b/WebCore/rendering/RenderMarquee.h
@@ -53,7 +53,7 @@ namespace WebCore {
class RenderLayer;
// This class handles the auto-scrolling of layers with overflow: marquee.
-class RenderMarquee {
+class RenderMarquee : public Noncopyable {
public:
RenderMarquee(RenderLayer*);
diff --git a/WebCore/rendering/RenderMedia.cpp b/WebCore/rendering/RenderMedia.cpp
index 1d4da23..2ff50df 100644
--- a/WebCore/rendering/RenderMedia.cpp
+++ b/WebCore/rendering/RenderMedia.cpp
@@ -121,6 +121,8 @@ void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
m_rewindButton->updateStyle();
if (m_returnToRealtimeButton)
m_returnToRealtimeButton->updateStyle();
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->updateStyle();
if (m_statusDisplay)
m_statusDisplay->updateStyle();
if (m_timelineContainer)
@@ -223,6 +225,13 @@ void RenderMedia::createReturnToRealtimeButton()
m_returnToRealtimeButton->attachToParent(m_panel.get());
}
+void RenderMedia::createToggleClosedCaptionsButton()
+{
+ ASSERT(!m_toggleClosedCaptionsButton);
+ m_toggleClosedCaptionsButton = new MediaControlToggleClosedCaptionsButtonElement(document(), mediaElement());
+ m_toggleClosedCaptionsButton->attachToParent(m_panel.get());
+}
+
void RenderMedia::createStatusDisplay()
{
ASSERT(!m_statusDisplay);
@@ -310,6 +319,7 @@ void RenderMedia::updateControls()
m_volumeSliderContainer = 0;
m_volumeSlider = 0;
m_controlsShadowRoot = 0;
+ m_toggleClosedCaptionsButton = 0;
}
m_opacityAnimationTo = 1.0f;
m_opacityAnimationTimer.stop();
@@ -333,6 +343,7 @@ void RenderMedia::updateControls()
}
createSeekBackButton();
createSeekForwardButton();
+ createToggleClosedCaptionsButton();
createFullscreenButton();
createMuteButton();
createVolumeSliderContainer();
@@ -379,6 +390,8 @@ void RenderMedia::updateControls()
m_rewindButton->update();
if (m_returnToRealtimeButton)
m_returnToRealtimeButton->update();
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->update();
if (m_statusDisplay)
m_statusDisplay->update();
if (m_fullscreenButton)
@@ -535,6 +548,9 @@ void RenderMedia::forwardEvent(Event* event)
if (m_returnToRealtimeButton && m_returnToRealtimeButton->hitTest(point))
m_returnToRealtimeButton->defaultEventHandler(event);
+ if (m_toggleClosedCaptionsButton && m_toggleClosedCaptionsButton->hitTest(point))
+ m_toggleClosedCaptionsButton->defaultEventHandler(event);
+
if (m_timeline && m_timeline->hitTest(point))
m_timeline->defaultEventHandler(event);
diff --git a/WebCore/rendering/RenderMedia.h b/WebCore/rendering/RenderMedia.h
index 602cd26..066b83d 100644
--- a/WebCore/rendering/RenderMedia.h
+++ b/WebCore/rendering/RenderMedia.h
@@ -40,6 +40,7 @@ class MediaControlPlayButtonElement;
class MediaControlSeekButtonElement;
class MediaControlRewindButtonElement;
class MediaControlReturnToRealtimeButtonElement;
+class MediaControlToggleClosedCaptionsButtonElement;
class MediaControlTimelineElement;
class MediaControlVolumeSliderElement;
class MediaControlFullscreenButtonElement;
@@ -96,6 +97,7 @@ private:
void createSeekForwardButton();
void createRewindButton();
void createReturnToRealtimeButton();
+ void createToggleClosedCaptionsButton();
void createStatusDisplay();
void createTimelineContainer();
void createTimeline();
@@ -123,6 +125,7 @@ private:
RefPtr<MediaControlSeekButtonElement> m_seekForwardButton;
RefPtr<MediaControlRewindButtonElement> m_rewindButton;
RefPtr<MediaControlReturnToRealtimeButtonElement> m_returnToRealtimeButton;
+ RefPtr<MediaControlToggleClosedCaptionsButtonElement> m_toggleClosedCaptionsButton;
RefPtr<MediaControlTimelineElement> m_timeline;
RefPtr<MediaControlVolumeSliderElement> m_volumeSlider;
RefPtr<MediaControlFullscreenButtonElement> m_fullscreenButton;
diff --git a/WebCore/rendering/RenderMediaControls.cpp b/WebCore/rendering/RenderMediaControls.cpp
index 9cc1493..17576ae 100644
--- a/WebCore/rendering/RenderMediaControls.cpp
+++ b/WebCore/rendering/RenderMediaControls.cpp
@@ -90,6 +90,15 @@ bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, R
case MediaFullscreenButton:
paintThemePart(SafariTheme::MediaFullscreenButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o));
break;
+ case MediaShowClosedCaptionsButton:
+ case MediaHideClosedCaptionsButton:
+#if SAFARI_THEME_VERSION >= 4
+ if (MediaControlToggleClosedCaptionsButtonElement* btn = static_cast<MediaControlToggleClosedCaptionsButtonElement*>(o->node())) {
+ bool captionsVisible = btn->displayType() == MediaHideClosedCaptionsButton;
+ paintThemePart(captionsVisible ? SafariTheme::MediaHideClosedCaptionsButtonPart : SafariTheme::MediaShowClosedCaptionsButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o));
+ }
+#endif
+ break;
case MediaMuteButton:
case MediaUnMuteButton:
if (MediaControlMuteButtonElement* btn = static_cast<MediaControlMuteButtonElement*>(o->node())) {
diff --git a/WebCore/rendering/RenderMediaControlsChromium.cpp b/WebCore/rendering/RenderMediaControlsChromium.cpp
index 56fbec4..50feb46 100644
--- a/WebCore/rendering/RenderMediaControlsChromium.cpp
+++ b/WebCore/rendering/RenderMediaControlsChromium.cpp
@@ -63,7 +63,7 @@ static bool hasSource(const HTMLMediaElement* mediaElement)
static bool paintMediaButton(GraphicsContext* context, const IntRect& rect, Image* image)
{
IntRect imageRect = image->rect();
- context->drawImage(image, rect);
+ context->drawImage(image, DeviceColorSpace, rect);
return true;
}
@@ -114,9 +114,9 @@ static bool paintMediaSlider(RenderObject* object, const RenderObject::PaintInfo
context->save();
context->setShouldAntialias(true);
context->setStrokeStyle(SolidStroke);
- context->setStrokeColor(style->borderLeftColor());
+ context->setStrokeColor(style->borderLeftColor(), DeviceColorSpace);
context->setStrokeThickness(style->borderLeftWidth());
- context->setFillColor(style->backgroundColor());
+ context->setFillColor(style->backgroundColor(), DeviceColorSpace);
context->drawRect(rect);
context->restore();
@@ -172,13 +172,13 @@ static bool paintMediaVolumeSlider(RenderObject* object, const RenderObject::Pai
GraphicsContext* context = paintInfo.context;
Color originalColor = context->strokeColor();
if (originalColor != Color::white)
- context->setStrokeColor(Color::white);
+ context->setStrokeColor(Color::white, DeviceColorSpace);
int x = rect.x() + rect.width() / 2;
context->drawLine(IntPoint(x, rect.y()), IntPoint(x, rect.y() + rect.height()));
if (originalColor != Color::white)
- context->setStrokeColor(originalColor);
+ context->setStrokeColor(originalColor, DeviceColorSpace);
return true;
}
@@ -207,17 +207,17 @@ static bool paintMediaTimelineContainer(RenderObject* object, const RenderObject
// Draw the left border using CSS defined width and color.
context->setStrokeThickness(object->style()->borderLeftWidth());
- context->setStrokeColor(object->style()->borderLeftColor().rgb());
+ context->setStrokeColor(object->style()->borderLeftColor().rgb(), DeviceColorSpace);
context->drawLine(IntPoint(rect.x() + 1, rect.y()),
IntPoint(rect.x() + 1, rect.y() + rect.height()));
// Draw the right border using CSS defined width and color.
context->setStrokeThickness(object->style()->borderRightWidth());
- context->setStrokeColor(object->style()->borderRightColor().rgb());
+ context->setStrokeColor(object->style()->borderRightColor().rgb(), DeviceColorSpace);
context->drawLine(IntPoint(rect.x() + rect.width() - 1, rect.y()),
IntPoint(rect.x() + rect.width() - 1, rect.y() + rect.height()));
- context->setStrokeColor(originalColor);
+ context->setStrokeColor(originalColor, DeviceColorSpace);
context->setStrokeThickness(originalThickness);
context->setStrokeStyle(originalStyle);
}
@@ -275,6 +275,8 @@ bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType
case MediaRewindButton:
case MediaReturnToRealtimeButton:
case MediaStatusDisplay:
+ case MediaShowClosedCaptionsButton:
+ case MediaHideClosedCaptionsButton:
ASSERT_NOT_REACHED();
break;
}
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 21ced26..712519b 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -4,6 +4,7 @@
* (C) 2000 Dirk Mueller (mueller@kde.org)
* (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -41,6 +42,8 @@
#include "RenderImageGeneratedContent.h"
#include "RenderInline.h"
#include "RenderListItem.h"
+#include "RenderRuby.h"
+#include "RenderRubyText.h"
#include "RenderTableCell.h"
#include "RenderTableCol.h"
#include "RenderTableRow.h"
@@ -106,46 +109,42 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
return image;
}
- RenderObject* o = 0;
+ if (node->hasTagName(rubyTag)) {
+ if (style->display() == INLINE)
+ return new (arena) RenderRubyAsInline(node);
+ else
+ 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);
switch (style->display()) {
case NONE:
- break;
+ return 0;
case INLINE:
- o = new (arena) RenderInline(node);
- break;
+ return new (arena) RenderInline(node);
case BLOCK:
- o = new (arena) RenderBlock(node);
- break;
case INLINE_BLOCK:
- o = new (arena) RenderBlock(node);
- break;
- case LIST_ITEM:
- o = new (arena) RenderListItem(node);
- break;
case RUN_IN:
case COMPACT:
- o = new (arena) RenderBlock(node);
- break;
+ return new (arena) RenderBlock(node);
+ case LIST_ITEM:
+ return new (arena) RenderListItem(node);
case TABLE:
case INLINE_TABLE:
- o = new (arena) RenderTable(node);
- break;
+ return new (arena) RenderTable(node);
case TABLE_ROW_GROUP:
case TABLE_HEADER_GROUP:
case TABLE_FOOTER_GROUP:
- o = new (arena) RenderTableSection(node);
- break;
+ return new (arena) RenderTableSection(node);
case TABLE_ROW:
- o = new (arena) RenderTableRow(node);
- break;
+ return new (arena) RenderTableRow(node);
case TABLE_COLUMN_GROUP:
case TABLE_COLUMN:
- o = new (arena) RenderTableCol(node);
- break;
+ return new (arena) RenderTableCol(node);
case TABLE_CELL:
- o = new (arena) RenderTableCell(node);
- break;
+ return new (arena) RenderTableCell(node);
case TABLE_CAPTION:
#if ENABLE(WCSS)
// As per the section 17.1 of the spec WAP-239-WCSS-20011026-a.pdf,
@@ -153,15 +152,13 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
// principal block box ([CSS2] section 9.2.1).
case WAP_MARQUEE:
#endif
- o = new (arena) RenderBlock(node);
- break;
+ return new (arena) RenderBlock(node);
case BOX:
case INLINE_BOX:
- o = new (arena) RenderFlexibleBox(node);
- break;
+ return new (arena) RenderFlexibleBox(node);
}
- return o;
+ return 0;
}
#ifndef NDEBUG
@@ -646,7 +643,7 @@ RenderBlock* RenderObject::containingBlock() const
}
if (!o || !o->isRenderBlock())
- return 0; // Probably doesn't happen any more, but leave just in case. -dwh
+ return 0; // This can still happen in case of an orphaned tree
return toRenderBlock(o);
}
@@ -722,7 +719,7 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
return;
case DOTTED:
case DASHED:
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeThickness(width);
graphicsContext->setStrokeStyle(style == DASHED ? DashedStroke : DottedStroke);
@@ -743,7 +740,7 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
if (adjbw1 == 0 && adjbw2 == 0) {
graphicsContext->setStrokeStyle(NoStroke);
- graphicsContext->setFillColor(c);
+ graphicsContext->setFillColor(c, m_style->colorSpace());
switch (s) {
case BSTop:
case BSBottom:
@@ -856,7 +853,7 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
// fall through
case SOLID: {
graphicsContext->setStrokeStyle(NoStroke);
- graphicsContext->setFillColor(c);
+ graphicsContext->setFillColor(c, m_style->colorSpace());
ASSERT(x2 >= x1);
ASSERT(y2 >= y1);
if (!adjbw1 && !adjbw2) {
@@ -916,7 +913,7 @@ void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, in
return;
case DOTTED:
case DASHED:
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeStyle(style == DOTTED ? DottedStroke : DashedStroke);
graphicsContext->setStrokeThickness(thickness);
graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
@@ -938,7 +935,7 @@ void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, in
}
graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeThickness(third);
graphicsContext->strokeArc(IntRect(x, outerY, radius.width() * 2, outerHeight), angleStart, angleSpan);
graphicsContext->setStrokeThickness(innerThird > 2 ? innerThird - 1 : innerThird);
@@ -957,13 +954,13 @@ void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, in
}
graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeThickness(thickness);
graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
float halfThickness = (thickness + 1.0f) / 4.0f;
int shiftForInner = static_cast<int>(halfThickness * 1.5f);
- graphicsContext->setStrokeColor(c2);
+ graphicsContext->setStrokeColor(c2, m_style->colorSpace());
graphicsContext->setStrokeThickness(halfThickness > 2 ? halfThickness - 1 : halfThickness);
graphicsContext->strokeArc(IntRect(x + shiftForInner, y + shiftForInner, (radius.width() - shiftForInner) * 2,
(radius.height() - shiftForInner) * 2), angleStart, angleSpan);
@@ -977,7 +974,7 @@ void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, in
c = c.dark();
case SOLID:
graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeThickness(thickness);
graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
break;
@@ -1341,6 +1338,50 @@ void RenderObject::showTreeForThis() const
node()->showTreeForThis();
}
+void RenderObject::showRenderObject() const
+{
+ showRenderObject(0);
+}
+
+void RenderObject::showRenderObject(int printedCharacters) const
+{
+ // As this function is intended to be used when debugging, the
+ // this pointer may be 0.
+ if (!this) {
+ fputs("(null)\n", stderr);
+ return;
+ }
+
+ printedCharacters += fprintf(stderr, "%s %p", renderName(), this);
+
+ if (node()) {
+ if (printedCharacters)
+ for (; printedCharacters < 39; printedCharacters++)
+ fputc(' ', stderr);
+ fputc('\t', stderr);
+ node()->showNode();
+ } else
+ fputc('\n', stderr);
+}
+
+void RenderObject::showRenderTreeAndMark(const RenderObject* markedObject1, const char* markedLabel1, const RenderObject* markedObject2, const char* markedLabel2, int depth) const
+{
+ int printedCharacters = 0;
+ if (markedObject1 == this && markedLabel1)
+ printedCharacters += fprintf(stderr, "%s", markedLabel1);
+ if (markedObject2 == this && markedLabel2)
+ printedCharacters += fprintf(stderr, "%s", markedLabel2);
+ for (; printedCharacters < depth * 2; printedCharacters++)
+ fputc(' ', stderr);
+
+ showRenderObject(printedCharacters);
+ if (!this)
+ return;
+
+ for (const RenderObject* child = firstChild(); child; child = child->nextSibling())
+ child->showRenderTreeAndMark(markedObject1, markedLabel1, markedObject2, markedLabel2, depth + 1);
+}
+
#endif // NDEBUG
Color RenderObject::selectionBackgroundColor() const
@@ -2372,9 +2413,20 @@ RenderBoxModelObject* RenderObject::offsetParent() const
VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity)
{
- // If this is a non-anonymous renderer, then it's simple.
- if (Node* node = this->node())
+ // If this is a non-anonymous renderer in an editable area, then it's simple.
+ if (Node* node = this->node()) {
+ if (!node->isContentEditable()) {
+ // If it can be found, we prefer a visually equivalent position that is editable.
+ Position position(node, offset);
+ Position candidate = position.downstream(Position::CanCrossEditingBoundary);
+ if (candidate.node()->isContentEditable())
+ return VisiblePosition(candidate, affinity);
+ candidate = position.upstream(Position::CanCrossEditingBoundary);
+ if (candidate.node()->isContentEditable())
+ return VisiblePosition(candidate, affinity);
+ }
return VisiblePosition(node, offset, affinity);
+ }
// We don't want to cross the boundary between editable and non-editable
// regions of the document, but that is either impossible or at least
@@ -2476,4 +2528,19 @@ void showTree(const WebCore::RenderObject* ro)
ro->showTreeForThis();
}
+void showRenderTree(const WebCore::RenderObject* object1)
+{
+ showRenderTree(object1, 0);
+}
+
+void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2)
+{
+ if (object1) {
+ const WebCore::RenderObject* root = object1;
+ while (root->parent())
+ root = root->parent();
+ root->showRenderTreeAndMark(object1, "*", object2, "-", 0);
+ }
+}
+
#endif
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index e358c98..d40ae6d 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -4,6 +4,7 @@
* (C) 2000 Dirk Mueller (mueller@kde.org)
* (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google 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
@@ -76,11 +77,13 @@ enum PaintPhase {
PaintPhaseMask
};
-enum PaintRestriction {
- PaintRestrictionNone,
- PaintRestrictionSelectionOnly,
- PaintRestrictionSelectionOnlyBlackText
+enum PaintBehaviorFlags {
+ PaintBehaviorNormal = 0,
+ PaintBehaviorSelectionOnly = 1 << 0,
+ PaintBehaviorForceBlackText = 1 << 1,
+ PaintBehaviorFlattenCompositingLayers = 1 << 2
};
+typedef unsigned PaintBehavior;
enum HitTestFilter {
HitTestAll,
@@ -228,6 +231,12 @@ private:
public:
#ifndef NDEBUG
void showTreeForThis() const;
+
+ void showRenderObject() const;
+ // We don't make printedCharacters an optional parameter so that
+ // showRenderObject can be called from gdb easily.
+ void showRenderObject(int printedCharacters) const;
+ void showRenderTreeAndMark(const RenderObject* markedObject1 = 0, const char* markedLabel1 = 0, const RenderObject* markedObject2 = 0, const char* markedLabel2 = 0, int depth = 0) const;
#endif
static RenderObject* createObject(Node*, RenderStyle*);
@@ -252,6 +261,7 @@ public:
virtual bool isBoxModelObject() const { return false; }
virtual bool isCounter() const { return false; }
virtual bool isFieldset() const { return false; }
+ virtual bool isFileUploadControl() const { return false; }
virtual bool isFrame() const { return false; }
virtual bool isFrameSet() const { return false; }
virtual bool isImage() const { return false; }
@@ -267,6 +277,10 @@ public:
virtual bool isRenderInline() const { return false; }
virtual bool isRenderPart() const { return false; }
virtual bool isRenderView() const { return false; }
+ virtual bool isRuby() const { return false; }
+ virtual bool isRubyBase() const { return false; }
+ virtual bool isRubyRun() const { return false; }
+ virtual bool isRubyText() const { return false; }
virtual bool isSlider() const { return false; }
virtual bool isTable() const { return false; }
virtual bool isTableCell() const { return false; }
@@ -1028,6 +1042,10 @@ inline void adjustFloatQuadForAbsoluteZoom(FloatQuad& quad, RenderObject* render
#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
void showTree(const WebCore::RenderObject*);
+void showRenderTree(const WebCore::RenderObject* object1);
+// We don't make object2 an optional parameter so that showRenderTree
+// can be called from gdb easily.
+void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2);
#endif
#endif // RenderObject_h
diff --git a/WebCore/rendering/RenderObjectChildList.cpp b/WebCore/rendering/RenderObjectChildList.cpp
index 23ab98f..d56a015 100644
--- a/WebCore/rendering/RenderObjectChildList.cpp
+++ b/WebCore/rendering/RenderObjectChildList.cpp
@@ -271,24 +271,29 @@ static RenderObject* findBeforeAfterParent(RenderObject* object)
return beforeAfterParent;
}
-static void invalidateCountersInContainer(RenderObject* container)
+static void invalidateCountersInContainer(RenderObject* container, const AtomicString& identifier)
{
if (!container)
return;
container = findBeforeAfterParent(container);
if (!container)
return;
+ // Sometimes the counter is attached directly on the container.
+ if (container->isCounter()) {
+ toRenderCounter(container)->invalidate(identifier);
+ return;
+ }
for (RenderObject* content = container->firstChild(); content; content = content->nextSibling()) {
if (content->isCounter())
- toRenderCounter(content)->invalidate();
+ toRenderCounter(content)->invalidate(identifier);
}
}
-void RenderObjectChildList::invalidateCounters(RenderObject* owner)
+void RenderObjectChildList::invalidateCounters(RenderObject* owner, const AtomicString& identifier)
{
ASSERT(!owner->documentBeingDestroyed());
- invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE));
- invalidateCountersInContainer(beforeAfterContainer(owner, AFTER));
+ invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE), identifier);
+ invalidateCountersInContainer(beforeAfterContainer(owner, AFTER), identifier);
}
void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject)
@@ -369,9 +374,11 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
RefPtr<RenderStyle> style = RenderStyle::create();
style->inheritFrom(pseudoElementStyle);
genChild->setStyle(style.release());
- } else
- // Must be a first-letter container. updateFirstLetter() will take care of it.
- ASSERT(genChild->style()->styleType() == FIRST_LETTER);
+ } else {
+ // RenderListItem may insert a list marker here. We do not need to care about this case.
+ // Otherwise, genChild must be a first-letter container. updateFirstLetter() will take care of it.
+ ASSERT(genChild->isListMarker() || genChild->style()->styleType() == FIRST_LETTER);
+ }
}
}
return; // We've updated the generated content. That's all we needed to do.
diff --git a/WebCore/rendering/RenderObjectChildList.h b/WebCore/rendering/RenderObjectChildList.h
index bf8800a..ba73c50 100644
--- a/WebCore/rendering/RenderObjectChildList.h
+++ b/WebCore/rendering/RenderObjectChildList.h
@@ -30,6 +30,7 @@
namespace WebCore {
+class AtomicString;
class RenderObject;
class RenderObjectChildList {
@@ -55,7 +56,7 @@ public:
void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool fullInsert = true);
void updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject = 0);
- void invalidateCounters(RenderObject* owner);
+ void invalidateCounters(RenderObject* owner, const AtomicString& identifier);
private:
RenderObject* m_firstChild;
diff --git a/WebCore/rendering/RenderOverflow.h b/WebCore/rendering/RenderOverflow.h
index ed8976a..253a672 100644
--- a/WebCore/rendering/RenderOverflow.h
+++ b/WebCore/rendering/RenderOverflow.h
@@ -37,7 +37,7 @@ namespace WebCore
// Examples of visual overflow are shadows, text stroke (and eventually outline and border-image).
// This object is allocated only when some of these fields have non-default values in the owning box.
-class RenderOverflow {
+class RenderOverflow : public Noncopyable {
public:
RenderOverflow(const IntRect& defaultRect = IntRect())
: m_topLayoutOverflow(defaultRect.y())
diff --git a/WebCore/rendering/RenderReplaced.cpp b/WebCore/rendering/RenderReplaced.cpp
index 27d2e72..ba579df 100644
--- a/WebCore/rendering/RenderReplaced.cpp
+++ b/WebCore/rendering/RenderReplaced.cpp
@@ -153,7 +153,7 @@ void RenderReplaced::paint(PaintInfo& paintInfo, int tx, int ty)
if (drawSelectionTint) {
IntRect selectionPaintingRect = localSelectionRect();
selectionPaintingRect.move(tx, ty);
- paintInfo.context->fillRect(selectionPaintingRect, selectionBackgroundColor());
+ paintInfo.context->fillRect(selectionPaintingRect, selectionBackgroundColor(), style()->colorSpace());
}
}
diff --git a/WebCore/rendering/RenderReplica.cpp b/WebCore/rendering/RenderReplica.cpp
index 5fa3c62..1d589ae 100644
--- a/WebCore/rendering/RenderReplica.cpp
+++ b/WebCore/rendering/RenderReplica.cpp
@@ -72,7 +72,7 @@ void RenderReplica::paint(PaintInfo& paintInfo, int tx, int ty)
// computing using the wrong rootLayer
layer()->parent()->paintLayer(layer()->transform() ? layer()->parent() : layer()->enclosingTransformedAncestor(),
paintInfo.context, paintInfo.rect,
- PaintRestrictionNone, 0, 0,
+ PaintBehaviorNormal, 0, 0,
RenderLayer::PaintLayerHaveTransparency | RenderLayer::PaintLayerAppliedTransform | RenderLayer::PaintLayerTemporaryClipRects | RenderLayer::PaintLayerPaintingReflection);
else if (paintInfo.phase == PaintPhaseMask)
paintMask(paintInfo, tx, ty);
diff --git a/WebCore/rendering/RenderRuby.cpp b/WebCore/rendering/RenderRuby.cpp
new file mode 100644
index 0000000..8d113f9
--- /dev/null
+++ b/WebCore/rendering/RenderRuby.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2009 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 "RenderRuby.h"
+
+#include "RenderRubyRun.h"
+
+namespace WebCore {
+
+//=== generic helper functions to avoid excessive code duplication ===
+
+static RenderRubyRun* lastRubyRun(const RenderObject* ruby)
+{
+ RenderObject* child = ruby->lastChild();
+ if (child && ruby->isAfterContent(child))
+ child = child->previousSibling();
+ ASSERT(!child || child->isRubyRun());
+ return static_cast<RenderRubyRun*>(child);
+}
+
+static inline RenderRubyRun* findRubyRunParent(RenderObject* child)
+{
+ while (child && !child->isRubyRun())
+ child = child->parent();
+ return static_cast<RenderRubyRun*>(child);
+}
+
+//=== ruby as inline object ===
+
+RenderRubyAsInline::RenderRubyAsInline(Node* node)
+ : RenderInline(node)
+{
+}
+
+RenderRubyAsInline::~RenderRubyAsInline()
+{
+}
+
+bool RenderRubyAsInline::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isRubyText()
+ || child->isRubyRun()
+ || child->isInline();
+}
+
+void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+ // Note: ':after' content is handled implicitely below
+
+ // if child is a ruby run, just add it normally
+ if (child->isRubyRun()) {
+ RenderInline::addChild(child, beforeChild);
+ return;
+ }
+
+ if (beforeChild && !isAfterContent(beforeChild)) {
+ // insert child into run
+ ASSERT(!beforeChild->isRubyRun());
+ RenderRubyRun* run = findRubyRunParent(beforeChild);
+ ASSERT(run); // beforeChild should always have a run as parent
+ if (run) {
+ run->addChild(child, beforeChild);
+ return;
+ }
+ ASSERT(false); // beforeChild should always have a run as parent!
+ // Emergency fallback: fall through and just append.
+ }
+
+ // If the new child would be appended, try to add the child to the previous run
+ // if possible, or create a new run otherwise.
+ // (The RenderRubyRun object will handle the details)
+ RenderRubyRun* lastRun = lastRubyRun(this);
+ if (!lastRun || lastRun->hasRubyText()) {
+ lastRun = RenderRubyRun::staticCreateRubyRun(this);
+ RenderInline::addChild(lastRun);
+ }
+ lastRun->addChild(child);
+}
+
+void RenderRubyAsInline::removeChild(RenderObject* child)
+{
+ // If the child's parent is *this, i.e. a ruby run or ':after' content,
+ // just use the normal remove method.
+ if (child->parent() == this) {
+ ASSERT(child->isRubyRun() || child->isAfterContent());
+ RenderInline::removeChild(child);
+ return;
+ }
+
+ // Find the containing run
+ RenderRubyRun* run = findRubyRunParent(child);
+ ASSERT(run);
+ run->removeChild(child);
+}
+
+
+//=== ruby as block object ===
+
+RenderRubyAsBlock::RenderRubyAsBlock(Node* node)
+ : RenderBlock(node)
+{
+}
+
+RenderRubyAsBlock::~RenderRubyAsBlock()
+{
+}
+
+bool RenderRubyAsBlock::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isRubyText()
+ || child->isRubyRun()
+ || child->isInline();
+}
+
+void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+ // Note: ':after' content is handled implicitely below
+
+ // if child is a ruby run, just add it normally
+ if (child->isRubyRun()) {
+ RenderBlock::addChild(child, beforeChild);
+ return;
+ }
+
+ if (beforeChild && !isAfterContent(beforeChild)) {
+ // insert child into run
+ ASSERT(!beforeChild->isRubyRun());
+ RenderObject* run = beforeChild;
+ while (run && !run->isRubyRun())
+ run = run->parent();
+ if (run) {
+ run->addChild(child, beforeChild);
+ return;
+ }
+ ASSERT(false); // beforeChild should always have a run as parent!
+ // Emergency fallback: fall through and just append.
+ }
+
+ // If the new child would be appended, try to add the child to the previous run
+ // if possible, or create a new run otherwise.
+ // (The RenderRubyRun object will handle the details)
+ RenderRubyRun* lastRun = lastRubyRun(this);
+ if (!lastRun || lastRun->hasRubyText()) {
+ lastRun = RenderRubyRun::staticCreateRubyRun(this);
+ RenderBlock::addChild(lastRun);
+ }
+ lastRun->addChild(child);
+}
+
+void RenderRubyAsBlock::removeChild(RenderObject* child)
+{
+ // If the child's parent is *this, just use the normal remove method.
+ if (child->parent() == this) {
+ // This should happen only during destruction of the whole ruby element, though.
+ RenderBlock::removeChild(child);
+ return;
+ }
+
+ // Find the containing run
+ RenderRubyRun* run = findRubyRunParent(child);
+ ASSERT(run);
+ run->removeChild(child);
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/rendering/RenderRuby.h b/WebCore/rendering/RenderRuby.h
new file mode 100644
index 0000000..a74150c
--- /dev/null
+++ b/WebCore/rendering/RenderRuby.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 RenderRuby_h
+#define RenderRuby_h
+
+#include "RenderBlock.h"
+#include "RenderInline.h"
+
+namespace WebCore {
+
+// Following the HTML 5 spec, the box object model for a <ruby> element allows several runs of ruby
+// bases with their respective ruby texts looks as follows:
+//
+// 1 RenderRuby object, corresponding to the whole <ruby> HTML element
+// 1+ RenderRubyRun (anonymous)
+// 0 or 1 RenderRubyText - shuffled to the front in order to re-use existing block layouting
+// 0-n inline object(s)
+// 0 or 1 RenderRubyBase - contains the inline objects that make up the ruby base
+// 1-n inline object(s)
+//
+// Note: <rp> elements are defined as having 'display:none' and thus normally are not assigned a renderer.
+
+// <ruby> when used as 'display:inline'
+class RenderRubyAsInline : public RenderInline {
+public:
+ RenderRubyAsInline(Node*);
+ virtual ~RenderRubyAsInline();
+
+ virtual const char* renderName() const { return "RenderRuby (inline)"; }
+
+ virtual bool isRuby() const { return true; }
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void removeChild(RenderObject* child);
+};
+
+// <ruby> when used as 'display:block' or 'display:inline-block'
+class RenderRubyAsBlock : public RenderBlock {
+public:
+ RenderRubyAsBlock(Node*);
+ virtual ~RenderRubyAsBlock();
+
+ virtual const char* renderName() const { return "RenderRuby (block)"; }
+
+ virtual bool isRuby() const { return true; }
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void removeChild(RenderObject* child);
+};
+
+} // namespace WebCore
+
+#endif // RenderRuby_h
diff --git a/WebCore/rendering/RenderRubyBase.cpp b/WebCore/rendering/RenderRubyBase.cpp
new file mode 100644
index 0000000..5cb25f4
--- /dev/null
+++ b/WebCore/rendering/RenderRubyBase.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 "RenderRubyBase.h"
+
+namespace WebCore {
+
+RenderRubyBase::RenderRubyBase(Node* node)
+ : RenderBlock(node)
+{
+ setInline(false);
+}
+
+RenderRubyBase::~RenderRubyBase()
+{
+}
+
+bool RenderRubyBase::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isInline();
+}
+
+void RenderRubyBase::splitToLeft(RenderBlock* leftBase, RenderObject* beforeChild)
+{
+ // This function removes all children that are before (!) beforeChild
+ // and appends them to leftBase.
+ ASSERT(leftBase);
+
+ // First make sure that beforeChild (if set) is indeed a direct child of this.
+ // Fallback: climb up the tree to make sure. This may result in somewhat incorrect rendering.
+ // FIXME: Can this happen? Is there a better/more correct way to solve this?
+ ASSERT(!beforeChild || beforeChild->parent() == this);
+ while (beforeChild && beforeChild->parent() != this)
+ beforeChild = beforeChild->parent();
+
+ RenderObject* child = firstChild();
+ while (child != beforeChild) {
+ RenderObject* nextChild = child->nextSibling();
+ moveChildTo(leftBase, leftBase->children(), child);
+ child = nextChild;
+ }
+}
+
+void RenderRubyBase::mergeWithRight(RenderBlock* rightBase)
+{
+ // This function removes all children and prepends (!) them to rightBase.
+ ASSERT(rightBase);
+
+ RenderObject* firstPos = rightBase->firstChild();
+ RenderObject* child = lastChild();
+ while (child) {
+ moveChildTo(rightBase, rightBase->children(), firstPos, child);
+ firstPos = child;
+ child = lastChild();
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/RenderRubyBase.h b/WebCore/rendering/RenderRubyBase.h
new file mode 100644
index 0000000..57baf99
--- /dev/null
+++ b/WebCore/rendering/RenderRubyBase.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 RenderRubyBase_h
+#define RenderRubyBase_h
+
+#include "RenderBlock.h"
+
+namespace WebCore {
+
+class RenderRubyBase : public RenderBlock {
+public:
+ RenderRubyBase(Node*);
+ virtual ~RenderRubyBase();
+
+ virtual const char* renderName() const { return "RenderRubyBase (anonymous)"; }
+
+ virtual bool isRubyBase() const { return true; }
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+
+ void splitToLeft(RenderBlock* leftBase, RenderObject* beforeChild);
+ void mergeWithRight(RenderBlock* rightBase);
+};
+
+} // namespace WebCore
+
+#endif // RenderRubyBase_h
diff --git a/WebCore/rendering/RenderRubyRun.cpp b/WebCore/rendering/RenderRubyRun.cpp
new file mode 100644
index 0000000..8578c55
--- /dev/null
+++ b/WebCore/rendering/RenderRubyRun.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2009 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 "RenderRubyRun.h"
+
+#include "RenderRubyBase.h"
+#include "RenderRubyText.h"
+#include "RenderView.h"
+
+using namespace std;
+
+namespace WebCore {
+
+RenderRubyRun::RenderRubyRun(Node* node)
+ : RenderBlock(node)
+ , m_beingDestroyed(false)
+{
+ setReplaced(true);
+ setInline(true);
+}
+
+RenderRubyRun::~RenderRubyRun()
+{
+}
+
+void RenderRubyRun::destroy()
+{
+ // Mark if the run is being destroyed to avoid trouble in removeChild().
+ m_beingDestroyed = true;
+ RenderBlock::destroy();
+}
+
+bool RenderRubyRun::hasRubyText() const
+{
+ // The only place where a ruby text can be is in the first position
+ // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' content themselves.
+ return firstChild() && firstChild()->isRubyText();
+}
+
+bool RenderRubyRun::hasRubyBase() const
+{
+ // The only place where a ruby base can be is in the last position
+ // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' content themselves.
+ return lastChild() && lastChild()->isRubyBase();
+}
+
+bool RenderRubyRun::isEmpty() const
+{
+ return !hasRubyText() && !hasRubyBase();
+}
+
+RenderRubyText* RenderRubyRun::rubyText() const
+{
+ RenderObject* child = firstChild();
+ return child && child->isRubyText() ? static_cast<RenderRubyText*>(child) : 0;
+}
+
+RenderRubyBase* RenderRubyRun::rubyBase() const
+{
+ RenderObject* child = lastChild();
+ return child && child->isRubyBase() ? static_cast<RenderRubyBase*>(child) : 0;
+}
+
+RenderRubyBase* RenderRubyRun::rubyBaseSafe()
+{
+ RenderRubyBase* base = rubyBase();
+ if (!base) {
+ base = createRubyBase();
+ RenderBlock::addChild(base);
+ }
+ return base;
+}
+
+RenderBlock* RenderRubyRun::firstLineBlock() const
+{
+ return 0;
+}
+
+void RenderRubyRun::updateFirstLetter()
+{
+}
+
+bool RenderRubyRun::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isRubyText() || child->isInline();
+}
+
+void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+ ASSERT(child);
+
+ // If child is a ruby text
+ if (child->isRubyText()) {
+ if (!beforeChild) {
+ // RenderRuby has already ascertained that we can add the child here.
+ ASSERT(!hasRubyText());
+ // prepend ruby texts as first child
+ RenderBlock::addChild(child, firstChild());
+ } else if (beforeChild->isRubyText()) {
+ // New text is inserted just before another.
+ // In this case the new text takes the place of the old one, and
+ // the old text goes into a new run that is inserted as next sibling.
+ ASSERT(beforeChild->parent() == this);
+ RenderObject* ruby = parent();
+ ASSERT(ruby->isRuby());
+ RenderBlock* newRun = staticCreateRubyRun(ruby);
+ ruby->addChild(newRun, nextSibling());
+ // Add the new ruby text and move the old one to the new run
+ // Note: Doing it in this order and not using RenderRubyRun's methods,
+ // in order to avoid automatic removal of the ruby run in case there is no
+ // other child besides the old ruby text.
+ RenderBlock::addChild(child, beforeChild);
+ RenderBlock::removeChild(beforeChild);
+ newRun->addChild(beforeChild);
+ } else {
+ ASSERT(hasRubyBase()); // Otherwise beforeChild would be borked.
+ // Insertion before a ruby base object.
+ // In this case we need insert a new run before the current one and split the base.
+ RenderObject* ruby = parent();
+ RenderRubyRun* newRun = staticCreateRubyRun(ruby);
+ ruby->addChild(newRun, this);
+ newRun->addChild(child);
+ rubyBaseSafe()->splitToLeft(newRun->rubyBaseSafe(), beforeChild);
+ }
+ } else {
+ // child is not a text -> insert it into the base
+ // (append it instead if beforeChild is the ruby text)
+ if (beforeChild && beforeChild->isRubyText())
+ beforeChild = 0;
+ rubyBaseSafe()->addChild(child, beforeChild);
+ }
+}
+
+void RenderRubyRun::removeChild(RenderObject* child)
+{
+ // If the child is a ruby text, then merge the ruby base with the base of
+ // the right sibling run, if possible.
+ if (!m_beingDestroyed && !documentBeingDestroyed() && child->isRubyText()) {
+ RenderRubyBase* base = rubyBase();
+ RenderObject* rightNeighbour = nextSibling();
+ if (base && rightNeighbour && rightNeighbour->isRubyRun()) {
+ // Ruby run without a base can happen only at the first run.
+ RenderRubyRun* rightRun = static_cast<RenderRubyRun*>(rightNeighbour);
+ ASSERT(rightRun->hasRubyBase());
+ base->mergeWithRight(rightRun->rubyBaseSafe());
+ // The now empty ruby base will be removed below.
+ }
+ }
+
+ RenderBlock::removeChild(child);
+
+ if (!m_beingDestroyed && !documentBeingDestroyed()) {
+ // Check if our base (if any) is now empty. If so, destroy it.
+ RenderBlock* base = rubyBase();
+ if (base && !base->firstChild()) {
+ RenderBlock::removeChild(base);
+ base->deleteLineBoxTree();
+ base->destroy();
+ }
+
+ // If any of the above leaves the run empty, destroy it as well.
+ if (isEmpty()) {
+ parent()->removeChild(this);
+ deleteLineBoxTree();
+ destroy();
+ }
+ }
+}
+
+RenderRubyBase* RenderRubyRun::createRubyBase() const
+{
+ RenderRubyBase* rb = new (renderArena()) RenderRubyBase(document() /* anonymous */);
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(BLOCK);
+ newStyle->setTextAlign(CENTER); // FIXME: use WEBKIT_CENTER?
+ rb->setStyle(newStyle.release());
+ return rb;
+}
+
+RenderRubyRun* RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby)
+{
+ ASSERT(parentRuby && parentRuby->isRuby());
+ RenderRubyRun* rr = new (parentRuby->renderArena()) RenderRubyRun(parentRuby->document() /* anonymous */);
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(parentRuby->style());
+ newStyle->setDisplay(INLINE_BLOCK);
+ rr->setStyle(newStyle.release());
+ return rr;
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/RenderRubyRun.h b/WebCore/rendering/RenderRubyRun.h
new file mode 100644
index 0000000..361dfe5
--- /dev/null
+++ b/WebCore/rendering/RenderRubyRun.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2009 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 RenderRubyRun_h
+#define RenderRubyRun_h
+
+#include "RenderBlock.h"
+
+namespace WebCore {
+
+class RenderRubyBase;
+class RenderRubyText;
+
+// RenderRubyRun are 'inline-block/table' like objects,and wrap a single pairing of a ruby base with its ruby text(s).
+// See RenderRuby.h for further comments on the structure
+
+class RenderRubyRun : public RenderBlock {
+public:
+ RenderRubyRun(Node*);
+ virtual ~RenderRubyRun();
+
+ virtual void destroy();
+
+ virtual const char* renderName() const { return "RenderRubyRun (anonymous)"; }
+
+ virtual bool isRubyRun() const { return true; }
+
+ bool hasRubyText() const;
+ bool hasRubyBase() const;
+ bool isEmpty() const;
+ RenderRubyText* rubyText() const;
+ RenderRubyBase* rubyBase() const;
+ RenderRubyBase* rubyBaseSafe(); // creates the base if it doesn't already exist
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void removeChild(RenderObject* child);
+
+ virtual RenderBlock* firstLineBlock() const;
+ virtual void updateFirstLetter();
+
+ static RenderRubyRun* staticCreateRubyRun(const RenderObject* parentRuby);
+
+protected:
+ RenderRubyBase* createRubyBase() const;
+
+private:
+ bool m_beingDestroyed;
+};
+
+} // namespace WebCore
+
+#endif // RenderRubyRun_h
diff --git a/WebCore/rendering/RenderRubyText.cpp b/WebCore/rendering/RenderRubyText.cpp
new file mode 100644
index 0000000..cfe3b5c
--- /dev/null
+++ b/WebCore/rendering/RenderRubyText.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 "RenderRubyText.h"
+
+namespace WebCore {
+
+RenderRubyText::RenderRubyText(Node* node)
+ : RenderBlock(node)
+{
+}
+
+RenderRubyText::~RenderRubyText()
+{
+}
+
+bool RenderRubyText::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isInline();
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/RenderRubyText.h b/WebCore/rendering/RenderRubyText.h
new file mode 100644
index 0000000..e475914
--- /dev/null
+++ b/WebCore/rendering/RenderRubyText.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 RenderRubyText_h
+#define RenderRubyText_h
+
+#include "RenderBlock.h"
+
+namespace WebCore {
+
+class RenderRubyText : public RenderBlock {
+public:
+ RenderRubyText(Node*);
+ virtual ~RenderRubyText();
+
+ virtual const char* renderName() const { return "RenderRubyText"; }
+
+ virtual bool isRubyText() const { return true; }
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+};
+
+} // namespace WebCore
+
+#endif // RenderRubyText_h
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index 7e0b40d..41a1a10 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -166,7 +166,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
if (imageElt->preserveAspectRatio()->align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
adjustRectsForAspectRatio(destRect, srcRect, imageElt->preserveAspectRatio());
- paintInfo.context->drawImage(image(), destRect, srcRect);
+ paintInfo.context->drawImage(image(), DeviceColorSpace, destRect, srcRect);
finishRenderSVGContent(this, paintInfo, filter, savedInfo.context);
}
diff --git a/WebCore/rendering/RenderScrollbarTheme.cpp b/WebCore/rendering/RenderScrollbarTheme.cpp
index 06ca32a..19143cc 100644
--- a/WebCore/rendering/RenderScrollbarTheme.cpp
+++ b/WebCore/rendering/RenderScrollbarTheme.cpp
@@ -109,7 +109,7 @@ IntRect RenderScrollbarTheme::constrainTrackRectToTrackPieces(Scrollbar* scrollb
void RenderScrollbarTheme::paintScrollCorner(ScrollView*, GraphicsContext* context, const IntRect& cornerRect)
{
// FIXME: Implement.
- context->fillRect(cornerRect, Color::white);
+ context->fillRect(cornerRect, Color::white, DeviceColorSpace);
}
void RenderScrollbarTheme::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar)
diff --git a/WebCore/rendering/RenderSelectionInfo.h b/WebCore/rendering/RenderSelectionInfo.h
index e7b7b78..c06a9ae 100644
--- a/WebCore/rendering/RenderSelectionInfo.h
+++ b/WebCore/rendering/RenderSelectionInfo.h
@@ -30,7 +30,7 @@
namespace WebCore {
-class RenderSelectionInfoBase {
+class RenderSelectionInfoBase : public Noncopyable {
public:
RenderSelectionInfoBase()
: m_object(0)
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index c8b60fd..7398a2f 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -52,7 +52,8 @@ 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 isIntegral;
+ bool hasStep;
+ double step;
double minimum;
double maximum; // maximum must be >= minimum.
@@ -79,19 +80,28 @@ struct SliderRange {
SliderRange::SliderRange(HTMLInputElement* element)
{
- // FIXME: What's the right way to handle an integral range with non-integral minimum and maximum?
- // Currently values are guaranteed to be integral but could be outside the range in that case.
-
- isIntegral = !equalIgnoringCase(element->getAttribute(precisionAttr), "float");
-
- maximum = element->rangeMaximum();
- minimum = element->rangeMinimum();
+ 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));
- return isIntegral ? round(clampedValue) : clampedValue;
+ 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)
@@ -356,10 +366,9 @@ void RenderSlider::layout()
thumb->repaintDuringLayoutIfMoved(oldThumbRect);
statePusher.pop();
+ addOverflowFromChild(thumb);
}
- addOverflowFromChild(thumb);
-
repainter.repaintAfterLayout();
setNeedsLayout(false);
@@ -374,7 +383,7 @@ void RenderSlider::updateFromElement()
bool clamped;
double value = range.valueFromElement(element, &clamped);
if (clamped)
- element->setValueFromRenderer(String::number(value));
+ element->setValueFromRenderer(HTMLInputElement::formStringFromDouble(value));
// Layout will take care of the thumb's size and position.
if (!m_thumb) {
@@ -430,7 +439,7 @@ void RenderSlider::setValueForPosition(int position)
if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart)
fraction = 1 - fraction;
double value = range.clampValue(range.valueFromProportion(fraction));
- element->setValueFromRenderer(String::number(value));
+ element->setValueFromRenderer(HTMLInputElement::formStringFromDouble(value));
// Also update the position if appropriate.
if (position != currentPosition()) {
diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp
index 8e0b613..4e7036e 100644
--- a/WebCore/rendering/RenderTableCell.cpp
+++ b/WebCore/rendering/RenderTableCell.cpp
@@ -168,6 +168,17 @@ void RenderTableCell::setOverrideSize(int size)
RenderBlock::setOverrideSize(size);
}
+IntSize RenderTableCell::offsetFromContainer(RenderObject* o) const
+{
+ ASSERT(o == container());
+
+ IntSize offset = RenderBlock::offsetFromContainer(o);
+ if (parent())
+ offset.expand(-parentBox()->x(), -parentBox()->y());
+
+ return offset;
+}
+
IntRect RenderTableCell::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
// If the table grid is dirty, we cannot get reliable information about adjoining cells,
@@ -231,30 +242,6 @@ void RenderTableCell::computeRectForRepaint(RenderBoxModelObject* repaintContain
RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);
}
-void RenderTableCell::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
-{
- if (repaintContainer == this)
- return;
-
- RenderView* v = view();
- if ((!v || !v->layoutStateEnabled()) && parent()) {
- // Rows are in the same coordinate space, so don't add their offset in.
- // FIXME: this is wrong with transforms
- transformState.move(-parentBox()->x(), -parentBox()->y());
- }
- RenderBlock::mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
-}
-
-void RenderTableCell::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
-{
- RenderBlock::mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
- if (parent()) {
- // Rows are in the same coordinate space, so add their offset back in.
- // FIXME: this is wrong with transforms
- transformState.move(parentBox()->x(), parentBox()->y());
- }
-}
-
int RenderTableCell::baselinePosition(bool firstLine, bool isRootLineBox) const
{
if (isRootLineBox)
diff --git a/WebCore/rendering/RenderTableCell.h b/WebCore/rendering/RenderTableCell.h
index 9532bb6..f285198 100644
--- a/WebCore/rendering/RenderTableCell.h
+++ b/WebCore/rendering/RenderTableCell.h
@@ -110,9 +110,6 @@ protected:
virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
- virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
-
private:
virtual const char* renderName() const { return isAnonymous() ? "RenderTableCell (anonymous)" : "RenderTableCell"; }
@@ -127,6 +124,7 @@ private:
virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
virtual void paintMask(PaintInfo&, int tx, int ty);
+ virtual IntSize offsetFromContainer(RenderObject*) const;
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
diff --git a/WebCore/rendering/RenderTableRow.cpp b/WebCore/rendering/RenderTableRow.cpp
index bafadfc..a11a14b 100644
--- a/WebCore/rendering/RenderTableRow.cpp
+++ b/WebCore/rendering/RenderTableRow.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1997 Martin Jones (mjones@kde.org)
* (C) 1997 Torben Weis (weis@kde.org)
* (C) 1998 Waldo Bastian (bastian@kde.org)
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index 5052c3a..b627afe 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -46,6 +46,14 @@ namespace WebCore {
using namespace HTMLNames;
+static inline void setRowHeightToRowStyleHeightIfNotRelative(RenderTableSection::RowStruct* row)
+{
+ ASSERT(row && row->rowRenderer);
+ row->height = row->rowRenderer->style()->height();
+ if (row->height.isRelative())
+ row->height = Length();
+}
+
RenderTableSection::RenderTableSection(Node* node)
: RenderBox(node)
, m_gridRows(0)
@@ -126,11 +134,8 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
m_grid[m_cRow].rowRenderer = toRenderTableRow(child);
- if (!beforeChild) {
- m_grid[m_cRow].height = child->style()->height();
- if (m_grid[m_cRow].height.isRelative())
- m_grid[m_cRow].height = Length();
- }
+ if (!beforeChild)
+ setRowHeightToRowStyleHeightIfNotRelative(&m_grid[m_cRow]);
// If the next renderer is actually wrapped in an anonymous table row, we need to go up and find that.
while (beforeChild && beforeChild->parent() != this)
@@ -1190,6 +1195,7 @@ void RenderTableSection::recalcCells()
RenderTableRow* tableRow = toRenderTableRow(row);
m_grid[m_cRow].rowRenderer = tableRow;
+ setRowHeightToRowStyleHeightIfNotRelative(&m_grid[m_cRow]);
for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
if (cell->isTableCell())
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index 40c3d75..95aa277 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -757,6 +757,17 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f
setPrefWidthsDirty(false);
}
+bool RenderText::isAllCollapsibleWhitespace()
+{
+ int length = textLength();
+ const UChar* text = characters();
+ for (int i = 0; i < length; i++) {
+ if (!style()->isCollapsibleWhiteSpace(text[i]))
+ return false;
+ }
+ return true;
+}
+
bool RenderText::containsOnlyWhitespace(unsigned from, unsigned len) const
{
unsigned currPos;
@@ -813,7 +824,9 @@ void RenderText::setSelectionState(SelectionState state)
}
}
- containingBlock()->setSelectionState(state);
+ // The returned value can be null in case of an orphaned tree.
+ if (RenderBlock* cb = containingBlock())
+ cb->setSelectionState(state);
}
void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, unsigned len, bool force)
diff --git a/WebCore/rendering/RenderText.h b/WebCore/rendering/RenderText.h
index 915ff40..d46bce9 100644
--- a/WebCore/rendering/RenderText.h
+++ b/WebCore/rendering/RenderText.h
@@ -121,7 +121,8 @@ public:
void checkConsistency() const;
virtual void calcPrefWidths(int leadWidth);
-
+ bool isAllCollapsibleWhitespace();
+
protected:
virtual void styleWillChange(StyleDifference, const RenderStyle*) { }
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index f430399..b258597 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -70,8 +70,8 @@ static Color disabledTextColor(const Color& textColor, const Color& backgroundCo
RenderTextControl::RenderTextControl(Node* node, bool placeholderVisible)
: RenderBlock(node)
, m_placeholderVisible(placeholderVisible)
- , m_edited(false)
- , m_userEdited(false)
+ , m_wasChangedSinceLastChangeEvent(false)
+ , m_lastChangeWasUserEdit(false)
{
}
@@ -195,17 +195,17 @@ void RenderTextControl::setInnerTextValue(const String& innerTextValue)
ASSERT(!ec);
}
- m_edited = false;
- m_userEdited = false;
+ // We set m_lastChangeWasUserEdit to false since this change was not explicty made by the user (say, via typing on the keyboard), see <rdar://problem/5359921>.
+ m_lastChangeWasUserEdit = false;
}
static_cast<Element*>(node())->setFormControlValueMatchesRenderer(true);
}
-void RenderTextControl::setUserEdited(bool isUserEdited)
+void RenderTextControl::setLastChangeWasUserEdit(bool lastChangeWasUserEdit)
{
- m_userEdited = isUserEdited;
- document()->setIgnoreAutofocus(isUserEdited);
+ m_lastChangeWasUserEdit = lastChangeWasUserEdit;
+ document()->setIgnoreAutofocus(lastChangeWasUserEdit);
}
int RenderTextControl::selectionStart()
@@ -312,8 +312,8 @@ int RenderTextControl::indexForVisiblePosition(const VisiblePosition& pos)
void RenderTextControl::subtreeHasChanged()
{
- m_edited = true;
- m_userEdited = true;
+ m_wasChangedSinceLastChangeEvent = true;
+ m_lastChangeWasUserEdit = true;
}
String RenderTextControl::finishText(Vector<UChar>& result) const
diff --git a/WebCore/rendering/RenderTextControl.h b/WebCore/rendering/RenderTextControl.h
index cdd8716..394eb9c 100644
--- a/WebCore/rendering/RenderTextControl.h
+++ b/WebCore/rendering/RenderTextControl.h
@@ -34,11 +34,11 @@ class RenderTextControl : public RenderBlock {
public:
virtual ~RenderTextControl();
- bool isEdited() const { return m_edited; }
- void setEdited(bool isEdited) { m_edited = isEdited; }
+ bool wasChangedSinceLastChangeEvent() const { return m_wasChangedSinceLastChangeEvent; }
+ void setChangedSinceLastChangeEvent(bool wasChangedSinceLastChangeEvent) { m_wasChangedSinceLastChangeEvent = wasChangedSinceLastChangeEvent; }
- bool isUserEdited() const { return m_userEdited; }
- void setUserEdited(bool isUserEdited);
+ bool lastChangeWasUserEdit() const { return m_lastChangeWasUserEdit; }
+ void setLastChangeWasUserEdit(bool lastChangeWasUserEdit);
int selectionStart();
int selectionEnd();
@@ -105,8 +105,8 @@ private:
String finishText(Vector<UChar>&) const;
- bool m_edited;
- bool m_userEdited;
+ bool m_wasChangedSinceLastChangeEvent;
+ bool m_lastChangeWasUserEdit;
RefPtr<TextControlInnerTextElement> m_innerText;
};
diff --git a/WebCore/rendering/RenderTextControlMultiLine.cpp b/WebCore/rendering/RenderTextControlMultiLine.cpp
index 6ff9235..afc3edd 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -67,8 +67,8 @@ bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitT
return false;
bool resultIsTextValueOrPlaceholder
- = !m_placeholderVisible && result.innerNode() == innerTextElement()
- || m_placeholderVisible && result.innerNode()->isDescendantOf(innerTextElement());
+ = (!m_placeholderVisible && result.innerNode() == innerTextElement())
+ || (m_placeholderVisible && result.innerNode()->isDescendantOf(innerTextElement()));
if (result.innerNode() == node() || resultIsTextValueOrPlaceholder)
hitInnerTextElement(result, x, y, tx, ty);
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index dd1c24c..56d4363 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -150,7 +150,7 @@ void RenderTextControlSingleLine::hidePopup()
void RenderTextControlSingleLine::subtreeHasChanged()
{
- bool wasEdited = isEdited();
+ bool wasChanged = wasChangedSinceLastChangeEvent();
RenderTextControl::subtreeHasChanged();
InputElement* input = inputElement();
@@ -167,7 +167,7 @@ void RenderTextControlSingleLine::subtreeHasChanged()
if (input->searchEventsShouldBeDispatched())
startSearchEventTimer();
- if (!wasEdited && node()->focused()) {
+ if (!wasChanged && node()->focused()) {
if (Frame* frame = document()->frame())
frame->textFieldDidBeginEditing(static_cast<Element*>(node()));
}
diff --git a/WebCore/rendering/RenderTheme.cpp b/WebCore/rendering/RenderTheme.cpp
index 238279a..f6afb77 100644
--- a/WebCore/rendering/RenderTheme.cpp
+++ b/WebCore/rendering/RenderTheme.cpp
@@ -1,7 +1,7 @@
/**
* This file is part of the theme implementation for form controls in WebCore.
*
- * Copyright (C) 2005, 2006, 2007, 2008 Apple Computer, Inc.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 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
@@ -282,6 +282,8 @@ bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInf
return paintMediaRewindButton(o, paintInfo, r);
case MediaReturnToRealtimeButtonPart:
return paintMediaReturnToRealtimeButton(o, paintInfo, r);
+ case MediaToggleClosedCaptionsButtonPart:
+ return paintMediaToggleClosedCaptionsButton(o, paintInfo, r);
case MediaSliderPart:
return paintMediaSliderTrack(o, paintInfo, r);
case MediaSliderThumbPart:
@@ -420,6 +422,8 @@ bool RenderTheme::shouldRenderMediaControlPart(ControlPart part, Element* e)
return mediaElement->movieLoadType() == MediaPlayer::LiveStream;
case MediaFullscreenButtonPart:
return mediaElement->supportsFullscreen();
+ case MediaToggleClosedCaptionsButtonPart:
+ return mediaElement->hasClosedCaptions();
default:
return true;
}
@@ -705,6 +709,10 @@ bool RenderTheme::isHovered(const RenderObject* o) const
bool RenderTheme::isDefault(const RenderObject* o) const
{
+ // A button should only have the default appearance if the page is active
+ if (!isActive(o))
+ return false;
+
if (!o->document())
return false;
diff --git a/WebCore/rendering/RenderTheme.h b/WebCore/rendering/RenderTheme.h
index 68e2eba..ee359d7 100644
--- a/WebCore/rendering/RenderTheme.h
+++ b/WebCore/rendering/RenderTheme.h
@@ -253,6 +253,7 @@ protected:
virtual bool paintMediaVolumeSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaRewindButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaReturnToRealtimeButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
+ virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaControlsBackground(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaCurrentTime(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaTimeRemaining(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
diff --git a/WebCore/rendering/RenderThemeChromiumLinux.cpp b/WebCore/rendering/RenderThemeChromiumLinux.cpp
index 9048ce3..4b09174 100644
--- a/WebCore/rendering/RenderThemeChromiumLinux.cpp
+++ b/WebCore/rendering/RenderThemeChromiumLinux.cpp
@@ -32,6 +32,10 @@
namespace WebCore {
+unsigned RenderThemeChromiumLinux::m_thumbInactiveColor = 0xf0ebe5;
+unsigned RenderThemeChromiumLinux::m_thumbActiveColor = 0xfaf8f5;
+unsigned RenderThemeChromiumLinux::m_trackColor = 0xe3ddd8;
+
PassRefPtr<RenderTheme> RenderThemeChromiumLinux::create()
{
return adoptRef(new RenderThemeChromiumLinux());
@@ -122,4 +126,12 @@ double RenderThemeChromiumLinux::caretBlinkIntervalInternal() const
return m_caretBlinkInterval;
}
+void RenderThemeChromiumLinux::setScrollbarColors(
+ SkColor inactiveColor, SkColor activeColor, SkColor trackColor)
+{
+ m_thumbInactiveColor = inactiveColor;
+ m_thumbActiveColor = activeColor;
+ m_trackColor = trackColor;
+}
+
} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeChromiumLinux.h b/WebCore/rendering/RenderThemeChromiumLinux.h
index e137ad5..8736b0d 100644
--- a/WebCore/rendering/RenderThemeChromiumLinux.h
+++ b/WebCore/rendering/RenderThemeChromiumLinux.h
@@ -54,6 +54,13 @@ namespace WebCore {
void setCaretBlinkInterval(double interval);
virtual double caretBlinkIntervalInternal() const;
+ static void setScrollbarColors(unsigned inactive_color,
+ unsigned active_color,
+ unsigned track_color);
+ static unsigned thumbInactiveColor() { return m_thumbInactiveColor; }
+ static unsigned thumbActiveColor() { return m_thumbActiveColor; }
+ static unsigned trackColor() { return m_trackColor; }
+
private:
RenderThemeChromiumLinux();
virtual ~RenderThemeChromiumLinux();
@@ -62,6 +69,10 @@ namespace WebCore {
virtual bool supportsControlTints() const;
double m_caretBlinkInterval;
+
+ static unsigned m_thumbInactiveColor;
+ static unsigned m_thumbActiveColor;
+ static unsigned m_trackColor;
};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeChromiumMac.mm b/WebCore/rendering/RenderThemeChromiumMac.mm
index bcfcd57..4e57cb5 100644
--- a/WebCore/rendering/RenderThemeChromiumMac.mm
+++ b/WebCore/rendering/RenderThemeChromiumMac.mm
@@ -983,7 +983,7 @@ bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const RenderOb
paintInfo.context->save();
- paintInfo.context->setFillColor(o->style()->color());
+ paintInfo.context->setFillColor(o->style()->color(), DeviceColorSpace);
paintInfo.context->setStrokeStyle(NoStroke);
FloatPoint arrow1[3];
@@ -1012,11 +1012,11 @@ bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const RenderOb
// Draw the separator to the left of the arrows
paintInfo.context->setStrokeThickness(1.0f); // Deliberately ignores zoom since it looks nicer if it stays thin.
paintInfo.context->setStrokeStyle(SolidStroke);
- paintInfo.context->setStrokeColor(leftSeparatorColor);
+ paintInfo.context->setStrokeColor(leftSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
IntPoint(leftEdgeOfSeparator, bounds.bottom()));
- paintInfo.context->setStrokeColor(rightSeparatorColor);
+ paintInfo.context->setStrokeColor(rightSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom()));
diff --git a/WebCore/rendering/RenderThemeChromiumSkia.cpp b/WebCore/rendering/RenderThemeChromiumSkia.cpp
index fb42bb7..016a264 100644
--- a/WebCore/rendering/RenderThemeChromiumSkia.cpp
+++ b/WebCore/rendering/RenderThemeChromiumSkia.cpp
@@ -231,7 +231,7 @@ bool RenderThemeChromiumSkia::paintCheckbox(RenderObject* o, const RenderObject:
else
image = this->isChecked(o) ? disabledCheckedImage : disabledUncheckedImage;
- i.context->drawImage(image, rect);
+ i.context->drawImage(image, o->style()->colorSpace(), rect);
return false;
}
@@ -263,7 +263,7 @@ bool RenderThemeChromiumSkia::paintRadio(RenderObject* o, const RenderObject::Pa
else
image = this->isChecked(o) ? disabledCheckedImage : disabledUncheckedImage;
- i.context->drawImage(image, rect);
+ i.context->drawImage(image, o->style()->colorSpace(), rect);
return false;
}
@@ -348,6 +348,15 @@ bool RenderThemeChromiumSkia::paintButton(RenderObject* o, const RenderObject::P
return false;
}
+void RenderThemeChromiumSkia::adjustButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+{
+ if (style->appearance() == PushButtonPart) {
+ // Ignore line-height.
+ style->setLineHeight(RenderStyle::initialLineHeight());
+ }
+}
+
+
bool RenderThemeChromiumSkia::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
return true;
@@ -358,6 +367,12 @@ bool RenderThemeChromiumSkia::paintTextArea(RenderObject* o, const RenderObject:
return paintTextField(o, i, r);
}
+void RenderThemeChromiumSkia::adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+{
+ // Ignore line-height.
+ style->setLineHeight(RenderStyle::initialLineHeight());
+}
+
bool RenderThemeChromiumSkia::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
return paintTextField(o, i, r);
@@ -393,7 +408,7 @@ bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* o, cons
static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef();
static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef();
- i.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, bounds);
+ i.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, o->style()->colorSpace(), bounds);
return false;
}
@@ -433,7 +448,7 @@ bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* o,
bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef();
- i.context->drawImage(magnifierImage, bounds);
+ i.context->drawImage(magnifierImage, o->style()->colorSpace(), bounds);
return false;
}
@@ -469,7 +484,7 @@ bool RenderThemeChromiumSkia::paintSearchFieldResultsButton(RenderObject* o, con
bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").releaseRef();
- i.context->drawImage(magnifierImage, bounds);
+ i.context->drawImage(magnifierImage, o->style()->colorSpace(), bounds);
return false;
}
diff --git a/WebCore/rendering/RenderThemeChromiumSkia.h b/WebCore/rendering/RenderThemeChromiumSkia.h
index 98e3a35..18fa859 100644
--- a/WebCore/rendering/RenderThemeChromiumSkia.h
+++ b/WebCore/rendering/RenderThemeChromiumSkia.h
@@ -71,11 +71,13 @@ namespace WebCore {
virtual void setRadioSize(RenderStyle*) const;
virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
diff --git a/WebCore/rendering/RenderThemeMac.h b/WebCore/rendering/RenderThemeMac.h
index 1d68c63..48c6c42 100644
--- a/WebCore/rendering/RenderThemeMac.h
+++ b/WebCore/rendering/RenderThemeMac.h
@@ -126,6 +126,7 @@ protected:
virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaRewindButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaReturnToRealtimeButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaControlsBackground(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaCurrentTime(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaTimeRemaining(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
diff --git a/WebCore/rendering/RenderThemeMac.mm b/WebCore/rendering/RenderThemeMac.mm
index 03e39a0..6304947 100644
--- a/WebCore/rendering/RenderThemeMac.mm
+++ b/WebCore/rendering/RenderThemeMac.mm
@@ -913,7 +913,7 @@ bool RenderThemeMac::paintMenuListButton(RenderObject* o, const RenderObject::Pa
paintInfo.context->save();
- paintInfo.context->setFillColor(o->style()->color());
+ paintInfo.context->setFillColor(o->style()->color(), o->style()->colorSpace());
paintInfo.context->setStrokeStyle(NoStroke);
FloatPoint arrow1[3];
@@ -942,11 +942,11 @@ bool RenderThemeMac::paintMenuListButton(RenderObject* o, const RenderObject::Pa
// Draw the separator to the left of the arrows
paintInfo.context->setStrokeThickness(1.0f); // Deliberately ignores zoom since it looks nicer if it stays thin.
paintInfo.context->setStrokeStyle(SolidStroke);
- paintInfo.context->setStrokeColor(leftSeparatorColor);
+ paintInfo.context->setStrokeColor(leftSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
IntPoint(leftEdgeOfSeparator, bounds.bottom()));
- paintInfo.context->setStrokeColor(rightSeparatorColor);
+ paintInfo.context->setStrokeColor(rightSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom()));
@@ -1427,8 +1427,6 @@ typedef enum {
static int mediaControllerTheme()
{
- static const long minimumQuickTimeVersion = 0x07630000; // 7.6.3
- static SInt32 quickTimeVersion = 0;
static int controllerTheme = -1;
if (controllerTheme != -1)
@@ -1436,23 +1434,17 @@ static int mediaControllerTheme()
controllerTheme = MediaControllerThemeClassic;
- if (!quickTimeVersion) {
- OSErr err;
- err = Gestalt(gestaltQuickTime, &quickTimeVersion);
- if (err != noErr)
- return controllerTheme;
- }
- if (quickTimeVersion < minimumQuickTimeVersion)
+ if (!wkMediaControllerThemeAvailable(MediaControllerThemeQuickTime))
return controllerTheme;
Boolean validKey;
- Boolean useQTMediaUI = CFPreferencesGetAppBooleanValue(CFSTR("UseQuickTimeMediaUI"), CFSTR("com.apple.WebCore"), &validKey);
+ Boolean useQTMediaUIPref = CFPreferencesGetAppBooleanValue(CFSTR("UseQuickTimeMediaUI"), CFSTR("com.apple.WebCore"), &validKey);
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
- if (validKey && !useQTMediaUI)
+ if (validKey && !useQTMediaUIPref)
return controllerTheme;
#else
- if (!validKey || !useQTMediaUI)
+ if (!validKey || !useQTMediaUIPref)
return controllerTheme;
#endif
@@ -1652,7 +1644,22 @@ bool RenderThemeMac::paintMediaReturnToRealtimeButton(RenderObject* o, const Ren
return false;
}
+bool RenderThemeMac::paintMediaToggleClosedCaptionsButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ HTMLInputElement* node = static_cast<HTMLInputElement*>(o->node());
+ if (!node)
+ return false;
+
+ MediaControlToggleClosedCaptionsButtonElement* btn = static_cast<MediaControlToggleClosedCaptionsButtonElement*>(node);
+ if (!btn)
+ return false;
+ LocalCurrentGraphicsContext localContext(paintInfo.context);
+ wkDrawMediaUIPart(btn->displayType(), mediaControllerTheme(), paintInfo.context->platformContext(), r, getMediaUIPartStateFlags(node));
+
+ return false;
+}
+
bool RenderThemeMac::paintMediaControlsBackground(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
Node* node = o->node();
@@ -1698,12 +1705,16 @@ String RenderThemeMac::extraMediaControlsStyleSheet()
return String();
}
-bool RenderThemeMac::shouldRenderMediaControlPart(ControlPart part, Element* e)
+bool RenderThemeMac::shouldRenderMediaControlPart(ControlPart part, Element* element)
{
- if (part == MediaFullscreenButtonPart)
- return mediaControllerTheme() == MediaControllerThemeQuickTime;
+ if (part == MediaToggleClosedCaptionsButtonPart) {
+
+ // We rely on QTKit to render captions so don't enable the button unless it will be able to do so.
+ if (!element->hasTagName(videoTag))
+ return false;
+ }
- return RenderTheme::shouldRenderMediaControlPart(part, e);
+ return RenderTheme::shouldRenderMediaControlPart(part, element);
}
#endif // ENABLE(VIDEO)
diff --git a/WebCore/rendering/RenderThemeSafari.cpp b/WebCore/rendering/RenderThemeSafari.cpp
index 2ea3b8b..9e97079 100644
--- a/WebCore/rendering/RenderThemeSafari.cpp
+++ b/WebCore/rendering/RenderThemeSafari.cpp
@@ -830,8 +830,8 @@ bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const RenderObject:
paintInfo.context->save();
- paintInfo.context->setFillColor(o->style()->color());
- paintInfo.context->setStrokeColor(NoStroke);
+ paintInfo.context->setFillColor(o->style()->color(), DeviceColorSpace);
+ paintInfo.context->setStrokeColor(NoStroke, DeviceColorSpace);
FloatPoint arrow[3];
arrow[0] = FloatPoint(leftEdge, centerY - arrowHeight / 2.0f);
@@ -851,11 +851,11 @@ bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const RenderObject:
// Draw the separator to the left of the arrows
paintInfo.context->setStrokeThickness(1.0f);
paintInfo.context->setStrokeStyle(SolidStroke);
- paintInfo.context->setStrokeColor(leftSeparatorColor);
+ paintInfo.context->setStrokeColor(leftSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
IntPoint(leftEdgeOfSeparator, bounds.bottom()));
- paintInfo.context->setStrokeColor(rightSeparatorColor);
+ paintInfo.context->setStrokeColor(rightSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom()));
diff --git a/WebCore/rendering/RenderThemeWin.cpp b/WebCore/rendering/RenderThemeWin.cpp
index 92bfd03..52afbd6 100644
--- a/WebCore/rendering/RenderThemeWin.cpp
+++ b/WebCore/rendering/RenderThemeWin.cpp
@@ -819,7 +819,7 @@ bool RenderThemeWin::paintSearchFieldCancelButton(RenderObject* o, const RenderO
static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef();
static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef();
- paintInfo.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, bounds);
+ paintInfo.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, o->style()->colorSpace(), bounds);
return false;
}
@@ -868,7 +868,7 @@ bool RenderThemeWin::paintSearchFieldResultsDecoration(RenderObject* o, const Re
bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef();
- paintInfo.context->drawImage(magnifierImage, bounds);
+ paintInfo.context->drawImage(magnifierImage, o->style()->colorSpace(), bounds);
return false;
}
@@ -904,7 +904,7 @@ bool RenderThemeWin::paintSearchFieldResultsButton(RenderObject* o, const Render
bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").releaseRef();
- paintInfo.context->drawImage(magnifierImage, bounds);
+ paintInfo.context->drawImage(magnifierImage, o->style()->colorSpace(), bounds);
return false;
}
@@ -955,6 +955,23 @@ Color RenderThemeWin::systemColor(int cssValueId) const
}
#if ENABLE(VIDEO)
+
+bool RenderThemeWin::shouldRenderMediaControlPart(ControlPart part, Element* element)
+{
+ if (part == MediaToggleClosedCaptionsButtonPart) {
+ // We rely on QuickTime to render captions so only enable the button for a video element.
+#if SAFARI_THEME_VERSION >= 4
+ if (!element->hasTagName(videoTag))
+ return false;
+#else
+ return false;
+#endif
+ }
+
+ return RenderTheme::shouldRenderMediaControlPart(part, element);
+}
+
+
bool RenderThemeWin::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
return RenderMediaControls::paintMediaControlsPart(MediaFullscreenButton, o, paintInfo, r);
@@ -989,6 +1006,12 @@ bool RenderThemeWin::paintMediaSliderThumb(RenderObject* o, const RenderObject::
{
return RenderMediaControls::paintMediaControlsPart(MediaSliderThumb, o, paintInfo, r);
}
+
+bool RenderThemeWin::paintMediaToggleClosedCaptionsButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ return RenderMediaControls::paintMediaControlsPart(MediaShowClosedCaptionsButton, o, paintInfo, r);
+}
+
#endif
}
diff --git a/WebCore/rendering/RenderThemeWin.h b/WebCore/rendering/RenderThemeWin.h
index 99c2004..a9fa5e6 100644
--- a/WebCore/rendering/RenderThemeWin.h
+++ b/WebCore/rendering/RenderThemeWin.h
@@ -125,6 +125,7 @@ public:
virtual bool supportsFocusRing(const RenderStyle*) const;
#if ENABLE(VIDEO)
+ virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
virtual bool paintMediaFullscreenButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
@@ -132,6 +133,7 @@ public:
virtual bool paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
#endif
private:
diff --git a/WebCore/rendering/RenderTreeAsText.cpp b/WebCore/rendering/RenderTreeAsText.cpp
index b7ab191..a6f5144 100644
--- a/WebCore/rendering/RenderTreeAsText.cpp
+++ b/WebCore/rendering/RenderTreeAsText.cpp
@@ -36,8 +36,10 @@
#include "HTMLNames.h"
#include "InlineTextBox.h"
#include "RenderBR.h"
+#include "RenderFileUploadControl.h"
#include "RenderInline.h"
#include "RenderListMarker.h"
+#include "RenderPart.h"
#include "RenderTableCell.h"
#include "RenderView.h"
#include "RenderWidget.h"
@@ -55,6 +57,10 @@
#include "SVGRenderTreeAsText.h"
#endif
+#if PLATFORM(QT)
+#include <QWidget>
+#endif
+
namespace WebCore {
using namespace HTMLNames;
@@ -217,6 +223,9 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o)
ts << " " << r;
if (!(o.isText() && !o.isBR())) {
+ if (o.isFileUploadControl()) {
+ ts << " " << quoteAndEscapeNonPrintables(toRenderFileUploadControl(&o)->fileTextValue());
+ }
if (o.parent() && (o.parent()->style()->color() != o.style()->color()))
ts << " [color=" << o.style()->color().name() << "]";
@@ -336,6 +345,24 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o)
}
}
+#if PLATFORM(QT)
+ // Print attributes of embedded QWidgets. E.g. when the WebCore::Widget
+ // is invisible the QWidget should be invisible too.
+ if (o.isRenderPart()) {
+ const RenderPart* part = toRenderPart(const_cast<RenderObject*>(&o));
+ if (part->widget() && part->widget()->platformWidget()) {
+ QWidget* wid = part->widget()->platformWidget();
+
+ ts << " [QT: ";
+ ts << "geometry: {" << wid->geometry() << "} ";
+ ts << "isHidden: " << wid->isHidden() << " ";
+ ts << "isSelfVisible: " << part->widget()->isSelfVisible() << " ";
+ ts << "isParentVisible: " << part->widget()->isParentVisible() << " ";
+ ts << "mask: {" << wid->mask().boundingRect() << "} ] ";
+ }
+ }
+#endif
+
return ts;
}
@@ -535,8 +562,11 @@ static void writeSelection(TextStream& ts, const RenderObject* o)
<< "selection end: position " << selection.end().deprecatedEditingOffset() << " of " << nodePosition(selection.end().node()) << "\n";
}
-String externalRepresentation(RenderObject* o)
+String externalRepresentation(Frame* frame)
{
+ frame->document()->updateLayout();
+
+ RenderObject* o = frame->contentRenderer();
if (!o)
return String();
@@ -544,8 +574,6 @@ String externalRepresentation(RenderObject* o)
#if ENABLE(SVG)
writeRenderResources(ts, o->document());
#endif
- if (o->view()->frameView())
- o->view()->frameView()->layout();
if (o->hasLayer()) {
RenderLayer* l = toRenderBox(o)->layer();
writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()));
@@ -554,10 +582,13 @@ String externalRepresentation(RenderObject* o)
return ts.release();
}
-static void writeCounterValuesFromChildren(TextStream& stream, RenderObject* parent)
+static void writeCounterValuesFromChildren(TextStream& stream, RenderObject* parent, bool& isFirstCounter)
{
for (RenderObject* child = parent->firstChild(); child; child = child->nextSibling()) {
if (child->isCounter()) {
+ if (!isFirstCounter)
+ stream << " ";
+ isFirstCounter = false;
String str(toRenderText(child)->text());
stream << str;
}
@@ -570,12 +601,13 @@ String counterValueForElement(Element* element)
RefPtr<Element> elementRef(element);
element->document()->updateLayout();
TextStream stream;
+ bool isFirstCounter = true;
// The counter renderers should be children of anonymous children
// (i.e., :before or :after pseudo-elements).
if (RenderObject* renderer = element->renderer()) {
for (RenderObject* child = renderer->firstChild(); child; child = child->nextSibling()) {
if (child->isAnonymous())
- writeCounterValuesFromChildren(stream, child);
+ writeCounterValuesFromChildren(stream, child, isFirstCounter);
}
}
return stream.release();
diff --git a/WebCore/rendering/RenderTreeAsText.h b/WebCore/rendering/RenderTreeAsText.h
index 325f109..b00f7c9 100644
--- a/WebCore/rendering/RenderTreeAsText.h
+++ b/WebCore/rendering/RenderTreeAsText.h
@@ -29,11 +29,12 @@
namespace WebCore {
class Element;
+class Frame;
class RenderObject;
class String;
class TextStream;
-String externalRepresentation(RenderObject*);
+String externalRepresentation(Frame*);
void write(TextStream&, const RenderObject&, int indent = 0);
// Helper function shared with SVGRenderTreeAsText
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index c4a666f..753afe4 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -210,7 +210,7 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, int, int)
if (baseColor.alpha() > 0) {
paintInfo.context->save();
paintInfo.context->setCompositeOperation(CompositeCopy);
- paintInfo.context->fillRect(paintInfo.rect, baseColor);
+ paintInfo.context->fillRect(paintInfo.rect, baseColor, style()->colorSpace());
paintInfo.context->restore();
} else
paintInfo.context->clearRect(paintInfo.rect);
@@ -338,7 +338,13 @@ IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
SelectionMap::iterator end = selectedObjects.end();
for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
RenderSelectionInfo* info = i->second;
- selRect.unite(info->rect());
+ // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
+ IntRect currRect = info->rect();
+ if (RenderBoxModelObject* repaintContainer = info->repaintContainer()) {
+ FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
+ currRect = absQuad.enclosingBoundingBox();
+ }
+ selRect.unite(currRect);
delete info;
}
return selRect;
@@ -437,7 +443,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
o = o->nextInPreOrder();
}
- m_cachedSelectionBounds = IntRect();
+ m_layer->clearBlockSelectionGapsBounds();
// Now that the selection state has been updated for the new objects, walk them again and
// put them in the new objects list.
@@ -450,9 +456,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
RenderBlockSelectionInfo* blockInfo = newSelectedBlocks.get(cb);
if (blockInfo)
break;
- blockInfo = new RenderBlockSelectionInfo(cb);
- newSelectedBlocks.set(cb, blockInfo);
- m_cachedSelectionBounds.unite(blockInfo->rects());
+ newSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
cb = cb->containingBlock();
}
}
@@ -529,7 +533,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
void RenderView::clearSelection()
{
- repaintViewRectangle(m_cachedSelectionBounds);
+ m_layer->repaintBlockSelectionGaps();
setSelection(0, -1, 0, -1, RepaintNewMinusOld);
}
diff --git a/WebCore/rendering/RenderView.h b/WebCore/rendering/RenderView.h
index a486b34..37b3f01 100644
--- a/WebCore/rendering/RenderView.h
+++ b/WebCore/rendering/RenderView.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML widget for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2006 Apple Computer, Inc.
*
@@ -77,9 +75,11 @@ public:
bool printing() const;
void setPrintImages(bool enable) { m_printImages = enable; }
bool printImages() const { return m_printImages; }
- void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_forcedPageBreak = false; }
+ void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_minimumColumnHeight = 0; m_forcedPageBreak = false; }
void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
+ void setMinimumColumnHeight(int height) { m_minimumColumnHeight = height; }
int bestTruncatedAt() const { return m_bestTruncatedAt; }
+ int minimumColumnHeight() const { return m_minimumColumnHeight; }
int truncatedAt() const { return m_truncatedAt; }
@@ -196,10 +196,9 @@ protected:
RenderWidgetSet m_widgets;
private:
- IntRect m_cachedSelectionBounds;
-
int m_bestTruncatedAt;
int m_truncatorWidth;
+ int m_minimumColumnHeight;
bool m_forcedPageBreak;
LayoutState* m_layoutState;
unsigned m_layoutStateDisableCount;
diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp
index 5a5c9f1..33f03e2 100644
--- a/WebCore/rendering/RenderWidget.cpp
+++ b/WebCore/rendering/RenderWidget.cpp
@@ -23,8 +23,8 @@
#include "config.h"
#include "RenderWidget.h"
-#include "AnimationController.h"
#include "AXObjectCache.h"
+#include "AnimationController.h"
#include "GraphicsContext.h"
#include "HitTestResult.h"
#include "RenderView.h"
@@ -40,18 +40,65 @@ static HashMap<const Widget*, RenderWidget*>& widgetRendererMap()
return *staticWidgetRendererMap;
}
+static size_t widgetHierarchyUpdateSuspendCount;
+
+typedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap;
+
+static WidgetToParentMap& widgetNewParentMap()
+{
+ DEFINE_STATIC_LOCAL(WidgetToParentMap, map, ());
+ return map;
+}
+
+void RenderWidget::suspendWidgetHierarchyUpdates()
+{
+ widgetHierarchyUpdateSuspendCount++;
+}
+
+void RenderWidget::resumeWidgetHierarchyUpdates()
+{
+ ASSERT(widgetHierarchyUpdateSuspendCount);
+ if (widgetHierarchyUpdateSuspendCount == 1) {
+ WidgetToParentMap map = widgetNewParentMap();
+ widgetNewParentMap().clear();
+ WidgetToParentMap::iterator end = map.end();
+ for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) {
+ Widget* child = it->first.get();
+ ScrollView* currentParent = child->parent();
+ FrameView* newParent = it->second;
+ if (newParent != currentParent) {
+ if (currentParent)
+ currentParent->removeChild(child);
+ if (newParent)
+ newParent->addChild(child);
+ }
+ }
+ }
+ widgetHierarchyUpdateSuspendCount--;
+}
+
+static void moveWidgetToParentSoon(Widget* child, FrameView* parent)
+{
+ if (!widgetHierarchyUpdateSuspendCount) {
+ if (parent)
+ parent->addChild(child);
+ else
+ child->removeFromParent();
+ return;
+ }
+ widgetNewParentMap().set(child, parent);
+}
+
RenderWidget::RenderWidget(Node* node)
: RenderReplaced(node)
, m_widget(0)
, m_frameView(node->document()->view())
- , m_refCount(0)
-{
- view()->addWidget(this);
-
// Reference counting is used to prevent the widget from being
// destroyed while inside the Widget code, which might not be
// able to handle that.
- ref();
+ , m_refCount(1)
+{
+ view()->addWidget(this);
}
void RenderWidget::destroy()
@@ -62,14 +109,6 @@ void RenderWidget::destroy()
// both RenderBox::destroy() and RenderObject::destroy().
// Fix originally made for <rdar://problem/4228818>.
- // <rdar://problem/6937089> suggests that node() can be null by the time we call renderArena()
- // in the end of this function. One way this might happen is if this function was invoked twice
- // in a row, so bail out and turn a crash into an assertion failure in debug builds and a leak
- // in release builds.
- ASSERT(node());
- if (!node())
- return;
-
animation()->cancelAnimations(this);
if (RenderView* v = view())
@@ -81,12 +120,8 @@ void RenderWidget::destroy()
}
remove();
- if (m_widget) {
- if (m_frameView)
- m_frameView->removeChild(m_widget.get());
- widgetRendererMap().remove(m_widget.get());
- }
-
+ setWidget(0);
+
// removes from override size map
if (hasOverrideSize())
setOverrideSize(-1);
@@ -100,14 +135,6 @@ void RenderWidget::destroy()
destroyLayer();
}
- // <rdar://problem/6937089> suggests that node() can be null here. One way this might happen is
- // if this function was re-entered (and therefore the null check at the beginning did not fail),
- // so bail out and turn a crash into an assertion failure in debug builds and a leak in release
- // builds.
- ASSERT(node());
- if (!node())
- return;
-
// Grab the arena from node()->document()->renderArena() before clearing the node pointer.
// Clear the node before deref-ing, as this may be deleted when deref is called.
RenderArena* arena = renderArena();
@@ -121,39 +148,43 @@ RenderWidget::~RenderWidget()
clearWidget();
}
-void RenderWidget::setWidgetGeometry(const IntRect& frame)
+bool RenderWidget::setWidgetGeometry(const IntRect& frame)
{
- if (node() && m_widget->frameRect() != frame) {
- RenderWidgetProtector protector(this);
- RefPtr<Node> protectedNode(node());
- m_widget->setFrameRect(frame);
- }
+ ASSERT(!widgetHierarchyUpdateSuspendCount);
+ if (!node() || m_widget->frameRect() == frame)
+ return false;
+
+ RenderWidgetProtector protector(this);
+ RefPtr<Node> protectedNode(node());
+ m_widget->setFrameRect(frame);
+ return true;
}
void RenderWidget::setWidget(PassRefPtr<Widget> widget)
{
- if (widget != m_widget) {
- if (m_widget) {
- m_widget->removeFromParent();
- widgetRendererMap().remove(m_widget.get());
- clearWidget();
- }
- m_widget = widget;
- if (m_widget) {
- widgetRendererMap().add(m_widget.get(), this);
- // if we've already received a layout, apply the calculated space to the
- // widget immediately, but we have to have really been full constructed (with a non-null
- // style pointer).
- if (style()) {
- if (!needsLayout())
- setWidgetGeometry(absoluteContentBox());
- if (style()->visibility() != VISIBLE)
- m_widget->hide();
- else
- m_widget->show();
- }
- m_frameView->addChild(m_widget.get());
+ if (widget == m_widget)
+ return;
+
+ if (m_widget) {
+ moveWidgetToParentSoon(m_widget.get(), 0);
+ widgetRendererMap().remove(m_widget.get());
+ clearWidget();
+ }
+ m_widget = widget;
+ if (m_widget) {
+ widgetRendererMap().add(m_widget.get(), this);
+ // If we've already received a layout, apply the calculated space to the
+ // widget immediately, but we have to have really been fully constructed (with a non-null
+ // style pointer).
+ if (style()) {
+ if (!needsLayout())
+ setWidgetGeometry(absoluteContentBox());
+ if (style()->visibility() != VISIBLE)
+ m_widget->hide();
+ else
+ m_widget->show();
}
+ moveWidgetToParentSoon(m_widget.get(), m_frameView);
}
}
@@ -229,11 +260,11 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty)
// Tell the widget to paint now. This is the only time the widget is allowed
// to paint itself. That way it will composite properly with z-indexed layers.
if (m_substituteImage)
- paintInfo.context->drawImage(m_substituteImage.get(), m_widget->frameRect());
+ paintInfo.context->drawImage(m_substituteImage.get(), style()->colorSpace(), m_widget->frameRect());
else
m_widget->paint(paintInfo.context, paintInfo.rect);
- if (m_widget->isFrameView() && paintInfo.overlapTestRequests && !static_cast<FrameView*>(m_widget.get())->useSlowRepaints()) {
+ if (m_widget->isFrameView() && paintInfo.overlapTestRequests && !static_cast<FrameView*>(m_widget.get())->useSlowRepaintsIfNotOverlapped()) {
ASSERT(!paintInfo.overlapTestRequests->contains(this));
paintInfo.overlapTestRequests->set(this, m_widget->frameRect());
}
@@ -245,7 +276,7 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty)
// Paint a partially transparent wash over selected widgets.
if (isSelected() && !document()->printing()) {
// FIXME: selectionRect() is in absolute, not painting coordinates.
- paintInfo.context->fillRect(selectionRect(), selectionBackgroundColor());
+ paintInfo.context->fillRect(selectionRect(), selectionBackgroundColor(), style()->colorSpace());
}
}
@@ -274,6 +305,7 @@ void RenderWidget::updateWidgetPosition()
int w = width() - borderLeft() - borderRight() - paddingLeft() - paddingRight();
int h = height() - borderTop() - borderBottom() - paddingTop() - paddingBottom();
+<<<<<<< HEAD:WebCore/rendering/RenderWidget.cpp
IntRect newBounds(absPos.x(), absPos.y(), w, h);
IntRect oldBounds(m_widget->frameRect());
bool boundsChanged = newBounds != oldBounds;
@@ -284,6 +316,10 @@ void RenderWidget::updateWidgetPosition()
}
#ifndef FLATTEN_IFRAME
+=======
+ bool boundsChanged = setWidgetGeometry(IntRect(absPos.x(), absPos.y(), w, h));
+
+>>>>>>> webkit.org at r51976:WebCore/rendering/RenderWidget.cpp
// if the frame bounds got changed, or if view needs layout (possibly indicating
// content size is wrong) we have to do a layout to set the right widget size
if (m_widget->isFrameView()) {
diff --git a/WebCore/rendering/RenderWidget.h b/WebCore/rendering/RenderWidget.h
index 78537fd..6cad04a 100644
--- a/WebCore/rendering/RenderWidget.h
+++ b/WebCore/rendering/RenderWidget.h
@@ -42,6 +42,9 @@ public:
void showSubstituteImage(PassRefPtr<Image>);
+ static void suspendWidgetHierarchyUpdates();
+ static void resumeWidgetHierarchyUpdates();
+
protected:
RenderWidget(Node*);
@@ -61,7 +64,7 @@ private:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual void setOverlapTestResult(bool);
- void setWidgetGeometry(const IntRect&);
+ bool setWidgetGeometry(const IntRect&);
friend class RenderWidgetProtector;
RenderArena* ref() { ++m_refCount; return renderArena(); }
diff --git a/WebCore/rendering/RootInlineBox.h b/WebCore/rendering/RootInlineBox.h
index b0b0e15..7fce1d3 100644
--- a/WebCore/rendering/RootInlineBox.h
+++ b/WebCore/rendering/RootInlineBox.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the line box implementation for KDE.
- *
* Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/rendering/SVGInlineTextBox.cpp b/WebCore/rendering/SVGInlineTextBox.cpp
index d0fa9ae..cf8464e 100644
--- a/WebCore/rendering/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/SVGInlineTextBox.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2007 Rob Buis <buis@kde.org>
* (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
*
@@ -384,7 +382,8 @@ void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int t
bool setShadow = false;
if (styleToUse->textShadow()) {
paintInfo.context->setShadow(IntSize(styleToUse->textShadow()->x, styleToUse->textShadow()->y),
- styleToUse->textShadow()->blur, styleToUse->textShadow()->color);
+ styleToUse->textShadow()->blur, styleToUse->textShadow()->color,
+ styleToUse->colorSpace());
setShadow = true;
}
@@ -477,7 +476,7 @@ void SVGInlineTextBox::paintSelection(int boxStartOffset, const SVGChar& svgChar
int adjust = startPos >= boxStartOffset ? boxStartOffset : 0;
p->drawHighlightForText(font, svgTextRunForInlineTextBox(textRenderer()->text()->characters() + start() + boxStartOffset, length, style, this, svgChar.x),
IntPoint((int) svgChar.x, (int) svgChar.y - font.ascent()),
- font.ascent() + font.descent(), color, startPos - adjust, endPos - adjust);
+ font.ascent() + font.descent(), color, style->colorSpace(), startPos - adjust, endPos - adjust);
p->restore();
}
diff --git a/WebCore/rendering/SVGInlineTextBox.h b/WebCore/rendering/SVGInlineTextBox.h
index 76837cc..ad39aab 100644
--- a/WebCore/rendering/SVGInlineTextBox.h
+++ b/WebCore/rendering/SVGInlineTextBox.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2007 Rob Buis <buis@kde.org>
* (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
*
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index ea087f9..a594410 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -94,8 +94,17 @@ void SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
paintInfo.context->beginTransparencyLayer(opacity);
}
- if (ShadowData* shadow = svgStyle->shadow())
- paintInfo.context->setShadow(IntSize(shadow->x, shadow->y), shadow->blur, shadow->color);
+ if (ShadowData* shadow = svgStyle->shadow()) {
+ int xShift = shadow->x < 0 ? shadow->x : 0;
+ int yShift = shadow->y < 0 ? shadow->y :0;
+ int widthShift = shadow->x < 0 ? 0 : shadow->x;
+ int heightShift = shadow->y < 0 ? 0 : shadow->y;
+ FloatRect shadowRect = FloatRect(boundingBox.x() + xShift, boundingBox.y() + yShift,
+ boundingBox.width() + widthShift, boundingBox.height() + heightShift);
+ paintInfo.context->clip(enclosingIntRect(shadowRect));
+ 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());
@@ -163,6 +172,11 @@ void SVGRenderBase::finishRenderSVGContent(RenderObject* object, RenderObject::P
float opacity = style->opacity();
if (opacity < 1.0f)
paintInfo.context->endTransparencyLayer();
+
+ // This needs to be done separately from opacity, because if both properties are set,
+ // then the transparency layers are nested.
+ if (style->svgStyle()->shadow())
+ paintInfo.context->endTransparencyLayer();
}
void renderSubtreeToImage(ImageBuffer* image, RenderObject* item)
diff --git a/WebCore/rendering/TableLayout.h b/WebCore/rendering/TableLayout.h
index 8ae0ce7..10d6e26 100644
--- a/WebCore/rendering/TableLayout.h
+++ b/WebCore/rendering/TableLayout.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2002 Lars Knoll (knoll@kde.org)
* (C) 2002 Dirk Mueller (mueller@kde.org)
*
@@ -23,11 +21,13 @@
#ifndef TableLayout_h
#define TableLayout_h
+#include <wtf/Noncopyable.h>
+
namespace WebCore {
class RenderTable;
-class TableLayout {
+class TableLayout : public Noncopyable {
public:
TableLayout(RenderTable* table)
: m_table(table)
diff --git a/WebCore/rendering/break_lines.h b/WebCore/rendering/break_lines.h
index 14f740f..4d6b8dc 100644
--- a/WebCore/rendering/break_lines.h
+++ b/WebCore/rendering/break_lines.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2005 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/rendering/style/ContentData.h b/WebCore/rendering/style/ContentData.h
index 24d5f86..2c261f8 100644
--- a/WebCore/rendering/style/ContentData.h
+++ b/WebCore/rendering/style/ContentData.h
@@ -25,15 +25,15 @@
#ifndef ContentData_h
#define ContentData_h
-#include "PlatformString.h"
#include "RenderStyleConstants.h"
-#include "StringImpl.h"
-#include "StyleImage.h"
#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
namespace WebCore {
class CounterContent;
+class StringImpl;
+class StyleImage;
struct ContentData : Noncopyable {
public:
diff --git a/WebCore/rendering/style/CounterContent.h b/WebCore/rendering/style/CounterContent.h
index cf11813..702d9c2 100644
--- a/WebCore/rendering/style/CounterContent.h
+++ b/WebCore/rendering/style/CounterContent.h
@@ -30,7 +30,7 @@
namespace WebCore {
-class CounterContent {
+class CounterContent : public FastAllocBase {
public:
CounterContent(const AtomicString& identifier, EListStyleType style, const AtomicString& separator)
: m_identifier(identifier)
diff --git a/WebCore/rendering/style/FillLayer.h b/WebCore/rendering/style/FillLayer.h
index fb928b6..9c615b4 100644
--- a/WebCore/rendering/style/FillLayer.h
+++ b/WebCore/rendering/style/FillLayer.h
@@ -59,7 +59,7 @@ struct FillSize {
LengthSize size;
};
-struct FillLayer {
+struct FillLayer : FastAllocBase {
public:
FillLayer(EFillLayerType);
~FillLayer();
diff --git a/WebCore/rendering/style/LineClampValue.h b/WebCore/rendering/style/LineClampValue.h
new file mode 100644
index 0000000..2119ca2
--- /dev/null
+++ b/WebCore/rendering/style/LineClampValue.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 LineClampValue_h
+#define LineClampValue_h
+
+#include "RenderStyleConstants.h"
+
+namespace WebCore {
+
+class LineClampValue {
+public:
+ LineClampValue()
+ : m_type(LineClampLineCount)
+ , m_value(-1)
+ {
+ }
+
+ LineClampValue(int value, ELineClampType type)
+ : m_type(type)
+ , m_value(value)
+ {
+ }
+
+ int value() const { return m_value; }
+
+ bool isPercentage() const { return m_type == LineClampPercentage; }
+
+ bool isNone() const { return m_value == -1; }
+
+ bool operator==(const LineClampValue& o) const
+ {
+ return value() == o.value() && isPercentage() == o.isPercentage();
+ }
+
+ bool operator!=(const LineClampValue& o) const
+ {
+ return !(*this == o);
+ }
+
+private:
+ ELineClampType m_type;
+ int m_value;
+};
+
+} // namespace WebCore
+
+#endif // LineClampValue_h
diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp
index a861fea..59d40b4 100644
--- a/WebCore/rendering/style/RenderStyle.cpp
+++ b/WebCore/rendering/style/RenderStyle.cpp
@@ -454,8 +454,8 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
if (inherited->m_effectiveZoom != other->inherited->m_effectiveZoom)
return StyleDifferenceLayout;
- if (rareNonInheritedData->opacity == 1 && other->rareNonInheritedData->opacity < 1 ||
- rareNonInheritedData->opacity < 1 && other->rareNonInheritedData->opacity == 1) {
+ if ((rareNonInheritedData->opacity == 1 && other->rareNonInheritedData->opacity < 1) ||
+ (rareNonInheritedData->opacity < 1 && other->rareNonInheritedData->opacity == 1)) {
// FIXME: We should add an optimized form of layout that just recomputes visual overflow.
return StyleDifferenceLayout;
}
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index 674f062..a72b66d 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -37,6 +37,7 @@
#include "CachedImage.h"
#include "CollapsedBorderValue.h"
#include "Color.h"
+#include "ColorSpace.h"
#include "ContentData.h"
#include "CounterDirectives.h"
#include "CursorList.h"
@@ -49,6 +50,7 @@
#include "Length.h"
#include "LengthBox.h"
#include "LengthSize.h"
+#include "LineClampValue.h"
#include "NinePieceImage.h"
#include "OutlineValue.h"
#include "Pair.h"
@@ -599,6 +601,7 @@ public:
const Color& textStrokeColor() const { return rareInheritedData->textStrokeColor; }
float textStrokeWidth() const { return rareInheritedData->textStrokeWidth; }
const Color& textFillColor() const { return rareInheritedData->textFillColor; }
+ ColorSpace colorSpace() const { return static_cast<ColorSpace>(rareInheritedData->colorSpace); }
float opacity() const { return rareNonInheritedData->opacity; }
ControlPart appearance() const { return static_cast<ControlPart>(rareNonInheritedData->m_appearance); }
EBoxAlignment boxAlign() const { return static_cast<EBoxAlignment>(rareNonInheritedData->flexibleBox->align); }
@@ -693,7 +696,7 @@ public:
bool isRunningAcceleratedAnimation() const { return rareNonInheritedData->m_runningAcceleratedAnimation; }
#endif
- int lineClamp() const { return rareNonInheritedData->lineClamp; }
+ const LineClampValue& lineClamp() const { return rareNonInheritedData->lineClamp; }
bool textSizeAdjust() const { return rareInheritedData->textSizeAdjust; }
ETextSecurity textSecurity() const { return static_cast<ETextSecurity>(rareInheritedData->textSecurity); }
@@ -934,6 +937,7 @@ public:
void setTextStrokeColor(const Color& c) { SET_VAR(rareInheritedData, textStrokeColor, c) }
void setTextStrokeWidth(float w) { SET_VAR(rareInheritedData, textStrokeWidth, w) }
void setTextFillColor(const Color& c) { SET_VAR(rareInheritedData, textFillColor, c) }
+ void setColorSpace(ColorSpace space) { SET_VAR(rareInheritedData, colorSpace, space) }
void setOpacity(float f) { SET_VAR(rareNonInheritedData, opacity, f); }
void setAppearance(ControlPart a) { SET_VAR(rareNonInheritedData, m_appearance, a); }
void setBoxAlign(EBoxAlignment a) { SET_VAR(rareNonInheritedData.access()->flexibleBox, align, a); }
@@ -1013,7 +1017,7 @@ public:
void setIsRunningAcceleratedAnimation(bool b = true) { SET_VAR(rareNonInheritedData, m_runningAcceleratedAnimation, b); }
#endif
- void setLineClamp(int c) { SET_VAR(rareNonInheritedData, lineClamp, c); }
+ void setLineClamp(LineClampValue c) { SET_VAR(rareNonInheritedData, lineClamp, c); }
void setTextSizeAdjust(bool b) { SET_VAR(rareInheritedData, textSizeAdjust, b); }
void setTextSecurity(ETextSecurity aTextSecurity) { SET_VAR(rareInheritedData, textSecurity, aTextSecurity); }
@@ -1186,9 +1190,10 @@ public:
static float initialPerspective() { return 0; }
static Length initialPerspectiveOriginX() { return Length(50.0, Percent); }
static Length initialPerspectiveOriginY() { return Length(50.0, Percent); }
+ static Color initialBackgroundColor() { return Color::transparent; }
// Keep these at the end.
- static int initialLineClamp() { return -1; }
+ static LineClampValue initialLineClamp() { return LineClampValue(); }
static bool initialTextSizeAdjust() { return true; }
static ETextSecurity initialTextSecurity() { return TSNONE; }
#if ENABLE(DASHBOARD_SUPPORT)
diff --git a/WebCore/rendering/style/RenderStyleConstants.h b/WebCore/rendering/style/RenderStyleConstants.h
index 3010947..92cd3d5 100644
--- a/WebCore/rendering/style/RenderStyleConstants.h
+++ b/WebCore/rendering/style/RenderStyleConstants.h
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* (C) 2000 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
* Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
@@ -69,8 +69,9 @@ enum PseudoId {
NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR, FILE_UPLOAD_BUTTON, INPUT_PLACEHOLDER,
SLIDER_THUMB, SEARCH_CANCEL_BUTTON, SEARCH_DECORATION, SEARCH_RESULTS_DECORATION, SEARCH_RESULTS_BUTTON, MEDIA_CONTROLS_PANEL,
MEDIA_CONTROLS_PLAY_BUTTON, MEDIA_CONTROLS_MUTE_BUTTON, MEDIA_CONTROLS_TIMELINE, MEDIA_CONTROLS_TIMELINE_CONTAINER,
- MEDIA_CONTROLS_VOLUME_SLIDER, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER, MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, 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_VOLUME_SLIDER, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER, MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, MEDIA_CONTROLS_TIME_REMAINING_DISPLAY,
+ 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,
@@ -321,6 +322,8 @@ enum ETransformStyle3D {
enum EBackfaceVisibility {
BackfaceVisibilityVisible, BackfaceVisibilityHidden
};
+
+enum ELineClampType { LineClampLineCount, LineClampPercentage };
} // namespace WebCore
diff --git a/WebCore/rendering/style/SVGRenderStyle.cpp b/WebCore/rendering/style/SVGRenderStyle.cpp
index e8827c4..728738b 100644
--- a/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -8,8 +8,6 @@
Copyright (C) 2002-2003 Dirk Mueller (mueller@kde.org)
Copyright (C) 2002 Apple Computer, Inc.
- This file is part of the KDE project
-
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
diff --git a/WebCore/rendering/style/SVGRenderStyle.h b/WebCore/rendering/style/SVGRenderStyle.h
index 12477d7..c65be97 100644
--- a/WebCore/rendering/style/SVGRenderStyle.h
+++ b/WebCore/rendering/style/SVGRenderStyle.h
@@ -3,8 +3,6 @@
2004, 2005 Rob Buis <buis@kde.org>
Copyright (C) 2005, 2006 Apple Computer, Inc.
- This file is part of the KDE project
-
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
diff --git a/WebCore/rendering/style/SVGRenderStyleDefs.cpp b/WebCore/rendering/style/SVGRenderStyleDefs.cpp
index 2ed1d8f..093f1f1 100644
--- a/WebCore/rendering/style/SVGRenderStyleDefs.cpp
+++ b/WebCore/rendering/style/SVGRenderStyleDefs.cpp
@@ -8,8 +8,6 @@
Copyright (C) 2002-2003 Dirk Mueller (mueller@kde.org)
Copyright (C) 2002 Apple Computer, Inc.
- This file is part of the KDE project
-
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
diff --git a/WebCore/rendering/style/SVGRenderStyleDefs.h b/WebCore/rendering/style/SVGRenderStyleDefs.h
index f4cf932..8f01d9f 100644
--- a/WebCore/rendering/style/SVGRenderStyleDefs.h
+++ b/WebCore/rendering/style/SVGRenderStyleDefs.h
@@ -8,8 +8,6 @@
(C) 2000-2003 Dirk Mueller (mueller@kde.org)
(C) 2002-2003 Apple Computer, Inc.
- This file is part of the KDE project
-
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
diff --git a/WebCore/rendering/style/ShadowData.h b/WebCore/rendering/style/ShadowData.h
index f4061f2..089cf77 100644
--- a/WebCore/rendering/style/ShadowData.h
+++ b/WebCore/rendering/style/ShadowData.h
@@ -26,6 +26,7 @@
#define ShadowData_h
#include "Color.h"
+#include <wtf/FastAllocBase.h>
namespace WebCore {
@@ -33,7 +34,7 @@ enum ShadowStyle { Normal, Inset };
// This struct holds information about shadows for the text-shadow and box-shadow properties.
-struct ShadowData {
+struct ShadowData : FastAllocBase {
ShadowData()
: x(0)
, y(0)
diff --git a/WebCore/rendering/style/StyleBackgroundData.cpp b/WebCore/rendering/style/StyleBackgroundData.cpp
index 68a9ddd..08f5527 100644
--- a/WebCore/rendering/style/StyleBackgroundData.cpp
+++ b/WebCore/rendering/style/StyleBackgroundData.cpp
@@ -22,12 +22,14 @@
#include "config.h"
#include "StyleBackgroundData.h"
+#include "RenderStyle.h"
#include "RenderStyleConstants.h"
namespace WebCore {
StyleBackgroundData::StyleBackgroundData()
: m_background(BackgroundFillLayer)
+ , m_color(RenderStyle::initialBackgroundColor())
{
}
diff --git a/WebCore/rendering/style/StyleRareInheritedData.cpp b/WebCore/rendering/style/StyleRareInheritedData.cpp
index 0f3b7e7..ff626b7 100644
--- a/WebCore/rendering/style/StyleRareInheritedData.cpp
+++ b/WebCore/rendering/style/StyleRareInheritedData.cpp
@@ -42,6 +42,7 @@ StyleRareInheritedData::StyleRareInheritedData()
, textSizeAdjust(RenderStyle::initialTextSizeAdjust())
, resize(RenderStyle::initialResize())
, userSelect(RenderStyle::initialUserSelect())
+ , colorSpace(DeviceColorSpace)
{
}
@@ -64,6 +65,7 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
, textSizeAdjust(o.textSizeAdjust)
, resize(o.resize)
, userSelect(o.userSelect)
+ , colorSpace(o.colorSpace)
{
}
@@ -90,7 +92,8 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
&& tapHighlightColor == o.tapHighlightColor
#endif
&& resize == o.resize
- && userSelect == o.userSelect;
+ && userSelect == o.userSelect
+ && colorSpace == o.colorSpace;
}
bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
diff --git a/WebCore/rendering/style/StyleRareInheritedData.h b/WebCore/rendering/style/StyleRareInheritedData.h
index 4abd3cf..1aa7b05 100644
--- a/WebCore/rendering/style/StyleRareInheritedData.h
+++ b/WebCore/rendering/style/StyleRareInheritedData.h
@@ -68,6 +68,7 @@ public:
bool textSizeAdjust : 1; // An Apple extension.
unsigned resize : 2; // EResize
unsigned userSelect : 1; // EUserSelect
+ unsigned colorSpace : 1; // ColorSpace
private:
StyleRareInheritedData();
diff --git a/WebCore/rendering/style/StyleRareNonInheritedData.h b/WebCore/rendering/style/StyleRareNonInheritedData.h
index 8dd22b3..452b273 100644
--- a/WebCore/rendering/style/StyleRareNonInheritedData.h
+++ b/WebCore/rendering/style/StyleRareNonInheritedData.h
@@ -29,6 +29,7 @@
#include "CursorData.h"
#include "DataRef.h"
#include "FillLayer.h"
+#include "LineClampValue.h"
#include "NinePieceImage.h"
#include "StyleTransformData.h"
#include <wtf/OwnPtr.h>
@@ -77,7 +78,7 @@ public:
bool animationDataEquivalent(const StyleRareNonInheritedData&) const;
bool transitionDataEquivalent(const StyleRareNonInheritedData&) const;
- int lineClamp; // An Apple extension.
+ LineClampValue lineClamp; // An Apple extension.
#if ENABLE(DASHBOARD_SUPPORT)
Vector<StyleDashboardRegion> m_dashboardRegions;
#endif