diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-07-10 01:17:51 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-07-10 01:17:51 (GMT) |
commit | 9c13caa3c99af01a9b4c3ff6e178e7dadb61741f (patch) | |
tree | b69df0a23c4628359fc3740e09958980eda7478e /src/3rdparty/webkit/WebCore/rendering | |
parent | bb1bdcab28e4c52dcea37dfaaa435045b1985eeb (diff) | |
parent | 883da42f7c75775502c818aa456c8576d8457ff8 (diff) | |
download | Qt-9c13caa3c99af01a9b4c3ff6e178e7dadb61741f.zip Qt-9c13caa3c99af01a9b4c3ff6e178e7dadb61741f.tar.gz Qt-9c13caa3c99af01a9b4c3ff6e178e7dadb61741f.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui-gv
Conflicts:
examples/itemviews/frozencolumn/main.cpp
src/declarative/canvas/qsimplecanvas.cpp
src/declarative/canvas/qsimplecanvas_p.h
src/declarative/canvas/qsimplecanvasitem.h
src/declarative/extra/qfxparticles.cpp
src/declarative/fx/fx.pri
src/declarative/fx/qfxblurfilter.h
src/declarative/fx/qfxcontentwrapper.cpp
src/declarative/fx/qfxflickable.cpp
src/declarative/fx/qfxfocuspanel.h
src/declarative/fx/qfxfocusrealm.h
src/declarative/fx/qfxhighlightfilter.cpp
src/declarative/fx/qfxhighlightfilter.h
src/declarative/fx/qfximage.cpp
src/declarative/fx/qfxitem.cpp
src/declarative/fx/qfxitem.h
src/declarative/fx/qfxrect.cpp
src/declarative/fx/qfxreflectionfilter.h
src/declarative/fx/qfxshadowfilter.cpp
src/declarative/fx/qfxshadowfilter.h
src/declarative/fx/qfxtext.cpp
src/declarative/fx/qfxtext.h
src/declarative/fx/qfxtextedit.cpp
src/declarative/opengl/glbasicshaders.h
src/declarative/test/qfxtestengine.cpp
src/declarative/test/qfxtestengine.h
src/declarative/test/qfxtestobjects.cpp
src/declarative/test/qfxtestobjects.h
src/declarative/test/qfxtestview.h
src/declarative/util/qfxglobal.h
src/declarative/util/qfxview.cpp
src/gui/graphicsview/qgraphicsitem_p.h
tools/qmlviewer/qmlviewer.cpp
Diffstat (limited to 'src/3rdparty/webkit/WebCore/rendering')
60 files changed, 2021 insertions, 1676 deletions
diff --git a/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp b/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp index 8f9feec..648e843 100644 --- a/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp @@ -59,7 +59,9 @@ void AutoTableLayout::recalcColumn(int effCol) RenderTableCell* maxContributor = 0; while (child) { - if (child->isTableSection()) { + if (child->isTableCol()) + static_cast<RenderTableCol*>(child)->calcPrefWidths(); + else if (child->isTableSection()) { RenderTableSection* section = static_cast<RenderTableSection*>(child); int numRows = section->numRows(); RenderTableCell* last = 0; diff --git a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp index f995fbf..63a4f54 100644 --- a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp @@ -128,6 +128,7 @@ int FixedTableLayout::calcWidthArray(int) currentEffectiveColumn++; } } + static_cast<RenderTableCol*>(child)->calcPrefWidths(); } else break; diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp index 0432a4c..be6b966 100644 --- a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp @@ -658,22 +658,20 @@ void InlineFlowBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty) paintTextDecorations(paintInfo, tx, ty, true); } -void InlineFlowBox::paintFillLayers(const RenderObject::PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, - int my, int mh, int _tx, int _ty, int w, int h, CompositeOperator op) +void InlineFlowBox::paintFillLayers(const RenderObject::PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int _tx, int _ty, int w, int h, CompositeOperator op) { if (!fillLayer) return; - paintFillLayers(paintInfo, c, fillLayer->next(), my, mh, _tx, _ty, w, h, op); - paintFillLayer(paintInfo, c, fillLayer, my, mh, _tx, _ty, w, h, op); + paintFillLayers(paintInfo, c, fillLayer->next(), _tx, _ty, w, h, op); + paintFillLayer(paintInfo, c, fillLayer, _tx, _ty, w, h, op); } -void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, - int my, int mh, int tx, int ty, int w, int h, CompositeOperator op) +void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int w, int h, CompositeOperator op) { StyleImage* img = fillLayer->image(); bool hasFillImage = img && img->canRender(renderer()->style()->effectiveZoom()); if ((!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent()) - boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, my, mh, tx, ty, w, h, this, op); + boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, w, h, this, op); else { // We have a fill image that spans multiple lines. // We need to adjust _tx and _ty by the width of all previous lines. @@ -692,7 +690,7 @@ void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, con totalWidth += curr->width(); paintInfo.context->save(); paintInfo.context->clip(IntRect(tx, ty, width(), height())); - boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, my, mh, startX, ty, totalWidth, h, this, op); + boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, startX, ty, totalWidth, h, this, op); paintInfo.context->restore(); } } @@ -720,13 +718,6 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int int w = width(); int h = height(); - int my = max(ty, paintInfo.rect.y()); - int mh; - if (ty < paintInfo.rect.y()) - mh = max(0, h - (paintInfo.rect.y() - ty)); - else - mh = min(paintInfo.rect.height(), h); - GraphicsContext* context = paintInfo.context; // You can use p::first-line to specify a background. If so, the root line boxes for @@ -738,7 +729,7 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int paintBoxShadow(context, styleToUse, tx, ty, w, h); Color c = styleToUse->backgroundColor(); - paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), my, mh, tx, ty, w, h); + paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), tx, ty, w, h); // :first-line cannot be used to put borders on a line. Always paint borders with our // non-first-line style. @@ -789,14 +780,6 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty int w = width(); int h = height(); - int my = max(ty, paintInfo.rect.y()); - int mh; - if (ty < paintInfo.rect.y()) - mh = max(0, h - (paintInfo.rect.y() - ty)); - else - mh = min(paintInfo.rect.height(), h); - - // Figure out if we need to push a transparency layer to render our mask. bool pushTransparencyLayer = false; const NinePieceImage& maskNinePieceImage = renderer()->style()->maskBoxImage(); @@ -811,7 +794,7 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty compositeOp = CompositeSourceOver; } - paintFillLayers(paintInfo, Color(), renderer()->style()->maskLayers(), my, mh, tx, ty, w, h, compositeOp); + paintFillLayers(paintInfo, Color(), renderer()->style()->maskLayers(), tx, ty, w, h, compositeOp); bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(renderer()->style()->effectiveZoom()); if (!hasBoxImage || !maskBoxImage->isLoaded()) diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h index 2462eba..ab1b6f2 100644 --- a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h +++ b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h @@ -87,10 +87,8 @@ public: virtual void paintBoxDecorations(RenderObject::PaintInfo&, int tx, int ty); virtual void paintMask(RenderObject::PaintInfo&, int tx, int ty); - void paintFillLayers(const RenderObject::PaintInfo&, const Color&, const FillLayer*, - int my, int mh, int tx, int ty, int w, int h, CompositeOperator = CompositeSourceOver); - void paintFillLayer(const RenderObject::PaintInfo&, const Color&, const FillLayer*, - int my, int mh, int tx, int ty, int w, int h, CompositeOperator = CompositeSourceOver); + void paintFillLayers(const RenderObject::PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int w, int h, CompositeOperator = CompositeSourceOver); + void paintFillLayer(const RenderObject::PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int w, int h, CompositeOperator = CompositeSourceOver); void paintBoxShadow(GraphicsContext*, RenderStyle*, int tx, int ty, int w, int h); virtual void paintTextDecorations(RenderObject::PaintInfo&, int tx, int ty, bool paintedChildren = false); virtual void paint(RenderObject::PaintInfo&, int tx, int ty); diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp b/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp index 418be15..53646f9 100644 --- a/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp @@ -770,8 +770,8 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, Do // Optionally highlight the text if (renderer()->document()->frame()->markedTextMatchesAreHighlighted()) { Color color = marker.activeMatch ? - theme()->platformActiveTextSearchHighlightColor() : - theme()->platformInactiveTextSearchHighlightColor(); + renderer()->theme()->platformActiveTextSearchHighlightColor() : + renderer()->theme()->platformInactiveTextSearchHighlightColor(); pt->save(); updateGraphicsContext(pt, color, color, 0); // Don't draw text at all! pt->clip(IntRect(tx + m_x, ty + y, m_width, h)); diff --git a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp index 5cd9363..fc2790c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp @@ -93,7 +93,7 @@ MediaTextDisplayElement::MediaTextDisplayElement(Document* doc, PseudoId pseudo, void MediaTextDisplayElement::attachToParent(Element* parent) { parent->addChild(this); - if (renderer()) + if (renderer() && parent->renderer()) parent->renderer()->addChild(renderer()); } @@ -101,6 +101,7 @@ void MediaTextDisplayElement::update() { if (renderer()) renderer()->updateFromElement(); + updateStyle(); } void MediaTextDisplayElement::updateStyle() @@ -125,20 +126,15 @@ MediaControlInputElement::MediaControlInputElement(Document* doc, PseudoId pseud , m_displayType(displayType) { setInputType(type); - RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId); - RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style); - if (renderer) { - setRenderer(renderer); - renderer->setStyle(style); - } - setAttached(); + updateStyle(); setInDocument(true); } void MediaControlInputElement::attachToParent(Element* parent) { parent->addChild(this); - parent->renderer()->addChild(renderer()); + if (renderer() && parent->renderer()) + parent->renderer()->addChild(renderer()); } void MediaControlInputElement::update() @@ -146,20 +142,41 @@ void MediaControlInputElement::update() updateDisplayType(); if (renderer()) renderer()->updateFromElement(); + updateStyle(); } void MediaControlInputElement::updateStyle() { - if (renderer() && m_mediaElement->renderer()) { - RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId); + if (!m_mediaElement || !m_mediaElement->renderer()) + return; + + RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId); + + bool needsRenderer = rendererIsNeeded(style); + if (renderer() && !needsRenderer) + detach(); + else if (!renderer() && needsRenderer) { + RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style); + if (!renderer) + return; + renderer->setStyle(style); + setRenderer(renderer); + setAttached(); + if (parent() && parent()->renderer()) { + // Find next sibling with a renderer to determine where to insert. + Node* sibling = nextSibling(); + while (sibling && !sibling->renderer()) + sibling = sibling->nextSibling(); + parent()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0); + } + } else if (renderer()) renderer()->setStyle(style); - } } bool MediaControlInputElement::hitTest(const IntPoint& absPoint) { if (renderer() && renderer()->style()->hasAppearance()) - return theme()->hitTestMediaControlPart(renderer(), absPoint); + return renderer()->theme()->hitTestMediaControlPart(renderer(), absPoint); return false; } @@ -322,6 +339,12 @@ void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event) HTMLInputElement::defaultEventHandler(event); } +bool MediaControlFullscreenButtonElement::rendererIsNeeded(RenderStyle* style) +{ + return m_mediaElement->supportsFullscreen() && MediaControlInputElement::rendererIsNeeded(style); +} + + // ---------------------------- } //namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h index d52d4bc..eefb2ce 100644 --- a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h +++ b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h @@ -91,8 +91,9 @@ public: MediaControlInputElement(Document*, PseudoId, const String& type, HTMLMediaElement*, MediaControlElementType); void attachToParent(Element*); void update(); - void updateStyle(); + virtual void updateStyle(); bool hitTest(const IntPoint& absPoint); + MediaControlElementType displayType() const { return m_displayType; } protected: virtual void updateDisplayType() { } @@ -151,6 +152,7 @@ class MediaControlFullscreenButtonElement : public MediaControlInputElement { public: MediaControlFullscreenButtonElement(Document*, HTMLMediaElement*); virtual void defaultEventHandler(Event*); + virtual bool rendererIsNeeded(RenderStyle*); }; // ---------------------------- diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp index 89cf112..98426ed 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp @@ -4366,8 +4366,16 @@ void RenderBlock::calcBlockPrefWidths() bool RenderBlock::hasLineIfEmpty() const { - return node() && ((node()->isContentEditable() && node()->rootEditableElement() == node()) || - (node()->isShadowNode() && node()->shadowParentNode()->hasTagName(inputTag))); + if (!node()) + return false; + + if (node()->isContentEditable() && node()->rootEditableElement() == node()) + return true; + + if (node()->isShadowNode() && (node()->shadowParentNode()->hasTagName(inputTag) || node()->shadowParentNode()->hasTagName(textareaTag))) + return true; + + return false; } int RenderBlock::lineHeight(bool firstLine, bool isRootLineBox) const diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h index f313b3d..31eae7c8 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h @@ -42,7 +42,9 @@ class RootInlineBox; struct BidiRun; template <class Iterator, class Run> class BidiResolver; +template <class Iterator> class MidpointState; typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver; +typedef MidpointState<InlineIterator> LineMidpointState; enum CaretType { CursorCaret, DragCaret }; @@ -157,18 +159,19 @@ public: IntRect rect; }; - void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end); - RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats); + void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end, bool previousLineBrokeCleanly); + RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly, + InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats); RootInlineBox* determineEndPosition(RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus, int& yPos); bool matchedEndLine(const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus, RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop); - bool generatesLineBoxesForInlineChild(RenderObject*); - void skipTrailingWhitespace(InlineIterator&); - int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine); + bool generatesLineBoxesForInlineChild(RenderObject*, bool isLineEmpty = true, bool previousLineBrokeCleanly = true); + void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly); + int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly); void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth); - InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, EClear* clear = 0); + InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, EClear* clear = 0); RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject); InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine); void computeHorizontalPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp index e9db716..ab0d153 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp @@ -248,22 +248,22 @@ int RenderBox::clientHeight() const return height() - borderTop() - borderBottom() - horizontalScrollbarHeight(); } -// scrollWidth/scrollHeight will be the same as overflowWidth/overflowHeight unless the -// object has overflow:hidden/scroll/auto specified and also has overflow. -// FIXME: It's not completely clear how scrollWidth/Height should behave for -// objects with visible overflow. int RenderBox::scrollWidth() const { if (hasOverflowClip()) return layer()->scrollWidth(); - return overflowWidth(); + // For objects with visible overflow, this matches IE. + if (style()->direction() == LTR) + return max(clientWidth(), rightmostPosition(true, false) - borderLeft()); + return clientWidth() - min(0, leftmostPosition(true, false) - borderLeft()); } int RenderBox::scrollHeight() const { if (hasOverflowClip()) return layer()->scrollHeight(); - return overflowHeight(); + // For objects with visible overflow, this matches IE. + return max(clientHeight(), lowestPosition(true, false) - borderTop()); } int RenderBox::scrollLeft() const @@ -582,9 +582,7 @@ void RenderBox::paintRootBoxDecorations(PaintInfo& paintInfo, int tx, int ty) int bw = max(w + marginLeft() + marginRight() + borderLeft() + borderRight(), rw); int bh = max(h + marginTop() + marginBottom() + borderTop() + borderBottom(), rh); - int my = max(by, paintInfo.rect.y()); - - paintFillLayers(paintInfo, bgColor, bgLayer, my, paintInfo.rect.height(), bx, by, bw, bh); + paintFillLayers(paintInfo, bgColor, bgLayer, bx, by, bw, bh); if (style()->hasBorder() && style()->display() != INLINE) paintBorder(paintInfo.context, tx, ty, w, h, style()); @@ -607,13 +605,6 @@ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty) // balloon layout is an example of this). borderFitAdjust(tx, w); - int my = max(ty, paintInfo.rect.y()); - int mh; - if (ty < paintInfo.rect.y()) - mh = max(0, h - (paintInfo.rect.y() - ty)); - else - mh = min(paintInfo.rect.height(), h); - // FIXME: Should eventually give the theme control over whether the box shadow should paint, since controls could have // custom shadows of their own. paintBoxShadow(paintInfo.context, tx, ty, w, h, style()); @@ -626,7 +617,7 @@ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty) // independent of the body. Go through the DOM to get to the root element's render object, // since the root could be inline and wrapped in an anonymous block. if (!isBody() || document()->documentElement()->renderer()->style()->hasBackground()) - paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), my, mh, tx, ty, w, h); + paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, w, h); if (style()->hasAppearance()) theme()->paintDecorations(this, paintInfo, IntRect(tx, ty, w, h)); } @@ -648,17 +639,10 @@ void RenderBox::paintMask(PaintInfo& paintInfo, int tx, int ty) // balloon layout is an example of this). borderFitAdjust(tx, w); - int my = max(ty, paintInfo.rect.y()); - int mh; - if (ty < paintInfo.rect.y()) - mh = max(0, h - (paintInfo.rect.y() - ty)); - else - mh = min(paintInfo.rect.height(), h); - - paintMaskImages(paintInfo, my, mh, tx, ty, w, h); + paintMaskImages(paintInfo, tx, ty, w, h); } -void RenderBox::paintMaskImages(const PaintInfo& paintInfo, int my, int mh, int tx, int ty, int w, int h) +void RenderBox::paintMaskImages(const PaintInfo& paintInfo, int tx, int ty, int w, int h) { // Figure out if we need to push a transparency layer to render our mask. bool pushTransparencyLayer = false; @@ -689,7 +673,7 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, int my, int mh, int compositeOp = CompositeSourceOver; } - paintFillLayers(paintInfo, Color(), style()->maskLayers(), my, mh, tx, ty, w, h, compositeOp); + paintFillLayers(paintInfo, Color(), style()->maskLayers(), tx, ty, w, h, compositeOp); paintNinePieceImage(paintInfo.context, tx, ty, w, h, style(), style()->maskBoxImage(), compositeOp); if (pushTransparencyLayer) @@ -715,20 +699,18 @@ IntRect RenderBox::maskClipRect() return result; } -void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, - int clipY, int clipH, int tx, int ty, int width, int height, CompositeOperator op) +void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int width, int height, CompositeOperator op) { if (!fillLayer) return; - paintFillLayers(paintInfo, c, fillLayer->next(), clipY, clipH, tx, ty, width, height, op); - paintFillLayer(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width, height, op); + paintFillLayers(paintInfo, c, fillLayer->next(), tx, ty, width, height, op); + paintFillLayer(paintInfo, c, fillLayer, tx, ty, width, height, op); } -void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, - int clipY, int clipH, int tx, int ty, int width, int height, CompositeOperator op) +void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int width, int height, CompositeOperator op) { - paintFillLayerExtended(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width, height, 0, op); + paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, width, height, 0, op); } void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBox.h b/src/3rdparty/webkit/WebCore/rendering/RenderBox.h index ceb3302..95c0637 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBox.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBox.h @@ -288,10 +288,10 @@ protected: virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); virtual void updateBoxModelInfoFromStyle(); - void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver); - void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver); + void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver); + void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver); - void paintMaskImages(const PaintInfo&, int clipY, int clipHeight, int tx, int ty, int width, int height); + void paintMaskImages(const PaintInfo&, int tx, int ty, int width, int height); #if PLATFORM(MAC) void paintCustomHighlight(int tx, int ty, const AtomicString& type, bool behindText); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp index 467fa82..8973e64 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp @@ -297,8 +297,7 @@ int RenderBoxModelObject::paddingRight(bool) const } -void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& c, const FillLayer* bgLayer, int clipY, int clipH, - int tx, int ty, int w, int h, InlineFlowBox* box, CompositeOperator op) +void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& c, const FillLayer* bgLayer, int tx, int ty, int w, int h, InlineFlowBox* box, CompositeOperator op) { GraphicsContext* context = paintInfo.context; bool includeLeftEdge = box ? box->includeLeftEdge() : true; @@ -411,7 +410,8 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co // Paint the color first underneath all images. if (!bgLayer->next()) { - IntRect rect(tx, clipY, w, clipH); + IntRect rect(tx, ty, w, h); + rect.intersect(paintInfo.rect); // If we have an alpha and we are painting the root element, go ahead and blend with the base background color. if (isOpaqueRoot) { Color baseColor = view()->frameView()->baseBackgroundColor(); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h index f2c6326..9feaf2f 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h @@ -90,8 +90,7 @@ public: void paintBorder(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true); bool paintNinePieceImage(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver); void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true); - virtual void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight, - int tx, int ty, int width, int height, InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver); + void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver); // The difference between this inline's baseline position and the line's baseline position. int verticalPosition(bool firstLine) const; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderDataGrid.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderDataGrid.cpp new file mode 100644 index 0000000..b207a31 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/rendering/RenderDataGrid.cpp @@ -0,0 +1,122 @@ +/* + * 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. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RenderDataGrid.h" + +#include "FocusController.h" +#include "Frame.h" +#include "GraphicsContext.h" +#include "Page.h" +#include "Scrollbar.h" + +using std::min; + +namespace WebCore { + +static const int cDefaultWidth = 300; + +RenderDataGrid::RenderDataGrid(Element* elt) + : RenderBlock(elt) +{ +} + +RenderDataGrid::~RenderDataGrid() +{ +} + +void RenderDataGrid::calcPrefWidths() +{ + m_minPrefWidth = 0; + m_maxPrefWidth = 0; + + if (style()->width().isFixed() && style()->width().value() > 0) + m_minPrefWidth = m_maxPrefWidth = calcContentBoxWidth(style()->width().value()); + else + m_maxPrefWidth = calcContentBoxWidth(cDefaultWidth); + + if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) { + m_maxPrefWidth = max(m_maxPrefWidth, calcContentBoxWidth(style()->minWidth().value())); + m_minPrefWidth = max(m_minPrefWidth, calcContentBoxWidth(style()->minWidth().value())); + } else if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent())) + m_minPrefWidth = 0; + else + m_minPrefWidth = m_maxPrefWidth; + + if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) { + m_maxPrefWidth = min(m_maxPrefWidth, calcContentBoxWidth(style()->maxWidth().value())); + m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value())); + } + + int toAdd = paddingLeft() + paddingRight() + borderLeft() + borderRight(); + m_minPrefWidth += toAdd; + m_maxPrefWidth += toAdd; + + setPrefWidthsDirty(false); +} + +void RenderDataGrid::paintObject(PaintInfo& paintInfo, int tx, int ty) +{ + if (style()->visibility() != VISIBLE) + return; + + // Paint our background and border. + RenderBlock::paintObject(paintInfo, tx, ty); + + if (paintInfo.phase != PaintPhaseForeground) + return; + + // Paint our column headers first. + paintColumnHeaders(paintInfo, tx, ty); +} + +void RenderDataGrid::paintColumnHeaders(PaintInfo&, int, int) +{ + gridElement()->columns(); + +} + +void RenderDataGrid::rebuildColumns() +{ +} + +// Scrolling implementation functions +void RenderDataGrid::valueChanged(Scrollbar*) +{ + // FIXME: Implement. +} + +void RenderDataGrid::invalidateScrollbarRect(Scrollbar*, const IntRect&) +{ + // FIXME: Implement. +} + +bool RenderDataGrid::isActive() const +{ + Page* page = document()->frame()->page(); + return page && page->focusController()->isActive(); +} + +} diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderDataGrid.h b/src/3rdparty/webkit/WebCore/rendering/RenderDataGrid.h new file mode 100644 index 0000000..6a4b32e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/rendering/RenderDataGrid.h @@ -0,0 +1,70 @@ +/* + * 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. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RenderDataGrid_h +#define RenderDataGrid_h + +#include "HTMLDataGridElement.h" +#include "RenderBlock.h" +#include "ScrollbarClient.h" +#include "StyleImage.h" +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class RenderDataGrid : public RenderBlock, private ScrollbarClient { +public: + RenderDataGrid(Element*); + ~RenderDataGrid(); + + virtual const char* renderName() const { return "RenderDataGrid"; } + + virtual bool canHaveChildren() const { return false; } + + virtual void calcPrefWidths(); + + virtual void paintObject(PaintInfo&, int tx, int ty); + + void columnsChanged(); + +private: + void paintColumnHeaders(PaintInfo&, int tx, int ty); + void rebuildColumns(); + + HTMLDataGridElement* gridElement() const { return static_cast<HTMLDataGridElement*>(node()); } + + // ScrollbarClient interface. + virtual void valueChanged(Scrollbar*); + virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&); + virtual bool isActive() const; + virtual bool scrollbarCornerPresent() const { return false; } // We don't support resize on data grids yet. If we did this would have to change. + + RefPtr<Scrollbar> m_vBar; +}; + +} + +#endif // RenderDataGrid_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp index 310dbe4..1275882 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp @@ -131,13 +131,9 @@ void RenderFieldset::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty) h -= yOff; ty += yOff; - int my = max(ty, paintInfo.rect.y()); - int end = min(paintInfo.rect.bottom(), ty + h); - int mh = end - my; - paintBoxShadow(paintInfo.context, tx, ty, w, h, style()); - paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), my, mh, tx, ty, w, h); + paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, w, h); if (!style()->hasBorder()) return; @@ -176,11 +172,7 @@ void RenderFieldset::paintMask(PaintInfo& paintInfo, int tx, int ty) h -= yOff; ty += yOff; - int my = max(ty, paintInfo.rect.y()); - int end = min(paintInfo.rect.bottom(), ty + h); - int mh = end - my; - - paintMaskImages(paintInfo, my, mh, tx, ty, w, h); + paintMaskImages(paintInfo, tx, ty, w, h); } void RenderFieldset::paintBorderMinusLegend(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp index 56ad490..cd84a09 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp @@ -452,11 +452,9 @@ bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu int tx = _tx + x(); int ty = _ty + y(); - HTMLMapElement* map = imageMap(); - if (map) { - // we're a client side image map - inside = map->mapMouseEvent(_x - tx, _y - ty, IntSize(contentWidth(), contentHeight()), tempResult); - tempResult.setInnerNonSharedNode(node()); + if (HTMLMapElement* map = imageMap()) { + if (map->mapMouseEvent(_x - tx, _y - ty, IntSize(contentWidth(), contentHeight()), tempResult)) + tempResult.setInnerNonSharedNode(node()); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp index 780b48f..ba85f1a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp @@ -229,11 +229,24 @@ RenderLayerCompositor* RenderLayer::compositor() const void RenderLayer::rendererContentChanged() { + // This can get called when video becomes accelerated, so the layers may change. + if (compositor()->updateLayerCompositingState(this)) + compositor()->setCompositingLayersNeedUpdate(); + if (m_backing) m_backing->rendererContentChanged(); } #endif // USE(ACCELERATED_COMPOSITING) +bool RenderLayer::hasAcceleratedCompositing() const +{ +#if USE(ACCELERATED_COMPOSITING) + return compositor()->hasAcceleratedCompositing(); +#else + return false; +#endif +} + void RenderLayer::setStaticY(int staticY) { if (m_staticY == staticY) @@ -306,9 +319,6 @@ void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint) child->updateLayerPositions(doFullRepaint, checkForRepaint); #if USE(ACCELERATED_COMPOSITING) - if (!parent()) - compositor()->updateRootLayerPosition(); - if (isComposited()) backing()->updateAfterLayout(); #endif @@ -338,7 +348,7 @@ void RenderLayer::updateTransform() ASSERT(box); m_transform->makeIdentity(); box->style()->applyTransform(*m_transform, box->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin); - makeMatrixRenderable(*m_transform); + makeMatrixRenderable(*m_transform, hasAcceleratedCompositing()); } if (had3DTransform != has3DTransform()) @@ -355,7 +365,7 @@ TransformationMatrix RenderLayer::currentTransform() const TransformationMatrix currTransform; RefPtr<RenderStyle> style = renderer()->animation()->getAnimatedStyleForRenderer(renderer()); style->applyTransform(currTransform, renderBox()->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin); - makeMatrixRenderable(currTransform); + makeMatrixRenderable(currTransform, hasAcceleratedCompositing()); return currTransform; } #endif @@ -948,7 +958,6 @@ void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint) const int shortDistanceLimit = 100; // We delimit a 200 pixels long square enclosing the original point const int speedReducer = 2; // Within this square we divide the scrolling speed by 2 - const int iconRadius = 10; Frame* frame = renderer()->document()->frame(); if (!frame) return; @@ -965,9 +974,9 @@ void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint) int xDelta = currentMousePosition.x() - sourcePoint.x(); int yDelta = currentMousePosition.y() - sourcePoint.y(); - if (abs(xDelta) < iconRadius) // at the center we let the space for the icon + if (abs(xDelta) < ScrollView::noPanScrollRadius) // at the center we let the space for the icon xDelta = 0; - if (abs(yDelta) < iconRadius) + if (abs(yDelta) < ScrollView::noPanScrollRadius) yDelta = 0; // Let's attenuate the speed for the short distances @@ -1053,8 +1062,10 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai child->updateLayerPositions(false, false); #if USE(ACCELERATED_COMPOSITING) - if (isComposited()) - m_backing->updateGraphicsLayerGeometry(); + if (compositor()->inCompositingMode()) { + if (RenderLayer* compositingAncestor = ancestorCompositingLayer()) + compositingAncestor->backing()->updateAfterLayout(); + } #endif RenderView* view = renderer()->view(); @@ -1300,7 +1311,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset ExceptionCode ec; - if (difference.width()) { + if (resize != RESIZE_VERTICAL && difference.width()) { if (element->isFormControlElement()) { // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>). style->setProperty(CSSPropertyMarginLeft, String::number(renderer->marginLeft() / zoomFactor) + "px", false, ec); @@ -1312,7 +1323,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset style->setProperty(CSSPropertyWidth, String::number(baseWidth + difference.width()) + "px", false, ec); } - if (difference.height()) { + if (resize != RESIZE_HORIZONTAL && difference.height()) { if (element->isFormControlElement()) { // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>). style->setProperty(CSSPropertyMarginTop, String::number(renderer->marginTop() / zoomFactor) + "px", false, ec); @@ -1894,7 +1905,7 @@ bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularit void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintRestriction paintRestriction, RenderObject *paintingRoot) { RenderObject::OverlapTestRequestMap overlapTestRequests; - paintLayer(this, p, damageRect, false, paintRestriction, paintingRoot, &overlapTestRequests); + paintLayer(this, p, damageRect, paintRestriction, paintingRoot, &overlapTestRequests); RenderObject::OverlapTestRequestMap::iterator end = overlapTestRequests.end(); for (RenderObject::OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) it->first->setOverlapTestResult(false); @@ -1930,15 +1941,29 @@ static void performOverlapTests(RenderObject::OverlapTestRequestMap& overlapTest overlapTestRequests.remove(overlappedRequestClients[i]); } +#if USE(ACCELERATED_COMPOSITING) +static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection) +{ + return paintingReflection && !layer->has3DTransform(); +} +#endif + void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, - const IntRect& paintDirtyRect, bool haveTransparency, PaintRestriction paintRestriction, + const IntRect& paintDirtyRect, PaintRestriction paintRestriction, RenderObject* paintingRoot, RenderObject::OverlapTestRequestMap* overlapTestRequests, - bool appliedTransform, bool temporaryClipRects) + PaintLayerFlags paintFlags) { #if USE(ACCELERATED_COMPOSITING) - // Composited RenderLayers are painted via the backing's paintIntoLayer(). - if (isComposited() && !backing()->paintingGoesToWindow()) - return; + 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()) + 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(). + return; + } + } #endif // Avoid painting layers when stylesheets haven't loaded. This eliminates FOUC. @@ -1952,24 +1977,24 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, return; if (paintsWithTransparency()) - haveTransparency = true; + 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() && !appliedTransform) { + if (paintsWithTransform() && !(paintFlags & PaintLayerAppliedTransform)) { // If the transform can't be inverted, then don't paint anything. if (!m_transform->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 (haveTransparency) + if (paintFlags & PaintLayerHaveTransparency) parent()->beginTransparencyLayers(p, rootLayer); // Make sure the parent's clip rects have been calculated. IntRect clipRect = paintDirtyRect; if (parent()) { ClipRects parentRects; - parentClipRects(rootLayer, parentRects, temporaryClipRects); + parentClipRects(rootLayer, parentRects, paintFlags & PaintLayerTemporaryClipRects); clipRect = parentRects.overflowClipRect(); clipRect.intersect(paintDirtyRect); } @@ -1991,7 +2016,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, p->concatCTM(transform); // Now do a paint with the root layer shifted to be us. - paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), haveTransparency, paintRestriction, paintingRoot, overlapTestRequests, true, temporaryClipRects); + paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintRestriction, paintingRoot, overlapTestRequests, paintFlags | PaintLayerAppliedTransform); p->restore(); @@ -2001,17 +2026,20 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, return; } + PaintLayerFlags localPaintFlags = paintFlags & ~PaintLayerAppliedTransform; + bool haveTransparency = localPaintFlags & PaintLayerHaveTransparency; + // Paint the reflection first if we have one. - if (m_reflection && !m_paintingInsideReflection && (!m_transform || appliedTransform)) { + if (m_reflection && !m_paintingInsideReflection) { // Mark that we are now inside replica painting. m_paintingInsideReflection = true; - reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot, overlapTestRequests, false, temporaryClipRects); + reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags | PaintLayerPaintingReflection); m_paintingInsideReflection = false; } // Calculate the clip rects we should use. IntRect layerBounds, damageRect, clipRectToApply, outlineRect; - calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, temporaryClipRects); + calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, localPaintFlags & PaintLayerTemporaryClipRects); int x = layerBounds.x(); int y = layerBounds.y(); int tx = x - renderBoxX(); @@ -2056,7 +2084,7 @@ 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, haveTransparency, paintRestriction, paintingRoot, overlapTestRequests, false, temporaryClipRects); + it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags); // Now establish the appropriate clip and paint our child RenderObjects. if (shouldPaint && !clipRectToApply.isEmpty()) { @@ -2095,12 +2123,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, haveTransparency, paintRestriction, paintingRoot, overlapTestRequests, false, temporaryClipRects); + it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, 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, haveTransparency, paintRestriction, paintingRoot, overlapTestRequests, false, temporaryClipRects); + it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags); if (renderer()->hasMask() && shouldPaint && !selectionOnly && !damageRect.isEmpty()) { setClip(p, paintDirtyRect, damageRect); @@ -2298,7 +2326,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont #if USE(ACCELERATED_COMPOSITING) if (isComposited()) { // It doesn't make sense to project hitTestRect into the plane of this layer, so use the same bounds we use for painting. - localHitTestRect = compositor()->calculateCompositedBounds(this, this); + localHitTestRect = backing()->compositedBounds(); } else #endif localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox(); @@ -3046,7 +3074,7 @@ void RenderLayer::repaintIncludingNonCompositingDescendants(RenderBoxModelObject bool RenderLayer::shouldBeNormalFlowOnly() const { - return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask()) && + return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isVideo()) && !renderer()->isPositioned() && !renderer()->isRelPositioned() && !renderer()->hasTransform() && @@ -3055,7 +3083,7 @@ bool RenderLayer::shouldBeNormalFlowOnly() const bool RenderLayer::isSelfPaintingLayer() const { - return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow(); + return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo(); } void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h index 9c8de5e..4feede8 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h @@ -289,6 +289,9 @@ public: // Allows updates of layer content without repainting. void rendererContentChanged(); #endif + + // Returns true if the accelerated compositing is enabled + bool hasAcceleratedCompositing() const; void updateLayerPosition(); void updateLayerPositions(bool doFullRepaint = false, bool checkForRepaint = true); @@ -439,10 +442,18 @@ private: void updateLayerListsIfNeeded(); + enum PaintLayerFlag { + PaintLayerHaveTransparency = 1, + PaintLayerAppliedTransform = 1 << 1, + PaintLayerTemporaryClipRects = 1 << 2, + PaintLayerPaintingReflection = 1 << 3 + }; + + typedef unsigned PaintLayerFlags; + void paintLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect, - bool haveTransparency, PaintRestriction, RenderObject* paintingRoot, - RenderObject::OverlapTestRequestMap* = 0, - bool appliedTransform = false, bool temporaryClipRects = false); + PaintRestriction, RenderObject* paintingRoot, RenderObject::OverlapTestRequestMap* = 0, + PaintLayerFlags paintFlags = 0); RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result, const IntRect& hitTestRect, const IntPoint& hitTestPoint, bool appliedTransform, @@ -482,6 +493,7 @@ private: void createReflection(); void updateReflectionStyle(); bool paintingInsideReflection() const { return m_paintingInsideReflection; } + void setPaintingInsideReflection(bool b) { m_paintingInsideReflection = b; } void parentClipRects(const RenderLayer* rootLayer, ClipRects&, bool temporaryClipRects = false) const; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp index e16ecf7..1c6d43c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp @@ -58,7 +58,6 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) , m_contentsLayer(0) , m_clippingLayer(0) , m_hasDirectlyCompositedContent(false) - , m_compositingContentOffsetDirty(true) { createGraphicsLayer(); } @@ -75,14 +74,17 @@ void RenderLayerBacking::createGraphicsLayer() m_graphicsLayer = GraphicsLayer::createGraphicsLayer(this); #ifndef NDEBUG - if (renderer()->node()->isDocumentNode()) - m_graphicsLayer->setName("Document Node"); - else { - if (renderer()->node()->isHTMLElement() && renderer()->node()->hasID()) - m_graphicsLayer->setName(renderer()->renderName() + String(" ") + static_cast<HTMLElement*>(renderer()->node())->id()); - else - m_graphicsLayer->setName(renderer()->renderName()); - } + if (renderer()->node()) { + if (renderer()->node()->isDocumentNode()) + m_graphicsLayer->setName("Document Node"); + else { + if (renderer()->node()->isHTMLElement() && renderer()->node()->hasID()) + m_graphicsLayer->setName(renderer()->renderName() + String(" ") + static_cast<HTMLElement*>(renderer()->node())->id()); + else + m_graphicsLayer->setName(renderer()->renderName()); + } + } else + m_graphicsLayer->setName("Anonymous Node"); #endif // NDEBUG updateLayerOpacity(); @@ -118,7 +120,7 @@ void RenderLayerBacking::updateLayerTransform() TransformationMatrix t; if (m_owningLayer->hasTransform()) { style->applyTransform(t, toRenderBox(renderer())->borderBoxRect().size(), RenderStyle::ExcludeTransformOrigin); - makeMatrixRenderable(t); + makeMatrixRenderable(t, compositor()->hasAcceleratedCompositing()); } m_graphicsLayer->setTransform(t); @@ -126,9 +128,21 @@ void RenderLayerBacking::updateLayerTransform() void RenderLayerBacking::updateAfterLayout() { - // Only need to update geometry if there isn't a layer update pending. - if (!compositor()->compositingLayersNeedUpdate()) - updateGraphicsLayerGeometry(); + RenderLayerCompositor* layerCompositor = compositor(); + if (!layerCompositor->compositingLayersNeedUpdate()) { + // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the + // position of this layer's GraphicsLayer depends on the position of our compositing + // ancestor's GraphicsLayer. That cannot be determined until all the descendant + // RenderLayers of that ancestor have been processed via updateLayerPositions(). + // + // The solution is to update compositing children of this layer here, + // via updateCompositingChildrenGeometry(). + setCompositedBounds(layerCompositor->calculateCompositedBounds(m_owningLayer, m_owningLayer)); + layerCompositor->updateCompositingChildrenGeometry(m_owningLayer, m_owningLayer); + + if (!m_owningLayer->parent()) + layerCompositor->updateRootLayerPosition(); + } } bool RenderLayerBacking::updateGraphicsLayerConfiguration() @@ -178,16 +192,16 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D); m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible); - m_compositingContentOffsetDirty = true; - RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer(); // We compute everything relative to the enclosing compositing layer. IntRect ancestorCompositingBounds; - if (compAncestor) - ancestorCompositingBounds = compositor()->calculateCompositedBounds(compAncestor, compAncestor); - - IntRect localCompositingBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); + if (compAncestor) { + ASSERT(compAncestor->backing()); + ancestorCompositingBounds = compAncestor->backing()->compositedBounds(); + } + + IntRect localCompositingBounds = compositedBounds(); IntRect relativeCompositingBounds(localCompositingBounds); int deltaX = 0, deltaY = 0; @@ -410,7 +424,7 @@ static bool hasBoxDecorationsWithBackgroundImage(const RenderStyle* style) bool RenderLayerBacking::rendererHasBackground() const { // FIXME: share more code here - if (renderer()->node()->isDocumentNode()) { + if (renderer()->node() && renderer()->node()->isDocumentNode()) { RenderObject* htmlObject = renderer()->firstChild(); if (!htmlObject) return false; @@ -433,7 +447,7 @@ bool RenderLayerBacking::rendererHasBackground() const const Color& RenderLayerBacking::rendererBackgroundColor() const { // FIXME: share more code here - if (renderer()->node()->isDocumentNode()) { + if (renderer()->node() && renderer()->node()->isDocumentNode()) { RenderObject* htmlObject = renderer()->firstChild(); RenderStyle* style = htmlObject->style(); if (style->hasBackground()) @@ -469,7 +483,7 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const if (!renderObject->firstChild()) return true; - if (renderObject->node()->isDocumentNode()) { + if (renderObject->node() && renderObject->node()->isDocumentNode()) { // Look to see if the root object has a non-simple backgound RenderObject* rootObject = renderObject->document()->documentElement()->renderer(); if (!rootObject) @@ -529,29 +543,29 @@ bool RenderLayerBacking::hasNonCompositingContent() const // FIXME: test for overflow controls. if (m_owningLayer->isStackingContext()) { // Use the m_hasCompositingDescendant bit to optimize? - Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList(); - if (negZOrderList && negZOrderList->size() > 0) { - for (Vector<RenderLayer*>::const_iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList()) { + size_t listSize = negZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = negZOrderList->at(i); if (!curLayer->isComposited()) return true; } } - Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList(); - if (posZOrderList && posZOrderList->size() > 0) { - for (Vector<RenderLayer*>::const_iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList()) { + size_t listSize = posZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = posZOrderList->at(i); if (!curLayer->isComposited()) return true; } } } - Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList(); - if (normalFlowList && normalFlowList->size() > 0) { - for (Vector<RenderLayer*>::const_iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList()) { + size_t listSize = normalFlowList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = normalFlowList->at(i); if (!curLayer->isComposited()) return true; } @@ -567,11 +581,15 @@ bool RenderLayerBacking::canUseDirectCompositing() const RenderObject* renderObject = renderer(); // Reject anything that isn't an image - if (!renderObject->isImage()) + if (!renderObject->isImage() && !renderObject->isVideo()) return false; if (renderObject->hasMask() || renderObject->hasReflection()) return false; + + // Video can use an inner layer even if it has box decorations; we draw those into another layer. + if (renderObject->isVideo()) + return true; // Reject anything that would require the image to be drawn via the GraphicsContext, // like border, shadows etc. Solid background color is OK. @@ -639,14 +657,7 @@ FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted. IntSize RenderLayerBacking::contentOffsetInCompostingLayer() { - if (!m_compositingContentOffsetDirty) - return m_compositingContentOffset; - - IntRect relativeCompositingBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); - m_compositingContentOffset = IntSize(-relativeCompositingBounds.x(), -relativeCompositingBounds.y()); - m_compositingContentOffsetDirty = false; - - return m_compositingContentOffset; + return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y()); } IntRect RenderLayerBacking::contentsBox(const GraphicsLayer*) @@ -654,7 +665,15 @@ IntRect RenderLayerBacking::contentsBox(const GraphicsLayer*) if (!renderer()->isBox()) return IntRect(); - IntRect contentsRect = toRenderBox(renderer())->contentBoxRect(); + IntRect contentsRect; +#if ENABLE(VIDEO) + if (renderer()->isVideo()) { + RenderVideo* videoRenderer = static_cast<RenderVideo*>(renderer()); + contentsRect = videoRenderer->videoBox(); + } else +#endif + contentsRect = toRenderBox(renderer())->contentBoxRect(); + IntSize contentOffset = contentOffsetInCompostingLayer(); contentsRect.move(contentOffset); return contentsRect; @@ -679,27 +698,47 @@ bool RenderLayerBacking::paintingGoesToWindow() const void RenderLayerBacking::setContentsNeedDisplay() { - if (m_graphicsLayer) + bool needViewUpdate = false; + + if (m_graphicsLayer && m_graphicsLayer->drawsContent()) { m_graphicsLayer->setNeedsDisplay(); - if (m_contentsLayer) + needViewUpdate = true; + } + + if (m_contentsLayer && m_contentsLayer->drawsContent()) { m_contentsLayer->setNeedsDisplay(); + needViewUpdate = true; + } + + // Make sure layout happens before we get rendered again. + if (needViewUpdate) + compositor()->scheduleViewUpdate(); } // r is in the coordinate space of the layer's render object void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r) { - if (m_graphicsLayer) { + bool needViewUpdate = false; + + if (m_graphicsLayer && m_graphicsLayer->drawsContent()) { FloatPoint dirtyOrigin = contentsToGraphicsLayerCoordinates(m_graphicsLayer, FloatPoint(r.x(), r.y())); FloatRect dirtyRect(dirtyOrigin, r.size()); FloatRect bounds(FloatPoint(), m_graphicsLayer->size()); - if (bounds.intersects(dirtyRect)) + if (bounds.intersects(dirtyRect)) { m_graphicsLayer->setNeedsDisplayInRect(dirtyRect); + needViewUpdate = true; + } } - if (m_contentsLayer) { + if (m_contentsLayer && m_contentsLayer->drawsContent()) { // FIXME: do incremental repaint m_contentsLayer->setNeedsDisplay(); + needViewUpdate = true; } + + // Make sure layout happens before we get rendered again. + if (needViewUpdate) + compositor()->scheduleViewUpdate(); } static void setClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect) @@ -720,7 +759,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 - bool haveTransparency, PaintRestriction paintRestriction, GraphicsLayerPaintingPhase paintingPhase, + PaintRestriction paintRestriction, GraphicsLayerPaintingPhase paintingPhase, RenderObject* paintingRoot) { if (paintingGoesToWindow()) { @@ -730,6 +769,14 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* m_owningLayer->updateLayerListsIfNeeded(); + // Paint the reflection first if we have one. + 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->setPaintingInsideReflection(false); + } + // Calculate the clip rects we should use. IntRect layerBounds, damageRect, clipRectToApply, outlineRect; m_owningLayer->calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect); @@ -747,13 +794,15 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* if (paintingRoot && !renderer()->isDescendantOf(paintingRoot)) paintingRootForRenderer = paintingRoot; - if (paintingPhase & GraphicsLayerPaintBackgroundMask) { + bool shouldPaint = m_owningLayer->hasVisibleContent() && m_owningLayer->isSelfPaintingLayer(); + + if (shouldPaint && (paintingPhase & GraphicsLayerPaintBackgroundMask)) { // If this is the root then we need to send in a bigger bounding box // because we'll be painting the background as well (see RenderBox::paintRootBoxDecorations()). IntRect paintBox = clipRectToApply; // FIXME: do we need this code? - if (renderer()->node()->isDocumentNode() && renderer()->document()->isHTMLDocument()) { + if (renderer()->node() && renderer()->node()->isDocumentNode() && renderer()->document()->isHTMLDocument()) { RenderBox* box = toRenderBox(renderer()); int w = box->width(); int h = box->height(); @@ -791,13 +840,13 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* restoreClip(context, paintDirtyRect, damageRect); } - if (paintingPhase & GraphicsLayerPaintForegroundMask) { + if (shouldPaint && (paintingPhase & GraphicsLayerPaintForegroundMask)) { // Now walk the sorted list of children with negative z-indices. Only RenderLayers without compositing layers will paint. // FIXME: should these be painted as background? 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, haveTransparency, paintRestriction, paintingRoot); + it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot); } bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText; @@ -836,14 +885,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, haveTransparency, paintRestriction, paintingRoot); + it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, 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, haveTransparency, paintRestriction, paintingRoot); + it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot); } if (renderer()->hasMask() && !selectionOnly && !damageRect.isEmpty()) { @@ -866,7 +915,7 @@ void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& co { // We have to use the same root as for hit testing, because both methods // can compute and cache clipRects. - IntRect enclosingBBox = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); + IntRect enclosingBBox = compositedBounds(); IntRect clipRect(clip); @@ -880,7 +929,7 @@ void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& co IntRect dirtyRect = enclosingBBox; dirtyRect.intersect(clipRect); - paintIntoLayer(m_owningLayer, &context, dirtyRect, false, PaintRestrictionNone, drawingPhase, renderer()); + paintIntoLayer(m_owningLayer, &context, dirtyRect, PaintRestrictionNone, drawingPhase, renderer()); } bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes) @@ -985,6 +1034,16 @@ void RenderLayerBacking::resumeAnimations() m_graphicsLayer->resumeAnimations(); } +IntRect RenderLayerBacking::compositedBounds() const +{ + return m_compositedBounds; +} + +void RenderLayerBacking::setCompositedBounds(const IntRect& bounds) +{ + m_compositedBounds = bounds; + +} int RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property) { int cssProperty = CSSPropertyInvalid; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h index a6a6c1f..50a77db 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h @@ -57,8 +57,10 @@ public: // Returns true if layer configuration changed. bool updateGraphicsLayerConfiguration(); - void updateGraphicsLayerGeometry(); - void updateInternalHierarchy(); + // Update graphics layer position and bounds. + void updateGraphicsLayerGeometry(); // make private + // Update contents and clipping structure. + void updateInternalHierarchy(); // make private GraphicsLayer* graphicsLayer() const { return m_graphicsLayer; } @@ -100,6 +102,9 @@ public: void suspendAnimations(); void resumeAnimations(); + IntRect compositedBounds() const; + void setCompositedBounds(const IntRect&); + FloatPoint graphicsLayerToContentsCoordinates(const GraphicsLayer*, const FloatPoint&); FloatPoint contentsToGraphicsLayerCoordinates(const GraphicsLayer*, const FloatPoint&); @@ -146,7 +151,7 @@ private: bool hasNonCompositingContent() const; void paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect, - bool haveTransparency, PaintRestriction paintRestriction, GraphicsLayerPaintingPhase, RenderObject* paintingRoot); + PaintRestriction paintRestriction, GraphicsLayerPaintingPhase, RenderObject* paintingRoot); static int graphicsLayerToCSSProperty(AnimatedPropertyID); static AnimatedPropertyID cssToGraphicsLayerProperty(int); @@ -159,10 +164,9 @@ private: GraphicsLayer* m_contentsLayer; // only used in cases where we need to draw the foreground separately GraphicsLayer* m_clippingLayer; // only used if we have clipping on a stacking context, with compositing children - IntSize m_compositingContentOffset; + IntRect m_compositedBounds; - bool m_hasDirectlyCompositedContent: 1; - bool m_compositingContentOffsetDirty: 1; + bool m_hasDirectlyCompositedContent; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp index fec3b1d..8b07ca9 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp @@ -38,7 +38,9 @@ #include "HitTestResult.h" #include "Page.h" #include "RenderLayerBacking.h" +#include "RenderVideo.h" #include "RenderView.h" +#include "Settings.h" #if PROFILE_LAYER_REBUILD #include <wtf/CurrentTime.h> @@ -58,16 +60,16 @@ namespace WebCore { struct CompositingState { CompositingState(RenderLayer* compAncestor) - : m_subtreeIsCompositing(false) - , m_compositingAncestor(compAncestor) + : m_compositingAncestor(compAncestor) + , m_subtreeIsCompositing(false) #ifndef NDEBUG , m_depth(0) #endif { } - bool m_subtreeIsCompositing; RenderLayer* m_compositingAncestor; + bool m_subtreeIsCompositing; #ifndef NDEBUG int m_depth; #endif @@ -86,6 +88,7 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView) , m_compositing(false) , m_rootLayerAttached(false) , m_compositingLayersNeedUpdate(false) + , m_hasAcceleratedCompositing(true) #if PROFILE_LAYER_REBUILD , m_rootLayerUpdateCount(0) #endif // PROFILE_LAYER_REBUILD @@ -108,9 +111,23 @@ void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */) // the empty root layer, which has minimal overhead. if (m_compositing) ensureRootPlatformLayer(); + else + destroyRootPlatformLayer(); } } +void RenderLayerCompositor::cacheAcceleratedCompositingEnabledFlag() +{ + bool hasAcceleratedCompositing = false; + if (Settings* settings = m_renderView->document()->settings()) + hasAcceleratedCompositing = settings-> acceleratedCompositingEnabled(); + + if (hasAcceleratedCompositing != m_hasAcceleratedCompositing) + setCompositingLayersNeedUpdate(); + + m_hasAcceleratedCompositing = hasAcceleratedCompositing; +} + void RenderLayerCompositor::setCompositingLayersNeedUpdate(bool needUpdate) { if (inCompositingMode()) { @@ -172,14 +189,16 @@ void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot) m_rootLayerUpdateCount, 1000.0 * (endTime - startTime)); #endif ASSERT(updateRoot || !m_compositingLayersNeedUpdate); + + if (!hasAcceleratedCompositing()) + enableCompositingMode(false); } -bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) +bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) { - bool needsLayer = needsToBeComposited(layer); bool layerChanged = false; - if (needsLayer) { + if (needsToBeComposited(layer)) { enableCompositingMode(); if (!layer->backing()) { @@ -201,6 +220,20 @@ bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, Comp } } +#if ENABLE(VIDEO) + if (layerChanged && layer->renderer()->isVideo()) { + // If it's a video, give the media player a chance to hook up to the layer. + RenderVideo* video = static_cast<RenderVideo*>(layer->renderer()); + video->acceleratedRenderingStateChanged(); + } +#endif + return layerChanged; +} + +bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) +{ + bool layerChanged = updateBacking(layer, shouldRepaint); + // See if we need content or clipping layers. Methods called here should assume // that the compositing state of descendant layers has not been updated yet. if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration()) @@ -226,17 +259,20 @@ void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer) // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant // RenderLayers that are rendered by the composited RenderLayer. -IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer, IntRect* layerBoundingBox) +IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) { IntRect boundingBoxRect, unionBounds; boundingBoxRect = unionBounds = layer->localBoundingBox(); ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0)); - Vector<RenderLayer*>* negZOrderList = layer->negZOrderList(); - if (negZOrderList) { - for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (!layer->isSelfPaintingLayer()) + return IntRect(); + + if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { + size_t listSize = negZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = negZOrderList->at(i); if (!curLayer->isComposited()) { IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer); unionBounds.unite(childUnionBounds); @@ -244,10 +280,10 @@ IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* laye } } - Vector<RenderLayer*>* posZOrderList = layer->posZOrderList(); - if (posZOrderList) { - for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { + size_t listSize = posZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = posZOrderList->at(i); if (!curLayer->isComposited()) { IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer); unionBounds.unite(childUnionBounds); @@ -255,10 +291,10 @@ IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* laye } } - Vector<RenderLayer*>* normalFlowList = layer->normalFlowList(); - if (normalFlowList) { - for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { + size_t listSize = normalFlowList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = normalFlowList->at(i); if (!curLayer->isComposited()) { IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer); unionBounds.unite(curAbsBounds); @@ -276,11 +312,6 @@ IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* laye layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY); unionBounds.move(ancestorRelX, ancestorRelY); - if (layerBoundingBox) { - boundingBoxRect.move(ancestorRelX, ancestorRelY); - *layerBoundingBox = boundingBoxRect; - } - return unionBounds; } @@ -291,18 +322,22 @@ void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child) { - if (child->isComposited()) - setCompositingParent(child, 0); - - // If the document is being torn down (document's renderer() is null), then there's - // no need to do any layer updating. - if (parent->renderer()->documentBeingDestroyed()) + if (!child->isComposited() || parent->renderer()->documentBeingDestroyed()) return; + setCompositingParent(child, 0); + RenderLayer* compLayer = parent->enclosingCompositingLayer(); if (compLayer) { - IntRect ancestorRect = calculateCompositedBounds(child, compLayer); - compLayer->setBackingNeedsRepaintInRect(ancestorRect); + ASSERT(compLayer->backing()); + IntRect compBounds = child->backing()->compositedBounds(); + + int offsetX = 0, offsetY = 0; + child->convertToLayerCoords(compLayer, offsetX, offsetY); + compBounds.move(offsetX, offsetY); + + compLayer->setBackingNeedsRepaintInRect(compBounds); + // The contents of this layer may be moving from a GraphicsLayer to the window, // so we need to make sure the window system synchronizes those changes on the screen. m_renderView->frameView()->setNeedsOneShotDrawingSynchronization(); @@ -332,7 +367,7 @@ RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const Rend // must be compositing so that its contents render over that child. // This implies that its positive z-index children must also be compositing. // -void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, struct CompositingState& ioCompState) +void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, struct CompositingState& compositingState) { layer->updateLayerPosition(); layer->updateZOrderLists(); @@ -340,39 +375,44 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, s // Clear the flag layer->setHasCompositingDescendant(false); - layer->setMustOverlayCompositedLayers(ioCompState.m_subtreeIsCompositing); + layer->setMustOverlayCompositedLayers(compositingState.m_subtreeIsCompositing); - const bool willBeComposited = needsToBeComposited(layer); - // If we are going to become composited, repaint the old rendering destination - if (!layer->isComposited() && willBeComposited) - repaintOnCompositingChange(layer); - - ioCompState.m_subtreeIsCompositing = willBeComposited; + // The children of this layer don't need to composite, unless there is + // a compositing layer among them, so start by inheriting the compositing + // ancestor with m_subtreeIsCompositing set to false. + CompositingState childState(compositingState.m_compositingAncestor); +#ifndef NDEBUG + ++childState.m_depth; +#endif - CompositingState childState = ioCompState; - if (willBeComposited) + const bool willBeComposited = needsToBeComposited(layer); + if (willBeComposited) { + // Tell the parent it has compositing descendants. + compositingState.m_subtreeIsCompositing = true; + // This layer now acts as the ancestor for kids. childState.m_compositingAncestor = layer; + } - // The children of this stacking context don't need to composite, unless there is - // a compositing layer among them, so start by assuming false. - childState.m_subtreeIsCompositing = false; - -#ifndef NDEBUG - ++childState.m_depth; +#if ENABLE(VIDEO) + // Video is special. It's a replaced element with a content layer, but has shadow content + // for the controller that must render in front. Without this, the controls fail to show + // when the video element is a stacking context (e.g. due to opacity or transform). + if (willBeComposited && layer->renderer()->isVideo()) + childState.m_subtreeIsCompositing = true; #endif if (layer->isStackingContext()) { ASSERT(!layer->m_zOrderListsDirty); - Vector<RenderLayer*>* negZOrderList = layer->negZOrderList(); - if (negZOrderList && negZOrderList->size() > 0) { - for (Vector<RenderLayer*>::const_iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { + size_t listSize = negZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = negZOrderList->at(i); computeCompositingRequirements(curLayer, childState); - // 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 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) { - // make |this| compositing + // make layer compositing layer->setMustOverlayCompositedLayers(true); childState.m_compositingAncestor = layer; } @@ -381,19 +421,19 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, s } ASSERT(!layer->m_normalFlowListDirty); - Vector<RenderLayer*>* normalFlowList = layer->normalFlowList(); - if (normalFlowList && normalFlowList->size() > 0) { - for (Vector<RenderLayer*>::const_iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { + size_t listSize = normalFlowList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = normalFlowList->at(i); computeCompositingRequirements(curLayer, childState); } } if (layer->isStackingContext()) { - Vector<RenderLayer*>* posZOrderList = layer->posZOrderList(); - if (posZOrderList && posZOrderList->size() > 0) { - for (Vector<RenderLayer*>::const_iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { + size_t listSize = posZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = posZOrderList->at(i); computeCompositingRequirements(curLayer, childState); } } @@ -408,19 +448,31 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, s // Subsequent layers in the parent stacking context also need to composite. if (childState.m_subtreeIsCompositing) - ioCompState.m_subtreeIsCompositing = true; + compositingState.m_subtreeIsCompositing = true; + + // If the layer is going into compositing mode, repaint its old location. + if (!layer->isComposited() && needsToBeComposited(layer)) + repaintOnCompositingChange(layer); // Set the flag to say that this SC has compositing children. // this can affect the answer to needsToBeComposited() when clipping, // but that's ok here. layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing); + + // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree(). + updateBacking(layer, CompositingChangeRepaintNow); } void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer) { ASSERT(childLayer->isComposited()); - ASSERT(!parentLayer || parentLayer->isComposited()); - + + // It's possible to be called with a parent that isn't yet composited when we're doing + // partial updates as required by painting or hit testing. Just bail in that case; + // we'll do a full layer update soon. + if (!parentLayer || !parentLayer->isComposited()) + return; + if (parentLayer) { GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers(); GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers(); @@ -451,20 +503,44 @@ void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer) } } -void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, struct CompositingState& ioCompState) +#if ENABLE(VIDEO) +bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const { - bool wasComposited = layer->isComposited(); + // FIXME: ideally we need to look at all ancestors for mask or video. But for now, + // just bail on the obvious cases. + if (o->hasMask() || o->hasReflection() || !m_hasAcceleratedCompositing) + return false; + return o->supportsAcceleratedRendering(); +} +#endif + +void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, struct CompositingState& compositingState) +{ // 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. - updateLayerCompositingState(layer, CompositingChangeWillRepaintLater); + RenderLayerBacking* layerBacking = layer->backing(); + if (layerBacking) { + // 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->setCompositedBounds(calculateCompositedBounds(layer, layer)); + + layerBacking->updateGraphicsLayerConfiguration(); + layerBacking->updateGraphicsLayerGeometry(); + + if (!layer->parent()) + updateRootLayerPosition(); + + // FIXME: make this more incremental + layerBacking->parentForSublayers()->removeAllChildren(); + } // host the document layer in the RenderView's root layer - if (layer->isRootLayer()) + if (layer->isRootLayer() && layer->isComposited()) parentInRootLayer(layer); - CompositingState childState = ioCompState; + CompositingState childState = compositingState; if (layer->isComposited()) childState.m_compositingAncestor = layer; @@ -472,14 +548,6 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru ++childState.m_depth; #endif - RenderLayerBacking* layerBacking = layer->backing(); - - // FIXME: make this more incremental - if (layerBacking) { - layerBacking->parentForSublayers()->removeAllChildren(); - layerBacking->updateInternalHierarchy(); - } - // The children of this stacking context don't need to composite, unless there is // a compositing layer among them, so start by assuming false. childState.m_subtreeIsCompositing = false; @@ -487,10 +555,10 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru if (layer->isStackingContext()) { ASSERT(!layer->m_zOrderListsDirty); - Vector<RenderLayer*>* negZOrderList = layer->negZOrderList(); - if (negZOrderList && negZOrderList->size() > 0) { - for (Vector<RenderLayer*>::const_iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { + size_t listSize = negZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = negZOrderList->at(i); rebuildCompositingLayerTree(curLayer, childState); if (curLayer->isComposited()) setCompositingParent(curLayer, childState.m_compositingAncestor); @@ -507,10 +575,10 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru } ASSERT(!layer->m_normalFlowListDirty); - Vector<RenderLayer*>* normalFlowList = layer->normalFlowList(); - if (normalFlowList && normalFlowList->size() > 0) { - for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { + size_t listSize = normalFlowList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = normalFlowList->at(i); rebuildCompositingLayerTree(curLayer, childState); if (curLayer->isComposited()) setCompositingParent(curLayer, childState.m_compositingAncestor); @@ -518,27 +586,57 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru } if (layer->isStackingContext()) { - Vector<RenderLayer*>* posZOrderList = layer->posZOrderList(); - if (posZOrderList && posZOrderList->size() > 0) { - for (Vector<RenderLayer*>::const_iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { + size_t listSize = posZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = posZOrderList->at(i); rebuildCompositingLayerTree(curLayer, childState); if (curLayer->isComposited()) setCompositingParent(curLayer, childState.m_compositingAncestor); } } } +} + + +// Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry. +void RenderLayerCompositor::updateCompositingChildrenGeometry(RenderLayer* compositingAncestor, RenderLayer* layer) +{ + if (layer != compositingAncestor) { + if (RenderLayerBacking* layerBacking = layer->backing()) { + layerBacking->setCompositedBounds(calculateCompositedBounds(layer, layer)); + layerBacking->updateGraphicsLayerGeometry(); + return; + } + } + + if (!layer->hasCompositingDescendant()) + return; - if (layerBacking) { - // Do work here that requires that we've processed all of the descendant layers - layerBacking->updateGraphicsLayerGeometry(); - } else if (wasComposited) { - // We stopped being a compositing layer. Now that our descendants have been udated, we can - // repaint our new rendering destination. - repaintOnCompositingChange(layer); + if (layer->isStackingContext()) { + if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { + size_t listSize = negZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) + updateCompositingChildrenGeometry(compositingAncestor, negZOrderList->at(i)); + } + } + + if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { + size_t listSize = normalFlowList->size(); + for (size_t i = 0; i < listSize; ++i) + updateCompositingChildrenGeometry(compositingAncestor, 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) + updateCompositingChildrenGeometry(compositingAncestor, posZOrderList->at(i)); + } } } + void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect) { recursiveRepaintLayerRect(rootRenderLayer(), absRect); @@ -550,10 +648,10 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const layer->setBackingNeedsRepaintInRect(rect); if (layer->hasCompositingDescendant()) { - Vector<RenderLayer*>* negZOrderList = layer->negZOrderList(); - if (negZOrderList) { - for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { + size_t listSize = negZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = negZOrderList->at(i); int x = 0, y = 0; curLayer->convertToLayerCoords(layer, x, y); IntRect childRect(rect); @@ -562,10 +660,10 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const } } - Vector<RenderLayer*>* posZOrderList = layer->posZOrderList(); - if (posZOrderList) { - for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { + size_t listSize = posZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = posZOrderList->at(i); int x = 0, y = 0; curLayer->convertToLayerCoords(layer, x, y); IntRect childRect(rect); @@ -573,17 +671,16 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const recursiveRepaintLayerRect(curLayer, childRect); } } - - Vector<RenderLayer*>* normalFlowList = layer->normalFlowList(); - if (normalFlowList) { - for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) { - RenderLayer* curLayer = (*it); - int x = 0, y = 0; - curLayer->convertToLayerCoords(layer, x, y); - IntRect childRect(rect); - childRect.move(-x, -y); - recursiveRepaintLayerRect(curLayer, childRect); - } + } + if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { + size_t listSize = normalFlowList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = normalFlowList->at(i); + int x = 0, y = 0; + curLayer->convertToLayerCoords(layer, x, y); + IntRect childRect(rect); + childRect.move(-x, -y); + recursiveRepaintLayerRect(curLayer, childRect); } } } @@ -629,7 +726,7 @@ void RenderLayerCompositor::willMoveOffscreen() void RenderLayerCompositor::updateRootLayerPosition() { if (m_rootPlatformLayer) - m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight())); + m_rootPlatformLayer->setSize(FloatSize(m_renderView->overflowWidth(), m_renderView->overflowHeight())); } bool RenderLayerCompositor::has3DContent() const @@ -639,52 +736,21 @@ bool RenderLayerCompositor::has3DContent() const bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const { + if (!m_hasAcceleratedCompositing || !layer->isSelfPaintingLayer()) + return false; + return requiresCompositingLayer(layer) || layer->mustOverlayCompositedLayers(); } -#define VERBOSE_COMPOSITINGLAYER 0 - // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons. // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. // static bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const { - // FIXME: cache the result of these tests? -#if VERBOSE_COMPOSITINGLAYER - bool gotReason = false; - - if (!gotReason && inCompositingMode() && layer->isRootLayer()) { - fprintf(stderr, "RenderLayer %p requires compositing layer because: it's the document root\n", layer); - gotReason = true; - } - - if (!gotReason && requiresCompositingForTransform(layer->renderer())) { - fprintf(stderr, "RenderLayer %p requires compositing layer because: it has 3d transform, perspective, backface, or animating transform\n", layer); - gotReason = true; - } - - if (!gotReason && layer->renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) { - fprintf(stderr, "RenderLayer %p requires compositing layer because: it has backface-visibility: hidden\n", layer); - gotReason = true; - } - - if (!gotReason && clipsCompositingDescendants(layer)) { - fprintf(stderr, "RenderLayer %p requires compositing layer because: it has overflow clip\n", layer); - gotReason = true; - } - - if (!gotReason && requiresCompositingForAnimation(layer->renderer())) { - fprintf(stderr, "RenderLayer %p requires compositing layer because: it has a running transition for opacity or transform\n", layer); - gotReason = true; - } - - if (!gotReason) - fprintf(stderr, "RenderLayer %p does not require compositing layer\n", layer); -#endif - // The root layer always has a compositing layer, but it may not have backing. return (inCompositingMode() && layer->isRootLayer()) || requiresCompositingForTransform(layer->renderer()) || + requiresCompositingForVideo(layer->renderer()) || layer->renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden || clipsCompositingDescendants(layer) || requiresCompositingForAnimation(layer->renderer()); @@ -737,7 +803,7 @@ bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer layer->renderer()->hasOverflowClip(); } -bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) +bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const { RenderStyle* style = renderer->style(); // Note that we ask the renderer if it has a transform, because the style may have transforms, @@ -745,12 +811,23 @@ bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* render return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective()); } -bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) +bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const +{ +#if ENABLE(VIDEO) + if (renderer->isVideo()) { + RenderVideo* video = static_cast<RenderVideo*>(renderer); + return canAccelerateVideoRendering(video); + } +#endif + return false; +} + +bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const { - AnimationController* animController = renderer->animation(); - if (animController) - return animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyOpacity) || - animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyWebkitTransform); + if (AnimationController* animController = renderer->animation()) { + return (animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode()) + || animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyWebkitTransform); + } return false; } @@ -768,7 +845,7 @@ void RenderLayerCompositor::ensureRootPlatformLayer() return; m_rootPlatformLayer = GraphicsLayer::createGraphicsLayer(0); - m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight())); + m_rootPlatformLayer->setSize(FloatSize(m_renderView->overflowWidth(), m_renderView->overflowHeight())); m_rootPlatformLayer->setPosition(FloatPoint(0, 0)); if (GraphicsLayer::compositingCoordinatesOrientation() == GraphicsLayer::CompositingCoordinatesBottomUp) @@ -780,6 +857,16 @@ void RenderLayerCompositor::ensureRootPlatformLayer() didMoveOnscreen(); } +void RenderLayerCompositor::destroyRootPlatformLayer() +{ + if (!m_rootPlatformLayer) + return; + + willMoveOffscreen(); + delete m_rootPlatformLayer; + m_rootPlatformLayer = 0; +} + bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const { const RenderStyle* style = layer->renderer()->style(); @@ -791,29 +878,29 @@ bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const return true; if (layer->isStackingContext()) { - Vector<RenderLayer*>* negZOrderList = layer->negZOrderList(); - if (negZOrderList) { - for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { + size_t listSize = negZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = negZOrderList->at(i); if (layerHas3DContent(curLayer)) return true; } } - Vector<RenderLayer*>* posZOrderList = layer->posZOrderList(); - if (posZOrderList) { - for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { + size_t listSize = posZOrderList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = posZOrderList->at(i); if (layerHas3DContent(curLayer)) return true; } } } - Vector<RenderLayer*>* normalFlowList = layer->normalFlowList(); - if (normalFlowList) { - for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) { - RenderLayer* curLayer = (*it); + if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { + size_t listSize = normalFlowList->size(); + for (size_t i = 0; i < listSize; ++i) { + RenderLayer* curLayer = normalFlowList->at(i); if (layerHas3DContent(curLayer)) return true; } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h index 76cb35f..bcd6a3f 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h @@ -33,6 +33,9 @@ namespace WebCore { #define PROFILE_LAYER_REBUILD 0 class GraphicsLayer; +#if ENABLE(VIDEO) +class RenderVideo; +#endif // RenderLayerCompositor manages the hierarchy of // composited RenderLayers. It determines which RenderLayers @@ -53,6 +56,12 @@ public: // This will make a compositing layer at the root automatically, and hook up to // the native view/window system. void enableCompositingMode(bool enable = true); + + // Returns true if the accelerated compositing is enabled + bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; } + + // Copy the acceleratedCompositingEnabledFlag from Settings + void cacheAcceleratedCompositingEnabledFlag(); void setCompositingLayersNeedUpdate(bool needUpdate = true); bool compositingLayersNeedUpdate() const { return m_compositingLayersNeedUpdate; } @@ -66,6 +75,9 @@ public: enum CompositingChangeRepaint { CompositingChangeRepaintNow, CompositingChangeWillRepaintLater }; bool updateLayerCompositingState(RenderLayer*, CompositingChangeRepaint = CompositingChangeRepaintNow); + // Update the geometry for compositing children of compositingAncestor. + void updateCompositingChildrenGeometry(RenderLayer* compositingAncestor, RenderLayer* layer); + // Whether layer's backing needs a graphics layer to do clipping by an ancestor (non-stacking-context parent with overflow). bool clippedByAncestor(RenderLayer*) const; // Whether layer's backing needs a graphics layer to clip z-order children of the given layer. @@ -75,7 +87,7 @@ public: bool needsContentsCompositingLayer(const RenderLayer*) const; // Return the bounding box required for compositing layer and its childern, relative to ancestorLayer. // If layerBoundingBox is not 0, on return it contains the bounding box of this layer only. - IntRect calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer, IntRect* layerBoundingBox = 0); + IntRect calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer); // Repaint the appropriate layers when the given RenderLayer starts or stops being composited. void repaintOnCompositingChange(RenderLayer*); @@ -97,6 +109,11 @@ public: void willMoveOffscreen(); void updateRootLayerPosition(); + +#if ENABLE(VIDEO) + // Use by RenderVideo to ask if it should try to use accelerated compositing. + bool canAccelerateVideoRendering(RenderVideo*) const; +#endif // Walk the tree looking for layers with 3d transforms. Useful in case you need // to know if there is non-affine content, e.g. for drawing into an image. @@ -108,6 +125,9 @@ private: // Whether the layer has an intrinsic need for compositing layer. bool requiresCompositingLayer(const RenderLayer*) const; + // Make or destroy the backing for this layer; returns true if backing changed. + bool updateBacking(RenderLayer*, CompositingChangeRepaint shouldRepaint); + // Repaint the given rect (which is layer's coords), and regions of child layers that intersect that rect. void recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect); @@ -123,10 +143,12 @@ private: bool layerHas3DContent(const RenderLayer*) const; void ensureRootPlatformLayer(); - + void destroyRootPlatformLayer(); + // Whether a running transition or animation enforces the need for a compositing layer. - static bool requiresCompositingForAnimation(RenderObject*); - static bool requiresCompositingForTransform(RenderObject*); + bool requiresCompositingForAnimation(RenderObject*) const; + bool requiresCompositingForTransform(RenderObject*) const; + bool requiresCompositingForVideo(RenderObject*) const; private: RenderView* m_renderView; @@ -134,6 +156,8 @@ private: bool m_compositing; bool m_rootLayerAttached; bool m_compositingLayersNeedUpdate; + bool m_hasAcceleratedCompositing; + #if PROFILE_LAYER_REBUILD int m_rootLayerUpdateCount; #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp index 2ffa2f6..b0eb097 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp @@ -269,15 +269,19 @@ void RenderMedia::updateControls() if (!m_controlsShadowRoot) { createControlsShadowRoot(); createPanel(); - createMuteButton(); - createPlayButton(); - createTimelineContainer(); - createTimeline(); - createSeekBackButton(); - createSeekForwardButton(); - createCurrentTimeDisplay(); - createTimeRemainingDisplay(); - createFullscreenButton(); + if (m_panel && m_panel->renderer()) { + createMuteButton(); + createPlayButton(); + createTimelineContainer(); + createSeekBackButton(); + createSeekForwardButton(); + createFullscreenButton(); + } + if (m_timelineContainer && m_timelineContainer->renderer()) { + createCurrentTimeDisplay(); + createTimeline(); + createTimeRemainingDisplay(); + } } if (media->canPlay()) { @@ -295,6 +299,10 @@ void RenderMedia::updateControls() m_playButton->update(); if (m_timeline) m_timeline->update(); + if (m_currentTimeDisplay) + m_currentTimeDisplay->update(); + if (m_timeRemainingDisplay) + m_timeRemainingDisplay->update(); if (m_seekBackButton) m_seekBackButton->update(); if (m_seekForwardButton) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp index f1ff55f..06d901a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp @@ -51,19 +51,20 @@ SOFT_LINK(SafariTheme, STPaintProgressIndicator, void, APIENTRY, (ProgressIndica static ThemeControlState determineState(RenderObject* o) { ThemeControlState result = 0; - if (theme()->isActive(o)) + RenderTheme* theme = o->theme(); + if (theme->isActive(o)) result |= SafariTheme::ActiveState; - if (theme()->isEnabled(o) && !theme()->isReadOnlyControl(o)) + if (theme->isEnabled(o) && !theme->isReadOnlyControl(o)) result |= SafariTheme::EnabledState; - if (theme()->isPressed(o)) + if (theme->isPressed(o)) result |= SafariTheme::PressedState; - if (theme()->isChecked(o)) + if (theme->isChecked(o)) result |= SafariTheme::CheckedState; - if (theme()->isIndeterminate(o)) + if (theme->isIndeterminate(o)) result |= SafariTheme::IndeterminateCheckedState; - if (theme()->isFocused(o)) + if (theme->isFocused(o)) result |= SafariTheme::FocusedState; - if (theme()->isDefault(o)) + if (theme->isDefault(o)) result |= SafariTheme::DefaultState; return result; } @@ -101,13 +102,17 @@ bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, R break; case MediaMuteButton: case MediaUnMuteButton: - if (HTMLMediaElement* mediaElement = parentMediaElement(o)) - paintThemePart(mediaElement->muted() ? SafariTheme::MediaUnMuteButtonPart : SafariTheme::MediaMuteButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); + if (MediaControlMuteButtonElement* btn = static_cast<MediaControlMuteButtonElement*>(o->node())) { + bool audioEnabled = btn->displayType() == MediaMuteButton; + paintThemePart(audioEnabled ? SafariTheme::MediaMuteButtonPart : SafariTheme::MediaUnMuteButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); + } break; case MediaPauseButton: case MediaPlayButton: - if (HTMLMediaElement* mediaElement = parentMediaElement(o)) - paintThemePart(mediaElement->canPlay() ? SafariTheme::MediaPlayButtonPart : SafariTheme::MediaPauseButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); + if (MediaControlPlayButtonElement* btn = static_cast<MediaControlPlayButtonElement*>(o->node())) { + bool currentlyPlaying = btn->displayType() == MediaPlayButton; + paintThemePart(currentlyPlaying ? SafariTheme::MediaPauseButtonPart : SafariTheme::MediaPlayButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); + } break; case MediaSeekBackButton: paintThemePart(SafariTheme::MediaSeekBackButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); @@ -116,15 +121,8 @@ bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, R paintThemePart(SafariTheme::MediaSeekForwardButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o)); break; case MediaSlider: { - HTMLMediaElement* mediaElement = parentMediaElement(o); - if (!mediaElement) - break; - - MediaPlayer* player = mediaElement->player(); - float duration = player ? player->duration() : 0; - float percentLoaded = duration ? player->maxTimeBuffered() /duration : 0; - - STPaintProgressIndicator(SafariTheme::MediaType, paintInfo.context->platformContext(), r, NSRegularControlSize, 0, percentLoaded); + if (HTMLMediaElement* mediaElement = parentMediaElement(o)) + STPaintProgressIndicator(SafariTheme::MediaType, paintInfo.context->platformContext(), r, NSRegularControlSize, 0, mediaElement->percentLoaded()); break; } case MediaSliderThumb: diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp index 95de7a2..4cd7b43 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp @@ -297,7 +297,7 @@ void RenderMenuList::hidePopup() void RenderMenuList::valueChanged(unsigned listIndex, bool fireOnChange) { SelectElement* select = toSelectElement(static_cast<Element*>(node())); - select->setSelectedIndex(select->listToOptionIndex(listIndex), true, fireOnChange); + select->setSelectedIndexByUser(select->listToOptionIndex(listIndex), true, fireOnChange); } String RenderMenuList::itemText(unsigned listIndex) const diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp index f81018d..098932a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp @@ -214,6 +214,13 @@ RenderObject::~RenderObject() #endif } +RenderTheme* RenderObject::theme() const +{ + ASSERT(document()->page()); + + return document()->page()->theme(); +} + bool RenderObject::isDescendantOf(const RenderObject* obj) const { for (const RenderObject* r = this; r; r = r->m_parent) { @@ -636,13 +643,16 @@ static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer* // Make sure we have a valid image. StyleImage* img = layer->image(); - bool shouldPaintBackgroundImage = img && img->canRender(renderer->style()->effectiveZoom()); + if (!img || !img->canRender(renderer->style()->effectiveZoom())) + return false; + + if (!layer->xPosition().isZero() || !layer->yPosition().isZero()) + return true; - // These are always percents or auto. - if (shouldPaintBackgroundImage && - (!layer->xPosition().isZero() || !layer->yPosition().isZero() || - layer->size().width().isPercent() || layer->size().height().isPercent())) - // The image will shift unpredictably if the size changes. + if (layer->isSizeSet()) { + if (layer->size().width().isPercent() || layer->size().height().isPercent()) + return true; + } else if (img->usesImageContainerSize()) return true; return false; @@ -1689,7 +1699,7 @@ void RenderObject::getTransformFromContainer(const RenderObject* containerObject transform.multLeft(layer->currentTransform()); #if ENABLE(3D_RENDERING) - if (containerObject && containerObject->style()->hasPerspective()) { + if (containerObject && containerObject->hasLayer() && containerObject->style()->hasPerspective()) { // Perpsective on the container affects us, so we have to factor it in here. ASSERT(containerObject->hasLayer()); FloatPoint perspectiveOrigin = toRenderBox(containerObject)->layer()->perspectiveOrigin(); @@ -1812,7 +1822,7 @@ void RenderObject::destroy() children->destroyLeftoverChildren(); // If this renderer is being autoscrolled, stop the autoscroll timer - if (document()->frame() && document()->frame()->eventHandler()->autoscrollRenderer() == this) + if (document()->frame()->eventHandler()->autoscrollRenderer() == this) document()->frame()->eventHandler()->stopAutoscrollTimer(true); if (m_hasCounterNodeMap) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderObject.h index 0901bff..311ef9c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderObject.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderObject.h @@ -48,6 +48,7 @@ class RenderInline; class RenderBlock; class RenderFlow; class RenderLayer; +class RenderTheme; class TransformState; class VisiblePosition; @@ -137,6 +138,8 @@ public: RenderObject(Node*); virtual ~RenderObject(); + RenderTheme* theme() const; + virtual const char* renderName() const = 0; RenderObject* parent() const { return m_parent; } @@ -273,6 +276,7 @@ public: virtual bool isTextControl() const { return false; } virtual bool isTextArea() const { return false; } virtual bool isTextField() const { return false; } + virtual bool isVideo() const { return false; } virtual bool isWidget() const { return false; } bool isRoot() const { return document()->documentElement() == m_node; } @@ -955,12 +959,14 @@ inline void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, R last->scheduleRelayout(); } -inline void makeMatrixRenderable(TransformationMatrix& matrix) +inline void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering) { #if !ENABLE(3D_RENDERING) + UNUSED_PARAM(has3DRendering); matrix.makeAffine(); #else - UNUSED_PARAM(matrix); + if (!has3DRendering) + matrix.makeAffine(); #endif } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp index 5d9de1e..7a3aa64 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp @@ -142,6 +142,24 @@ static inline bool shouldUseEmbedDescendant(HTMLObjectElement* objectElement, co #endif } +static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues) +{ + // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e. Real and WMP + // require "src" attribute). + int srcIndex = -1, dataIndex = -1; + for (unsigned int i = 0; i < paramNames->size(); ++i) { + if (equalIgnoringCase((*paramNames)[i], "src")) + srcIndex = i; + else if (equalIgnoringCase((*paramNames)[i], "data")) + dataIndex = i; + } + + if (srcIndex == -1 && dataIndex != -1) { + paramNames->append("src"); + paramValues->append((*paramValues)[dataIndex]); + } +} + void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins) { String url; @@ -238,6 +256,8 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins) } } + mapDataParamToSrc(¶mNames, ¶mValues); + // If we still don't have a type, try to map from a specific CLASSID to a type. if (serviceType.isEmpty()) serviceType = serviceTypeForClassId(o->classId(), pluginData); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderReplica.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderReplica.cpp index e805298..5fa3c62 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderReplica.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderReplica.cpp @@ -72,9 +72,8 @@ 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, - true, PaintRestrictionNone, 0, 0, - true, // appliedTransform - true); // temporaryClipRects + PaintRestrictionNone, 0, 0, + RenderLayer::PaintLayerHaveTransparency | RenderLayer::PaintLayerAppliedTransform | RenderLayer::PaintLayerTemporaryClipRects | RenderLayer::PaintLayerPaintingReflection); else if (paintInfo.phase == PaintPhaseMask) paintMask(paintInfo, tx, ty); } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.h b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.h index 524c4e8..245d750 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbar.h @@ -70,6 +70,7 @@ public: IntRect trackPieceRectWithMargins(ScrollbarPart, const IntRect&); int minimumThumbLength(); + virtual bool isCustomScrollbar() const { return true; } private: PassRefPtr<RenderStyle> getScrollbarPseudoStyle(ScrollbarPart, PseudoId); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp index 105cdf7..48b0d1c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp @@ -285,6 +285,9 @@ void RenderTable::layout() if (collapsing) section->recalcOuterBorder(); ASSERT(!section->needsLayout()); + } else if (child->isTableCol()) { + child->layoutIfNeeded(); + ASSERT(!child->needsLayout()); } } @@ -511,16 +514,9 @@ void RenderTable::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty) ty += captionHeight; } - int my = max(ty, paintInfo.rect.y()); - int mh; - if (ty < paintInfo.rect.y()) - mh = max(0, h - (paintInfo.rect.y() - ty)); - else - mh = min(paintInfo.rect.height(), h); - paintBoxShadow(paintInfo.context, tx, ty, w, h, style()); - paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), my, mh, tx, ty, w, h); + paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, w, h); if (style()->hasBorder() && !collapseBorders()) paintBorder(paintInfo.context, tx, ty, w, h, style()); @@ -542,14 +538,7 @@ void RenderTable::paintMask(PaintInfo& paintInfo, int tx, int ty) ty += captionHeight; } - int my = max(ty, paintInfo.rect.y()); - int mh; - if (ty < paintInfo.rect.y()) - mh = max(0, h - (paintInfo.rect.y() - ty)); - else - mh = min(paintInfo.rect.height(), h); - - paintMaskImages(paintInfo, my, mh, tx, ty, w, h); + paintMaskImages(paintInfo, tx, ty, w, h); } void RenderTable::calcPrefWidths() diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp index 81c96f1..9b02c9d 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp @@ -818,10 +818,6 @@ void RenderTableCell::paintBackgroundsBehindCell(PaintInfo& paintInfo, int tx, i int w = width(); int h = height(); - int my = max(ty, paintInfo.rect.y()); - int end = min(paintInfo.rect.bottom(), ty + h); - int mh = end - my; - Color c = backgroundObject->style()->backgroundColor(); const FillLayer* bgLayer = backgroundObject->style()->backgroundLayers(); @@ -835,7 +831,7 @@ void RenderTableCell::paintBackgroundsBehindCell(PaintInfo& paintInfo, int tx, i paintInfo.context->save(); paintInfo.context->clip(clipRect); } - paintFillLayers(paintInfo, c, bgLayer, my, mh, tx, ty, w, h); + paintFillLayers(paintInfo, c, bgLayer, tx, ty, w, h); if (shouldClip) paintInfo.context->restore(); } @@ -874,11 +870,7 @@ void RenderTableCell::paintMask(PaintInfo& paintInfo, int tx, int ty) int w = width(); int h = height(); - int my = max(ty, paintInfo.rect.y()); - int end = min(paintInfo.rect.bottom(), ty + h); - int mh = end - my; - - paintMaskImages(paintInfo, my, mh, tx, ty, w, h); + paintMaskImages(paintInfo, tx, ty, w, h); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.cpp index f17963c..d9a4172 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.cpp @@ -75,11 +75,8 @@ IntRect RenderTableCol::clippedOverflowRectForRepaint(RenderBoxModelObject* repa // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we // might have propagated a background color or borders into. // FIXME: check for repaintContainer each time here? - RenderObject* table = parent(); - if (table && !table->isTable()) - table = table->parent(); - if (table && table->isTable()) - return table->clippedOverflowRectForRepaint(repaintContainer); + if (RenderObject* parentTable = table()) + return parentTable->clippedOverflowRectForRepaint(repaintContainer); return IntRect(); } @@ -90,4 +87,20 @@ void RenderTableCol::imageChanged(WrappedImagePtr, const IntRect*) repaint(); } +void RenderTableCol::calcPrefWidths() +{ + setPrefWidthsDirty(false); + + for (RenderObject* child = firstChild(); child; child = child->nextSibling()) + child->setPrefWidthsDirty(false); +} + +RenderTable* RenderTableCol::table() const +{ + RenderObject* table = parent(); + if (table && !table->isTable()) + table = table->parent(); + return table && table->isTable() ? static_cast<RenderTable*>(table) : 0; +} + } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.h b/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.h index 8c494b2..6b17ec4 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableCol.h @@ -29,6 +29,7 @@ #define RenderTableCol_h #include "RenderBox.h" +#include "RenderTable.h" namespace WebCore { @@ -54,10 +55,14 @@ public: virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer); virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); + virtual void calcPrefWidths(); + int span() const { return m_span; } void setSpan(int s) { m_span = s; } - + private: + RenderTable* table() const; + RenderObjectChildList m_children; int m_span; }; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp index ea6f8b1..29c8c8a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp @@ -248,9 +248,11 @@ void RenderTextControl::setSelectionRange(int start, int end) else endPosition = visiblePositionForIndex(end); - ASSERT(startPosition.isNotNull() && endPosition.isNotNull()); - ASSERT(startPosition.deepEquivalent().node()->shadowAncestorNode() == node() && endPosition.deepEquivalent().node()->shadowAncestorNode() == node()); - + // startPosition and endPosition can be null position for example when + // "-webkit-user-select: none" style attribute is specified. + if (startPosition.isNotNull() && endPosition.isNotNull()) { + ASSERT(startPosition.deepEquivalent().node()->shadowAncestorNode() == node() && endPosition.deepEquivalent().node()->shadowAncestorNode() == node()); + } VisibleSelection newSelection = VisibleSelection(startPosition, endPosition); if (Frame* frame = document()->frame()) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp index 7ff251c..df31c2b 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp @@ -48,6 +48,9 @@ void RenderTextControlMultiLine::subtreeHasChanged() if (!node()->focused()) return; + // Fire the "input" DOM event + node()->dispatchEvent(eventNames().inputEvent, true, false); + if (Frame* frame = document()->frame()) frame->textDidChangeInTextArea(static_cast<Element*>(node())); } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp index b75ace9..a5db44e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp @@ -223,17 +223,12 @@ void RenderTextControlSingleLine::layout() int desiredHeight = textBlockHeight(); int currentHeight = innerTextRenderer->height(); - if (m_innerBlock || currentHeight > height()) { + if (currentHeight > height()) { if (desiredHeight != currentHeight) relayoutChildren = true; innerTextRenderer->style()->setHeight(Length(desiredHeight, Fixed)); - } - - if (m_innerBlock) { - ASSERT(innerBlockRenderer); - if (desiredHeight != innerBlockRenderer->height()) - relayoutChildren = true; - innerBlockRenderer->style()->setHeight(Length(desiredHeight, Fixed)); + if (m_innerBlock) + innerBlockRenderer->style()->setHeight(Length(desiredHeight, Fixed)); } // Set the text block width @@ -251,13 +246,11 @@ void RenderTextControlSingleLine::layout() RenderBlock::layoutBlock(relayoutChildren); - // For text fields, center the inner text vertically - // Don't do this for search fields, since we don't honor height for them - if (!m_innerBlock) { - currentHeight = innerTextRenderer->height(); - if (currentHeight < height()) - innerTextRenderer->setLocation(innerTextRenderer->x(), (height() - currentHeight) / 2); - } + // Center the child block vertically + RenderBox* childBlock = innerBlockRenderer ? innerBlockRenderer : innerTextRenderer; + currentHeight = childBlock->height(); + if (currentHeight < height()) + childBlock->setLocation(childBlock->x(), (height() - currentHeight) / 2); } bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction hitTestAction) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp index e67e612..517d911 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp @@ -62,7 +62,7 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El else if (style->display() == COMPACT || style->display() == RUN_IN || style->display() == LIST_ITEM || style->display() == TABLE) style->setDisplay(BLOCK); - if (UAHasAppearance && theme()->isControlStyled(style, border, background, backgroundColor)) { + if (UAHasAppearance && isControlStyled(style, border, background, backgroundColor)) { if (part == MenulistPart) { style->setAppearance(MenulistButtonPart); part = MenulistButtonPart; @@ -849,4 +849,9 @@ Color RenderTheme::platformInactiveTextSearchHighlightColor() const return Color(255, 255, 0); // Yellow. } +Color RenderTheme::focusRingColor() const +{ + return Color(0, 0, 0); // Black. +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h index bc81d4d..a1519ce 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h @@ -23,13 +23,16 @@ #ifndef RenderTheme_h #define RenderTheme_h -#include "RenderObject.h" #if USE(NEW_THEME) #include "Theme.h" #else #include "ThemeTypes.h" #endif +#include "RenderObject.h" +#include "RenderTheme.h" #include "ScrollTypes.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> namespace WebCore { @@ -38,11 +41,24 @@ class PopupMenu; class RenderMenuList; class CSSStyleSheet; -class RenderTheme { -public: +class RenderTheme : public RefCounted<RenderTheme> { +protected: RenderTheme(); + +public: virtual ~RenderTheme() { } + // This function is to be implemented in your platform-specific theme implementation to hand back the + // appropriate platform theme. When the theme is needed in non-page dependent code, a default theme is + // used as fallback, which is returned for a nulled page, so the platform code needs to account for this. + static PassRefPtr<RenderTheme> themeForPage(Page* page); + + // When the theme is needed in non-page dependent code, the defaultTheme() is used as fallback. + static inline PassRefPtr<RenderTheme> defaultTheme() + { + return themeForPage(0); + }; + // This method is called whenever style has been computed for an element and the appearance // property has been set to a value other than "none". The theme should map in all of the appropriate // metrics and defaults given the contents of the style. This includes sophisticated operations like @@ -121,6 +137,8 @@ public: virtual Color platformActiveTextSearchHighlightColor() const; virtual Color platformInactiveTextSearchHighlightColor() const; + virtual Color focusRingColor() const; + virtual void platformColorsDidChange(); virtual double caretBlinkInterval() const { return 0.5; } @@ -257,10 +275,6 @@ private: #endif }; -// Function to obtain the theme. This is implemented in your platform-specific theme implementation to hand -// back the appropriate platform theme. -RenderTheme* theme(); - } // namespace WebCore #endif // RenderTheme_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp index 94ee64f..c4020d3 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2007 Alp Toker <alp@atoker.com> * Copyright (C) 2008 Collabora Ltd. * Copyright (C) 2008, 2009 Google Inc. + * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -24,541 +25,45 @@ #include "config.h" #include "RenderThemeChromiumLinux.h" -#include "ChromiumBridge.h" +#include "Color.h" #include "CSSValueKeywords.h" -#include "GraphicsContext.h" -#include "HTMLMediaElement.h" -#include "HTMLNames.h" -#include "Image.h" -#include "MediaControlElements.h" -#include "PlatformContextSkia.h" -#include "RenderBox.h" #include "RenderObject.h" -#include "ScrollbarTheme.h" -#include "TransformationMatrix.h" #include "UserAgentStyleSheets.h" -#include "SkShader.h" -#include "SkGradientShader.h" - namespace WebCore { -enum PaddingType { - TopPadding, - RightPadding, - BottomPadding, - LeftPadding -}; - -static const int styledMenuListInternalPadding[4] = { 1, 4, 1, 4 }; - -// The default variable-width font size. We use this as the default font -// size for the "system font", and as a base size (which we then shrink) for -// form control fonts. -static const float defaultFontSize = 16.0; - -// The background for the media player controls should be a 60% opaque black rectangle. This -// matches the UI mockups for the default UI theme. -static const float defaultMediaControlOpacity = 0.6f; - -// These values all match Safari/Win. -static const float defaultControlFontPixelSize = 13; -static const float defaultCancelButtonSize = 9; -static const float minCancelButtonSize = 5; -static const float maxCancelButtonSize = 21; -static const float defaultSearchFieldResultsDecorationSize = 13; -static const float minSearchFieldResultsDecorationSize = 9; -static const float maxSearchFieldResultsDecorationSize = 30; -static const float defaultSearchFieldResultsButtonWidth = 18; - -static bool supportsFocus(ControlPart appearance) -{ - // This causes WebKit to draw the focus rings for us. - return false; -} - -static void setSizeIfAuto(RenderStyle* style, const IntSize& size) -{ - if (style->width().isIntrinsicOrAuto()) - style->setWidth(Length(size.width(), Fixed)); - if (style->height().isAuto()) - style->setHeight(Length(size.height(), Fixed)); -} - -// We aim to match IE here. -// -IE uses a font based on the encoding as the default font for form controls. -// -Gecko uses MS Shell Dlg (actually calls GetStockObject(DEFAULT_GUI_FONT), -// which returns MS Shell Dlg) -// -Safari uses Lucida Grande. -// -// FIXME: The only case where we know we don't match IE is for ANSI encodings. -// IE uses MS Shell Dlg there, which we render incorrectly at certain pixel -// sizes (e.g. 15px). So, for now we just use Arial. -static const char* defaultGUIFont() -{ - return "Arial"; -} - -#if ENABLE(VIDEO) -// Attempt to retrieve a HTMLMediaElement from a Node. Returns NULL if one cannot be found. -static HTMLMediaElement* mediaElementParent(Node* node) +PassRefPtr<RenderTheme> RenderThemeChromiumLinux::create() { - if (!node) - return 0; - Node* mediaNode = node->shadowAncestorNode(); - if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag))) - return 0; - - return static_cast<HTMLMediaElement*>(mediaNode); + return adoptRef(new RenderThemeChromiumLinux()); } -#endif -RenderTheme* theme() +PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) { - static RenderThemeChromiumLinux theme; - return &theme; + static RenderTheme* rt = RenderThemeChromiumLinux::create().releaseRef(); + return rt; } RenderThemeChromiumLinux::RenderThemeChromiumLinux() { } -// Use the Windows style sheets to match their metrics. -String RenderThemeChromiumLinux::extraDefaultStyleSheet() +RenderThemeChromiumLinux::~RenderThemeChromiumLinux() { - return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet)); } -String RenderThemeChromiumLinux::extraQuirksStyleSheet() +Color RenderThemeChromiumLinux::systemColor(int cssValueId) const { - return String(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet)); -} + static const Color linuxButtonGrayColor(0xffdddddd); -#if ENABLE(VIDEO) -String RenderThemeChromiumLinux::extraMediaControlsStyleSheet() -{ - return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet)); -} -#endif - -bool RenderThemeChromiumLinux::supportsFocusRing(const RenderStyle* style) const -{ - return supportsFocus(style->appearance()); -} - -Color RenderThemeChromiumLinux::platformActiveSelectionBackgroundColor() const -{ - return Color(0x1e, 0x90, 0xff); -} - -Color RenderThemeChromiumLinux::platformInactiveSelectionBackgroundColor() const -{ - return Color(0xc8, 0xc8, 0xc8); -} - -Color RenderThemeChromiumLinux::platformActiveSelectionForegroundColor() const -{ - return Color::black; -} - -Color RenderThemeChromiumLinux::platformInactiveSelectionForegroundColor() const -{ - return Color(0x32, 0x32, 0x32); -} - -Color RenderThemeChromiumLinux::platformTextSearchHighlightColor() const -{ - return Color(0xff, 0xff, 0x96); -} - -double RenderThemeChromiumLinux::caretBlinkInterval() const -{ - // Disable the blinking caret in layout test mode, as it introduces - // a race condition for the pixel tests. http://b/1198440 - if (ChromiumBridge::layoutTestMode()) - return 0; - - // We cache the interval so we don't have to repeatedly request it from gtk. - return 0.5; -} - -void RenderThemeChromiumLinux::systemFont(int propId, FontDescription& fontDescription) const -{ - float fontSize = defaultFontSize; - - switch (propId) { - case CSSValueWebkitMiniControl: - case CSSValueWebkitSmallControl: - case CSSValueWebkitControl: - // Why 2 points smaller? Because that's what Gecko does. Note that we - // are assuming a 96dpi screen, which is the default that we use on - // Windows. - static const float pointsPerInch = 72.0f; - static const float pixelsPerInch = 96.0f; - fontSize -= (2.0f / pointsPerInch) * pixelsPerInch; - break; - } - - fontDescription.firstFamily().setFamily(defaultGUIFont()); - fontDescription.setSpecifiedSize(fontSize); - fontDescription.setIsAbsoluteSize(true); - fontDescription.setGenericFamily(FontDescription::NoFamily); - fontDescription.setWeight(FontWeightNormal); - fontDescription.setItalic(false); -} - -int RenderThemeChromiumLinux::minimumMenuListSize(RenderStyle* style) const -{ - return 0; -} - -bool RenderThemeChromiumLinux::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) -{ - static Image* const checkedImage = Image::loadPlatformResource("linuxCheckboxOn").releaseRef(); - static Image* const uncheckedImage = Image::loadPlatformResource("linuxCheckboxOff").releaseRef(); - - Image* image = this->isChecked(o) ? checkedImage : uncheckedImage; - i.context->drawImage(image, rect); - return false; -} - -void RenderThemeChromiumLinux::setCheckboxSize(RenderStyle* style) const -{ - // If the width and height are both specified, then we have nothing to do. - if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) - return; - - // FIXME: A hard-coded size of 13 is used. This is wrong but necessary - // for now. It matches Firefox. At different DPI settings on Windows, - // querying the theme gives you a larger size that accounts for the higher - // DPI. Until our entire engine honors a DPI setting other than 96, we - // can't rely on the theme's metrics. - const IntSize size(13, 13); - setSizeIfAuto(style, size); -} - -bool RenderThemeChromiumLinux::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) -{ - static Image* const checkedImage = Image::loadPlatformResource("linuxRadioOn").releaseRef(); - static Image* const uncheckedImage = Image::loadPlatformResource("linuxRadioOff").releaseRef(); - - Image* image = this->isChecked(o) ? checkedImage : uncheckedImage; - i.context->drawImage(image, rect); - return false; -} - -void RenderThemeChromiumLinux::setRadioSize(RenderStyle* style) const -{ - // Use same sizing for radio box as checkbox. - setCheckboxSize(style); -} - -static void paintButtonLike(RenderTheme* theme, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) { - SkCanvas* const canvas = i.context->platformContext()->canvas(); - SkPaint paint; - SkRect skrect; - const int right = rect.x() + rect.width(); - const int bottom = rect.y() + rect.height(); - - // If the button is too small, fallback to drawing a single, solid color - if (rect.width() < 5 || rect.height() < 5) { - paint.setARGB(0xff, 0xe9, 0xe9, 0xe9); - skrect.set(rect.x(), rect.y(), right, bottom); - canvas->drawRect(skrect, paint); - return; - } - - const int borderAlpha = theme->isHovered(o) ? 0x80 : 0x55; - paint.setARGB(borderAlpha, 0, 0, 0); - canvas->drawLine(rect.x() + 1, rect.y(), right - 1, rect.y(), paint); - canvas->drawLine(right - 1, rect.y() + 1, right - 1, bottom - 1, paint); - canvas->drawLine(rect.x() + 1, bottom - 1, right - 1, bottom - 1, paint); - canvas->drawLine(rect.x(), rect.y() + 1, rect.x(), bottom - 1, paint); - - paint.setARGB(0xff, 0, 0, 0); - SkPoint p[2]; - const int lightEnd = theme->isPressed(o) ? 1 : 0; - const int darkEnd = !lightEnd; - p[lightEnd].set(SkIntToScalar(rect.x()), SkIntToScalar(rect.y())); - p[darkEnd].set(SkIntToScalar(rect.x()), SkIntToScalar(bottom - 1)); - SkColor colors[2]; - colors[0] = SkColorSetARGB(0xff, 0xf8, 0xf8, 0xf8); - colors[1] = SkColorSetARGB(0xff, 0xdd, 0xdd, 0xdd); - - SkShader* s = SkGradientShader::CreateLinear( - p, colors, NULL, 2, SkShader::kClamp_TileMode, NULL); - paint.setStyle(SkPaint::kFill_Style); - paint.setShader(s); - s->unref(); - - skrect.set(rect.x() + 1, rect.y() + 1, right - 1, bottom - 1); - canvas->drawRect(skrect, paint); - - paint.setShader(NULL); - paint.setARGB(0xff, 0xce, 0xce, 0xce); - canvas->drawPoint(rect.x() + 1, rect.y() + 1, paint); - canvas->drawPoint(right - 2, rect.y() + 1, paint); - canvas->drawPoint(rect.x() + 1, bottom - 2, paint); - canvas->drawPoint(right - 2, bottom - 2, paint); -} - -bool RenderThemeChromiumLinux::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) -{ - paintButtonLike(this, o, i, rect); - return false; -} - -bool RenderThemeChromiumLinux::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) -{ - return true; -} - -void RenderThemeChromiumLinux::adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const -{ - // Scale the button size based on the font size - float fontScale = style->fontSize() / defaultControlFontPixelSize; - int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize)); - style->setWidth(Length(cancelButtonSize, Fixed)); - style->setHeight(Length(cancelButtonSize, Fixed)); + if (cssValueId == CSSValueButtonface) + return linuxButtonGrayColor; + return RenderTheme::systemColor(cssValueId); } -bool RenderThemeChromiumLinux::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) -{ - IntRect bounds = r; - ASSERT(o->parent()); - if (!o->parent() || !o->parent()->isBox()) - return false; - - RenderBox* parentRenderBox = toRenderBox(o->parent()); - - IntRect parentBox = parentRenderBox->absoluteContentBox(); - - // Make sure the scaled button stays square and will fit in its parent's box - bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height()))); - bounds.setWidth(bounds.height()); - - // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will - // be one pixel closer to the bottom of the field. This tends to look better with the text. - bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); - - static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef(); - static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef(); - i.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, bounds); - return false; -} - -void RenderThemeChromiumLinux::adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const -{ - IntSize emptySize(1, 11); - style->setWidth(Length(emptySize.width(), Fixed)); - style->setHeight(Length(emptySize.height(), Fixed)); -} - -void RenderThemeChromiumLinux::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const -{ - // Scale the decoration size based on the font size - float fontScale = style->fontSize() / defaultControlFontPixelSize; - int magnifierSize = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), - maxSearchFieldResultsDecorationSize)); - style->setWidth(Length(magnifierSize, Fixed)); - style->setHeight(Length(magnifierSize, Fixed)); -} - -bool RenderThemeChromiumLinux::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) -{ - IntRect bounds = r; - ASSERT(o->parent()); - if (!o->parent() || !o->parent()->isBox()) - return false; - - RenderBox* parentRenderBox = toRenderBox(o->parent()); - IntRect parentBox = parentRenderBox->absoluteContentBox(); - - // Make sure the scaled decoration stays square and will fit in its parent's box - bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height()))); - bounds.setWidth(bounds.height()); - - // Center the decoration vertically. Round up though, so if it has to be one pixel off-center, it will - // be one pixel closer to the bottom of the field. This tends to look better with the text. - bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); - - static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef(); - i.context->drawImage(magnifierImage, bounds); - return false; -} - -void RenderThemeChromiumLinux::adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const -{ - // Scale the button size based on the font size - float fontScale = style->fontSize() / defaultControlFontPixelSize; - int magnifierHeight = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), - maxSearchFieldResultsDecorationSize)); - int magnifierWidth = lroundf(magnifierHeight * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize); - style->setWidth(Length(magnifierWidth, Fixed)); - style->setHeight(Length(magnifierHeight, Fixed)); -} - -bool RenderThemeChromiumLinux::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) -{ - IntRect bounds = r; - ASSERT(o->parent()); - if (!o->parent()) - return false; - if (!o->parent() || !o->parent()->isBox()) - return false; - - RenderBox* parentRenderBox = toRenderBox(o->parent()); - IntRect parentBox = parentRenderBox->absoluteContentBox(); - - // Make sure the scaled decoration will fit in its parent's box - bounds.setHeight(std::min(parentBox.height(), bounds.height())); - bounds.setWidth(std::min(parentBox.width(), static_cast<int>(bounds.height() * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize))); - - // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will - // be one pixel closer to the bottom of the field. This tends to look better with the text. - bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); - - static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").releaseRef(); - i.context->drawImage(magnifierImage, bounds); - return false; -} - -bool RenderThemeChromiumLinux::paintMediaButtonInternal(GraphicsContext* context, const IntRect& rect, Image* image) -{ - context->beginTransparencyLayer(defaultMediaControlOpacity); - - // Draw background. - Color oldFill = context->fillColor(); - Color oldStroke = context->strokeColor(); - - context->setFillColor(Color::black); - context->setStrokeColor(Color::black); - context->drawRect(rect); - - context->setFillColor(oldFill); - context->setStrokeColor(oldStroke); - - // Create a destination rectangle for the image that is centered in the drawing rectangle, rounded left, and down. - IntRect imageRect = image->rect(); - imageRect.setY(rect.y() + (rect.height() - image->height() + 1) / 2); - imageRect.setX(rect.x() + (rect.width() - image->width() + 1) / 2); - - context->drawImage(image, imageRect, CompositeSourceAtop); - context->endTransparencyLayer(); - - return false; -} - -bool RenderThemeChromiumLinux::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) -{ -#if ENABLE(VIDEO) - HTMLMediaElement* mediaElement = mediaElementParent(o->node()); - if (!mediaElement) - return false; - - static Image* mediaPlay = Image::loadPlatformResource("mediaPlay").releaseRef(); - static Image* mediaPause = Image::loadPlatformResource("mediaPause").releaseRef(); - - return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->paused() ? mediaPlay : mediaPause); -#else - return false; -#endif -} - -bool RenderThemeChromiumLinux::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) -{ -#if ENABLE(VIDEO) - HTMLMediaElement* mediaElement = mediaElementParent(o->node()); - if (!mediaElement) - return false; - - static Image* soundFull = Image::loadPlatformResource("mediaSoundFull").releaseRef(); - static Image* soundNone = Image::loadPlatformResource("mediaSoundNone").releaseRef(); - - return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->muted() ? soundNone: soundFull); -#else - return false; -#endif -} - -void RenderThemeChromiumLinux::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const -{ - // Height is locked to auto on all browsers. - style->setLineHeight(RenderStyle::initialLineHeight()); -} - -bool RenderThemeChromiumLinux::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) -{ - SkCanvas* const canvas = i.context->platformContext()->canvas(); - const int right = rect.x() + rect.width(); - const int middle = rect.y() + rect.height() / 2; - - paintButtonLike(this, o, i, rect); - - SkPaint paint; - paint.setARGB(0xff, 0, 0, 0); - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kFill_Style); - - SkPath path; - path.moveTo(right - 13, middle - 3); - path.rLineTo(6, 0); - path.rLineTo(-3, 6); - path.close(); - canvas->drawPath(path, paint); - - return false; -} - -void RenderThemeChromiumLinux::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const -{ - adjustMenuListStyle(selector, style, e); -} - -// Used to paint styled menulists (i.e. with a non-default border) -bool RenderThemeChromiumLinux::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) -{ - return paintMenuList(o, i, rect); -} - -int RenderThemeChromiumLinux::popupInternalPaddingLeft(RenderStyle* style) const -{ - return menuListInternalPadding(style, LeftPadding); -} - -int RenderThemeChromiumLinux::popupInternalPaddingRight(RenderStyle* style) const -{ - return menuListInternalPadding(style, RightPadding); -} - -int RenderThemeChromiumLinux::popupInternalPaddingTop(RenderStyle* style) const -{ - return menuListInternalPadding(style, TopPadding); -} - -int RenderThemeChromiumLinux::popupInternalPaddingBottom(RenderStyle* style) const -{ - return menuListInternalPadding(style, BottomPadding); -} - -int RenderThemeChromiumLinux::buttonInternalPaddingLeft() const -{ - return 3; -} - -int RenderThemeChromiumLinux::buttonInternalPaddingRight() const -{ - return 3; -} - -int RenderThemeChromiumLinux::buttonInternalPaddingTop() const -{ - return 1; -} - -int RenderThemeChromiumLinux::buttonInternalPaddingBottom() const +String RenderThemeChromiumLinux::extraDefaultStyleSheet() { - return 1; + return RenderThemeChromiumSkia::extraDefaultStyleSheet() + + String(themeChromiumLinuxUserAgentStyleSheet, sizeof(themeChromiumLinuxUserAgentStyleSheet)); } bool RenderThemeChromiumLinux::controlSupportsTints(const RenderObject* o) const @@ -586,22 +91,9 @@ Color RenderThemeChromiumLinux::inactiveListBoxSelectionForegroundColor() const return Color(0x32, 0x32, 0x32); } -int RenderThemeChromiumLinux::menuListInternalPadding(RenderStyle* style, int paddingType) const +bool RenderThemeChromiumLinux::supportsControlTints() const { - // This internal padding is in addition to the user-supplied padding. - // Matches the FF behavior. - int padding = styledMenuListInternalPadding[paddingType]; - - // Reserve the space for right arrow here. The rest of the padding is - // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from - // RenderMenuList to lay out the individual items in the popup. - // If the MenuList actually has appearance "NoAppearance", then that means - // we don't draw a button, so don't reserve space for it. - const int bar_type = style->direction() == LTR ? RightPadding : LeftPadding; - if (paddingType == bar_type && style->appearance() != NoControlPart) - padding += ScrollbarTheme::nativeTheme()->scrollbarThickness(); - - return padding; + return true; } -} // namespace WebCore +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h index 7838509..e75ddd5 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h @@ -7,6 +7,7 @@ * Copyright (C) 2007 Alp Toker <alp@atoker.com> * Copyright (C) 2008, 2009 Google, Inc. * All rights reserved. + * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,100 +29,20 @@ #ifndef RenderThemeChromiumLinux_h #define RenderThemeChromiumLinux_h -#include "RenderTheme.h" +#include "RenderThemeChromiumSkia.h" namespace WebCore { - class RenderThemeChromiumLinux : public RenderTheme { + class RenderThemeChromiumLinux : public RenderThemeChromiumSkia { public: - RenderThemeChromiumLinux(); - ~RenderThemeChromiumLinux() { } - + static PassRefPtr<RenderTheme> create(); virtual String extraDefaultStyleSheet(); - virtual String extraQuirksStyleSheet(); -#if ENABLE(VIDEO) - virtual String extraMediaControlsStyleSheet(); -#endif - - // A method asking if the theme's controls actually care about redrawing when hovered. - virtual bool supportsHover(const RenderStyle*) const { return true; } - - // A method asking if the theme is able to draw the focus ring. - virtual bool supportsFocusRing(const RenderStyle*) const; - - // The platform selection color. - virtual Color platformActiveSelectionBackgroundColor() const; - virtual Color platformInactiveSelectionBackgroundColor() const; - virtual Color platformActiveSelectionForegroundColor() const; - virtual Color platformInactiveSelectionForegroundColor() const; - virtual Color platformTextSearchHighlightColor() const; - - virtual double caretBlinkInterval() const; - - // System fonts. - virtual void systemFont(int propId, FontDescription&) const; - - virtual int minimumMenuListSize(RenderStyle*) const; - - virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void setCheckboxSize(RenderStyle*) const; - - virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void setRadioSize(RenderStyle*) const; - - virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual bool paintTextArea(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); } - virtual bool paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); } - - virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - // MenuList refers to an unstyled menulist (meaning a menulist without - // background-color or border set) and MenuListButton refers to a styled - // menulist (a menulist with background-color or border set). They have - // this distinction to support showing aqua style themes whenever they - // possibly can, which is something we don't want to replicate. - // - // In short, we either go down the MenuList code path or the MenuListButton - // codepath. We never go down both. And in both cases, they render the - // entire menulist. - virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - // These methods define the padding for the MenuList's inner block. - virtual int popupInternalPaddingLeft(RenderStyle*) const; - virtual int popupInternalPaddingRight(RenderStyle*) const; - virtual int popupInternalPaddingTop(RenderStyle*) const; - virtual int popupInternalPaddingBottom(RenderStyle*) const; - - virtual int buttonInternalPaddingLeft() const; - virtual int buttonInternalPaddingRight() const; - virtual int buttonInternalPaddingTop() const; - virtual int buttonInternalPaddingBottom() const; + virtual Color systemColor(int cssValidId) const; // A method asking if the control changes its tint when the window has focus or not. virtual bool controlSupportsTints(const RenderObject*) const; - // A general method asking if any control tinting is supported at all. - virtual bool supportsControlTints() const { return true; } - // List Box selection color virtual Color activeListBoxSelectionBackgroundColor() const; virtual Color activeListBoxSelectionForegroundColor() const; @@ -129,10 +50,13 @@ namespace WebCore { virtual Color inactiveListBoxSelectionForegroundColor() const; private: - int menuListInternalPadding(RenderStyle*, int paddingType) const; - bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*); + RenderThemeChromiumLinux(); + virtual ~RenderThemeChromiumLinux(); + + // A general method asking if any control tinting is supported at all. + virtual bool supportsControlTints() const; }; } // namespace WebCore -#endif +#endif // RenderThemeChromiumLinux_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h index f072000..5497d52 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h @@ -3,6 +3,7 @@ * * Copyright (C) 2005 Apple Computer, Inc. * Copyright (C) 2008, 2009 Google, Inc. + * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -41,8 +42,7 @@ namespace WebCore { class RenderThemeChromiumMac : public RenderTheme { public: - RenderThemeChromiumMac(); - virtual ~RenderThemeChromiumMac(); + static PassRefPtr<RenderTheme> create(); // A method to obtain the baseline position for a "leaf" control. This will only be used if a baseline // position cannot be determined by examining child content. Checkboxes and radio buttons are examples of @@ -63,6 +63,8 @@ namespace WebCore { virtual Color platformActiveSelectionBackgroundColor() const; virtual Color platformInactiveSelectionBackgroundColor() const; virtual Color activeListBoxSelectionBackgroundColor() const; + + virtual Color focusRingColor() const; virtual void platformColorsDidChange(); @@ -140,6 +142,9 @@ namespace WebCore { virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); private: + RenderThemeChromiumMac(); + virtual ~RenderThemeChromiumMac(); + IntRect inflateRect(const IntRect&, const IntSize&, const int* margins, float zoomLevel = 1.0f) const; // Get the control size based off the font. Used by some of the controls (like buttons). diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm index f6081a5..bd90831 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm @@ -1,6 +1,7 @@ /* * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2008, 2009 Google, Inc. + * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -31,6 +32,8 @@ #import <math.h> #import "BitmapImage.h" +#import "ChromiumBridge.h" +#import "ColorMac.h" #import "CSSStyleSelector.h" #import "CSSValueKeywords.h" #import "Element.h" @@ -124,10 +127,15 @@ IntRect NSRectToIntRect(const NSRect & rect) return IntRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); } -RenderTheme* theme() +PassRefPtr<RenderTheme> RenderThemeChromiumMac::create() { - static RenderThemeChromiumMac* macTheme = new RenderThemeChromiumMac; - return macTheme; + return adoptRef(new RenderThemeChromiumMac); +} + +PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) +{ + static RenderTheme* rt = RenderThemeChromiumMac::create().releaseRef(); + return rt; } RenderThemeChromiumMac::RenderThemeChromiumMac() @@ -164,6 +172,14 @@ Color RenderThemeChromiumMac::activeListBoxSelectionBackgroundColor() const return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent])); } +Color RenderThemeChromiumMac::focusRingColor() const +{ + if (ChromiumBridge::layoutTestMode()) + return oldAquaFocusRingColor(); + + return systemColor(CSSValueWebkitFocusRingColor); +} + static FontWeight toFontWeight(NSInteger appKitFontWeight) { ASSERT(appKitFontWeight > 0 && appKitFontWeight < 15); @@ -416,6 +432,9 @@ Color RenderThemeChromiumMac::systemColor(int cssValueId) const case CSSValueThreedlightshadow: color = convertNSColorToColor([NSColor controlLightHighlightColor]); break; + case CSSValueWebkitFocusRingColor: + color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]); + break; case CSSValueWindow: color = convertNSColorToColor([NSColor windowBackgroundColor]); break; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp index bf217c8..1fb0cb2 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp @@ -1,2 +1,619 @@ -// FIXME: This is a placeholder to avoid some issues with webkit.gyp in the chromium tree. Having this placeholder until we can factor out -// RenderThemeChromiumSkia from RenderThemeChromiumLinux will keep the HEAD of both trees compatible. +/* + * Copyright (C) 2007 Apple Inc. + * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2008, 2009 Google Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "RenderThemeChromiumSkia.h" + +#include "ChromiumBridge.h" +#include "CSSValueKeywords.h" +#include "GraphicsContext.h" +#include "HTMLMediaElement.h" +#include "HTMLNames.h" +#include "Image.h" +#include "MediaControlElements.h" +#include "PlatformContextSkia.h" +#include "RenderBox.h" +#include "RenderObject.h" +#include "ScrollbarTheme.h" +#include "TransformationMatrix.h" +#include "UserAgentStyleSheets.h" + +#include "SkShader.h" +#include "SkGradientShader.h" + +namespace WebCore { + +enum PaddingType { + TopPadding, + RightPadding, + BottomPadding, + LeftPadding +}; + +static const int styledMenuListInternalPadding[4] = { 1, 4, 1, 4 }; + +// The background for the media player controls should be a 60% opaque black rectangle. This +// matches the UI mockups for the default UI theme. +static const float defaultMediaControlOpacity = 0.6f; + +// These values all match Safari/Win. +static const float defaultControlFontPixelSize = 13; +static const float defaultCancelButtonSize = 9; +static const float minCancelButtonSize = 5; +static const float maxCancelButtonSize = 21; +static const float defaultSearchFieldResultsDecorationSize = 13; +static const float minSearchFieldResultsDecorationSize = 9; +static const float maxSearchFieldResultsDecorationSize = 30; +static const float defaultSearchFieldResultsButtonWidth = 18; + +static void setSizeIfAuto(RenderStyle* style, const IntSize& size) +{ + if (style->width().isIntrinsicOrAuto()) + style->setWidth(Length(size.width(), Fixed)); + if (style->height().isAuto()) + style->setHeight(Length(size.height(), Fixed)); +} + +#if ENABLE(VIDEO) +// Attempt to retrieve a HTMLMediaElement from a Node. Returns NULL if one cannot be found. +static HTMLMediaElement* mediaElementParent(Node* node) +{ + if (!node) + return 0; + Node* mediaNode = node->shadowAncestorNode(); + if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag))) + return 0; + + return static_cast<HTMLMediaElement*>(mediaNode); +} +#endif + +// We aim to match IE here. +// -IE uses a font based on the encoding as the default font for form controls. +// -Gecko uses MS Shell Dlg (actually calls GetStockObject(DEFAULT_GUI_FONT), +// which returns MS Shell Dlg) +// -Safari uses Lucida Grande. +// +// FIXME: The only case where we know we don't match IE is for ANSI encodings. +// IE uses MS Shell Dlg there, which we render incorrectly at certain pixel +// sizes (e.g. 15px). So, for now we just use Arial. +const String& RenderThemeChromiumSkia::defaultGUIFont() +{ + DEFINE_STATIC_LOCAL(String, fontFace, ("Arial")); + return fontFace; +} + +float RenderThemeChromiumSkia::defaultFontSize = 16.0; + +RenderThemeChromiumSkia::RenderThemeChromiumSkia() +{ +} + +RenderThemeChromiumSkia::~RenderThemeChromiumSkia() +{ +} + +// Use the Windows style sheets to match their metrics. +String RenderThemeChromiumSkia::extraDefaultStyleSheet() +{ + return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet)); +} + +String RenderThemeChromiumSkia::extraQuirksStyleSheet() +{ + return String(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet)); +} + +#if ENABLE(VIDEO) +String RenderThemeChromiumSkia::extraMediaControlsStyleSheet() +{ + return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet)); +} +#endif + +bool RenderThemeChromiumSkia::supportsHover(const RenderStyle* style) const +{ + return true; +} + +bool RenderThemeChromiumSkia::supportsFocusRing(const RenderStyle* style) const +{ + // This causes WebKit to draw the focus rings for us. + return false; +} + +Color RenderThemeChromiumSkia::platformActiveSelectionBackgroundColor() const +{ + return Color(0x1e, 0x90, 0xff); +} + +Color RenderThemeChromiumSkia::platformInactiveSelectionBackgroundColor() const +{ + return Color(0xc8, 0xc8, 0xc8); +} + +Color RenderThemeChromiumSkia::platformActiveSelectionForegroundColor() const +{ + return Color::black; +} + +Color RenderThemeChromiumSkia::platformInactiveSelectionForegroundColor() const +{ + return Color(0x32, 0x32, 0x32); +} + +Color RenderThemeChromiumSkia::focusRingColor() const +{ + static Color focusRingColor(229, 151, 0, 255); + return focusRingColor; +} + +double RenderThemeChromiumSkia::caretBlinkInterval() const +{ + // Disable the blinking caret in layout test mode, as it introduces + // a race condition for the pixel tests. http://b/1198440 + if (ChromiumBridge::layoutTestMode()) + return 0; + + return caretBlinkIntervalInternal(); +} + +void RenderThemeChromiumSkia::systemFont(int propId, FontDescription& fontDescription) const +{ + float fontSize = defaultFontSize; + + switch (propId) { + case CSSValueWebkitMiniControl: + case CSSValueWebkitSmallControl: + case CSSValueWebkitControl: + // Why 2 points smaller? Because that's what Gecko does. Note that we + // are assuming a 96dpi screen, which is the default that we use on + // Windows. + static const float pointsPerInch = 72.0f; + static const float pixelsPerInch = 96.0f; + fontSize -= (2.0f / pointsPerInch) * pixelsPerInch; + break; + } + + fontDescription.firstFamily().setFamily(defaultGUIFont()); + fontDescription.setSpecifiedSize(fontSize); + fontDescription.setIsAbsoluteSize(true); + fontDescription.setGenericFamily(FontDescription::NoFamily); + fontDescription.setWeight(FontWeightNormal); + fontDescription.setItalic(false); +} + +int RenderThemeChromiumSkia::minimumMenuListSize(RenderStyle* style) const +{ + return 0; +} + +bool RenderThemeChromiumSkia::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +{ + static Image* const checkedImage = Image::loadPlatformResource("linuxCheckboxOn").releaseRef(); + static Image* const uncheckedImage = Image::loadPlatformResource("linuxCheckboxOff").releaseRef(); + + Image* image = this->isChecked(o) ? checkedImage : uncheckedImage; + i.context->drawImage(image, rect); + return false; +} + +void RenderThemeChromiumSkia::setCheckboxSize(RenderStyle* style) const +{ + // If the width and height are both specified, then we have nothing to do. + if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) + return; + + // FIXME: A hard-coded size of 13 is used. This is wrong but necessary + // for now. It matches Firefox. At different DPI settings on Windows, + // querying the theme gives you a larger size that accounts for the higher + // DPI. Until our entire engine honors a DPI setting other than 96, we + // can't rely on the theme's metrics. + const IntSize size(13, 13); + setSizeIfAuto(style, size); +} + +bool RenderThemeChromiumSkia::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +{ + static Image* const checkedImage = Image::loadPlatformResource("linuxRadioOn").releaseRef(); + static Image* const uncheckedImage = Image::loadPlatformResource("linuxRadioOff").releaseRef(); + + Image* image = this->isChecked(o) ? checkedImage : uncheckedImage; + i.context->drawImage(image, rect); + return false; +} + +void RenderThemeChromiumSkia::setRadioSize(RenderStyle* style) const +{ + // Use same sizing for radio box as checkbox. + setCheckboxSize(style); +} + +static SkColor brightenColor(double h, double s, double l, float brightenAmount) +{ + l += brightenAmount; + if (l > 1.0) + l = 1.0; + if (l < 0.0) + l = 0.0; + + return makeRGBAFromHSLA(h, s, l, 1.0); +} + +static void paintButtonLike(RenderTheme* theme, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +{ + SkCanvas* const canvas = i.context->platformContext()->canvas(); + SkPaint paint; + SkRect skrect; + const int right = rect.x() + rect.width(); + const int bottom = rect.y() + rect.height(); + SkColor baseColor = SkColorSetARGB(0xff, 0xdd, 0xdd, 0xdd); + if (o->style()->hasBackground()) + baseColor = o->style()->backgroundColor().rgb(); + double h, s, l; + Color(baseColor).getHSL(h, s, l); + // Our standard gradient is from 0xdd to 0xf8. This is the amount of + // increased luminance between those values. + SkColor lightColor(brightenColor(h, s, l, 0.105)); + + // If the button is too small, fallback to drawing a single, solid color + if (rect.width() < 5 || rect.height() < 5) { + paint.setColor(baseColor); + skrect.set(rect.x(), rect.y(), right, bottom); + canvas->drawRect(skrect, paint); + return; + } + + const int borderAlpha = theme->isHovered(o) ? 0x80 : 0x55; + paint.setARGB(borderAlpha, 0, 0, 0); + canvas->drawLine(rect.x() + 1, rect.y(), right - 1, rect.y(), paint); + canvas->drawLine(right - 1, rect.y() + 1, right - 1, bottom - 1, paint); + canvas->drawLine(rect.x() + 1, bottom - 1, right - 1, bottom - 1, paint); + canvas->drawLine(rect.x(), rect.y() + 1, rect.x(), bottom - 1, paint); + + paint.setARGB(0xff, 0, 0, 0); + SkPoint p[2]; + const int lightEnd = theme->isPressed(o) ? 1 : 0; + const int darkEnd = !lightEnd; + p[lightEnd].set(SkIntToScalar(rect.x()), SkIntToScalar(rect.y())); + p[darkEnd].set(SkIntToScalar(rect.x()), SkIntToScalar(bottom - 1)); + SkColor colors[2]; + colors[0] = lightColor; + colors[1] = baseColor; + + SkShader* shader = SkGradientShader::CreateLinear( + p, colors, NULL, 2, SkShader::kClamp_TileMode, NULL); + paint.setStyle(SkPaint::kFill_Style); + paint.setShader(shader); + shader->unref(); + + skrect.set(rect.x() + 1, rect.y() + 1, right - 1, bottom - 1); + canvas->drawRect(skrect, paint); + + paint.setShader(NULL); + paint.setColor(brightenColor(h, s, l, -0.0588)); + canvas->drawPoint(rect.x() + 1, rect.y() + 1, paint); + canvas->drawPoint(right - 2, rect.y() + 1, paint); + canvas->drawPoint(rect.x() + 1, bottom - 2, paint); + canvas->drawPoint(right - 2, bottom - 2, paint); +} + +bool RenderThemeChromiumSkia::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +{ + paintButtonLike(this, o, i, rect); + return false; +} + +bool RenderThemeChromiumSkia::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +{ + return true; +} + +bool RenderThemeChromiumSkia::paintTextArea(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +{ + return paintTextField(o, i, r); +} + +bool RenderThemeChromiumSkia::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +{ + return paintTextField(o, i, r); +} + +void RenderThemeChromiumSkia::adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const +{ + // Scale the button size based on the font size + float fontScale = style->fontSize() / defaultControlFontPixelSize; + int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize)); + style->setWidth(Length(cancelButtonSize, Fixed)); + style->setHeight(Length(cancelButtonSize, Fixed)); +} + +bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +{ + IntRect bounds = r; + ASSERT(o->parent()); + if (!o->parent() || !o->parent()->isBox()) + return false; + + RenderBox* parentRenderBox = toRenderBox(o->parent()); + + IntRect parentBox = parentRenderBox->absoluteContentBox(); + + // Make sure the scaled button stays square and will fit in its parent's box + bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height()))); + bounds.setWidth(bounds.height()); + + // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will + // be one pixel closer to the bottom of the field. This tends to look better with the text. + bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); + + static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef(); + static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef(); + i.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, bounds); + return false; +} + +void RenderThemeChromiumSkia::adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const +{ + IntSize emptySize(1, 11); + style->setWidth(Length(emptySize.width(), Fixed)); + style->setHeight(Length(emptySize.height(), Fixed)); +} + +void RenderThemeChromiumSkia::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const +{ + // Scale the decoration size based on the font size + float fontScale = style->fontSize() / defaultControlFontPixelSize; + int magnifierSize = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), + maxSearchFieldResultsDecorationSize)); + style->setWidth(Length(magnifierSize, Fixed)); + style->setHeight(Length(magnifierSize, Fixed)); +} + +bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +{ + IntRect bounds = r; + ASSERT(o->parent()); + if (!o->parent() || !o->parent()->isBox()) + return false; + + RenderBox* parentRenderBox = toRenderBox(o->parent()); + IntRect parentBox = parentRenderBox->absoluteContentBox(); + + // Make sure the scaled decoration stays square and will fit in its parent's box + bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height()))); + bounds.setWidth(bounds.height()); + + // Center the decoration vertically. Round up though, so if it has to be one pixel off-center, it will + // be one pixel closer to the bottom of the field. This tends to look better with the text. + bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); + + static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef(); + i.context->drawImage(magnifierImage, bounds); + return false; +} + +void RenderThemeChromiumSkia::adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const +{ + // Scale the button size based on the font size + float fontScale = style->fontSize() / defaultControlFontPixelSize; + int magnifierHeight = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), + maxSearchFieldResultsDecorationSize)); + int magnifierWidth = lroundf(magnifierHeight * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize); + style->setWidth(Length(magnifierWidth, Fixed)); + style->setHeight(Length(magnifierHeight, Fixed)); +} + +bool RenderThemeChromiumSkia::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +{ + IntRect bounds = r; + ASSERT(o->parent()); + if (!o->parent()) + return false; + if (!o->parent() || !o->parent()->isBox()) + return false; + + RenderBox* parentRenderBox = toRenderBox(o->parent()); + IntRect parentBox = parentRenderBox->absoluteContentBox(); + + // Make sure the scaled decoration will fit in its parent's box + bounds.setHeight(std::min(parentBox.height(), bounds.height())); + bounds.setWidth(std::min(parentBox.width(), static_cast<int>(bounds.height() * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize))); + + // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will + // be one pixel closer to the bottom of the field. This tends to look better with the text. + bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); + + static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").releaseRef(); + i.context->drawImage(magnifierImage, bounds); + return false; +} + +bool RenderThemeChromiumSkia::paintMediaButtonInternal(GraphicsContext* context, const IntRect& rect, Image* image) +{ + context->beginTransparencyLayer(defaultMediaControlOpacity); + + // Draw background. + Color oldFill = context->fillColor(); + Color oldStroke = context->strokeColor(); + + context->setFillColor(Color::black); + context->setStrokeColor(Color::black); + context->drawRect(rect); + + context->setFillColor(oldFill); + context->setStrokeColor(oldStroke); + + // Create a destination rectangle for the image that is centered in the drawing rectangle, rounded left, and down. + IntRect imageRect = image->rect(); + imageRect.setY(rect.y() + (rect.height() - image->height() + 1) / 2); + imageRect.setX(rect.x() + (rect.width() - image->width() + 1) / 2); + + context->drawImage(image, imageRect, CompositeSourceAtop); + context->endTransparencyLayer(); + + return false; +} + +bool RenderThemeChromiumSkia::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ +#if ENABLE(VIDEO) + HTMLMediaElement* mediaElement = mediaElementParent(o->node()); + if (!mediaElement) + return false; + + static Image* mediaPlay = Image::loadPlatformResource("mediaPlay").releaseRef(); + static Image* mediaPause = Image::loadPlatformResource("mediaPause").releaseRef(); + + return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->paused() ? mediaPlay : mediaPause); +#else + return false; +#endif +} + +bool RenderThemeChromiumSkia::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) +{ +#if ENABLE(VIDEO) + HTMLMediaElement* mediaElement = mediaElementParent(o->node()); + if (!mediaElement) + return false; + + static Image* soundFull = Image::loadPlatformResource("mediaSoundFull").releaseRef(); + static Image* soundNone = Image::loadPlatformResource("mediaSoundNone").releaseRef(); + + return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->muted() ? soundNone: soundFull); +#else + return false; +#endif +} + +void RenderThemeChromiumSkia::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const +{ + // Height is locked to auto on all browsers. + style->setLineHeight(RenderStyle::initialLineHeight()); +} + +bool RenderThemeChromiumSkia::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +{ + SkCanvas* const canvas = i.context->platformContext()->canvas(); + const int right = rect.x() + rect.width(); + const int middle = rect.y() + rect.height() / 2; + + paintButtonLike(this, o, i, rect); + + SkPaint paint; + paint.setARGB(0xff, 0, 0, 0); + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kFill_Style); + + SkPath path; + path.moveTo(right - 13, middle - 3); + path.rLineTo(6, 0); + path.rLineTo(-3, 6); + path.close(); + canvas->drawPath(path, paint); + + return false; +} + +void RenderThemeChromiumSkia::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +{ + adjustMenuListStyle(selector, style, e); +} + +// Used to paint styled menulists (i.e. with a non-default border) +bool RenderThemeChromiumSkia::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +{ + return paintMenuList(o, i, rect); +} + +int RenderThemeChromiumSkia::popupInternalPaddingLeft(RenderStyle* style) const +{ + return menuListInternalPadding(style, LeftPadding); +} + +int RenderThemeChromiumSkia::popupInternalPaddingRight(RenderStyle* style) const +{ + return menuListInternalPadding(style, RightPadding); +} + +int RenderThemeChromiumSkia::popupInternalPaddingTop(RenderStyle* style) const +{ + return menuListInternalPadding(style, TopPadding); +} + +int RenderThemeChromiumSkia::popupInternalPaddingBottom(RenderStyle* style) const +{ + return menuListInternalPadding(style, BottomPadding); +} + +int RenderThemeChromiumSkia::buttonInternalPaddingLeft() const +{ + return 3; +} + +int RenderThemeChromiumSkia::buttonInternalPaddingRight() const +{ + return 3; +} + +int RenderThemeChromiumSkia::buttonInternalPaddingTop() const +{ + return 1; +} + +int RenderThemeChromiumSkia::buttonInternalPaddingBottom() const +{ + return 1; +} + +// static +void RenderThemeChromiumSkia::setDefaultFontSize(int fontSize) +{ + defaultFontSize = static_cast<float>(fontSize); +} + +double RenderThemeChromiumSkia::caretBlinkIntervalInternal() const +{ + return RenderTheme::caretBlinkInterval(); +} + +int RenderThemeChromiumSkia::menuListInternalPadding(RenderStyle* style, int paddingType) const +{ + // This internal padding is in addition to the user-supplied padding. + // Matches the FF behavior. + int padding = styledMenuListInternalPadding[paddingType]; + + // Reserve the space for right arrow here. The rest of the padding is + // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from + // RenderMenuList to lay out the individual items in the popup. + // If the MenuList actually has appearance "NoAppearance", then that means + // we don't draw a button, so don't reserve space for it. + const int barType = style->direction() == LTR ? RightPadding : LeftPadding; + if (paddingType == barType && style->appearance() != NoControlPart) + padding += ScrollbarTheme::nativeTheme()->scrollbarThickness(); + + return padding; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h index bf217c8..b81d4fa 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h @@ -1,2 +1,144 @@ -// FIXME: This is a placeholder to avoid some issues with webkit.gyp in the chromium tree. Having this placeholder until we can factor out -// RenderThemeChromiumSkia from RenderThemeChromiumLinux will keep the HEAD of both trees compatible. +/* + * This file is part of the WebKit project. + * + * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com + * Copyright (C) 2007 Holger Hans Peter Freyther + * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * Copyright (C) 2008, 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 + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef RenderThemeChromiumSkia_h +#define RenderThemeChromiumSkia_h + +#include "RenderTheme.h" + +namespace WebCore { + + class RenderThemeChromiumSkia : public RenderTheme { + public: + RenderThemeChromiumSkia(); + virtual ~RenderThemeChromiumSkia(); + + virtual String extraDefaultStyleSheet(); + virtual String extraQuirksStyleSheet(); +#if ENABLE(VIDEO) + virtual String extraMediaControlsStyleSheet(); +#endif + + // A method asking if the theme's controls actually care about redrawing when hovered. + virtual bool supportsHover(const RenderStyle*) const; + + // A method asking if the theme is able to draw the focus ring. + virtual bool supportsFocusRing(const RenderStyle*) const; + + // The platform selection color. + virtual Color platformActiveSelectionBackgroundColor() const; + virtual Color platformInactiveSelectionBackgroundColor() const; + virtual Color platformActiveSelectionForegroundColor() const; + virtual Color platformInactiveSelectionForegroundColor() const; + virtual Color focusRingColor() const; + + // To change the blink interval, override caretBlinkIntervalInternal instead of this one so that we may share layout test code an intercepts. + virtual double caretBlinkInterval() const; + + // System fonts. + virtual void systemFont(int propId, FontDescription&) const; + + virtual int minimumMenuListSize(RenderStyle*) const; + + virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void setCheckboxSize(RenderStyle*) const; + + virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void setRadioSize(RenderStyle*) const; + + virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + + virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + // MenuList refers to an unstyled menulist (meaning a menulist without + // background-color or border set) and MenuListButton refers to a styled + // menulist (a menulist with background-color or border set). They have + // this distinction to support showing aqua style themes whenever they + // possibly can, which is something we don't want to replicate. + // + // In short, we either go down the MenuList code path or the MenuListButton + // codepath. We never go down both. And in both cases, they render the + // entire menulist. + virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + // These methods define the padding for the MenuList's inner block. + virtual int popupInternalPaddingLeft(RenderStyle*) const; + virtual int popupInternalPaddingRight(RenderStyle*) const; + virtual int popupInternalPaddingTop(RenderStyle*) const; + virtual int popupInternalPaddingBottom(RenderStyle*) const; + + virtual int buttonInternalPaddingLeft() const; + virtual int buttonInternalPaddingRight() const; + virtual int buttonInternalPaddingTop() const; + virtual int buttonInternalPaddingBottom() const; + + // Provide a way to pass the default font size from the Settings object + // to the render theme. FIXME: http://b/1129186 A cleaner way would be + // to remove the default font size from this object and have callers + // that need the value to get it directly from the appropriate Settings + // object. + static void setDefaultFontSize(int); + + protected: + static const String& defaultGUIFont(); + + // The default variable-width font size. We use this as the default font + // size for the "system font", and as a base size (which we then shrink) for + // form control fonts. + static float defaultFontSize; + + virtual double caretBlinkIntervalInternal() const; + + private: + int menuListInternalPadding(RenderStyle*, int paddingType) const; + bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*); + }; + +} // namespace WebCore + +#endif // RenderThemeChromiumSkia_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp index 5288191..4ed8d88 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp @@ -3,6 +3,7 @@ * * Copyright (C) 2006 Apple Computer, Inc. * Copyright (C) 2008, 2009 Google, Inc. + * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -29,7 +30,6 @@ #include <vssym32.h> #include "ChromiumBridge.h" -#include "CSSStyleSheet.h" #include "CSSValueKeywords.h" #include "FontSelector.h" #include "FontUtilsChromiumWin.h" @@ -40,9 +40,7 @@ #include "RenderBox.h" #include "RenderSlider.h" #include "ScrollbarTheme.h" -#include "SkiaUtils.h" #include "TransparencyWin.h" -#include "UserAgentStyleSheets.h" #include "WindowsVersion.h" // FIXME: This dependency should eventually be removed. @@ -57,28 +55,6 @@ namespace WebCore { namespace { - -// The background for the media player controls should be a 60% opaque black rectangle. This -// matches the UI mockups for the default UI theme. -static const float defaultMediaControlOpacity = 0.6f; - -// These values all match Safari/Win. -static const float defaultControlFontPixelSize = 13; -static const float defaultCancelButtonSize = 9; -static const float minCancelButtonSize = 5; -static const float maxCancelButtonSize = 21; -static const float defaultSearchFieldResultsDecorationSize = 13; -static const float minSearchFieldResultsDecorationSize = 9; -static const float maxSearchFieldResultsDecorationSize = 30; -static const float defaultSearchFieldResultsButtonWidth = 18; - -bool canvasHasMultipleLayers(const SkCanvas* canvas) -{ - SkCanvas::LayerIter iter(const_cast<SkCanvas*>(canvas), false); - iter.next(); // There is always at least one layer. - return !iter.done(); // There is > 1 layer if the the iterator can stil advance. -} - class ThemePainter : public TransparencyWin { public: ThemePainter(GraphicsContext* context, const IntRect& r) @@ -93,6 +69,13 @@ public: } private: + static bool canvasHasMultipleLayers(const SkCanvas* canvas) + { + SkCanvas::LayerIter iter(const_cast<SkCanvas*>(canvas), false); + iter.next(); // There is always at least one layer. + return !iter.done(); // There is > 1 layer if the the iterator can stil advance. + } + static LayerMode getLayerMode(GraphicsContext* context, TransformMode transformMode) { if (context->platformContext()->isDrawingToImageBuffer()) // Might have transparent background. @@ -116,7 +99,8 @@ private: } // namespace -static void getNonClientMetrics(NONCLIENTMETRICS* metrics) { +static void getNonClientMetrics(NONCLIENTMETRICS* metrics) +{ static UINT size = WebCore::isVistaOrNewer() ? sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA; metrics->cbSize = size; @@ -124,20 +108,6 @@ static void getNonClientMetrics(NONCLIENTMETRICS* metrics) { ASSERT(success); } -enum PaddingType { - TopPadding, - RightPadding, - BottomPadding, - LeftPadding -}; - -static const int styledMenuListInternalPadding[4] = { 1, 4, 1, 4 }; - -// The default variable-width font size. We use this as the default font -// size for the "system font", and as a base size (which we then shrink) for -// form control fonts. -static float defaultFontSize = 16.0; - static FontDescription smallSystemFont; static FontDescription menuFont; static FontDescription labelFont; @@ -159,14 +129,6 @@ static bool supportsFocus(ControlPart appearance) return false; } -static void setFixedPadding(RenderStyle* style, const int padding[4]) -{ - style->setPaddingLeft(Length(padding[LeftPadding], Fixed)); - style->setPaddingRight(Length(padding[RightPadding], Fixed)); - style->setPaddingTop(Length(padding[TopPadding], Fixed)); - style->setPaddingBottom(Length(padding[BottomPadding], Fixed)); -} - // Return the height of system font |font| in pixels. We use this size by // default for some non-form-control elements. static float systemFontSize(const LOGFONT& font) @@ -201,20 +163,6 @@ static float systemFontSize(const LOGFONT& font) return ((size < 12.0f) && (GetACP() == 936)) ? 12.0f : size; } -// We aim to match IE here. -// -IE uses a font based on the encoding as the default font for form controls. -// -Gecko uses MS Shell Dlg (actually calls GetStockObject(DEFAULT_GUI_FONT), -// which returns MS Shell Dlg) -// -Safari uses Lucida Grande. -// -// FIXME: The only case where we know we don't match IE is for ANSI encodings. -// IE uses MS Shell Dlg there, which we render incorrectly at certain pixel -// sizes (e.g. 15px). So, for now we just use Arial. -static wchar_t* defaultGUIFont() -{ - return L"Arial"; -} - // Converts |points| to pixels. One point is 1/72 of an inch. static float pointsToPixels(float points) { @@ -233,14 +181,6 @@ static float pointsToPixels(float points) return points / pointsPerInch * pixelsPerInch; } -static void setSizeIfAuto(RenderStyle* style, const IntSize& size) -{ - if (style->width().isIntrinsicOrAuto()) - style->setWidth(Length(size.width(), Fixed)); - if (style->height().isAuto()) - style->setHeight(Length(size.height(), Fixed)); -} - static double querySystemBlinkInterval(double defaultInterval) { UINT blinkTime = GetCaretBlinkTime(); @@ -251,44 +191,17 @@ static double querySystemBlinkInterval(double defaultInterval) return blinkTime / 1000.0; } -#if ENABLE(VIDEO) -// Attempt to retrieve a HTMLMediaElement from a Node. Returns NULL if one cannot be found. -static HTMLMediaElement* mediaElementParent(Node* node) -{ - if (!node) - return 0; - Node* mediaNode = node->shadowAncestorNode(); - if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag))) - return 0; - - return static_cast<HTMLMediaElement*>(mediaNode); -} -#endif - -// Implement WebCore::theme() for getting the global RenderTheme. -RenderTheme* theme() +PassRefPtr<RenderTheme> RenderThemeChromiumWin::create() { - static RenderThemeChromiumWin winTheme; - return &winTheme; + return adoptRef(new RenderThemeChromiumWin); } -String RenderThemeChromiumWin::extraDefaultStyleSheet() +PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) { - return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet)); + static RenderTheme* rt = RenderThemeChromiumWin::create().releaseRef(); + return rt; } -String RenderThemeChromiumWin::extraQuirksStyleSheet() -{ - return String(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet)); -} - -#if ENABLE(VIDEO) -String RenderThemeChromiumWin::extraMediaControlsStyleSheet() -{ - return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet)); -} -#endif - bool RenderThemeChromiumWin::supportsFocusRing(const RenderStyle* style) const { // Let webkit draw one of its halo rings around any focused element, @@ -337,23 +250,11 @@ Color RenderThemeChromiumWin::platformInactiveTextSearchHighlightColor() const return Color(0xff, 0xff, 0x96); // Yellow. } -double RenderThemeChromiumWin::caretBlinkInterval() const -{ - // Disable the blinking caret in layout test mode, as it introduces - // a race condition for the pixel tests. http://b/1198440 - if (ChromiumBridge::layoutTestMode()) - return 0; - - // This involves a system call, so we cache the result. - static double blinkInterval = querySystemBlinkInterval(RenderTheme::caretBlinkInterval()); - return blinkInterval; -} - void RenderThemeChromiumWin::systemFont(int propId, FontDescription& fontDescription) const { // This logic owes much to RenderThemeSafari.cpp. - FontDescription* cachedDesc = NULL; - wchar_t* faceName = 0; + FontDescription* cachedDesc = 0; + AtomicString faceName; float fontSize = 0; switch (propId) { case CSSValueSmallCaption: @@ -361,7 +262,7 @@ void RenderThemeChromiumWin::systemFont(int propId, FontDescription& fontDescrip if (!smallSystemFont.isAbsoluteSize()) { NONCLIENTMETRICS metrics; getNonClientMetrics(&metrics); - faceName = metrics.lfSmCaptionFont.lfFaceName; + faceName = AtomicString(metrics.lfSmCaptionFont.lfFaceName, wcslen(metrics.lfSmCaptionFont.lfFaceName)); fontSize = systemFontSize(metrics.lfSmCaptionFont); } break; @@ -370,7 +271,7 @@ void RenderThemeChromiumWin::systemFont(int propId, FontDescription& fontDescrip if (!menuFont.isAbsoluteSize()) { NONCLIENTMETRICS metrics; getNonClientMetrics(&metrics); - faceName = metrics.lfMenuFont.lfFaceName; + faceName = AtomicString(metrics.lfMenuFont.lfFaceName, wcslen(metrics.lfMenuFont.lfFaceName)); fontSize = systemFontSize(metrics.lfMenuFont); } break; @@ -400,9 +301,7 @@ void RenderThemeChromiumWin::systemFont(int propId, FontDescription& fontDescrip cachedDesc = &fontDescription; if (fontSize) { - ASSERT(faceName); - cachedDesc->firstFamily().setFamily(AtomicString(faceName, - wcslen(faceName))); + cachedDesc->firstFamily().setFamily(faceName); cachedDesc->setIsAbsoluteSize(true); cachedDesc->setGenericFamily(FontDescription::NoFamily); cachedDesc->setSpecifiedSize(fontSize); @@ -412,11 +311,6 @@ void RenderThemeChromiumWin::systemFont(int propId, FontDescription& fontDescrip fontDescription = *cachedDesc; } -int RenderThemeChromiumWin::minimumMenuListSize(RenderStyle* style) const -{ - return 0; -} - void RenderThemeChromiumWin::adjustSliderThumbSize(RenderObject* o) const { // These sizes match what WinXP draws for various menus. @@ -431,25 +325,13 @@ void RenderThemeChromiumWin::adjustSliderThumbSize(RenderObject* o) const } } -void RenderThemeChromiumWin::setCheckboxSize(RenderStyle* style) const +bool RenderThemeChromiumWin::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { - // If the width and height are both specified, then we have nothing to do. - if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) - return; - - // FIXME: A hard-coded size of 13 is used. This is wrong but necessary - // for now. It matches Firefox. At different DPI settings on Windows, - // querying the theme gives you a larger size that accounts for the higher - // DPI. Until our entire engine honors a DPI setting other than 96, we - // can't rely on the theme's metrics. - const IntSize size(13, 13); - setSizeIfAuto(style, size); + return paintButton(o, i, r); } - -void RenderThemeChromiumWin::setRadioSize(RenderStyle* style) const +bool RenderThemeChromiumWin::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { - // Use same sizing for radio box as checkbox. - setCheckboxSize(style); + return paintButton(o, i, r); } bool RenderThemeChromiumWin::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) @@ -483,178 +365,9 @@ bool RenderThemeChromiumWin::paintSliderTrack(RenderObject* o, const RenderObjec return false; } -void RenderThemeChromiumWin::adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const -{ - // Scale the button size based on the font size - float fontScale = style->fontSize() / defaultControlFontPixelSize; - int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize)); - style->setWidth(Length(cancelButtonSize, Fixed)); - style->setHeight(Length(cancelButtonSize, Fixed)); -} - -bool RenderThemeChromiumWin::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) -{ - IntRect bounds = r; - ASSERT(o->parent()); - if (!o->parent() || !o->parent()->isBox()) - return false; - - RenderBox* parentRenderBox = toRenderBox(o->parent()); - - IntRect parentBox = parentRenderBox->absoluteContentBox(); - - // Make sure the scaled button stays square and will fit in its parent's box - bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height()))); - bounds.setWidth(bounds.height()); - - // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will - // be one pixel closer to the bottom of the field. This tends to look better with the text. - bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); - - static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef(); - static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef(); - i.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, bounds); - return false; -} - -void RenderThemeChromiumWin::adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const -{ - IntSize emptySize(1, 11); - style->setWidth(Length(emptySize.width(), Fixed)); - style->setHeight(Length(emptySize.height(), Fixed)); -} - -void RenderThemeChromiumWin::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const +bool RenderThemeChromiumWin::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { - // Scale the decoration size based on the font size - float fontScale = style->fontSize() / defaultControlFontPixelSize; - int magnifierSize = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), - maxSearchFieldResultsDecorationSize)); - style->setWidth(Length(magnifierSize, Fixed)); - style->setHeight(Length(magnifierSize, Fixed)); -} - -bool RenderThemeChromiumWin::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) -{ - IntRect bounds = r; - ASSERT(o->parent()); - if (!o->parent() || !o->parent()->isBox()) - return false; - - RenderBox* parentRenderBox = toRenderBox(o->parent()); - IntRect parentBox = parentRenderBox->absoluteContentBox(); - - // Make sure the scaled decoration stays square and will fit in its parent's box - bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height()))); - bounds.setWidth(bounds.height()); - - // Center the decoration vertically. Round up though, so if it has to be one pixel off-center, it will - // be one pixel closer to the bottom of the field. This tends to look better with the text. - bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); - - static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef(); - i.context->drawImage(magnifierImage, bounds); - return false; -} - -void RenderThemeChromiumWin::adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const -{ - // Scale the button size based on the font size - float fontScale = style->fontSize() / defaultControlFontPixelSize; - int magnifierHeight = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), - maxSearchFieldResultsDecorationSize)); - int magnifierWidth = lroundf(magnifierHeight * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize); - style->setWidth(Length(magnifierWidth, Fixed)); - style->setHeight(Length(magnifierHeight, Fixed)); -} - -bool RenderThemeChromiumWin::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) -{ - IntRect bounds = r; - ASSERT(o->parent()); - if (!o->parent()) - return false; - if (!o->parent() || !o->parent()->isBox()) - return false; - - RenderBox* parentRenderBox = toRenderBox(o->parent()); - IntRect parentBox = parentRenderBox->absoluteContentBox(); - - // Make sure the scaled decoration will fit in its parent's box - bounds.setHeight(std::min(parentBox.height(), bounds.height())); - bounds.setWidth(std::min(parentBox.width(), static_cast<int>(bounds.height() * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize))); - - // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will - // be one pixel closer to the bottom of the field. This tends to look better with the text. - bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); - - static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").releaseRef(); - i.context->drawImage(magnifierImage, bounds); - return false; -} - -bool RenderThemeChromiumWin::paintMediaButtonInternal(GraphicsContext* context, const IntRect& rect, Image* image) -{ - context->beginTransparencyLayer(defaultMediaControlOpacity); - - // Draw background. - Color oldFill = context->fillColor(); - Color oldStroke = context->strokeColor(); - - context->setFillColor(Color::black); - context->setStrokeColor(Color::black); - context->drawRect(rect); - - context->setFillColor(oldFill); - context->setStrokeColor(oldStroke); - - // Create a destination rectangle for the image that is centered in the drawing rectangle, rounded left, and down. - IntRect imageRect = image->rect(); - imageRect.setY(rect.y() + (rect.height() - image->height() + 1) / 2); - imageRect.setX(rect.x() + (rect.width() - image->width() + 1) / 2); - - context->drawImage(image, imageRect, CompositeSourceAtop); - context->endTransparencyLayer(); - - return false; -} - -bool RenderThemeChromiumWin::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) -{ -#if ENABLE(VIDEO) - HTMLMediaElement* mediaElement = mediaElementParent(o->node()); - if (!mediaElement) - return false; - - static Image* mediaPlay = Image::loadPlatformResource("mediaPlay").releaseRef(); - static Image* mediaPause = Image::loadPlatformResource("mediaPause").releaseRef(); - - return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->paused() ? mediaPlay : mediaPause); -#else - return false; -#endif -} - -bool RenderThemeChromiumWin::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) -{ -#if ENABLE(VIDEO) - HTMLMediaElement* mediaElement = mediaElementParent(o->node()); - if (!mediaElement) - return false; - - static Image* soundFull = Image::loadPlatformResource("mediaSoundFull").releaseRef(); - static Image* soundNone = Image::loadPlatformResource("mediaSoundNone").releaseRef(); - - return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->muted() ? soundNone: soundFull); -#else - return false; -#endif -} - -void RenderThemeChromiumWin::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const -{ - // Height is locked to auto on all browsers. - style->setLineHeight(RenderStyle::initialLineHeight()); + return paintSliderTrack(o, i, r); } // Used to paint unstyled menulists (i.e. with the default border) @@ -709,66 +422,22 @@ bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const RenderObject:: return false; } -void RenderThemeChromiumWin::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const -{ - adjustMenuListStyle(selector, style, e); -} - -// Used to paint styled menulists (i.e. with a non-default border) -bool RenderThemeChromiumWin::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) -{ - return paintMenuList(o, i, r); -} - -int RenderThemeChromiumWin::popupInternalPaddingLeft(RenderStyle* style) const -{ - return menuListInternalPadding(style, LeftPadding); -} - -int RenderThemeChromiumWin::popupInternalPaddingRight(RenderStyle* style) const -{ - return menuListInternalPadding(style, RightPadding); -} - -int RenderThemeChromiumWin::popupInternalPaddingTop(RenderStyle* style) const -{ - return menuListInternalPadding(style, TopPadding); -} - -int RenderThemeChromiumWin::popupInternalPaddingBottom(RenderStyle* style) const -{ - return menuListInternalPadding(style, BottomPadding); -} - -int RenderThemeChromiumWin::buttonInternalPaddingLeft() const -{ - return 3; -} - -int RenderThemeChromiumWin::buttonInternalPaddingRight() const -{ - return 3; -} - -int RenderThemeChromiumWin::buttonInternalPaddingTop() const -{ - return 1; -} - -int RenderThemeChromiumWin::buttonInternalPaddingBottom() const -{ - return 1; -} - // static void RenderThemeChromiumWin::setDefaultFontSize(int fontSize) { - defaultFontSize = static_cast<float>(fontSize); + RenderThemeChromiumSkia::setDefaultFontSize(fontSize); // Reset cached fonts. smallSystemFont = menuFont = labelFont = FontDescription(); } +double RenderThemeChromiumWin::caretBlinkIntervalInternal() const +{ + // This involves a system call, so we cache the result. + static double blinkInterval = querySystemBlinkInterval(RenderTheme::caretBlinkInterval()); + return blinkInterval; +} + unsigned RenderThemeChromiumWin::determineState(RenderObject* o) { unsigned result = TS_NORMAL; @@ -909,22 +578,4 @@ bool RenderThemeChromiumWin::paintTextFieldInternal(RenderObject* o, return false; } -int RenderThemeChromiumWin::menuListInternalPadding(RenderStyle* style, int paddingType) const -{ - // This internal padding is in addition to the user-supplied padding. - // Matches the FF behavior. - int padding = styledMenuListInternalPadding[paddingType]; - - // Reserve the space for right arrow here. The rest of the padding is set - // by adjustMenuListStyle, since PopupMenuChromium.cpp uses the padding - // from RenderMenuList to lay out the individual items in the popup. If - // the MenuList actually has appearance "NoAppearance", then that means we - // don't draw a button, so don't reserve space for it. - const int barType = style->direction() == LTR ? RightPadding : LeftPadding; - if (paddingType == barType && style->appearance() != NoControlPart) - padding += ScrollbarTheme::nativeTheme()->scrollbarThickness(); - - return padding; -} - } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h index 6ba6595..5e98c9b 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h @@ -24,7 +24,7 @@ #ifndef RenderThemeChromiumWin_h #define RenderThemeChromiumWin_h -#include "RenderTheme.h" +#include "RenderThemeChromiumSkia.h" #if WIN32 typedef void* HANDLE; @@ -42,19 +42,9 @@ namespace WebCore { unsigned m_classicState; }; - class RenderThemeChromiumWin : public RenderTheme { + class RenderThemeChromiumWin : public RenderThemeChromiumSkia { public: - RenderThemeChromiumWin() { } - ~RenderThemeChromiumWin() { } - - virtual String extraDefaultStyleSheet(); - virtual String extraQuirksStyleSheet(); -#if ENABLE(VIDEO) - virtual String extraMediaControlsStyleSheet(); -#endif - - // A method asking if the theme's controls actually care about redrawing when hovered. - virtual bool supportsHover(const RenderStyle*) const { return true; } + static PassRefPtr<RenderTheme> create(); // A method asking if the theme is able to draw the focus ring. virtual bool supportsFocusRing(const RenderStyle*) const; @@ -67,46 +57,18 @@ namespace WebCore { virtual Color platformActiveTextSearchHighlightColor() const; virtual Color platformInactiveTextSearchHighlightColor() const; - virtual double caretBlinkInterval() const; - // System fonts. virtual void systemFont(int propId, FontDescription&) const; - virtual int minimumMenuListSize(RenderStyle*) const; - virtual void adjustSliderThumbSize(RenderObject*) const; - virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintButton(o, i, r); } - virtual void setCheckboxSize(RenderStyle*) const; - - virtual bool paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintButton(o, i, r); } - virtual void setRadioSize(RenderStyle*) const; - + // Various paint functions. + virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual bool paintTextArea(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); } - virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual bool paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintSliderTrack(o, i, r); } - - virtual bool paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); } - - virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); // MenuList refers to an unstyled menulist (meaning a menulist without // background-color or border set) and MenuListButton refers to a styled @@ -117,30 +79,19 @@ namespace WebCore { // In short, we either go down the MenuList code path or the MenuListButton // codepath. We never go down both. And in both cases, they render the // entire menulist. - virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - // These methods define the padding for the MenuList's inner block. - virtual int popupInternalPaddingLeft(RenderStyle*) const; - virtual int popupInternalPaddingRight(RenderStyle*) const; - virtual int popupInternalPaddingTop(RenderStyle*) const; - virtual int popupInternalPaddingBottom(RenderStyle*) const; - - virtual int buttonInternalPaddingLeft() const; - virtual int buttonInternalPaddingRight() const; - virtual int buttonInternalPaddingTop() const; - virtual int buttonInternalPaddingBottom() const; - - // Provide a way to pass the default font size from the Settings object - // to the render theme. FIXME: http://b/1129186 A cleaner way would be - // to remove the default font size from this object and have callers - // that need the value to get it directly from the appropriate Settings - // object. + + // Override RenderThemeChromiumSkia's setDefaultFontSize method to also reset the local font property caches. + // See comment in RenderThemeChromiumSkia::setDefaultFontSize() regarding ugliness of this hack. static void setDefaultFontSize(int); + protected: + virtual double caretBlinkIntervalInternal() const; + private: + RenderThemeChromiumWin() { } + virtual ~RenderThemeChromiumWin() { } + unsigned determineState(RenderObject*); unsigned determineSliderThumbState(RenderObject*); unsigned determineClassicState(RenderObject*); @@ -148,9 +99,6 @@ namespace WebCore { ThemeData getThemeData(RenderObject*); bool paintTextFieldInternal(RenderObject*, const RenderObject::PaintInfo&, const IntRect&, bool); - bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*); - - int menuListInternalPadding(RenderStyle*, int paddingType) const; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h index 63f1d97..ba32105 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h @@ -39,8 +39,7 @@ class RenderStyle; class RenderThemeMac : public RenderTheme { public: - RenderThemeMac(); - virtual ~RenderThemeMac(); + static PassRefPtr<RenderTheme> create(); // A method asking if the control changes its tint when the window has focus or not. virtual bool controlSupportsTints(const RenderObject*) const; @@ -59,6 +58,7 @@ public: virtual Color platformActiveListBoxSelectionForegroundColor() const; virtual Color platformInactiveListBoxSelectionBackgroundColor() const; virtual Color platformInactiveListBoxSelectionForegroundColor() const; + virtual Color focusRingColor() const; virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return SmallScrollbar; } @@ -134,6 +134,9 @@ protected: #endif private: + RenderThemeMac(); + virtual ~RenderThemeMac(); + IntRect inflateRect(const IntRect&, const IntSize&, const int* margins, float zoomLevel = 1.0f) const; FloatRect convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp index 3affd1f..914f7ee 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007, 2008 Apple Inc. + * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -65,13 +66,22 @@ enum { leftPadding }; -RenderTheme* theme() +PassRefPtr<RenderTheme> RenderThemeSafari::create() { - static RenderThemeSafari safariTheme; - static RenderThemeWin windowsTheme; + return adoptRef(new RenderThemeSafari); +} + +PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) +{ + static RenderTheme* safariTheme = RenderThemeSafari::create().releaseRef(); + static RenderTheme* windowsTheme = RenderThemeWin::create().releaseRef(); + + // FIXME: This is called before Settings has been initialized by WebKit, so will return a + // potentially wrong answer the very first time it's called (see + // <https://bugs.webkit.org/show_bug.cgi?id=26493>). if (Settings::shouldPaintNativeControls()) - return &windowsTheme; - return &safariTheme; + return windowsTheme; // keep the reference of one. + return safariTheme; // keep the reference of one. } #if !defined(NDEBUG) && defined(USE_DEBUG_SAFARI_THEME) @@ -84,6 +94,17 @@ SOFT_LINK(SafariTheme, paintThemePart, void, __stdcall, (ThemePart part, CGConte #if defined(SAFARI_THEME_VERSION) && SAFARI_THEME_VERSION >= 2 SOFT_LINK(SafariTheme, STPaintProgressIndicator, void, APIENTRY, (ProgressIndicatorType type, CGContextRef context, const CGRect& rect, NSControlSize size, ThemeControlState state, float value), (type, context, rect, size, state, value)) #endif +SOFT_LINK_OPTIONAL(SafariTheme, STCopyThemeColor, CGColorRef, APIENTRY, (unsigned color, SafariTheme::ThemeControlState)); + +static const unsigned stFocusRingColorID = 4; + +static const unsigned aquaFocusRingColor = 0xFF7DADD9; + +static RGBA32 makeRGBAFromCGColor(CGColorRef color) +{ + const CGFloat* components = CGColorGetComponents(color); + return makeRGBA(255 * components[0], 255 * components[1], 255 * components[2], 255 * components[3]); +} ThemeControlState RenderThemeSafari::determineState(RenderObject* o) const { @@ -139,6 +160,22 @@ Color RenderThemeSafari::activeListBoxSelectionBackgroundColor() const return Color(56, 117, 215); } +Color RenderThemeSafari::focusRingColor() const +{ + static Color focusRingColor; + + if (!focusRingColor.isValid()) { + if (STCopyThemeColorPtr()) { + RetainPtr<CGColorRef> color(AdoptCF, STCopyThemeColorPtr()(stFocusRingColorID, SafariTheme::ActiveState)); + focusRingColor = makeRGBAFromCGColor(color.get()); + } + if (!focusRingColor.isValid()) + focusRingColor = aquaFocusRingColor; + } + + return focusRingColor; +} + static float systemFontSizeForControlSize(NSControlSize controlSize) { static float sizes[] = { 13.0f, 11.0f, 9.0f }; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.h index 8ac5acf..4685238 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2007, 2008 Apple Inc. + * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -46,8 +47,7 @@ class RenderStyle; class RenderThemeSafari : public RenderTheme { public: - RenderThemeSafari(); - virtual ~RenderThemeSafari(); + static PassRefPtr<RenderTheme> create(); // A method to obtain the baseline position for a "leaf" control. This will only be used if a baseline // position cannot be determined by examining child content. Checkboxes and radio buttons are examples of @@ -69,6 +69,8 @@ public: virtual Color platformInactiveSelectionBackgroundColor() const; virtual Color activeListBoxSelectionBackgroundColor() const; + virtual Color focusRingColor() const; + // System fonts. virtual void systemFont(int propId, FontDescription&) const; @@ -137,6 +139,9 @@ protected: #endif private: + RenderThemeSafari(); + virtual ~RenderThemeSafari(); + IntRect inflateRect(const IntRect&, const IntSize&, const int* margins) const; // Get the control size based off the font. Used by some of the controls (like buttons). diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp index 1fa5162..9491aae 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006, 2007 Apple Inc. + * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -134,11 +135,16 @@ void RenderThemeWin::setWebKitIsBeingUnloaded() gWebKitIsBeingUnloaded = true; } +PassRefPtr<RenderTheme> RenderThemeWin::create() +{ + return adoptRef(new RenderThemeWin); +} + #if !USE(SAFARI_THEME) -RenderTheme* theme() +PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) { - static RenderThemeWin winTheme; - return &winTheme; + static RenderTheme* winTheme = RenderThemeWin::create().releaseRef(); + return winTheme; } #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.h index 25473a1..99c2004 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.h @@ -2,6 +2,7 @@ * This file is part of the WebKit project. * * Copyright (C) 2006, 2008 Apple Computer, Inc. + * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -48,8 +49,7 @@ struct ThemeData { class RenderThemeWin : public RenderTheme { public: - RenderThemeWin(); - ~RenderThemeWin(); + static PassRefPtr<RenderTheme> create(); virtual String extraDefaultStyleSheet(); virtual String extraQuirksStyleSheet(); @@ -135,6 +135,9 @@ public: #endif private: + RenderThemeWin(); + ~RenderThemeWin(); + void addIntrinsicMargins(RenderStyle*) const; void close(); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.cpp index d47e2f3..246d0c0 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.cpp @@ -35,6 +35,11 @@ #include "HTMLVideoElement.h" #include "MediaPlayer.h" +#if USE(ACCELERATED_COMPOSITING) +#include "RenderLayer.h" +#include "RenderLayerBacking.h" +#endif + using namespace std; namespace WebCore { @@ -139,6 +144,10 @@ void RenderVideo::updatePlayer() mediaPlayer->setVisible(false); return; } + +#if USE(ACCELERATED_COMPOSITING) + layer()->rendererContentChanged(); +#endif IntRect videoBounds = videoBox(); mediaPlayer->setFrameView(document()->view()); @@ -246,6 +255,32 @@ void RenderVideo::calcPrefWidths() setPrefWidthsDirty(false); } +#if USE(ACCELERATED_COMPOSITING) +bool RenderVideo::supportsAcceleratedRendering() const +{ + MediaPlayer* p = player(); + if (p) + return p->supportsAcceleratedRendering(); + + return false; +} + +void RenderVideo::acceleratedRenderingStateChanged() +{ + MediaPlayer* p = player(); + if (p) + p->acceleratedRenderingStateChanged(); +} + +GraphicsLayer* RenderVideo::videoGraphicsLayer() const +{ + if (hasLayer() && layer()->isComposited()) + return layer()->backing()->graphicsLayer(); + + return 0; +} +#endif // USE(ACCELERATED_COMPOSITING) + } // namespace WebCore #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h index 43c1e7b..1c7b259 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h @@ -33,6 +33,9 @@ namespace WebCore { class HTMLMediaElement; +#if USE(ACCELERATED_COMPOSITING) +class GraphicsLayer; +#endif class RenderVideo : public RenderMedia { public: @@ -41,6 +44,9 @@ public: virtual const char* renderName() const { return "RenderVideo"; } + virtual bool requiresLayer() const { return true; } + virtual bool isVideo() const { return true; } + virtual void paintReplaced(PaintInfo& paintInfo, int tx, int ty); virtual void layout(); @@ -51,9 +57,16 @@ public: virtual void calcPrefWidths(); void videoSizeChanged(); + IntRect videoBox() const; void updateFromElement(); +#if USE(ACCELERATED_COMPOSITING) + bool supportsAcceleratedRendering() const; + virtual void acceleratedRenderingStateChanged(); + GraphicsLayer* videoGraphicsLayer() const; +#endif + protected: virtual void intrinsicSizeChanged() { videoSizeChanged(); } @@ -64,8 +77,6 @@ private: bool isWidthSpecified() const; bool isHeightSpecified() const; - IntRect videoBox() const; - void updatePlayer(); }; diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp index c2c8e0b..f3f2b8c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp @@ -120,7 +120,7 @@ void SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject #if ENABLE(FILTERS) if (filter) { filter->addClient(styledElement); - filter->prepareFilter(paintInfo.context, object->objectBoundingBox()); + filter->prepareFilter(paintInfo.context, object); } else if (!filterId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement); #endif @@ -152,7 +152,7 @@ void SVGRenderBase::finishRenderSVGContent(RenderObject* object, RenderObject::P #if ENABLE(FILTERS) if (filter) { - filter->applyFilter(paintInfo.context, object->objectBoundingBox()); + filter->applyFilter(paintInfo.context, object); paintInfo.context = savedContext; } #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/bidi.cpp b/src/3rdparty/webkit/WebCore/rendering/bidi.cpp index 3659912..635ad9a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/bidi.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/bidi.cpp @@ -78,17 +78,6 @@ public: int nextBreakablePosition; }; -// Midpoint globals. The goal is not to do any allocation when dealing with -// these midpoints, so we just keep an array around and never clear it. We track -// the number of items and position using the two other variables. -static Vector<InlineIterator>* smidpoints; -static unsigned sNumMidpoints; -static unsigned sCurrMidpoint; -static bool betweenMidpoints; - -static bool isLineEmpty = true; -static bool previousLineBrokeCleanly = true; - static int getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline) { bool leftSide = (child->style()->direction() == LTR) ? !endOfInline : endOfInline; @@ -327,35 +316,35 @@ ALWAYS_INLINE Direction InlineIterator::direction() const // ------------------------------------------------------------------------------------------------- -static void chopMidpointsAt(RenderObject* obj, unsigned pos) +static void chopMidpointsAt(LineMidpointState& lineMidpointState, RenderObject* obj, unsigned pos) { - if (!sNumMidpoints) + if (!lineMidpointState.numMidpoints) return; - InlineIterator* midpoints = smidpoints->data(); - for (int i = sNumMidpoints - 1; i >= 0; i--) { + InlineIterator* midpoints = lineMidpointState.midpoints.data(); + for (int i = lineMidpointState.numMidpoints - 1; i >= 0; i--) { const InlineIterator& point = midpoints[i]; if (point.obj == obj && point.pos == pos) { - sNumMidpoints = i; + lineMidpointState.numMidpoints = i; break; } } } -static void checkMidpoints(InlineIterator& lBreak) +static void checkMidpoints(LineMidpointState& lineMidpointState, InlineIterator& lBreak) { // Check to see if our last midpoint is a start point beyond the line break. If so, // shave it off the list, and shave off a trailing space if the previous end point doesn't // preserve whitespace. - if (lBreak.obj && sNumMidpoints && sNumMidpoints % 2 == 0) { - InlineIterator* midpoints = smidpoints->data(); - InlineIterator& endpoint = midpoints[sNumMidpoints-2]; - const InlineIterator& startpoint = midpoints[sNumMidpoints-1]; + if (lBreak.obj && lineMidpointState.numMidpoints && !(lineMidpointState.numMidpoints % 2)) { + InlineIterator* midpoints = lineMidpointState.midpoints.data(); + InlineIterator& endpoint = midpoints[lineMidpointState.numMidpoints - 2]; + const InlineIterator& startpoint = midpoints[lineMidpointState.numMidpoints - 1]; InlineIterator currpoint = endpoint; while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBreak) currpoint.increment(); if (currpoint == lBreak) { // We hit the line break before the start point. Shave off the start point. - sNumMidpoints--; + lineMidpointState.numMidpoints--; if (endpoint.obj->style()->collapseWhiteSpace()) { if (endpoint.obj->isText()) { // Don't shave a character off the endpoint if it was from a soft hyphen. @@ -375,13 +364,13 @@ static void checkMidpoints(InlineIterator& lBreak) } } -static void addMidpoint(const InlineIterator& midpoint) +static void addMidpoint(LineMidpointState& lineMidpointState, const InlineIterator& midpoint) { - if (smidpoints->size() <= sNumMidpoints) - smidpoints->grow(sNumMidpoints + 10); + if (lineMidpointState.midpoints.size() <= lineMidpointState.numMidpoints) + lineMidpointState.midpoints.grow(lineMidpointState.numMidpoints + 10); - InlineIterator* midpoints = smidpoints->data(); - midpoints[sNumMidpoints++] = midpoint; + InlineIterator* midpoints = lineMidpointState.midpoints.data(); + midpoints[lineMidpointState.numMidpoints++] = midpoint; } static void appendRunsForObject(int start, int end, RenderObject* obj, InlineBidiResolver& resolver) @@ -390,18 +379,19 @@ static void appendRunsForObject(int start, int end, RenderObject* obj, InlineBid (obj->isPositioned() && !obj->style()->hasStaticX() && !obj->style()->hasStaticY() && !obj->container()->isRenderInline())) return; - bool haveNextMidpoint = (sCurrMidpoint < sNumMidpoints); + LineMidpointState& lineMidpointState = resolver.midpointState(); + bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointState.numMidpoints); InlineIterator nextMidpoint; if (haveNextMidpoint) - nextMidpoint = smidpoints->at(sCurrMidpoint); - if (betweenMidpoints) { + nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidpoint]; + if (lineMidpointState.betweenMidpoints) { if (!(haveNextMidpoint && nextMidpoint.obj == obj)) return; // This is a new start point. Stop ignoring objects and // adjust our start. - betweenMidpoints = false; + lineMidpointState.betweenMidpoints = false; start = nextMidpoint.pos; - sCurrMidpoint++; + lineMidpointState.currentMidpoint++; if (start < end) return appendRunsForObject(start, end, obj, resolver); } else { @@ -413,8 +403,8 @@ static void appendRunsForObject(int start, int end, RenderObject* obj, InlineBid // An end midpoint has been encountered within our object. We // need to go ahead and append a run with our endpoint. if (static_cast<int>(nextMidpoint.pos + 1) <= end) { - betweenMidpoints = true; - sCurrMidpoint++; + lineMidpointState.betweenMidpoints = true; + lineMidpointState.currentMidpoint++; if (nextMidpoint.pos != UINT_MAX) { // UINT_MAX means stop at the object and don't include any of it. if (static_cast<int>(nextMidpoint.pos + 1) > start) resolver.addRun(new (obj->renderArena()) @@ -791,7 +781,7 @@ void RenderBlock::computeVerticalPositionsForLine(RootInlineBox* lineBox, BidiRu } // collects one line of the paragraph and transforms it to visual order -void RenderBlock::bidiReorderLine(InlineBidiResolver& resolver, const InlineIterator& end) +void RenderBlock::bidiReorderLine(InlineBidiResolver& resolver, const InlineIterator& end, bool previousLineBrokeCleanly) { resolver.createBidiRunsForLine(end, style()->visuallyOrdered(), previousLineBrokeCleanly); } @@ -874,7 +864,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i InlineBidiResolver resolver; unsigned floatIndex; bool firstLine = true; - RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, resolver, floats, floatIndex); + bool previousLineBrokeCleanly = true; + RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, previousLineBrokeCleanly, resolver, floats, floatIndex); if (fullLayout && !selfNeedsLayout()) { setNeedsLayout(true, false); // Mark ourselves as needing a full layout. This way we'll repaint like @@ -891,11 +882,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i FloatingObject* lastFloat = m_floatingObjects ? m_floatingObjects->last() : 0; - if (!smidpoints) - smidpoints = new Vector<InlineIterator>(); - - sNumMidpoints = 0; - sCurrMidpoint = 0; + LineMidpointState& lineMidpointState = resolver.midpointState(); // We also find the first clean line and extract these lines. We will add them back // if we determine that we're able to synchronize after handling all our dirty lines. @@ -943,16 +930,19 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i bool checkForFloatsFromLastLine = false; int lastHeight = height(); + bool isLineEmpty = true; + while (!end.atEnd()) { // FIXME: Is this check necessary before the first iteration or can it be moved to the end? if (checkForEndLineMatch && (endLineMatched = matchedEndLine(resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineYPos, repaintBottom, repaintTop))) break; - betweenMidpoints = false; + lineMidpointState.reset(); + isLineEmpty = true; EClear clear = CNONE; - end = findNextLineBreak(resolver, firstLine, &clear); + end = findNextLineBreak(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, &clear); if (resolver.position().atEnd()) { resolver.deleteRuns(); checkForFloatsFromLastLine = true; @@ -961,7 +951,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i ASSERT(end != resolver.position()); if (!isLineEmpty) { - bidiReorderLine(resolver, end); + bidiReorderLine(resolver, end, previousLineBrokeCleanly); ASSERT(resolver.position() == end); BidiRun* trailingSpaceRun = 0; @@ -1075,8 +1065,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i } lastHeight = height(); - sNumMidpoints = 0; - sCurrMidpoint = 0; + lineMidpointState.reset(); resolver.setPosition(end); } @@ -1133,9 +1122,6 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i } } - sNumMidpoints = 0; - sCurrMidpoint = 0; - // Now add in the bottom border/padding. setHeight(height() + toAdd); @@ -1154,7 +1140,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i checkLinesForTextOverflow(); } -RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats) +RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly, + InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats) { RootInlineBox* curr = 0; RootInlineBox* last = 0; @@ -1385,7 +1372,7 @@ bool RenderBlock::matchedEndLine(const InlineBidiResolver& resolver, const Inlin return false; } -static inline bool skipNonBreakingSpace(const InlineIterator& it) +static inline bool skipNonBreakingSpace(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly) { if (it.obj->style()->nbspMode() != SPACE || it.current() != noBreakSpace) return false; @@ -1401,7 +1388,7 @@ static inline bool skipNonBreakingSpace(const InlineIterator& it) return true; } -static inline bool shouldCollapseWhiteSpace(const RenderStyle* style) +static inline bool shouldCollapseWhiteSpace(const RenderStyle* style, bool isLineEmpty, bool previousLineBrokeCleanly) { return style->collapseWhiteSpace() || (style->whiteSpace() == PRE_WRAP && (!isLineEmpty || !previousLineBrokeCleanly)); } @@ -1424,7 +1411,7 @@ static bool inlineFlowRequiresLineBox(RenderInline* flow) return !flow->firstChild() && flow->hasHorizontalBordersPaddingOrMargin(); } -static inline bool requiresLineBox(const InlineIterator& it) +static inline bool requiresLineBox(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly) { if (it.obj->isFloatingOrPositioned()) return false; @@ -1432,19 +1419,20 @@ static inline bool requiresLineBox(const InlineIterator& it) if (it.obj->isRenderInline() && !inlineFlowRequiresLineBox(toRenderInline(it.obj))) return false; - if (!shouldCollapseWhiteSpace(it.obj->style()) || it.obj->isBR()) + if (!shouldCollapseWhiteSpace(it.obj->style(), isLineEmpty, previousLineBrokeCleanly) || it.obj->isBR()) return true; UChar current = it.current(); - return current != ' ' && current != '\t' && current != softHyphen && (current != '\n' || shouldPreserveNewline(it.obj)) && !skipNonBreakingSpace(it); + return current != ' ' && current != '\t' && current != softHyphen && (current != '\n' || shouldPreserveNewline(it.obj)) + && !skipNonBreakingSpace(it, isLineEmpty, previousLineBrokeCleanly); } -bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj) +bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj, bool isLineEmpty, bool previousLineBrokeCleanly) { ASSERT(inlineObj->parent() == this); InlineIterator it(this, inlineObj, 0); - while (!it.atEnd() && !requiresLineBox(it)) + while (!it.atEnd() && !requiresLineBox(it, isLineEmpty, previousLineBrokeCleanly)) it.increment(); return !it.atEnd(); @@ -1456,9 +1444,9 @@ bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj) // object iteration process. // NB. this function will insert any floating elements that would otherwise // be skipped but it will not position them. -void RenderBlock::skipTrailingWhitespace(InlineIterator& iterator) +void RenderBlock::skipTrailingWhitespace(InlineIterator& iterator, bool isLineEmpty, bool previousLineBrokeCleanly) { - while (!iterator.atEnd() && !requiresLineBox(iterator)) { + while (!iterator.atEnd() && !requiresLineBox(iterator, isLineEmpty, previousLineBrokeCleanly)) { RenderObject* object = iterator.obj; if (object->isFloating()) { insertFloatingObject(toRenderBox(object)); @@ -1489,10 +1477,10 @@ void RenderBlock::skipTrailingWhitespace(InlineIterator& iterator) } } -int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstLine) +int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly) { int availableWidth = lineWidth(height(), firstLine); - while (!resolver.position().atEnd() && !requiresLineBox(resolver.position())) { + while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), isLineEmpty, previousLineBrokeCleanly)) { RenderObject* object = resolver.position().obj; if (object->isFloating()) { insertFloatingObject(toRenderBox(object)); @@ -1529,14 +1517,14 @@ int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstL // This is currently just used for list markers and inline flows that have line boxes. Neither should // have an effect on whitespace at the start of the line. -static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObject* o) +static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObject* o, LineMidpointState& lineMidpointState) { RenderObject* next = bidiNext(block, o); if (next && !next->isBR() && next->isText() && toRenderText(next)->textLength() > 0) { RenderText* nextText = toRenderText(next); UChar nextChar = nextText->characters()[0]; if (nextText->style()->isCollapsibleWhiteSpace(nextChar)) { - addMidpoint(InlineIterator(0, o, 0)); + addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); return true; } } @@ -1575,13 +1563,15 @@ static inline unsigned textWidth(RenderText* text, unsigned from, unsigned len, return font.width(TextRun(text->characters() + from, len, !collapseWhiteSpace, xPos)); } -InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, EClear* clear) +InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, + EClear* clear) { ASSERT(resolver.position().block == this); bool appliedStartWidth = resolver.position().pos > 0; - - int width = skipLeadingWhitespace(resolver, firstLine); + LineMidpointState& lineMidpointState = resolver.midpointState(); + + int width = skipLeadingWhitespace(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly); int w = 0; int tmpW = 0; @@ -1706,8 +1696,8 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool ignoreStart.obj = o; ignoreStart.pos = 0; if (ignoringSpaces) { - addMidpoint(ignoreStart); // Stop ignoring spaces. - addMidpoint(ignoreStart); // Start ignoring again. + addMidpoint(lineMidpointState, ignoreStart); // Stop ignoring spaces. + addMidpoint(lineMidpointState, ignoreStart); // Start ignoring again. } } @@ -1726,10 +1716,10 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool isLineEmpty = false; if (ignoringSpaces) { trailingSpaceObject = 0; - addMidpoint(InlineIterator(0, o, 0)); // Stop ignoring spaces. - addMidpoint(InlineIterator(0, o, 0)); // Start ignoring again. + addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); // Stop ignoring spaces. + addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); // Start ignoring again. } else if (style()->collapseWhiteSpace() && resolver.position().obj == o - && shouldSkipWhitespaceAfterStartObject(this, o)) { + && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) { // Like with list markers, we start ignoring spaces to make sure that any // additional spaces we see will be discarded. currentCharacterIsSpace = true; @@ -1753,7 +1743,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool } if (ignoringSpaces) - addMidpoint(InlineIterator(0, o, 0)); + addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); isLineEmpty = false; ignoringSpaces = false; @@ -1764,7 +1754,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool // Optimize for a common case. If we can't find whitespace after the list // item, then this is all moot. -dwh if (o->isListMarker() && !static_cast<RenderListMarker*>(o)->isInside()) { - if (style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(this, o)) { + 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. currentCharacterIsSpace = true; @@ -1827,10 +1817,11 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool else beforeSoftHyphen = InlineIterator(0, last, last->isText() ? toRenderText(last)->textLength() - 1 : 0); // Two consecutive soft hyphens. Avoid overlapping midpoints. - if (sNumMidpoints && smidpoints->at(sNumMidpoints - 1).obj == o && smidpoints->at(sNumMidpoints - 1).pos == pos) - sNumMidpoints--; + if (lineMidpointState.numMidpoints && lineMidpointState.midpoints[lineMidpointState.numMidpoints - 1].obj == o && + lineMidpointState.midpoints[lineMidpointState.numMidpoints - 1].pos == pos) + lineMidpointState.numMidpoints--; else - addMidpoint(beforeSoftHyphen); + addMidpoint(lineMidpointState, beforeSoftHyphen); // Add the width up to but not including the hyphen. tmpW += textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing; @@ -1842,7 +1833,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool InlineIterator afterSoftHyphen(0, o, pos); afterSoftHyphen.increment(); - addMidpoint(afterSoftHyphen); + addMidpoint(lineMidpointState, afterSoftHyphen); } pos++; @@ -1873,7 +1864,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool ignoringSpaces = false; lastSpaceWordSpacing = 0; lastSpace = pos; // e.g., "Foo goo", don't add in any of the ignored spaces. - addMidpoint(InlineIterator(0, o, pos)); + addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); stoppedIgnoringSpaces = true; } else { // Just keep ignoring these spaces. @@ -1911,15 +1902,15 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool lBreak.obj = o; lBreak.pos = pos; lBreak.nextBreakablePosition = nextBreakable; - skipTrailingWhitespace(lBreak); + skipTrailingWhitespace(lBreak, isLineEmpty, previousLineBrokeCleanly); } } if (lineWasTooWide || w + tmpW > width) { if (lBreak.obj && shouldPreserveNewline(lBreak.obj) && lBreak.obj->isText() && !toRenderText(lBreak.obj)->isWordBreak() && toRenderText(lBreak.obj)->characters()[lBreak.pos] == '\n') { if (!stoppedIgnoringSpaces && pos > 0) { // We need to stop right before the newline and then start up again. - addMidpoint(InlineIterator(0, o, pos - 1)); // Stop - addMidpoint(InlineIterator(0, o, pos)); // Start + addMidpoint(lineMidpointState, InlineIterator(0, o, pos - 1)); // Stop + addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); // Start } lBreak.increment(); previousLineBrokeCleanly = true; @@ -1937,8 +1928,8 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool if (c == '\n' && preserveNewline) { if (!stoppedIgnoringSpaces && pos > 0) { // We need to stop right before the newline and then start up again. - addMidpoint(InlineIterator(0, o, pos - 1)); // Stop - addMidpoint(InlineIterator(0, o, pos)); // Start + addMidpoint(lineMidpointState, InlineIterator(0, o, pos - 1)); // Stop + addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); // Start } lBreak.obj = o; lBreak.pos = pos; @@ -1984,7 +1975,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool // We just entered a mode where we are ignoring // spaces. Create a midpoint to terminate the run // before the second space. - addMidpoint(ignoreStart); + addMidpoint(lineMidpointState, ignoreStart); } } } else if (ignoringSpaces) { @@ -1993,7 +1984,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool ignoringSpaces = false; lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; lastSpace = pos; // e.g., "Foo goo", don't add in any of the ignored spaces. - addMidpoint(InlineIterator(0, o, pos)); + addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); } if (currentCharacterIsSpace && !previousCharacterIsSpace) { @@ -2145,15 +2136,15 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool lBreak.increment(); // Sanity check our midpoints. - checkMidpoints(lBreak); + checkMidpoints(lineMidpointState, lBreak); if (trailingSpaceObject) { // This object is either going to be part of the last midpoint, or it is going // to be the actual endpoint. In both cases we just decrease our pos by 1 level to // exclude the space, allowing it to - in effect - collapse into the newline. - if (sNumMidpoints%2==1) { - InlineIterator* midpoints = smidpoints->data(); - midpoints[sNumMidpoints-1].pos--; + if (lineMidpointState.numMidpoints % 2) { + InlineIterator* midpoints = lineMidpointState.midpoints.data(); + midpoints[lineMidpointState.numMidpoints - 1].pos--; } //else if (lBreak.pos > 0) // lBreak.pos--; @@ -2163,7 +2154,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool unsigned length = text->textLength(); unsigned pos = length >= 2 ? length - 2 : UINT_MAX; InlineIterator endMid(0, trailingSpaceObject, pos); - addMidpoint(endMid); + addMidpoint(lineMidpointState, endMid); } } @@ -2179,9 +2170,9 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool if (lBreak.obj && lBreak.pos >= 2 && lBreak.obj->isText()) { // For soft hyphens on line breaks, we have to chop out the midpoints that made us // ignore the hyphen so that it will render at the end of the line. - UChar c = toRenderText(lBreak.obj)->characters()[lBreak.pos-1]; + UChar c = toRenderText(lBreak.obj)->characters()[lBreak.pos - 1]; if (c == softHyphen) - chopMidpointsAt(lBreak.obj, lBreak.pos-2); + chopMidpointsAt(lineMidpointState, lBreak.obj, lBreak.pos - 2); } return lBreak; diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp index f3a2cd9..e4027db 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp @@ -206,7 +206,7 @@ void RenderStyle::setHasPseudoStyle(PseudoId pseudo) noninherited_flags._pseudoBits |= pseudoBit(pseudo); } -RenderStyle* RenderStyle::getCachedPseudoStyle(PseudoId pid) +RenderStyle* RenderStyle::getCachedPseudoStyle(PseudoId pid) const { if (!m_cachedPseudoStyle || styleType() != NOPSEUDO) return 0; @@ -225,7 +225,7 @@ RenderStyle* RenderStyle::addCachedPseudoStyle(PassRefPtr<RenderStyle> pseudo) return m_cachedPseudoStyle.get(); } -bool RenderStyle::inheritedNotEqual(RenderStyle* other) const +bool RenderStyle::inheritedNotEqual(const RenderStyle* other) const { return inherited_flags != other->inherited_flags || inherited != other->inherited || diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h index a390ea3..46c91cd 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h +++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h @@ -301,10 +301,10 @@ public: void inheritFrom(const RenderStyle* inheritParent); - PseudoId styleType() { return static_cast<PseudoId>(noninherited_flags._styleType); } + PseudoId styleType() const { return static_cast<PseudoId>(noninherited_flags._styleType); } void setStyleType(PseudoId styleType) { noninherited_flags._styleType = styleType; } - RenderStyle* getCachedPseudoStyle(PseudoId); + RenderStyle* getCachedPseudoStyle(PseudoId) const; RenderStyle* addCachedPseudoStyle(PassRefPtr<RenderStyle>); bool affectedByHoverRules() const { return noninherited_flags._affectedByHover; } @@ -1025,7 +1025,7 @@ public: const CounterDirectiveMap* counterDirectives() const; CounterDirectiveMap& accessCounterDirectives(); - bool inheritedNotEqual(RenderStyle*) const; + bool inheritedNotEqual(const RenderStyle*) const; StyleDifference diff(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; diff --git a/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.cpp b/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.cpp index 790799b..ce21720 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.cpp @@ -80,6 +80,7 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const && nbspMode == o.nbspMode && khtmlLineBreak == o.khtmlLineBreak && textSizeAdjust == o.textSizeAdjust + && resize == o.resize && userSelect == o.userSelect; } |