summaryrefslogtreecommitdiff
path: root/src/3rdparty/webkit/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/rendering')
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp6
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/BidiRun.cpp74
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/BidiRun.h65
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/CounterNode.cpp221
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/CounterNode.h27
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/EllipsisBox.cpp49
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/EllipsisBox.h8
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/HitTestRequest.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/HitTestResult.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp66
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h18
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/InlineIterator.h266
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/InlineRunBox.h54
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp115
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/InlineTextBox.h27
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/LayoutState.cpp9
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp61
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h13
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderArena.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderArena.h3
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderBR.cpp4
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderBR.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp443
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderBlock.h30
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp376
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp113
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderBox.h16
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp208
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h4
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderButton.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderButton.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderCounter.cpp378
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderCounter.h9
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderEmbeddedObject.cpp427
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderEmbeddedObject.h69
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp5
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.cpp37
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.h25
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderFlexibleBox.cpp50
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.cpp89
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h32
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderFrame.cpp1
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.cpp138
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.h5
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp84
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderImage.h18
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderInline.cpp57
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderInline.h4
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp396
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderLayer.h39
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp252
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h24
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp284
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h26
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderLineBoxList.cpp33
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp6
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderListItem.cpp51
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderListMarker.cpp884
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderListMarker.h1
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderMarquee.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp51
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderMedia.h12
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp9
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.cpp18
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp103
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderMenuList.h18
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp284
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderObject.h76
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.cpp23
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.h3
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderOverflow.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderPart.cpp57
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderPart.h8
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp287
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderPartObject.h7
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderPath.cpp278
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderPath.h24
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderProgress.cpp118
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderProgress.h60
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderReplaced.h3
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderReplica.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderReplica.h4
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderRuby.cpp197
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderRuby.h91
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderRubyBase.cpp190
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderRubyBase.h67
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderRubyRun.cpp228
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderRubyRun.h85
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderRubyText.cpp54
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderRubyText.h56
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.cpp32
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.h11
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.cpp59
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.h11
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGGradientStop.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.cpp12
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.h3
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.cpp132
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.h65
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.cpp40
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.h16
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.h4
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.cpp10
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.h4
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGResource.h85
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceClipper.cpp150
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceClipper.h61
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceMasker.cpp196
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceMasker.h79
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.cpp145
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.h23
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp101
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h50
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGTSpan.h6
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGText.cpp59
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h13
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp18
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.h6
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.cpp63
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.h18
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderScrollbarTheme.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSelectionInfo.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSlider.cpp81
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp71
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTable.h1
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp82
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTableCell.h6
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTableRow.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTableSection.cpp21
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderText.cpp147
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderText.h11
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp104
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTextControl.h18
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp17
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.h1
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp38
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTextFragment.cpp4
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp87
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTheme.h23
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp56
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h30
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h1
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm103
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp154
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h8
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h1
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp8
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp29
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderThemeWince.cpp23
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.cpp123
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.h11
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderVideo.cpp166
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderVideo.h21
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderView.cpp31
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderView.h11
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp197
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderWidget.h10
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RootInlineBox.cpp1
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RootInlineBox.h6
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.cpp4
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.h54
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.cpp105
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.h21
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGMarkerData.h134
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGMarkerLayoutInfo.cpp124
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGMarkerLayoutInfo.h74
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp149
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.h79
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.cpp112
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.h7
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.cpp178
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.h7
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp80
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h67
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/TableLayout.h6
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/TextControlInnerElements.cpp7
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/TrailingFloatsRootInlineBox.h48
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/TransformState.cpp8
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/TransformState.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/break_lines.cpp62
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/break_lines.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/ContentData.h6
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/CounterContent.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/FillLayer.cpp11
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/FillLayer.h3
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/LineClampValue.h69
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp11
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h68
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h101
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.cpp55
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.h344
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.h2
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/ShadowData.h3
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.cpp5
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.h1
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.cpp5
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.h1
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/style/StyleRareNonInheritedData.h3
208 files changed, 9737 insertions, 3614 deletions
diff --git a/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp b/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp
index 3749782ff5..fdbec52a3b 100644
--- a/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.cpp
@@ -382,7 +382,7 @@ int AutoTableLayout::calcEffectiveWidth()
float spanMax = max(maxWidth, cMaxWidth);
tMaxWidth = max(tMaxWidth, spanMax * 100 * percentScaleFactor / w.rawValue());
- // all non percent columns in the span get percent vlaues to sum up correctly.
+ // all non percent columns in the span get percent values to sum up correctly.
int percentMissing = w.rawValue() - totalPercent;
float totalWidth = 0;
for (unsigned int pos = col; pos < lastCol; pos++) {
@@ -664,8 +664,8 @@ void AutoTableLayout::layout()
}
}
- // if we have overallocated, reduce every cell according to the difference between desired width and minwidth
- // this seems to produce to the pixel exaxt results with IE. Wonder is some of this also holds for width distributing.
+ // If we have overallocated, reduce every cell according to the difference between desired width and minwidth
+ // this seems to produce to the pixel exact results with IE. Wonder is some of this also holds for width distributing.
if (available < 0) {
// Need to reduce cells with the following prioritization:
// (1) Auto
diff --git a/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.h b/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.h
index 641a68b952..f1ef7681db 100644
--- a/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.h
+++ b/src/3rdparty/webkit/WebCore/rendering/AutoTableLayout.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2002 Lars Knoll (knoll@kde.org)
* (C) 2002 Dirk Mueller (mueller@kde.org)
*
diff --git a/src/3rdparty/webkit/WebCore/rendering/BidiRun.cpp b/src/3rdparty/webkit/WebCore/rendering/BidiRun.cpp
new file mode 100644
index 0000000000..ac130469b3
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/BidiRun.cpp
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
+ *
+ * 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 "BidiRun.h"
+#include "InlineBox.h"
+#include "RenderArena.h"
+#include <wtf/RefCountedLeakCounter.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+#ifndef NDEBUG
+static RefCountedLeakCounter bidiRunCounter("BidiRun");
+
+static bool inBidiRunDestroy;
+#endif
+
+void BidiRun::destroy()
+{
+#ifndef NDEBUG
+ inBidiRunDestroy = true;
+#endif
+ RenderArena* renderArena = m_object->renderArena();
+ delete this;
+#ifndef NDEBUG
+ inBidiRunDestroy = false;
+#endif
+
+ // Recover the size left there for us by operator delete and free the memory.
+ renderArena->free(*reinterpret_cast<size_t*>(this), this);
+}
+
+void* BidiRun::operator new(size_t sz, RenderArena* renderArena) throw()
+{
+#ifndef NDEBUG
+ bidiRunCounter.increment();
+#endif
+ return renderArena->allocate(sz);
+}
+
+void BidiRun::operator delete(void* ptr, size_t sz)
+{
+#ifndef NDEBUG
+ bidiRunCounter.decrement();
+#endif
+ ASSERT(inBidiRunDestroy);
+
+ // Stash size where destroy() can find it.
+ *(size_t*)ptr = sz;
+}
+
+}
diff --git a/src/3rdparty/webkit/WebCore/rendering/BidiRun.h b/src/3rdparty/webkit/WebCore/rendering/BidiRun.h
new file mode 100644
index 0000000000..542081a720
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/BidiRun.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
+ *
+ * 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 BidiRun_h
+#define BidiRun_h
+
+#include <wtf/StdLibExtras.h>
+#include "BidiResolver.h"
+#include "RenderText.h"
+
+namespace WebCore {
+
+class BidiContext;
+class InlineBox;
+
+struct BidiRun : BidiCharacterRun {
+ BidiRun(int start, int stop, RenderObject* object, BidiContext* context, WTF::Unicode::Direction dir)
+ : BidiCharacterRun(start, stop, context, dir)
+ , m_object(object)
+ , m_box(0)
+ {
+ }
+
+ void destroy();
+
+ // Overloaded new operator.
+ void* operator new(size_t, RenderArena*) throw();
+
+ // Overridden to prevent the normal delete from being called.
+ void operator delete(void*, size_t);
+
+ BidiRun* next() { return static_cast<BidiRun*>(m_next); }
+
+private:
+ // The normal operator new is disallowed.
+ void* operator new(size_t) throw();
+
+public:
+ RenderObject* m_object;
+ InlineBox* m_box;
+};
+
+}
+
+#endif // BidiRun_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/CounterNode.cpp b/src/3rdparty/webkit/WebCore/rendering/CounterNode.cpp
index f546abb113..c164c81a48 100644
--- a/src/3rdparty/webkit/WebCore/rendering/CounterNode.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/CounterNode.cpp
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
*
@@ -24,20 +22,14 @@
#include "config.h"
#include "CounterNode.h"
+#include "RenderCounter.h"
#include "RenderObject.h"
#include <stdio.h>
-// FIXME: There's currently no strategy for getting the counter tree updated when new
-// elements with counter-reset and counter-increment styles are added to the render tree.
-// Also, the code can't handle changes where an existing node needs to change into a
-// "reset" node, or from a "reset" node back to not a "reset" node. As of this writing,
-// at least some of these problems manifest as failures in the t1204-increment and
-// t1204-reset tests in the CSS 2.1 test suite.
-
namespace WebCore {
-CounterNode::CounterNode(RenderObject* o, bool isReset, int value)
- : m_isReset(isReset)
+CounterNode::CounterNode(RenderObject* o, bool hasResetType, int value)
+ : m_hasResetType(hasResetType)
, m_value(value)
, m_countInParent(0)
, m_renderer(o)
@@ -46,38 +38,95 @@ CounterNode::CounterNode(RenderObject* o, bool isReset, int value)
, m_nextSibling(0)
, m_firstChild(0)
, m_lastChild(0)
-{
+{
+}
+
+CounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWithin) const
+{
+ if (this == stayWithin)
+ return 0;
+
+ const CounterNode* current = this;
+ CounterNode* next;
+ while (!(next = current->m_nextSibling)) {
+ current = current->m_parent;
+ if (!current || current == stayWithin)
+ return 0;
+ }
+ return next;
+}
+
+CounterNode* CounterNode::nextInPreOrder(const CounterNode* stayWithin) const
+{
+ if (CounterNode* next = m_firstChild)
+ return next;
+
+ return nextInPreOrderAfterChildren(stayWithin);
+}
+
+CounterNode* CounterNode::lastDescendant() const
+{
+ CounterNode* last = m_lastChild;
+ if (!last)
+ return 0;
+
+ while (CounterNode* lastChild = last->m_lastChild)
+ last = lastChild;
+
+ return last;
+}
+
+CounterNode* CounterNode::previousInPreOrder() const
+{
+ CounterNode* previous = m_previousSibling;
+ if (!previous)
+ return m_parent;
+
+ while (CounterNode* lastChild = previous->m_lastChild)
+ previous = lastChild;
+
+ return previous;
}
int CounterNode::computeCountInParent() const
{
- int increment = m_isReset ? 0 : m_value;
+ int increment = actsAsReset() ? 0 : m_value;
if (m_previousSibling)
return m_previousSibling->m_countInParent + increment;
ASSERT(m_parent->m_firstChild == this);
return m_parent->m_value + increment;
}
-void CounterNode::recount()
+void CounterNode::resetRenderer(const AtomicString& identifier) const
{
- for (CounterNode* c = this; c; c = c->m_nextSibling) {
- int oldCount = c->m_countInParent;
- int newCount = c->computeCountInParent();
+ if (!m_renderer || m_renderer->documentBeingDestroyed())
+ return;
+ if (RenderObjectChildList* children = m_renderer->virtualChildren())
+ children->invalidateCounters(m_renderer, identifier);
+}
+
+void CounterNode::resetRenderers(const AtomicString& identifier) const
+{
+ const CounterNode* node = this;
+ do {
+ node->resetRenderer(identifier);
+ node = node->nextInPreOrder(this);
+ } while (node);
+}
+
+void CounterNode::recount(const AtomicString& identifier)
+{
+ for (CounterNode* node = this; node; node = node->m_nextSibling) {
+ int oldCount = node->m_countInParent;
+ int newCount = node->computeCountInParent();
if (oldCount == newCount)
break;
- c->m_countInParent = newCount;
- // m_renderer contains the parent of the render node
- // corresponding to a CounterNode. Let's find the counter
- // child and make this re-layout.
- for (RenderObject* o = c->m_renderer->firstChild(); o; o = o->nextSibling())
- if (!o->documentBeingDestroyed() && o->isCounter()) {
- o->setNeedsLayoutAndPrefWidthsRecalc();
- break;
- }
+ node->m_countInParent = newCount;
+ node->resetRenderers(identifier);
}
}
-void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild)
+void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, const AtomicString& identifier)
{
ASSERT(newChild);
ASSERT(!newChild->m_parent);
@@ -85,6 +134,11 @@ void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild)
ASSERT(!newChild->m_nextSibling);
ASSERT(!refChild || refChild->m_parent == this);
+ if (newChild->m_hasResetType) {
+ while (m_lastChild != refChild)
+ RenderCounter::destroyCounterNode(m_lastChild->renderer(), identifier);
+ }
+
CounterNode* next;
if (refChild) {
@@ -95,91 +149,106 @@ void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild)
m_firstChild = newChild;
}
- if (next) {
- ASSERT(next->m_previousSibling == refChild);
- next->m_previousSibling = newChild;
- } else {
- ASSERT(m_lastChild == refChild);
- m_lastChild = newChild;
- }
-
newChild->m_parent = this;
newChild->m_previousSibling = refChild;
- newChild->m_nextSibling = next;
- newChild->m_countInParent = newChild->computeCountInParent();
+ if (!newChild->m_firstChild || newChild->m_hasResetType) {
+ newChild->m_nextSibling = next;
+ if (next) {
+ ASSERT(next->m_previousSibling == refChild);
+ next->m_previousSibling = newChild;
+ } else {
+ ASSERT(m_lastChild == refChild);
+ m_lastChild = newChild;
+ }
+
+ newChild->m_countInParent = newChild->computeCountInParent();
+ newChild->resetRenderers(identifier);
+ if (next)
+ next->recount(identifier);
+ return;
+ }
+
+ // The code below handles the case when a formerly root increment counter is loosing its root position
+ // and therefore its children become next siblings.
+ CounterNode* last = newChild->m_lastChild;
+ CounterNode* first = newChild->m_firstChild;
+
+ newChild->m_nextSibling = first;
+ first->m_previousSibling = newChild;
+ // The case when the original next sibling of the inserted node becomes a child of
+ // one of the former children of the inserted node is not handled as it is believed
+ // to be impossible since:
+ // 1. if the increment counter node lost it's root position as a result of another
+ // counter node being created, it will be inserted as the last child so next is null.
+ // 2. if the increment counter node lost it's root position as a result of a renderer being
+ // inserted into the document's render tree, all its former children counters are attached
+ // to children of the inserted renderer and hence cannot be in scope for counter nodes
+ // attached to renderers that were already in the document's render tree.
+ last->m_nextSibling = next;
if (next)
- next->recount();
+ next->m_previousSibling = last;
+ else
+ m_lastChild = last;
+ for (next = first; ; next = next->m_nextSibling) {
+ next->m_parent = this;
+ if (last == next)
+ break;
+ }
+ newChild->m_firstChild = 0;
+ newChild->m_lastChild = 0;
+ newChild->m_countInParent = newChild->computeCountInParent();
+ newChild->resetRenderer(identifier);
+ first->recount(identifier);
}
-void CounterNode::removeChild(CounterNode* oldChild)
+void CounterNode::removeChild(CounterNode* oldChild, const AtomicString& identifier)
{
ASSERT(oldChild);
ASSERT(!oldChild->m_firstChild);
ASSERT(!oldChild->m_lastChild);
CounterNode* next = oldChild->m_nextSibling;
- CounterNode* prev = oldChild->m_previousSibling;
+ CounterNode* previous = oldChild->m_previousSibling;
oldChild->m_nextSibling = 0;
oldChild->m_previousSibling = 0;
oldChild->m_parent = 0;
- if (prev)
- prev->m_nextSibling = next;
+ if (previous)
+ previous->m_nextSibling = next;
else {
ASSERT(m_firstChild == oldChild);
m_firstChild = next;
}
-
+
if (next)
- next->m_previousSibling = prev;
+ next->m_previousSibling = previous;
else {
ASSERT(m_lastChild == oldChild);
- m_lastChild = prev;
+ m_lastChild = previous;
}
-
+
if (next)
- next->recount();
+ next->recount(identifier);
}
#ifndef NDEBUG
-static const CounterNode* nextInPreOrderAfterChildren(const CounterNode* node)
-{
- CounterNode* next = node->nextSibling();
- if (!next) {
- next = node->parent();
- while (next && !next->nextSibling())
- next = next->parent();
- if (next)
- next = next->nextSibling();
- }
- return next;
-}
-
-static const CounterNode* nextInPreOrder(const CounterNode* node)
-{
- if (CounterNode* child = node->firstChild())
- return child;
- return nextInPreOrderAfterChildren(node);
-}
-
static void showTreeAndMark(const CounterNode* node)
{
const CounterNode* root = node;
while (root->parent())
root = root->parent();
- for (const CounterNode* c = root; c; c = nextInPreOrder(c)) {
- if (c == node)
- fprintf(stderr, "*");
- for (const CounterNode* d = c; d && d != root; d = d->parent())
- fprintf(stderr, "\t");
- if (c->isReset())
- fprintf(stderr, "reset: %d %d\n", c->value(), c->countInParent());
- else
- fprintf(stderr, "increment: %d %d\n", c->value(), c->countInParent());
+ for (const CounterNode* current = root; current; current = current->nextInPreOrder()) {
+ fwrite((current == node) ? "*" : " ", 1, 1, stderr);
+ for (const CounterNode* parent = current; parent && parent != root; parent = parent->parent())
+ fwrite(" ", 1, 2, stderr);
+ fprintf(stderr, "%p %s: %d %d P:%p PS:%p NS:%p R:%p\n",
+ current, current->actsAsReset() ? "reset____" : "increment", current->value(),
+ current->countInParent(), current->parent(), current->previousSibling(),
+ current->nextSibling(), current->renderer());
}
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/CounterNode.h b/src/3rdparty/webkit/WebCore/rendering/CounterNode.h
index b432e1d5ce..15f2eb8f19 100644
--- a/src/3rdparty/webkit/WebCore/rendering/CounterNode.h
+++ b/src/3rdparty/webkit/WebCore/rendering/CounterNode.h
@@ -35,13 +35,15 @@
namespace WebCore {
+class AtomicString;
class RenderObject;
class CounterNode : public Noncopyable {
public:
CounterNode(RenderObject*, bool isReset, int value);
- bool isReset() const { return m_isReset; }
+ bool actsAsReset() const { return m_hasResetType || !m_parent; }
+ bool hasResetType() const { return m_hasResetType; }
int value() const { return m_value; }
int countInParent() const { return m_countInParent; }
RenderObject* renderer() const { return m_renderer; }
@@ -51,15 +53,30 @@ public:
CounterNode* nextSibling() const { return m_nextSibling; }
CounterNode* firstChild() const { return m_firstChild; }
CounterNode* lastChild() const { return m_lastChild; }
+ CounterNode* lastDescendant() const;
+ CounterNode* previousInPreOrder() const;
+ CounterNode* nextInPreOrder(const CounterNode* stayWithin = 0) const;
+ CounterNode* nextInPreOrderAfterChildren(const CounterNode* stayWithin = 0) const;
- void insertAfter(CounterNode* newChild, CounterNode* beforeChild);
- void removeChild(CounterNode*);
+ void insertAfter(CounterNode* newChild, CounterNode* beforeChild, const AtomicString& identifier);
+
+ // identifier must match the identifier of this counter.
+ void removeChild(CounterNode*, const AtomicString& identifier);
private:
int computeCountInParent() const;
- void recount();
+ void recount(const AtomicString& identifier);
+
+ // Invalidates the text in the renderer of this counter, if any.
+ // identifier must match the identifier of this counter.
+ void resetRenderer(const AtomicString& identifier) const;
+
+ // Invalidates the text in the renderer of this counter, if any,
+ // and in the renderers of all descendants of this counter, if any.
+ // identifier must match the identifier of this counter.
+ void resetRenderers(const AtomicString& identifier) const;
- bool m_isReset;
+ bool m_hasResetType;
int m_value;
int m_countInParent;
RenderObject* m_renderer;
diff --git a/src/3rdparty/webkit/WebCore/rendering/EllipsisBox.cpp b/src/3rdparty/webkit/WebCore/rendering/EllipsisBox.cpp
index db9a101fde..6ec31950ce 100644
--- a/src/3rdparty/webkit/WebCore/rendering/EllipsisBox.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/EllipsisBox.cpp
@@ -1,6 +1,4 @@
/**
-* This file is part of the html renderer for KDE.
- *
* Copyright (C) 2003, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -25,6 +23,7 @@
#include "Document.h"
#include "GraphicsContext.h"
#include "HitTestResult.h"
+#include "RootInlineBox.h"
namespace WebCore {
@@ -34,17 +33,30 @@ void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
RenderStyle* style = m_renderer->style(m_firstLine);
Color textColor = style->color();
if (textColor != context->fillColor())
- context->setFillColor(textColor);
+ context->setFillColor(textColor, style->colorSpace());
bool setShadow = false;
if (style->textShadow()) {
context->setShadow(IntSize(style->textShadow()->x, style->textShadow()->y),
- style->textShadow()->blur, style->textShadow()->color);
+ style->textShadow()->blur, style->textShadow()->color, style->colorSpace());
setShadow = true;
}
+ if (selectionState() != RenderObject::SelectionNone) {
+ paintSelection(context, tx, ty, style, style->font());
+
+ // Select the correct color for painting the text.
+ Color foreground = paintInfo.forceBlackText ? Color::black : renderer()->selectionForegroundColor();
+ if (foreground.isValid() && foreground != textColor)
+ context->setFillColor(foreground, style->colorSpace());
+ }
+
const String& str = m_str;
context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->font().ascent()));
+ // Restore the regular fill color.
+ if (textColor != context->fillColor())
+ context->setFillColor(textColor, style->colorSpace());
+
if (setShadow)
context->clearShadow();
@@ -56,6 +68,35 @@ void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
}
}
+IntRect EllipsisBox::selectionRect(int tx, int ty)
+{
+ RenderStyle* style = m_renderer->style(m_firstLine);
+ const Font& f = style->font();
+ return enclosingIntRect(f.selectionRectForText(TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()),
+ IntPoint(m_x + tx, m_y + ty + root()->selectionTop()), root()->selectionHeight()));
+}
+
+void EllipsisBox::paintSelection(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font)
+{
+ Color textColor = style->color();
+ Color c = m_renderer->selectionBackgroundColor();
+ if (!c.isValid() || !c.alpha())
+ return;
+
+ // If the text color ends up being the same as the selection background, invert the selection
+ // background.
+ if (textColor == c)
+ c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
+
+ context->save();
+ int y = root()->selectionTop();
+ int h = root()->selectionHeight();
+ context->clip(IntRect(m_x + tx, y + ty, m_width, h));
+ context->drawHighlightForText(font, TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()),
+ IntPoint(m_x + tx, m_y + ty + y), h, c, style->colorSpace());
+ context->restore();
+}
+
bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
{
tx += m_x;
diff --git a/src/3rdparty/webkit/WebCore/rendering/EllipsisBox.h b/src/3rdparty/webkit/WebCore/rendering/EllipsisBox.h
index 9dbd27f994..087fc722c8 100644
--- a/src/3rdparty/webkit/WebCore/rendering/EllipsisBox.h
+++ b/src/3rdparty/webkit/WebCore/rendering/EllipsisBox.h
@@ -1,6 +1,4 @@
/**
-* This file is part of the html renderer for KDE.
- *
* Copyright (C) 2003, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -37,18 +35,24 @@ public:
, m_height(height)
, m_str(ellipsisStr)
, m_markupBox(markupBox)
+ , m_selectionState(RenderObject::SelectionNone)
{
}
virtual void paint(RenderObject::PaintInfo&, int tx, int ty);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty);
+ void setSelectionState(RenderObject::SelectionState s) { m_selectionState = s; }
+ IntRect selectionRect(int tx, int ty);
private:
virtual int height() const { return m_height; }
+ virtual RenderObject::SelectionState selectionState() { return m_selectionState; }
+ void paintSelection(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&);
int m_height;
AtomicString m_str;
InlineBox* m_markupBox;
+ RenderObject::SelectionState m_selectionState;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp
index 4852708eba..09af518c43 100644
--- a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2002 Lars Knoll (knoll@kde.org)
* (C) 2002 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2003, 2006 Apple Computer, Inc.
diff --git a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.h b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.h
index ed7c089e09..758ddbb3f2 100644
--- a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.h
+++ b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2002 Lars Knoll (knoll@kde.org)
* (C) 2002 Dirk Mueller (mueller@kde.org)
*
diff --git a/src/3rdparty/webkit/WebCore/rendering/HitTestRequest.h b/src/3rdparty/webkit/WebCore/rendering/HitTestRequest.h
index 46dd7b8af1..ca1445ae02 100644
--- a/src/3rdparty/webkit/WebCore/rendering/HitTestRequest.h
+++ b/src/3rdparty/webkit/WebCore/rendering/HitTestRequest.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
*
diff --git a/src/3rdparty/webkit/WebCore/rendering/HitTestResult.h b/src/3rdparty/webkit/WebCore/rendering/HitTestResult.h
index 25e10585c5..d1906ba64b 100644
--- a/src/3rdparty/webkit/WebCore/rendering/HitTestResult.h
+++ b/src/3rdparty/webkit/WebCore/rendering/HitTestResult.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp
index baea956bc0..23dc4e7ba6 100644
--- a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.cpp
@@ -165,7 +165,7 @@ void InlineFlowBox::attachLineBoxToRenderObject()
void InlineFlowBox::adjustPosition(int dx, int dy)
{
- InlineRunBox::adjustPosition(dx, dy);
+ InlineBox::adjustPosition(dx, dy);
for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
child->adjustPosition(dx, dy);
if (m_overflow)
@@ -429,7 +429,7 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
}
lineHeight = baseline + baselineToBottom;
} else if (parentLineHeight.isPercent()) {
- lineHeight = parentLineHeight.calcMinValue(curr->renderer()->style()->fontSize(), true);
+ lineHeight = parentLineHeight.calcMinValue(curr->renderer()->style()->fontSize());
baseline = 0;
for (size_t i = 0; i < usedFonts.size(); ++i) {
int halfLeading = (lineHeight - usedFonts[i]->ascent() - usedFonts[i]->descent()) / 2;
@@ -532,9 +532,6 @@ void InlineFlowBox::computeVerticalOverflow(int lineTop, int lineBottom, bool st
// Any spillage outside of the line top and bottom is not considered overflow. We just ignore this, since it only happens
// from the "your ascent/descent don't affect the line" quirk.
- // FIXME: Technically this means there can be repaint errors in the case where a line box has a shadow or background that spills
- // outside of the block. We should consider making any line box that has anything to render just stop respecting the quirk or making
- // boxes that render something set visual overflow.
int topOverflow = max(y(), lineTop);
int bottomOverflow = min(y() + boxHeight, lineBottom);
@@ -706,11 +703,11 @@ void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, con
// FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
// but it isn't even clear how this should work at all.
int xOffsetOnLine = 0;
- for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
+ for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
xOffsetOnLine += curr->width();
int startX = tx - xOffsetOnLine;
int totalWidth = xOffsetOnLine;
- for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
totalWidth += curr->width();
paintInfo.context->save();
paintInfo.context->clip(IntRect(tx, ty, width(), height()));
@@ -735,13 +732,24 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int
if (!renderer()->shouldPaintWithinRoot(paintInfo) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
return;
- // Move x/y to our coordinates.
- tx += m_x;
- ty += m_y;
-
+ int x = m_x;
+ int y = m_y;
int w = width();
int h = height();
+ // Constrain our background/border painting to the line top and bottom if necessary.
+ bool strictMode = renderer()->document()->inStrictMode();
+ if (!hasTextChildren() && !strictMode) {
+ RootInlineBox* rootBox = root();
+ int bottom = min(rootBox->lineBottom(), y + h);
+ y = max(rootBox->lineTop(), y);
+ h = bottom - y;
+ }
+
+ // Move x/y to our coordinates.
+ tx += x;
+ ty += y;
+
GraphicsContext* context = paintInfo.context;
// You can use p::first-line to specify a background. If so, the root line boxes for
@@ -780,11 +788,11 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int
// FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
// but it isn't even clear how this should work at all.
int xOffsetOnLine = 0;
- for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
+ for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
xOffsetOnLine += curr->width();
int startX = tx - xOffsetOnLine;
int totalWidth = xOffsetOnLine;
- for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
totalWidth += curr->width();
context->save();
context->clip(IntRect(tx, ty, w, h));
@@ -800,13 +808,24 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty
if (!renderer()->shouldPaintWithinRoot(paintInfo) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
return;
- // Move x/y to our coordinates.
- tx += m_x;
- ty += m_y;
-
+ int x = m_x;
+ int y = m_y;
int w = width();
int h = height();
+ // Constrain our background/border painting to the line top and bottom if necessary.
+ bool strictMode = renderer()->document()->inStrictMode();
+ if (!hasTextChildren() && !strictMode) {
+ RootInlineBox* rootBox = root();
+ int bottom = min(rootBox->lineBottom(), y + h);
+ y = max(rootBox->lineTop(), y);
+ h = bottom - y;
+ }
+
+ // Move x/y to our coordinates.
+ tx += x;
+ ty += y;
+
const NinePieceImage& maskNinePieceImage = renderer()->style()->maskBoxImage();
StyleImage* maskBoxImage = renderer()->style()->maskBoxImage().image();
@@ -840,11 +859,11 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty
// We have a mask image that spans multiple lines.
// We need to adjust _tx and _ty by the width of all previous lines.
int xOffsetOnLine = 0;
- for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
+ for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
xOffsetOnLine += curr->width();
int startX = tx - xOffsetOnLine;
int totalWidth = xOffsetOnLine;
- for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
totalWidth += curr->width();
paintInfo.context->save();
paintInfo.context->clip(IntRect(tx, ty, w, h));
@@ -974,6 +993,7 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
setClip = true;
}
+ ColorSpace colorSpace = renderer()->style()->colorSpace();
bool setShadow = false;
do {
if (shadow) {
@@ -982,24 +1002,24 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
ty -= extraOffset;
extraOffset = 0;
}
- context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color);
+ context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color, colorSpace);
setShadow = true;
shadow = shadow->next;
}
if (paintUnderline) {
- context->setStrokeColor(underline);
+ context->setStrokeColor(underline, colorSpace);
context->setStrokeStyle(SolidStroke);
// Leave one pixel of white between the baseline and the underline.
context->drawLineForText(IntPoint(tx, ty + baselinePos + 1), w, isPrinting);
}
if (paintOverline) {
- context->setStrokeColor(overline);
+ context->setStrokeColor(overline, colorSpace);
context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty), w, isPrinting);
}
if (paintLineThrough) {
- context->setStrokeColor(linethrough);
+ context->setStrokeColor(linethrough, colorSpace);
context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty + 2 * baselinePos / 3), w, isPrinting);
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h
index 23b5cc99e2..ecb4724b0d 100644
--- a/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h
+++ b/src/3rdparty/webkit/WebCore/rendering/InlineFlowBox.h
@@ -21,7 +21,7 @@
#ifndef InlineFlowBox_h
#define InlineFlowBox_h
-#include "InlineRunBox.h"
+#include "InlineBox.h"
#include "RenderOverflow.h"
namespace WebCore {
@@ -30,12 +30,14 @@ class HitTestRequest;
class HitTestResult;
class RenderLineBoxList;
-class InlineFlowBox : public InlineRunBox {
+class InlineFlowBox : public InlineBox {
public:
InlineFlowBox(RenderObject* obj)
- : InlineRunBox(obj)
+ : InlineBox(obj)
, m_firstChild(0)
, m_lastChild(0)
+ , m_prevLineBox(0)
+ , m_nextLineBox(0)
, m_includeLeftEdge(false)
, m_includeRightEdge(false)
#ifndef NDEBUG
@@ -54,8 +56,10 @@ public:
virtual ~InlineFlowBox();
#endif
- InlineFlowBox* prevFlowBox() const { return static_cast<InlineFlowBox*>(m_prevLine); }
- InlineFlowBox* nextFlowBox() const { return static_cast<InlineFlowBox*>(m_nextLine); }
+ InlineFlowBox* prevLineBox() const { return m_prevLineBox; }
+ InlineFlowBox* nextLineBox() const { return m_nextLineBox; }
+ void setNextLineBox(InlineFlowBox* n) { m_nextLineBox = n; }
+ void setPreviousLineBox(InlineFlowBox* p) { m_prevLineBox = p; }
InlineBox* firstChild() const { checkConsistency(); return m_firstChild; }
InlineBox* lastChild() const { checkConsistency(); return m_lastChild; }
@@ -164,12 +168,14 @@ public:
protected:
OwnPtr<RenderOverflow> m_overflow;
-private:
virtual bool isInlineFlowBox() const { return true; }
InlineBox* m_firstChild;
InlineBox* m_lastChild;
+ InlineFlowBox* m_prevLineBox; // The previous box that also uses our RenderObject
+ InlineFlowBox* m_nextLineBox; // The next box that also uses our RenderObject
+
bool m_includeLeftEdge : 1;
bool m_includeRightEdge : 1;
bool m_hasTextChildren : 1;
diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineIterator.h b/src/3rdparty/webkit/WebCore/rendering/InlineIterator.h
new file mode 100644
index 0000000000..9310ea8ab8
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/InlineIterator.h
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right reserved.
+ * Copyright (C) 2010 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 InlineIterator_h
+#define InlineIterator_h
+
+#include "BidiRun.h"
+#include "RenderBlock.h"
+#include "RenderText.h"
+#include <wtf/AlwaysInline.h>
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+class InlineIterator {
+public:
+ InlineIterator()
+ : block(0)
+ , obj(0)
+ , pos(0)
+ , nextBreakablePosition(-1)
+ {
+ }
+
+ InlineIterator(RenderBlock* b, RenderObject* o, unsigned p)
+ : block(b)
+ , obj(o)
+ , pos(p)
+ , nextBreakablePosition(-1)
+ {
+ }
+
+ void increment(InlineBidiResolver* resolver = 0);
+ bool atEnd() const;
+
+ UChar current() const;
+ WTF::Unicode::Direction direction() const;
+
+ RenderBlock* block;
+ RenderObject* obj;
+ unsigned pos;
+ int nextBreakablePosition;
+};
+
+inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
+{
+ return it1.pos == it2.pos && it1.obj == it2.obj;
+}
+
+inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
+{
+ return it1.pos != it2.pos || it1.obj != it2.obj;
+}
+
+static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, InlineBidiResolver* resolver = 0, bool skipInlines = true, bool* endOfInlinePtr = 0)
+{
+ RenderObject* next = 0;
+ bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;
+ bool endOfInline = false;
+
+ while (current) {
+ next = 0;
+ if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned() && !current->isText()) {
+ next = current->firstChild();
+ if (next && resolver && next->isRenderInline()) {
+ EUnicodeBidi ub = next->style()->unicodeBidi();
+ if (ub != UBNormal) {
+ TextDirection dir = next->style()->direction();
+ WTF::Unicode::Direction d = (ub == Embed
+ ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding : WTF::Unicode::LeftToRightEmbedding)
+ : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride));
+ resolver->embed(d);
+ }
+ }
+ }
+
+ if (!next) {
+ if (!skipInlines && !oldEndOfInline && current->isRenderInline()) {
+ next = current;
+ endOfInline = true;
+ break;
+ }
+
+ while (current && current != block) {
+ if (resolver && current->isRenderInline() && current->style()->unicodeBidi() != UBNormal)
+ resolver->embed(WTF::Unicode::PopDirectionalFormat);
+
+ next = current->nextSibling();
+ if (next) {
+ if (resolver && next->isRenderInline()) {
+ EUnicodeBidi ub = next->style()->unicodeBidi();
+ if (ub != UBNormal) {
+ TextDirection dir = next->style()->direction();
+ WTF::Unicode::Direction d = (ub == Embed
+ ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding: WTF::Unicode::LeftToRightEmbedding)
+ : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride));
+ resolver->embed(d);
+ }
+ }
+ break;
+ }
+
+ current = current->parent();
+ if (!skipInlines && current && current != block && current->isRenderInline()) {
+ next = current;
+ endOfInline = true;
+ break;
+ }
+ }
+ }
+
+ if (!next)
+ break;
+
+ if (next->isText() || next->isFloating() || next->isReplaced() || next->isPositioned()
+ || ((!skipInlines || !next->firstChild()) // Always return EMPTY inlines.
+ && next->isRenderInline()))
+ break;
+ current = next;
+ }
+
+ if (endOfInlinePtr)
+ *endOfInlinePtr = endOfInline;
+
+ return next;
+}
+
+static inline RenderObject* bidiFirst(RenderBlock* block, InlineBidiResolver* resolver, bool skipInlines = true)
+{
+ if (!block->firstChild())
+ return 0;
+
+ RenderObject* o = block->firstChild();
+ if (o->isRenderInline()) {
+ if (resolver) {
+ EUnicodeBidi ub = o->style()->unicodeBidi();
+ if (ub != UBNormal) {
+ TextDirection dir = o->style()->direction();
+ WTF::Unicode::Direction d = (ub == Embed
+ ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding : WTF::Unicode::LeftToRightEmbedding)
+ : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride));
+ resolver->embed(d);
+ }
+ }
+ if (skipInlines && o->firstChild())
+ o = bidiNext(block, o, resolver, skipInlines);
+ else {
+ // Never skip empty inlines.
+ if (resolver)
+ resolver->commitExplicitEmbedding();
+ return o;
+ }
+ }
+
+ if (o && !o->isText() && !o->isReplaced() && !o->isFloating() && !o->isPositioned())
+ o = bidiNext(block, o, resolver, skipInlines);
+
+ if (resolver)
+ resolver->commitExplicitEmbedding();
+ return o;
+}
+
+inline void InlineIterator::increment(InlineBidiResolver* resolver)
+{
+ if (!obj)
+ return;
+ if (obj->isText()) {
+ pos++;
+ if (pos >= toRenderText(obj)->textLength()) {
+ obj = bidiNext(block, obj, resolver);
+ pos = 0;
+ nextBreakablePosition = -1;
+ }
+ } else {
+ obj = bidiNext(block, obj, resolver);
+ pos = 0;
+ nextBreakablePosition = -1;
+ }
+}
+
+inline bool InlineIterator::atEnd() const
+{
+ return !obj;
+}
+
+inline UChar InlineIterator::current() const
+{
+ if (!obj || !obj->isText())
+ return 0;
+
+ RenderText* text = toRenderText(obj);
+ if (pos >= text->textLength())
+ return 0;
+
+ return text->characters()[pos];
+}
+
+ALWAYS_INLINE WTF::Unicode::Direction InlineIterator::direction() const
+{
+ if (UChar c = current())
+ return WTF::Unicode::direction(c);
+
+ if (obj && obj->isListMarker())
+ return obj->style()->direction() == LTR ? WTF::Unicode::LeftToRight : WTF::Unicode::RightToLeft;
+
+ return WTF::Unicode::OtherNeutral;
+}
+
+template<>
+inline void InlineBidiResolver::increment()
+{
+ current.increment(this);
+}
+
+template <>
+inline void InlineBidiResolver::appendRun()
+{
+ if (!emptyRun && !eor.atEnd()) {
+ int start = sor.pos;
+ RenderObject *obj = sor.obj;
+ while (obj && obj != eor.obj && obj != endOfLine.obj) {
+ RenderBlock::appendRunsForObject(start, obj->length(), obj, *this);
+ start = 0;
+ obj = bidiNext(sor.block, obj);
+ }
+ if (obj) {
+ unsigned pos = obj == eor.obj ? eor.pos : UINT_MAX;
+ if (obj == endOfLine.obj && endOfLine.pos <= pos) {
+ reachedEndOfLine = true;
+ pos = endOfLine.pos;
+ }
+ // It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
+ int end = obj->length() ? pos+1 : 0;
+ RenderBlock::appendRunsForObject(start, end, obj, *this);
+ }
+
+ eor.increment();
+ sor = eor;
+ }
+
+ m_direction = WTF::Unicode::OtherNeutral;
+ m_status.eor = WTF::Unicode::OtherNeutral;
+}
+
+}
+
+#endif // InlineIterator_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineRunBox.h b/src/3rdparty/webkit/WebCore/rendering/InlineRunBox.h
deleted file mode 100644
index 0f7c29bf1b..0000000000
--- a/src/3rdparty/webkit/WebCore/rendering/InlineRunBox.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This file is part of the line box implementation for KDE.
- *
- * Copyright (C) 2003, 2006 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef InlineRunBox_h
-#define InlineRunBox_h
-
-#include "InlineBox.h"
-
-namespace WebCore {
-
-class InlineRunBox : public InlineBox {
-public:
- InlineRunBox(RenderObject* obj)
- : InlineBox(obj)
- , m_prevLine(0)
- , m_nextLine(0)
- {
- }
-
- InlineRunBox* prevLineBox() const { return m_prevLine; }
- InlineRunBox* nextLineBox() const { return m_nextLine; }
- void setNextLineBox(InlineRunBox* n) { m_nextLine = n; }
- void setPreviousLineBox(InlineRunBox* p) { m_prevLine = p; }
-
- virtual void paintBoxDecorations(RenderObject::PaintInfo&, int /*tx*/, int /*ty*/) { }
- virtual void paintTextDecorations(RenderObject::PaintInfo&, int /*tx*/, int /*ty*/, bool /*paintedChildren*/ = false) { }
-
-protected:
- InlineRunBox* m_prevLine; // The previous box that also uses our RenderObject
- InlineRunBox* m_nextLine; // The next box that also uses our RenderObject
-};
-
-} // namespace WebCore
-
-#endif // InlineRunBox_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp b/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp
index 751340d5f4..9f17b0c05d 100644
--- a/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.cpp
@@ -23,9 +23,11 @@
#include "config.h"
#include "InlineTextBox.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
#include "Editor.h"
+#include "EllipsisBox.h"
#include "Frame.h"
#include "GraphicsContext.h"
#include "HitTestResult.h"
@@ -81,6 +83,23 @@ RenderObject::SelectionState InlineTextBox::selectionState()
else if (state == RenderObject::SelectionBoth)
state = RenderObject::SelectionNone;
}
+
+ // If there are ellipsis following, make sure their selection is updated.
+ if (m_truncation != cNoTruncation && root()->ellipsisBox()) {
+ EllipsisBox* ellipsis = root()->ellipsisBox();
+ if (state != RenderObject::SelectionNone) {
+ int start, end;
+ selectionStartEnd(start, end);
+ // The ellipsis should be considered to be selected if the end of
+ // the selection is past the beginning of the truncation and the
+ // beginning of the selection is before or at the beginning of the
+ // truncation.
+ ellipsis->setSelectionState(end >= m_truncation && start <= m_truncation ?
+ RenderObject::SelectionInside : RenderObject::SelectionNone);
+ } else
+ ellipsis->setSelectionState(RenderObject::SelectionNone);
+ }
+
return state;
}
@@ -89,7 +108,7 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos)
int sPos = max(startPos - m_start, 0);
int ePos = min(endPos - m_start, (int)m_len);
- if (sPos >= ePos)
+ if (sPos > ePos)
return IntRect();
RenderText* textObj = textRenderer();
@@ -214,7 +233,7 @@ Color correctedTextColor(Color textColor, Color backgroundColor)
return textColor.light();
}
-void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, const Color& strokeColor, float strokeThickness)
+void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, const Color& strokeColor, float strokeThickness, ColorSpace colorSpace)
{
int mode = context->textDrawingMode();
if (strokeThickness > 0) {
@@ -225,12 +244,12 @@ void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, con
}
}
- if (mode & cTextFill && fillColor != context->fillColor())
- context->setFillColor(fillColor);
+ if (mode & cTextFill && (fillColor != context->fillColor() || colorSpace != context->fillColorSpace()))
+ context->setFillColor(fillColor, colorSpace);
if (mode & cTextStroke) {
if (strokeColor != context->strokeColor())
- context->setStrokeColor(strokeColor);
+ context->setStrokeColor(strokeColor, colorSpace);
if (strokeThickness != context->strokeThickness())
context->setStrokeThickness(strokeThickness);
}
@@ -254,12 +273,13 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in
return false;
}
-static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, int startOffset, int endOffset, const IntPoint& textOrigin, int x, int y, int w, int h, ShadowData* shadow, bool stroked)
+static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, int startOffset, int endOffset, int truncationPoint, const IntPoint& textOrigin, int x, int y, int w, int h, ShadowData* shadow, bool stroked)
{
Color fillColor = context->fillColor();
+ ColorSpace fillColorSpace = context->fillColorSpace();
bool opaque = fillColor.alpha() == 255;
if (!opaque)
- context->setFillColor(Color::black);
+ context->setFillColor(Color::black, fillColorSpace);
do {
IntSize extraOffset;
@@ -279,17 +299,17 @@ static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
extraOffset = IntSize(0, 2 * h + max(0, shadowOffset.height()) + shadowBlur);
shadowOffset -= extraOffset;
}
- context->setShadow(shadowOffset, shadowBlur, shadowColor);
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, fillColorSpace);
} else if (!opaque)
- context->setFillColor(fillColor);
+ context->setFillColor(fillColor, fillColorSpace);
if (startOffset <= endOffset)
context->drawText(font, textRun, textOrigin + extraOffset, startOffset, endOffset);
else {
if (endOffset > 0)
context->drawText(font, textRun, textOrigin + extraOffset, 0, endOffset);
- if (startOffset < textRun.length())
- context->drawText(font, textRun, textOrigin + extraOffset, startOffset);
+ if (startOffset < truncationPoint)
+ context->drawText(font, textRun, textOrigin + extraOffset, startOffset, truncationPoint);
}
if (!shadow)
@@ -459,18 +479,25 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
if (paintSelectedTextOnly || paintSelectedTextSeparately)
selectionStartEnd(sPos, ePos);
+ int length = m_len;
+ if (m_truncation != cNoTruncation) {
+ sPos = min<int>(sPos, m_truncation);
+ ePos = min<int>(ePos, m_truncation);
+ length = m_truncation;
+ }
+
if (!paintSelectedTextOnly) {
// For stroked painting, we have to change the text drawing mode. It's probably dangerous to leave that mutated as a side
// effect, so only when we know we're stroking, do a save/restore.
if (textStrokeWidth > 0)
context->save();
- updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth);
+ updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());
if (!paintSelectedTextSeparately || ePos <= sPos) {
// FIXME: Truncate right-to-left text correctly.
- paintTextWithShadows(context, font, textRun, 0, m_truncation == cNoTruncation ? m_len : m_truncation, textOrigin, m_x + tx, m_y + ty, width(), height(), textShadow, textStrokeWidth > 0);
+ paintTextWithShadows(context, font, textRun, 0, length, length, textOrigin, m_x + tx, m_y + ty, width(), height(), textShadow, textStrokeWidth > 0);
} else
- paintTextWithShadows(context, font, textRun, ePos, sPos, textOrigin, m_x + tx, m_y + ty, width(), height(), textShadow, textStrokeWidth > 0);
+ paintTextWithShadows(context, font, textRun, ePos, sPos, length, textOrigin, m_x + tx, m_y + ty, width(), height(), textShadow, textStrokeWidth > 0);
if (textStrokeWidth > 0)
context->restore();
@@ -481,8 +508,8 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
if (selectionStrokeWidth > 0)
context->save();
- updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth);
- paintTextWithShadows(context, font, textRun, sPos, ePos, textOrigin, m_x + tx, m_y + ty, width(), height(), selectionShadow, selectionStrokeWidth > 0);
+ updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth, styleToUse->colorSpace());
+ paintTextWithShadows(context, font, textRun, sPos, ePos, length, textOrigin, m_x + tx, m_y + ty, width(), height(), selectionShadow, selectionStrokeWidth > 0);
if (selectionStrokeWidth > 0)
context->restore();
@@ -490,7 +517,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
// Paint decorations
if (d != TDNONE && paintInfo.phase != PaintPhaseSelection && styleToUse->htmlHacks()) {
- context->setStrokeColor(styleToUse->color());
+ context->setStrokeColor(styleToUse->color(), styleToUse->colorSpace());
paintDecoration(context, tx, ty, d, textShadow);
}
@@ -561,13 +588,16 @@ void InlineTextBox::paintSelection(GraphicsContext* context, int tx, int ty, Ren
c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
context->save();
- updateGraphicsContext(context, c, c, 0); // Don't draw text at all!
+ updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw text at all!
int y = selectionTop();
int h = selectionHeight();
+ // If the text is truncated, let the thing being painted in the truncation
+ // draw its own highlight.
+ int length = m_truncation != cNoTruncation ? m_truncation : m_len;
context->clip(IntRect(m_x + tx, y + ty, m_width, h));
- context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
+ context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, length, textRenderer()->allowTabs(), textPos(), m_toAdd,
direction() == RTL, m_dirOverride || style->visuallyOrdered()),
- IntPoint(m_x + tx, y + ty), h, c, sPos, ePos);
+ IntPoint(m_x + tx, y + ty), h, c, style->colorSpace(), sPos, ePos);
context->restore();
}
@@ -584,13 +614,13 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, int tx,
Color c = Color(225, 221, 85);
- updateGraphicsContext(context, c, c, 0); // Don't draw text at all!
+ updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw text at all!
int y = selectionTop();
int h = selectionHeight();
context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
direction() == RTL, m_dirOverride || style->visuallyOrdered()),
- IntPoint(m_x + tx, y + ty), h, c, sPos, ePos);
+ IntPoint(m_x + tx, y + ty), h, c, style->colorSpace(), sPos, ePos);
context->restore();
}
@@ -660,6 +690,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
setClip = true;
}
+ ColorSpace colorSpace = renderer()->style()->colorSpace();
bool setShadow = false;
do {
@@ -669,24 +700,24 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
ty -= extraOffset;
extraOffset = 0;
}
- context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color);
+ context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color, colorSpace);
setShadow = true;
shadow = shadow->next;
}
if (deco & UNDERLINE) {
- context->setStrokeColor(underline);
+ context->setStrokeColor(underline, colorSpace);
context->setStrokeStyle(SolidStroke);
// Leave one pixel of white between the baseline and the underline.
context->drawLineForText(IntPoint(tx, ty + baseline + 1), width, isPrinting);
}
if (deco & OVERLINE) {
- context->setStrokeColor(overline);
+ context->setStrokeColor(overline, colorSpace);
context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty), width, isPrinting);
}
if (deco & LINE_THROUGH) {
- context->setStrokeColor(linethrough);
+ context->setStrokeColor(linethrough, colorSpace);
context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty + 2 * baseline / 3), width, isPrinting);
}
@@ -698,7 +729,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
context->clearShadow();
}
-void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font, bool grammar)
+void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
{
// Never print spelling/grammar markers (5327887)
if (textRenderer()->document()->printing())
@@ -737,8 +768,11 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
// Store rendered rects for bad grammar markers, so we can hit-test against it elsewhere in order to
// display a toolTip. We don't do this for misspelling markers.
- if (grammar)
+ if (grammar) {
+ markerRect.move(-tx, -ty);
+ markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
+ }
}
// IMPORTANT: The misspelling underline is not considered when calculating the text bounds, so we have to
@@ -761,7 +795,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
pt->drawLineForMisspellingOrBadGrammar(IntPoint(tx + m_x + start, ty + m_y + underlineOffset), width, grammar);
}
-void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font)
+void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font)
{
// Use same y positioning and height as for selection, so that when the selection and this highlight are on
// the same word there are no pieces sticking out.
@@ -771,10 +805,10 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, Do
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
- IntPoint startPoint = IntPoint(m_x + tx, y + ty);
- // Always compute and store the rect associated with this marker
- IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
+ // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
+ IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, y), h, sPos, ePos));
+ markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
// Optionally highlight the text
@@ -783,14 +817,14 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, Do
renderer()->theme()->platformActiveTextSearchHighlightColor() :
renderer()->theme()->platformInactiveTextSearchHighlightColor();
pt->save();
- updateGraphicsContext(pt, color, color, 0); // Don't draw text at all!
+ updateGraphicsContext(pt, color, color, 0, style->colorSpace()); // Don't draw text at all!
pt->clip(IntRect(tx + m_x, ty + y, m_width, h));
- pt->drawHighlightForText(font, run, startPoint, h, color, sPos, ePos);
+ pt->drawHighlightForText(font, run, IntPoint(m_x + tx, y + ty), h, color, style->colorSpace(), sPos, ePos);
pt->restore();
}
}
-void InlineTextBox::computeRectForReplacementMarker(int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font)
+void InlineTextBox::computeRectForReplacementMarker(int /*tx*/, int /*ty*/, const DocumentMarker& marker, RenderStyle* style, const Font& font)
{
// Replacement markers are not actually drawn, but their rects need to be computed for hit testing.
int y = selectionTop();
@@ -799,10 +833,11 @@ void InlineTextBox::computeRectForReplacementMarker(int tx, int ty, DocumentMark
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
- IntPoint startPoint = IntPoint(m_x + tx, y + ty);
+ IntPoint startPoint = IntPoint(m_x, y);
// Compute and store the rect associated with this marker.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
+ markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
}
@@ -817,7 +852,7 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, Re
// Give any document markers that touch this run a chance to draw before the text has been drawn.
// Note end() points at the last char, not one past it like endOffset and ranges do.
for ( ; markerIt != markers.end(); markerIt++) {
- DocumentMarker marker = *markerIt;
+ const DocumentMarker& marker = *markerIt;
// Paint either the background markers or the foreground markers, but not both
switch (marker.type) {
@@ -911,7 +946,7 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, int tx, int
start += 1;
width -= 2;
- ctx->setStrokeColor(underline.color);
+ ctx->setStrokeColor(underline.color, renderer()->style()->colorSpace());
ctx->setStrokeThickness(lineThickness);
ctx->drawLineForText(IntPoint(tx + start, ty + height() - lineThickness), width, textRenderer()->document()->printing());
}
@@ -936,7 +971,7 @@ int InlineTextBox::textPos() const
if (x() == 0)
return 0;
- RenderBlock *blockElement = renderer()->containingBlock();
+ RenderBlock* blockElement = renderer()->containingBlock();
return direction() == RTL ? x() - blockElement->borderRight() - blockElement->paddingRight()
: x() - blockElement->borderLeft() - blockElement->paddingLeft();
}
@@ -947,7 +982,7 @@ int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const
return 0;
RenderText* text = toRenderText(renderer());
- RenderStyle *style = text->style(m_firstLine);
+ RenderStyle* style = text->style(m_firstLine);
const Font* f = &style->font();
return f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()),
_x - m_x, includePartialGlyphs);
diff --git a/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.h b/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.h
index 3bbb4537ad..96ca4c3873 100644
--- a/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.h
+++ b/src/3rdparty/webkit/WebCore/rendering/InlineTextBox.h
@@ -23,7 +23,7 @@
#ifndef InlineTextBox_h
#define InlineTextBox_h
-#include "InlineRunBox.h"
+#include "InlineBox.h"
#include "RenderText.h" // so textRenderer() can be inline
namespace WebCore {
@@ -34,21 +34,25 @@ const unsigned short cNoTruncation = USHRT_MAX;
const unsigned short cFullTruncation = USHRT_MAX - 1;
// Helper functions shared by InlineTextBox / SVGRootInlineBox
-void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, const Color& strokeColor, float strokeThickness);
+void updateGraphicsContext(GraphicsContext*, const Color& fillColor, const Color& strokeColor, float strokeThickness, ColorSpace);
Color correctedTextColor(Color textColor, Color backgroundColor);
-class InlineTextBox : public InlineRunBox {
+class InlineTextBox : public InlineBox {
public:
InlineTextBox(RenderObject* obj)
- : InlineRunBox(obj)
+ : InlineBox(obj)
+ , m_prevTextBox(0)
+ , m_nextTextBox(0)
, m_start(0)
, m_len(0)
, m_truncation(cNoTruncation)
{
}
- InlineTextBox* nextTextBox() const { return static_cast<InlineTextBox*>(nextLineBox()); }
- InlineTextBox* prevTextBox() const { return static_cast<InlineTextBox*>(prevLineBox()); }
+ InlineTextBox* prevTextBox() const { return m_prevTextBox; }
+ InlineTextBox* nextTextBox() const { return m_nextTextBox; }
+ void setNextTextBox(InlineTextBox* n) { m_nextTextBox = n; }
+ void setPreviousTextBox(InlineTextBox* p) { m_prevTextBox = p; }
unsigned start() const { return m_start; }
unsigned end() const { return m_len ? m_start + m_len - 1 : m_start; }
@@ -62,6 +66,8 @@ public:
void setFallbackFonts(const HashSet<const SimpleFontData*>&);
void takeFallbackFonts(Vector<const SimpleFontData*>&);
+ unsigned short truncation() { return m_truncation; }
+
private:
virtual int selectionTop();
virtual int selectionHeight();
@@ -114,6 +120,9 @@ public:
bool containsCaretOffset(int offset) const; // false for offset after line break
private:
+ InlineTextBox* m_prevTextBox; // The previous box that also uses our RenderObject
+ InlineTextBox* m_nextTextBox; // The next box that also uses our RenderObject
+
int m_start;
unsigned short m_len;
@@ -131,9 +140,9 @@ protected:
private:
void paintDecoration(GraphicsContext*, int tx, int ty, int decoration, ShadowData*);
void paintSelection(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&);
- void paintSpellingOrGrammarMarker(GraphicsContext*, int tx, int ty, DocumentMarker, RenderStyle*, const Font&, bool grammar);
- void paintTextMatchMarker(GraphicsContext*, int tx, int ty, DocumentMarker, RenderStyle*, const Font&);
- void computeRectForReplacementMarker(int tx, int ty, DocumentMarker, RenderStyle*, const Font&);
+ void paintSpellingOrGrammarMarker(GraphicsContext*, int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&, bool grammar);
+ void paintTextMatchMarker(GraphicsContext*, int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&);
+ void computeRectForReplacementMarker(int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&);
};
inline RenderText* InlineTextBox::textRenderer() const
diff --git a/src/3rdparty/webkit/WebCore/rendering/LayoutState.cpp b/src/3rdparty/webkit/WebCore/rendering/LayoutState.cpp
index 883f74d563..c94e77b702 100644
--- a/src/3rdparty/webkit/WebCore/rendering/LayoutState.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/LayoutState.cpp
@@ -62,20 +62,17 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const IntSize&
m_clipped = !fixed && prev->m_clipped;
if (m_clipped)
m_clipRect = prev->m_clipRect;
+
if (renderer->hasOverflowClip()) {
- int x = m_offset.width();
- int y = m_offset.height();
RenderLayer* layer = renderer->layer();
- IntRect clipRect(x, y, layer->width(), layer->height());
- clipRect.move(renderer->view()->layoutDelta());
+ IntRect clipRect(toPoint(m_offset) + renderer->view()->layoutDelta(), layer->size());
if (m_clipped)
m_clipRect.intersect(clipRect);
else {
m_clipRect = clipRect;
m_clipped = true;
}
- layer->subtractScrolledContentOffset(x, y);
- m_offset = IntSize(x, y);
+ m_offset -= layer->scrolledContentOffset();
}
m_layoutDelta = m_next->m_layoutDelta;
diff --git a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp
index 9611660427..569f214845 100644
--- a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp
@@ -38,6 +38,7 @@
#include "HTMLNames.h"
#include "LocalizedStrings.h"
#include "MouseEvent.h"
+#include "Page.h"
#include "RenderMedia.h"
#include "RenderSlider.h"
#include "RenderTheme.h"
@@ -347,6 +348,9 @@ MediaControlInputElement::MediaControlInputElement(Document* document, PseudoId
case MEDIA_CONTROLS_VOLUME_SLIDER:
m_displayType = MediaVolumeSlider;
break;
+ case MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON:
+ m_displayType = MediaShowClosedCaptionsButton;
+ break;
default:
ASSERT_NOT_REACHED();
break;
@@ -500,7 +504,7 @@ void MediaControlSeekButtonElement::defaultEventHandler(Event* event)
m_capturing = true;
frame->eventHandler()->setCapturingMouseEventsNode(this);
}
- m_mediaElement->pause();
+ m_mediaElement->pause(event->fromUserGesture());
m_seekTimer.startRepeating(cSeekRepeatDelay);
event->setDefaultHandled();
} else if (event->type() == eventNames().mouseupEvent) {
@@ -577,6 +581,29 @@ void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event
// ----------------------------
+MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document* doc, HTMLMediaElement* element)
+ : MediaControlInputElement(doc, MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON, "button", element)
+{
+}
+
+void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ m_mediaElement->setClosedCaptionsVisible(!m_mediaElement->closedCaptionsVisible());
+ setChecked(m_mediaElement->closedCaptionsVisible());
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
+{
+ setDisplayType(m_mediaElement->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
+}
+
+
+// ----------------------------
+
MediaControlTimelineElement::MediaControlTimelineElement(Document* document, HTMLMediaElement* element)
: MediaControlInputElement(document, MEDIA_CONTROLS_TIMELINE, "range", element)
{
@@ -588,6 +615,9 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event)
if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
return;
+ if (!attached())
+ return;
+
if (event->type() == eventNames().mousedownEvent)
m_mediaElement->beginScrubbing();
@@ -633,6 +663,9 @@ void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
return;
+ if (!attached())
+ return;
+
MediaControlInputElement::defaultEventHandler(event);
if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
@@ -649,10 +682,9 @@ void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
void MediaControlVolumeSliderElement::update()
{
float volume = m_mediaElement->volume();
- if (value().toFloat() != volume) {
+ if (value().toFloat() != volume)
setValue(String::number(volume));
- MediaControlInputElement::update();
- }
+ MediaControlInputElement::update();
}
// ----------------------------
@@ -705,30 +737,9 @@ void MediaControlTimeDisplayElement::setVisible(bool visible)
renderer()->setStyle(style.get());
}
-String MediaControlTimeDisplayElement::formatTime(float time)
-{
- if (!isfinite(time))
- time = 0;
- int seconds = (int)fabsf(time);
- int hours = seconds / (60 * 60);
- int minutes = (seconds / 60) % 60;
- seconds %= 60;
- if (hours) {
- if (hours > 9)
- return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
-
- return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
- }
-
- return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
-}
-
void MediaControlTimeDisplayElement::setCurrentValue(float time)
{
m_currentValue = time;
-
- ExceptionCode ec;
- setInnerText(formatTime(m_currentValue), ec);
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h
index 8b297733fd..21831ceef7 100644
--- a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h
+++ b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.h
@@ -54,6 +54,8 @@ enum MediaControlElementType {
MediaSliderThumb,
MediaRewindButton,
MediaReturnToRealtimeButton,
+ MediaShowClosedCaptionsButton,
+ MediaHideClosedCaptionsButton,
MediaUnMuteButton,
MediaPauseButton,
MediaTimelineContainer,
@@ -221,6 +223,15 @@ public:
// ----------------------------
+class MediaControlToggleClosedCaptionsButtonElement : public MediaControlInputElement {
+public:
+ MediaControlToggleClosedCaptionsButtonElement(Document*, HTMLMediaElement*);
+ virtual void defaultEventHandler(Event*);
+ virtual void updateDisplayType();
+};
+
+// ----------------------------
+
class MediaControlTimelineElement : public MediaControlInputElement {
public:
MediaControlTimelineElement(Document*, HTMLMediaElement*);
@@ -257,8 +268,6 @@ public:
float currentValue() const { return m_currentValue; }
private:
- String formatTime(float time);
-
float m_currentValue;
bool m_isVisible;
};
diff --git a/src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.cpp b/src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.cpp
index 214fb096a0..ababcfd40f 100644
--- a/src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.cpp
@@ -1,8 +1,6 @@
/*
Copyright (C) 2007 Rob Buis <buis@kde.org>
- This file is part of the KDE project
-
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
diff --git a/src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.h b/src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.h
index 3d8939a76a..c17c19c7b7 100644
--- a/src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.h
+++ b/src/3rdparty/webkit/WebCore/rendering/PointerEventsHitRules.h
@@ -1,8 +1,6 @@
/*
Copyright (C) 2007 Rob Buis <buis@kde.org>
- This file is part of the KDE project
-
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderArena.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderArena.cpp
index 34325d4be9..1dafb2f1c5 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderArena.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderArena.cpp
@@ -114,7 +114,7 @@ void RenderArena::free(size_t size, void* ptr)
// Use standard free so that memory debugging tools work.
RenderArenaDebugHeader* header = static_cast<RenderArenaDebugHeader*>(ptr) - 1;
ASSERT(header->signature == signature);
- ASSERT(header->size == size);
+ ASSERT_UNUSED(size, header->size == size);
ASSERT(header->arena == this);
header->signature = signatureDead;
::free(header);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderArena.h b/src/3rdparty/webkit/WebCore/rendering/RenderArena.h
index 3c27d15455..32139fbd77 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderArena.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderArena.h
@@ -36,12 +36,13 @@
#define RenderArena_h
#include "Arena.h"
+#include <wtf/Noncopyable.h>
namespace WebCore {
static const size_t gMaxRecycledSize = 400;
-class RenderArena {
+class RenderArena : public Noncopyable {
public:
RenderArena(unsigned arenaSize = 4096);
~RenderArena();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBR.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBR.cpp
index e05c8b4733..340d6b7927 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderBR.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderBR.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* Copyright (C) 2006 Apple Computer, Inc.
*
@@ -64,7 +62,7 @@ int RenderBR::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
return s->font().lineSpacing();
}
if (lh.isPercent())
- return lh.calcMinValue(s->fontSize(), true);
+ return lh.calcMinValue(s->fontSize());
return lh.value();
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBR.h b/src/3rdparty/webkit/WebCore/rendering/RenderBR.h
index 7eae8ea407..8850d4693f 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderBR.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderBR.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
*
* This library is free software; you can redistribute it and/or
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp
index d5bb7787c4..a7b8a0227f 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2007 David Smith (catfish.man@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -44,6 +44,7 @@
#include "RenderView.h"
#include "SelectionController.h"
#include "Settings.h"
+#include "TransformState.h"
#include <wtf/StdLibExtras.h>
using namespace std;
@@ -58,13 +59,7 @@ static const int verticalLineClickFudgeFactor = 3;
using namespace HTMLNames;
-static void moveChild(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* from, RenderObjectChildList* fromChildList, RenderObject* child)
-{
- ASSERT(from == child->parent());
- toChildList->appendChildNode(to, fromChildList->removeChildNode(from, child, false), false);
-}
-
-struct ColumnInfo {
+struct ColumnInfo : public Noncopyable {
ColumnInfo()
: m_desiredColumnWidth(0)
, m_desiredColumnCount(1)
@@ -188,7 +183,7 @@ void RenderBlock::destroy()
// that will outlast this block. In the non-anonymous block case those
// children will be destroyed by the time we return from this function.
if (isAnonymousBlock()) {
- for (InlineFlowBox* box = firstLineBox(); box; box = box->nextFlowBox()) {
+ for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
while (InlineBox* childBox = box->firstChild())
childBox->remove();
}
@@ -266,8 +261,14 @@ void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
// Make sure we don't append things after :after-generated content if we have it.
- if (!beforeChild && isAfterContent(lastChild()))
- beforeChild = lastChild();
+ if (!beforeChild) {
+ RenderObject* lastRenderer = lastChild();
+
+ if (isAfterContent(lastRenderer))
+ beforeChild = lastRenderer;
+ else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild()))
+ beforeChild = lastRenderer->lastChild();
+ }
bool madeBoxesNonInline = false;
@@ -402,6 +403,44 @@ RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
m_lineBoxes.appendLineBox(rootBox);
return rootBox;
}
+
+void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child)
+{
+ ASSERT(this == child->parent());
+ toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false);
+}
+
+void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child)
+{
+ ASSERT(this == child->parent());
+ ASSERT(!beforeChild || to == beforeChild->parent());
+ toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false);
+}
+
+void RenderBlock::moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList)
+{
+ RenderObject* nextChild = children()->firstChild();
+ while (nextChild) {
+ RenderObject* child = nextChild;
+ nextChild = child->nextSibling();
+ toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false);
+ }
+}
+
+void RenderBlock::moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild)
+{
+ ASSERT(!beforeChild || to == beforeChild->parent());
+ if (!beforeChild) {
+ moveAllChildrenTo(to, toChildList);
+ return;
+ }
+ RenderObject* nextChild = children()->firstChild();
+ while (nextChild) {
+ RenderObject* child = nextChild;
+ nextChild = child->nextSibling();
+ toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false);
+ }
+}
void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
{
@@ -439,9 +478,9 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
RenderObject* no = o;
o = no->nextSibling();
- moveChild(block, block->children(), this, children(), no);
+ moveChildTo(block, block->children(), no);
}
- moveChild(block, block->children(), this, children(), inlineRunEnd);
+ moveChildTo(block, block->children(), inlineRunEnd);
}
#ifndef NDEBUG
@@ -509,20 +548,12 @@ void RenderBlock::removeChild(RenderObject* oldChild)
// Take all the children out of the |next| block and put them in
// the |prev| block.
prev->setNeedsLayoutAndPrefWidthsRecalc();
- RenderObject* o = next->firstChild();
-
RenderBlock* nextBlock = toRenderBlock(next);
RenderBlock* prevBlock = toRenderBlock(prev);
- while (o) {
- RenderObject* no = o;
- o = no->nextSibling();
- moveChild(prevBlock, prevBlock->children(), nextBlock, nextBlock->children(), no);
- }
-
+ nextBlock->moveAllChildrenTo(prevBlock, prevBlock->children());
+ // Delete the now-empty block's lines and nuke it.
nextBlock->deleteLineBoxTree();
-
- // Nuke the now-empty block.
- next->destroy();
+ nextBlock->destroy();
}
RenderBox::removeChild(oldChild);
@@ -535,17 +566,15 @@ void RenderBlock::removeChild(RenderObject* oldChild)
setNeedsLayoutAndPrefWidthsRecalc();
RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, false));
setChildrenInline(true);
- RenderObject* o = anonBlock->firstChild();
- while (o) {
- RenderObject* no = o;
- o = no->nextSibling();
- moveChild(this, children(), anonBlock, anonBlock->children(), no);
- }
-
+ anonBlock->moveAllChildrenTo(this, children());
// Delete the now-empty block's lines and nuke it.
anonBlock->deleteLineBoxTree();
anonBlock->destroy();
}
+
+ // If this was our last child be sure to clear out our line boxes.
+ if (childrenInline() && !firstChild())
+ lineBoxes()->deleteLineBoxes(renderArena());
}
bool RenderBlock::isSelfCollapsingBlock() const
@@ -609,15 +638,15 @@ void RenderBlock::finishDelayUpdateScrollInfo()
if (gDelayUpdateScrollInfo == 0) {
ASSERT(gDelayedUpdateScrollInfoSet);
- for (DelayedUpdateScrollInfoSet::iterator it = gDelayedUpdateScrollInfoSet->begin(); it != gDelayedUpdateScrollInfoSet->end(); ++it) {
+ OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
+ gDelayedUpdateScrollInfoSet = 0;
+
+ for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
RenderBlock* block = *it;
if (block->hasOverflowClip()) {
block->layer()->updateScrollInfoAfterLayout();
}
}
-
- delete gDelayedUpdateScrollInfoSet;
- gDelayedUpdateScrollInfoSet = 0;
}
}
@@ -747,8 +776,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
if (previousHeight != height())
relayoutChildren = true;
- // It's weird that we're treating float information as normal flow overflow, but we do this because floatRect() isn't
- // able to be propagated up the render tree yet. Overflow information is however. This check is designed to catch anyone
+ // This check is designed to catch anyone
// who wasn't going to propagate float information up to the parent and yet could potentially be painted by its ancestor.
if (isRoot() || expandsToEncloseOverhangingFloats())
addOverflowFromFloats();
@@ -788,11 +816,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
if (hasOverflowClip()) {
// Adjust repaint rect for scroll offset
- int x = repaintRect.x();
- int y = repaintRect.y();
- layer()->subtractScrolledContentOffset(x, y);
- repaintRect.setX(x);
- repaintRect.setY(y);
+ repaintRect.move(-layer()->scrolledContentOffset());
// Don't allow this rect to spill out of our overflow box.
repaintRect.intersect(IntRect(0, 0, width(), height()));
@@ -860,7 +884,11 @@ void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marg
}
y += (collapsedTopPos - collapsedTopNeg) - marginTop;
}
- child->layer()->setStaticY(y);
+ RenderLayer* childLayer = child->layer();
+ if (childLayer->staticY() != y) {
+ child->layer()->setStaticY(y);
+ child->setChildNeedsLayout(true, false);
+ }
}
}
@@ -949,7 +977,7 @@ bool RenderBlock::handleRunInChild(RenderBox* child)
// Move the nodes from the old child to the new child, but skip any :before/:after content. It has already
// been regenerated by the new inline.
for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild; runInChild = runInChild->nextSibling()) {
- if (runInIsGenerated || runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER) {
+ if (runInIsGenerated || (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER)) {
blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
}
@@ -1512,7 +1540,7 @@ void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
// Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
// z-index. We paint after we painted the background/border, so that the scrollbars will
// sit above the background/border.
- if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground))
+ if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && shouldPaintWithinRoot(paintInfo))
layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
}
@@ -1630,9 +1658,18 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
// Check for page-break-before: always, and if it's set, break and bail.
- if (isPrinting && !childrenInline() && child->style()->pageBreakBefore() == PBALWAYS &&
- inRootBlockContext() && (ty + child->y()) > paintInfo.rect.y() &&
- (ty + child->y()) < paintInfo.rect.bottom()) {
+ if (isPrinting && !childrenInline() && child->style()->pageBreakBefore() == PBALWAYS
+ && (ty + child->y()) > paintInfo.rect.y()
+ && (ty + child->y()) < paintInfo.rect.bottom()) {
+ view()->setBestTruncatedAt(ty + child->y(), this, true);
+ return;
+ }
+
+ // Check for page-break-inside: avoid, and it it's set, break and bail.
+ if (isPrinting && !childrenInline() && child->style()->pageBreakInside() == PBAVOID
+ && ty + child->y() > paintInfo.rect.y()
+ && ty + child->y() < paintInfo.rect.bottom()
+ && ty + child->y() + child->height() > paintInfo.rect.bottom()) {
view()->setBestTruncatedAt(ty + child->y(), this, true);
return;
}
@@ -1641,9 +1678,9 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
child->paint(info, tx, ty);
// Check for page-break-after: always, and if it's set, break and bail.
- if (isPrinting && !childrenInline() && child->style()->pageBreakAfter() == PBALWAYS &&
- inRootBlockContext() && (ty + child->y() + child->height()) > paintInfo.rect.y() &&
- (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
+ if (isPrinting && !childrenInline() && child->style()->pageBreakAfter() == PBALWAYS
+ && (ty + child->y() + child->height()) > paintInfo.rect.y()
+ && (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginBottom()), this, true);
return;
}
@@ -1663,7 +1700,7 @@ void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType typ
offsetForContents(tx, ty);
if (type == CursorCaret)
- document()->frame()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
+ document()->frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
else
document()->frame()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
}
@@ -1690,11 +1727,14 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
if (paintPhase == PaintPhaseBlockBackground)
return;
- // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).s
+ // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
int scrolledX = tx;
int scrolledY = ty;
- if (hasOverflowClip())
- layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
+ if (hasOverflowClip()) {
+ IntSize offset = layer()->scrolledContentOffset();
+ scrolledX -= offset.width();
+ scrolledY -= offset.height();
+ }
// 2. paint contents
if (paintPhase != PaintPhaseSelfOutline) {
@@ -1896,23 +1936,26 @@ bool RenderBlock::isSelectionRoot() const
return false;
}
-GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* /*repaintContainer*/)
+GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
{
ASSERT(!needsLayout());
if (!shouldPaintSelectionGaps())
return GapRects();
- // FIXME: this is broken with transforms and a non-null repaintContainer
- FloatPoint absContentPoint = localToAbsolute(FloatPoint());
+ // FIXME: this is broken with transforms
+ TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
+ mapLocalToContainer(repaintContainer, false, false, transformState);
+ IntPoint offsetFromRepaintContainer = roundedIntPoint(transformState.mappedPoint());
+
if (hasOverflowClip())
- absContentPoint -= layer()->scrolledContentOffset();
+ offsetFromRepaintContainer -= layer()->scrolledContentOffset();
int lastTop = 0;
int lastLeft = leftSelectionOffset(this, lastTop);
int lastRight = rightSelectionOffset(this, lastTop);
- return fillSelectionGaps(this, absContentPoint.x(), absContentPoint.y(), absContentPoint.x(), absContentPoint.y(), lastTop, lastLeft, lastRight);
+ return fillSelectionGaps(this, offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), lastTop, lastLeft, lastRight);
}
void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
@@ -1922,7 +1965,18 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
int lastLeft = leftSelectionOffset(this, lastTop);
int lastRight = rightSelectionOffset(this, lastTop);
paintInfo.context->save();
- fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
+ IntRect gapRectsBounds = fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
+ if (!gapRectsBounds.isEmpty()) {
+ if (RenderLayer* layer = enclosingLayer()) {
+ gapRectsBounds.move(IntSize(-tx, -ty));
+ if (!hasLayer()) {
+ FloatRect localBounds(gapRectsBounds);
+ gapRectsBounds = localToContainerQuad(localBounds, layer->renderer()).enclosingBoundingBox();
+ gapRectsBounds.move(layer->scrolledContentOffset());
+ }
+ layer->addBlockSelectionGapsBounds(gapRectsBounds);
+ }
+ }
paintInfo.context->restore();
}
}
@@ -2109,7 +2163,7 @@ IntRect RenderBlock::fillHorizontalSelectionGap(RenderObject* selObj, int xPos,
return IntRect();
IntRect gapRect(xPos, yPos, width, height);
if (paintInfo && selObj->style()->visibility() == VISIBLE)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -2130,7 +2184,7 @@ IntRect RenderBlock::fillVerticalSelectionGap(int lastTop, int lastLeft, int las
IntRect gapRect(left, top, width, height);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
return gapRect;
}
@@ -2146,7 +2200,7 @@ IntRect RenderBlock::fillLeftSelectionGap(RenderObject* selObj, int xPos, int yP
IntRect gapRect(left, top, width, height);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -2162,7 +2216,7 @@ IntRect RenderBlock::fillRightSelectionGap(RenderObject* selObj, int xPos, int y
IntRect gapRect(left, top, width, height);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -2304,8 +2358,14 @@ void RenderBlock::removeFloatingObject(RenderBox* o)
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
while (it.current()) {
if (it.current()->m_renderer == o) {
- if (childrenInline())
- markLinesDirtyInVerticalRange(0, it.current()->m_bottom);
+ if (childrenInline()) {
+ int bottom = it.current()->m_bottom;
+ // Special-case zero- and less-than-zero-height floats: those don't touch
+ // the line that they're on, but it still needs to be dirtied. This is
+ // accomplished by pretending they have a height of 1.
+ bottom = max(bottom, it.current()->m_top + 1);
+ markLinesDirtyInVerticalRange(0, bottom);
+ }
m_floatingObjects->removeRef(it.current());
}
++it;
@@ -2584,30 +2644,15 @@ RenderBlock::floatBottom() const
return bottom;
}
-IntRect RenderBlock::floatRect() const
-{
- IntRect result;
- if (!m_floatingObjects || hasOverflowClip() || hasColumns())
- return result;
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for (; (r = it.current()); ++it) {
- if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
- IntRect childRect = r->m_renderer->visibleOverflowRect();
- childRect.move(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop());
- result.unite(childRect);
- }
- }
-
- return result;
-}
-
int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
{
int bottom = includeSelf && width() > 0 ? height() : 0;
if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
return bottom;
+
+ if (!firstChild() && (!width() || !height()))
+ return bottom;
if (!hasColumns()) {
// FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
@@ -2700,6 +2745,9 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
return right;
+ if (!firstChild() && (!width() || !height()))
+ return right;
+
if (!hasColumns()) {
// FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
// For now, we have to descend into all the children, since we may have a huge abs div inside
@@ -2764,7 +2812,7 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
if (!includeSelf) {
right = max(right, borderLeft() + paddingLeft() + paddingRight() + relativeOffset);
if (childrenInline()) {
- for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) {
+ for (InlineFlowBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) {
int childRightEdge = currBox->x() + currBox->width();
// If this node is a root editable element, then the rightmostPosition should account for a caret at the end.
@@ -2794,6 +2842,9 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
return left;
+ if (!firstChild() && (!width() || !height()))
+ return left;
+
if (!hasColumns()) {
// FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
// For now, we have to descend into all the children, since we may have a huge abs div inside
@@ -2856,7 +2907,7 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
}
if (!includeSelf && firstLineBox()) {
- for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox())
+ for (InlineFlowBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox())
left = min(left, (int)currBox->x() + relativeOffset);
}
@@ -2891,7 +2942,7 @@ RenderBlock::rightBottom()
return bottom;
}
-void RenderBlock::markLinesDirtyInVerticalRange(int top, int bottom)
+void RenderBlock::markLinesDirtyInVerticalRange(int top, int bottom, RootInlineBox* highest)
{
if (top >= bottom)
return;
@@ -2903,7 +2954,7 @@ void RenderBlock::markLinesDirtyInVerticalRange(int top, int bottom)
lowestDirtyLine = lowestDirtyLine->prevRootBox();
}
- while (afterLowest && afterLowest->blockHeight() >= top) {
+ while (afterLowest && afterLowest != highest && afterLowest->blockHeight() >= top) {
afterLowest->markDirty();
afterLowest = afterLowest->prevRootBox();
}
@@ -2965,8 +3016,8 @@ void RenderBlock::clearFloats()
addIntrudingFloats(block, xoffset, offset);
if (childrenInline()) {
- int changeTop = INT_MAX;
- int changeBottom = INT_MIN;
+ int changeTop = numeric_limits<int>::max();
+ int changeBottom = numeric_limits<int>::min();
if (m_floatingObjects) {
for (FloatingObject* f = m_floatingObjects->first(); f; f = m_floatingObjects->next()) {
FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
@@ -3143,6 +3194,32 @@ void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove
}
}
+int RenderBlock::visibleTopOfHighestFloatExtendingBelow(int bottom, int maxHeight) const
+{
+ int top = bottom;
+ if (m_floatingObjects) {
+ FloatingObject* floatingObject;
+ for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); (floatingObject = it.current()); ++it) {
+ RenderBox* floatingBox = floatingObject->m_renderer;
+ IntRect visibleOverflow = floatingBox->visibleOverflowRect();
+ visibleOverflow.move(floatingBox->x(), floatingBox->y());
+ if (visibleOverflow.y() < top && visibleOverflow.bottom() > bottom && visibleOverflow.height() <= maxHeight && floatingBox->containingBlock() == this)
+ top = visibleOverflow.y();
+ }
+ }
+
+ if (!childrenInline()) {
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->isFloatingOrPositioned() || !child->isRenderBlock())
+ continue;
+ RenderBlock* childBlock = toRenderBlock(child);
+ top = min(top, childBlock->y() + childBlock->visibleTopOfHighestFloatExtendingBelow(bottom - childBlock->y(), maxHeight));
+ }
+ }
+
+ return top;
+}
+
int RenderBlock::getClearDelta(RenderBox* child, int yPos)
{
// There is no need to compute clearance if we have no floats.
@@ -3167,18 +3244,35 @@ int RenderBlock::getClearDelta(RenderBox* child, int yPos)
}
// We also clear floats if we are too big to sit on the same line as a float (and wish to avoid floats by default).
- // FIXME: Note that the remaining space checks aren't quite accurate, since you should be able to clear only some floats (the minimum # needed
- // to fit) and not all (we should be using nextFloatBottomBelow and looping).
int result = clearSet ? max(0, bottom - yPos) : 0;
if (!result && child->avoidsFloats()) {
- int oldYPos = child->y();
- int oldWidth = child->width();
- child->setY(yPos);
- child->calcWidth();
- if (child->width() > lineWidth(yPos, false) && child->minPrefWidth() <= availableWidth())
- result = max(0, floatBottom() - yPos);
- child->setY(oldYPos);
- child->setWidth(oldWidth);
+ int availableWidth = this->availableWidth();
+ if (child->minPrefWidth() > availableWidth)
+ return 0;
+
+ int y = yPos;
+ while (true) {
+ int widthAtY = lineWidth(y, false);
+ if (widthAtY == availableWidth)
+ return y - yPos;
+
+ int oldChildY = child->y();
+ int oldChildWidth = child->width();
+ child->setY(y);
+ child->calcWidth();
+ int childWidthAtY = child->width();
+ child->setY(oldChildY);
+ child->setWidth(oldChildWidth);
+
+ if (childWidthAtY <= widthAtY)
+ return y - yPos;
+
+ y = nextFloatBottomBelow(y);
+ ASSERT(y >= yPos);
+ if (y < yPos)
+ break;
+ }
+ ASSERT_NOT_REACHED();
}
return result;
}
@@ -3217,8 +3311,11 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Hit test descendants first.
int scrolledX = tx;
int scrolledY = ty;
- if (hasOverflowClip())
- layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
+ if (hasOverflowClip()) {
+ IntSize offset = layer()->scrolledContentOffset();
+ scrolledX -= offset.width();
+ scrolledY -= offset.height();
+ }
// Hit test contents if we don't have columns.
if (!hasColumns() && hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction))
@@ -3395,7 +3492,7 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint&
RootInlineBox* firstRootBoxWithChildren = 0;
RootInlineBox* lastRootBoxWithChildren = 0;
for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
- if (!root->firstChild())
+ if (!root->firstLeafChild())
continue;
if (!firstRootBoxWithChildren)
firstRootBoxWithChildren = root;
@@ -3493,15 +3590,16 @@ VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
void RenderBlock::offsetForContents(int& tx, int& ty) const
{
+ IntPoint contentsPoint(tx, ty);
+
if (hasOverflowClip())
- layer()->addScrolledContentOffset(tx, ty);
+ contentsPoint += layer()->scrolledContentOffset();
- if (hasColumns()) {
- IntPoint contentsPoint(tx, ty);
+ if (hasColumns())
adjustPointToColumnContents(contentsPoint);
- tx = contentsPoint.x();
- ty = contentsPoint.y();
- }
+
+ tx = contentsPoint.x();
+ ty = contentsPoint.y();
}
int RenderBlock::availableWidth() const
@@ -3542,11 +3640,15 @@ void RenderBlock::calcColumnWidth()
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
} else if (colGap < availWidth) {
desiredColumnCount = availWidth / colGap;
+ if (desiredColumnCount < 1)
+ desiredColumnCount = 1;
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
}
} else if (style()->hasAutoColumnCount()) {
if (colWidth < availWidth) {
desiredColumnCount = (availWidth + colGap) / (colWidth + colGap);
+ if (desiredColumnCount < 1)
+ desiredColumnCount = 1;
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
}
} else {
@@ -3556,6 +3658,8 @@ void RenderBlock::calcColumnWidth()
desiredColumnWidth = colWidth;
} else if (colWidth < availWidth) {
desiredColumnCount = (availWidth + colGap) / (colWidth + colGap);
+ if (desiredColumnCount < 1)
+ desiredColumnCount = 1;
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
}
}
@@ -3606,7 +3710,7 @@ Vector<IntRect>* RenderBlock::columnRects() const
return &gColumnInfoMap->get(this)->m_columnRects;
}
-int RenderBlock::layoutColumns(int endOfContent)
+int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
{
// Don't do anything if we have no columns
if (!hasColumns())
@@ -3619,17 +3723,20 @@ int RenderBlock::layoutColumns(int endOfContent)
bool computeIntrinsicHeight = (endOfContent == -1);
- // Fill the columns in to the available height. Attempt to balance the height of the columns
- int availableHeight = contentHeight();
- int colHeight = computeIntrinsicHeight ? availableHeight / desiredColumnCount : availableHeight;
-
+ // Fill the columns in to the available height. Attempt to balance the height of the columns.
// Add in half our line-height to help with best-guess initial balancing.
int columnSlop = lineHeight(false) / 2;
int remainingSlopSpace = columnSlop * desiredColumnCount;
+ int availableHeight = contentHeight();
+ int colHeight;
+ if (computeIntrinsicHeight && requestedColumnHeight >= 0)
+ colHeight = requestedColumnHeight;
+ else if (computeIntrinsicHeight)
+ colHeight = availableHeight / desiredColumnCount + columnSlop;
+ else
+ colHeight = availableHeight;
+ int originalColHeight = colHeight;
- if (computeIntrinsicHeight)
- colHeight += columnSlop;
-
int colGap = columnGap();
// Compute a collection of column rects.
@@ -3645,7 +3752,8 @@ int RenderBlock::layoutColumns(int endOfContent)
int currY = top;
unsigned colCount = desiredColumnCount;
int maxColBottom = borderTop() + paddingTop();
- int contentBottom = top + availableHeight;
+ int contentBottom = top + availableHeight;
+ int minimumColumnHeight = -1;
for (unsigned i = 0; i < colCount; i++) {
// If we aren't constrained, then the last column can just get all the remaining space.
if (computeIntrinsicHeight && i == colCount - 1)
@@ -3653,11 +3761,13 @@ int RenderBlock::layoutColumns(int endOfContent)
// This represents the real column position.
IntRect colRect(currX, top, desiredColumnWidth, colHeight);
-
+
+ int truncationPoint = visibleTopOfHighestFloatExtendingBelow(currY + colHeight, colHeight);
+
// For the simulated paint, we pretend like everything is in one long strip.
- IntRect pageRect(left, currY, desiredColumnWidth, colHeight);
+ IntRect pageRect(left, currY, desiredColumnWidth, truncationPoint - currY);
v->setPrintRect(pageRect);
- v->setTruncatedAt(currY + colHeight);
+ v->setTruncatedAt(truncationPoint);
GraphicsContext context((PlatformGraphicsContext*)0);
RenderObject::PaintInfo paintInfo(&context, pageRect, PaintPhaseForeground, false, 0, 0);
@@ -3665,9 +3775,14 @@ int RenderBlock::layoutColumns(int endOfContent)
paintObject(paintInfo, 0, 0);
setHasColumns(true);
+ if (computeIntrinsicHeight && v->minimumColumnHeight() > originalColHeight) {
+ // The initial column height was too small to contain one line of text.
+ minimumColumnHeight = max(minimumColumnHeight, v->minimumColumnHeight());
+ }
+
int adjustedBottom = v->bestTruncatedAt();
if (adjustedBottom <= currY)
- adjustedBottom = currY + colHeight;
+ adjustedBottom = truncationPoint;
colRect.setHeight(adjustedBottom - currY);
@@ -3701,6 +3816,11 @@ int RenderBlock::layoutColumns(int endOfContent)
colCount++;
}
+ if (minimumColumnHeight >= 0) {
+ // If originalColHeight was too small, we need to try to layout again.
+ return layoutColumns(endOfContent, minimumColumnHeight);
+ }
+
int overflowRight = max(width(), currX - colGap);
int overflowLeft = min(0, currX + desiredColumnWidth + colGap);
int overflowHeight = maxColBottom;
@@ -3737,8 +3857,20 @@ void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
// Add in half the column gap to the left and right of the rect.
IntRect colRect = colRects->at(i);
IntRect gapAndColumnRect(colRect.x() - leftGap, colRect.y(), colRect.width() + colGap, colRect.height());
-
- if (gapAndColumnRect.contains(point)) {
+
+ if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.right()) {
+ // FIXME: The clamping that follows is not completely right for right-to-left
+ // content.
+ // Clamp everything above the column to its top left.
+ if (point.y() < gapAndColumnRect.y())
+ point = gapAndColumnRect.location();
+ // Clamp everything below the column to the next column's top left. If there is
+ // no next column, this still maps to just after this column.
+ else if (point.y() >= gapAndColumnRect.bottom()) {
+ point = gapAndColumnRect.location();
+ point.move(0, gapAndColumnRect.height());
+ }
+
// We're inside the column. Translate the x and y into our column coordinate space.
point.move(columnPoint.x() - colRect.x(), yOffset);
return;
@@ -3786,6 +3918,31 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const
r = result;
}
+void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
+{
+ if (!hasColumns())
+ return;
+
+ // FIXME: This is incorrect for right-to-left columns.
+
+ Vector<IntRect>& columnRects = *this->columnRects();
+
+ int gapWidth = columnGap();
+ int xOffset = 0;
+ int yOffset = 0;
+ size_t columnCount = columnRects.size();
+ for (size_t i = 0; i < columnCount; ++i) {
+ IntRect columnRect = columnRects[i];
+ if (point.y() < columnRect.bottom() + yOffset) {
+ offset.expand(xOffset, -yOffset);
+ return;
+ }
+
+ xOffset += columnRect.width() + gapWidth;
+ yOffset += columnRect.height();
+ }
+}
+
void RenderBlock::calcPrefWidths()
{
ASSERT(prefWidthsDirty());
@@ -4181,6 +4338,10 @@ void RenderBlock::calcInlinePrefWidths()
} else
inlineMax += childMax;
}
+
+ // Ignore spaces after a list marker.
+ if (child->isListMarker())
+ stripFrontSpaces = true;
} else {
m_minPrefWidth = max(inlineMin, m_minPrefWidth);
m_maxPrefWidth = max(inlineMax, m_maxPrefWidth);
@@ -4484,7 +4645,7 @@ void RenderBlock::updateFirstLetter()
// Drill into inlines looking for our first text child.
RenderObject* currChild = firstLetterBlock->firstChild();
- while (currChild && currChild->needsLayout() && (!currChild->isReplaced() || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
+ while (currChild && currChild->needsLayout() && ((!currChild->isReplaced() && !currChild->isRenderButton() && !currChild->isMenuList()) || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
if (currChild->isFloatingOrPositioned()) {
if (currChild->style()->styleType() == FIRST_LETTER)
break;
@@ -4582,17 +4743,6 @@ void RenderBlock::updateFirstLetter()
}
}
-bool RenderBlock::inRootBlockContext() const
-{
- if (isTableCell() || isFloatingOrPositioned() || hasOverflowClip())
- return false;
-
- if (isRoot() || isRenderView())
- return true;
-
- return containingBlock()->inRootBlockContext();
-}
-
// Helper methods for obtaining the last line, computing line counts and heights for line counts
// (crawling into blocks).
static bool shouldCheckLines(RenderObject* obj)
@@ -4943,7 +5093,7 @@ IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int*
return IntRect(x, y, caretWidth, height);
}
-void RenderBlock::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
+void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
{
// For blocks inside inlines, we go ahead and include margins so that we run right up to the
// inline boxes above and below us (thus getting merged with them to form a single irregular
@@ -4955,16 +5105,19 @@ void RenderBlock::addFocusRingRects(GraphicsContext* graphicsContext, int tx, in
bool prevInlineHasLineBox = toRenderInline(inlineContinuation()->node()->renderer())->firstLineBox();
int topMargin = prevInlineHasLineBox ? collapsedMarginTop() : 0;
int bottomMargin = nextInlineHasLineBox ? collapsedMarginBottom() : 0;
- graphicsContext->addFocusRingRect(IntRect(tx, ty - topMargin,
- width(), height() + topMargin + bottomMargin));
- } else
- graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
+ IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
+ if (!rect.isEmpty())
+ rects.append(rect);
+ } else if (width() && height())
+ rects.append(IntRect(tx, ty, width(), height()));
if (!hasOverflowClip() && !hasControlClip()) {
for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
int top = max(curr->lineTop(), curr->y());
int bottom = min(curr->lineBottom(), curr->y() + curr->height());
- graphicsContext->addFocusRingRect(IntRect(tx + curr->x(), ty + top, curr->width(), bottom - top));
+ IntRect rect(tx + curr->x(), ty + top, curr->width(), bottom - top);
+ if (!rect.isEmpty())
+ rects.append(rect);
}
for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
@@ -4976,13 +5129,13 @@ void RenderBlock::addFocusRingRects(GraphicsContext* graphicsContext, int tx, in
pos = curr->localToAbsolute();
else
pos = FloatPoint(tx + box->x(), ty + box->y());
- box->addFocusRingRects(graphicsContext, pos.x(), pos.y());
+ box->addFocusRingRects(rects, pos.x(), pos.y());
}
}
}
if (inlineContinuation())
- inlineContinuation()->addFocusRingRects(graphicsContext,
+ inlineContinuation()->addFocusRingRects(rects,
tx - x() + inlineContinuation()->containingBlock()->x(),
ty - y() + inlineContinuation()->containingBlock()->y());
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h
index 3300d01117..184f98384c 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2007 David Smith (catfish.man@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -34,7 +34,6 @@ namespace WebCore {
class InlineIterator;
class RenderInline;
-class RootInlineBox;
struct BidiRun;
@@ -91,8 +90,6 @@ public:
bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); }
bool containsFloat(RenderObject*);
- IntRect floatRect() const;
-
int lineWidth(int y, bool firstLine) const;
virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
@@ -130,6 +127,7 @@ public:
void clearTruncation();
void adjustRectForColumns(IntRect&) const;
+ virtual void adjustForColumns(IntSize&, const IntPoint&) const;
void addContinuationWithOutline(RenderInline*);
@@ -140,7 +138,15 @@ public:
// style from this RenderBlock.
RenderBlock* createAnonymousBlock(bool isFlexibleBox = false) const;
+ static void appendRunsForObject(int start, int end, RenderObject*, InlineBidiResolver&);
+ static bool requiresLineBox(const InlineIterator&, bool isLineEmpty = true, bool previousLineBrokeCleanly = true);
+
protected:
+ void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child);
+ void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child);
+ void moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList);
+ void moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild);
+
int maxTopPosMargin() const { return m_maxMargin ? m_maxMargin->m_topPos : MaxMargin::topPosDefault(this); }
int maxTopNegMargin() const { return m_maxMargin ? m_maxMargin->m_topNeg : MaxMargin::topNegDefault(this); }
int maxBottomPosMargin() const { return m_maxMargin ? m_maxMargin->m_bottomPos : MaxMargin::bottomPosDefault(this); }
@@ -310,7 +316,6 @@ private:
// Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
// children.
virtual RenderBlock* firstLineBlock() const;
- bool inRootBlockContext() const;
virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth);
virtual RenderStyle* outlineStyleForRepaint() const;
@@ -349,12 +354,12 @@ private:
virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
- virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
void adjustPointToColumnContents(IntPoint&) const;
void adjustForBorderFit(int x, int& left, int& right) const; // Helper function for borderFitAdjust
- void markLinesDirtyInVerticalRange(int top, int bottom);
+ void markLinesDirtyInVerticalRange(int top, int bottom, RootInlineBox* highest = 0);
void newLine(EClear);
@@ -366,13 +371,14 @@ private:
void offsetForContents(int& tx, int& ty) const;
void calcColumnWidth();
- int layoutColumns(int endOfContent = -1);
+ int layoutColumns(int endOfContent = -1, int requestedColumnHeight = -1);
+ int visibleTopOfHighestFloatExtendingBelow(int bottom, int maxHeight) const;
bool expandsToEncloseOverhangingFloats() const;
void updateScrollInfoAfterLayout();
- struct FloatingObject {
+ struct FloatingObject : Noncopyable {
enum Type {
FloatLeft,
FloatRight
@@ -488,7 +494,7 @@ private:
RenderInline* m_inlineContinuation;
// Allocated only when some of these fields have non-default values
- struct MaxMargin {
+ struct MaxMargin : Noncopyable {
MaxMargin(const RenderBlock* o)
: m_topPos(topPosDefault(o))
, m_topNeg(topNegDefault(o))
@@ -514,6 +520,10 @@ private:
RenderLineBoxList m_lineBoxes; // All of the root line boxes created for this block flow. For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
mutable int m_lineHeight;
+
+ // RenderRubyBase objects need to be able to split and merge, moving their children around
+ // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
+ friend class RenderRubyBase;
};
inline RenderBlock* toRenderBlock(RenderObject* object)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp
index 19923f15c0..6e890606c5 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009 Apple Inc. All right reserved.
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right reserved.
+ * Copyright (C) 2010 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
@@ -23,12 +24,14 @@
#include "BidiResolver.h"
#include "CharacterNames.h"
+#include "InlineIterator.h"
#include "InlineTextBox.h"
#include "Logging.h"
#include "RenderArena.h"
#include "RenderInline.h"
#include "RenderListMarker.h"
#include "RenderView.h"
+#include "TrailingFloatsRootInlineBox.h"
#include "break_lines.h"
#include <wtf/AlwaysInline.h>
#include <wtf/RefCountedLeakCounter.h>
@@ -44,36 +47,6 @@ namespace WebCore {
// We don't let our line box tree for a single line get any deeper than this.
const unsigned cMaxLineDepth = 200;
-class InlineIterator {
-public:
- InlineIterator()
- : block(0)
- , obj(0)
- , pos(0)
- , nextBreakablePosition(-1)
- {
- }
-
- InlineIterator(RenderBlock* b, RenderObject* o, unsigned p)
- : block(b)
- , obj(o)
- , pos(p)
- , nextBreakablePosition(-1)
- {
- }
-
- void increment(InlineBidiResolver* resolver = 0);
- bool atEnd() const;
-
- UChar current() const;
- Direction direction() const;
-
- RenderBlock* block;
- RenderObject* obj;
- unsigned pos;
- int nextBreakablePosition;
-};
-
static int getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
{
bool leftSide = (child->style()->direction() == LTR) ? !endOfInline : endOfInline;
@@ -98,247 +71,6 @@ static int inlineWidth(RenderObject* child, bool start = true, bool end = true)
return extraWidth;
}
-struct BidiRun : BidiCharacterRun {
- BidiRun(int start, int stop, RenderObject* object, BidiContext* context, Direction dir)
- : BidiCharacterRun(start, stop, context, dir)
- , m_object(object)
- , m_box(0)
- {
- }
-
- void destroy();
-
- // Overloaded new operator.
- void* operator new(size_t, RenderArena*) throw();
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void*, size_t);
-
- BidiRun* next() { return static_cast<BidiRun*>(m_next); }
-
-private:
- // The normal operator new is disallowed.
- void* operator new(size_t) throw();
-
-public:
- RenderObject* m_object;
- InlineBox* m_box;
-};
-
-#ifndef NDEBUG
-static RefCountedLeakCounter bidiRunCounter("BidiRun");
-
-static bool inBidiRunDestroy;
-#endif
-
-void BidiRun::destroy()
-{
-#ifndef NDEBUG
- inBidiRunDestroy = true;
-#endif
- RenderArena* renderArena = m_object->renderArena();
- delete this;
-#ifndef NDEBUG
- inBidiRunDestroy = false;
-#endif
-
- // Recover the size left there for us by operator delete and free the memory.
- renderArena->free(*reinterpret_cast<size_t*>(this), this);
-}
-
-void* BidiRun::operator new(size_t sz, RenderArena* renderArena) throw()
-{
-#ifndef NDEBUG
- bidiRunCounter.increment();
-#endif
- return renderArena->allocate(sz);
-}
-
-void BidiRun::operator delete(void* ptr, size_t sz)
-{
-#ifndef NDEBUG
- bidiRunCounter.decrement();
-#endif
- ASSERT(inBidiRunDestroy);
-
- // Stash size where destroy() can find it.
- *(size_t*)ptr = sz;
-}
-
-// ---------------------------------------------------------------------
-
-inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
-{
- return it1.pos == it2.pos && it1.obj == it2.obj;
-}
-
-inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
-{
- return it1.pos != it2.pos || it1.obj != it2.obj;
-}
-
-static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, InlineBidiResolver* resolver = 0, bool skipInlines = true, bool* endOfInlinePtr = 0)
-{
- RenderObject* next = 0;
- bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;
- bool endOfInline = false;
-
- while (current) {
- next = 0;
- if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned() && !current->isText()) {
- next = current->firstChild();
- if (next && resolver && next->isRenderInline()) {
- EUnicodeBidi ub = next->style()->unicodeBidi();
- if (ub != UBNormal) {
- TextDirection dir = next->style()->direction();
- Direction d = (ub == Embed
- ? (dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding)
- : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));
- resolver->embed(d);
- }
- }
- }
-
- if (!next) {
- if (!skipInlines && !oldEndOfInline && current->isRenderInline()) {
- next = current;
- endOfInline = true;
- break;
- }
-
- while (current && current != block) {
- if (resolver && current->isRenderInline() && current->style()->unicodeBidi() != UBNormal)
- resolver->embed(PopDirectionalFormat);
-
- next = current->nextSibling();
- if (next) {
- if (resolver && next->isRenderInline()) {
- EUnicodeBidi ub = next->style()->unicodeBidi();
- if (ub != UBNormal) {
- TextDirection dir = next->style()->direction();
- Direction d = (ub == Embed
- ? (dir == RTL ? RightToLeftEmbedding: LeftToRightEmbedding)
- : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));
- resolver->embed(d);
- }
- }
- break;
- }
-
- current = current->parent();
- if (!skipInlines && current && current != block && current->isRenderInline()) {
- next = current;
- endOfInline = true;
- break;
- }
- }
- }
-
- if (!next)
- break;
-
- if (next->isText() || next->isFloating() || next->isReplaced() || next->isPositioned()
- || ((!skipInlines || !next->firstChild()) // Always return EMPTY inlines.
- && next->isRenderInline()))
- break;
- current = next;
- }
-
- if (endOfInlinePtr)
- *endOfInlinePtr = endOfInline;
-
- return next;
-}
-
-static RenderObject* bidiFirst(RenderBlock* block, InlineBidiResolver* resolver, bool skipInlines = true)
-{
- if (!block->firstChild())
- return 0;
-
- RenderObject* o = block->firstChild();
- if (o->isRenderInline()) {
- if (resolver) {
- EUnicodeBidi ub = o->style()->unicodeBidi();
- if (ub != UBNormal) {
- TextDirection dir = o->style()->direction();
- Direction d = (ub == Embed
- ? (dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding)
- : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));
- resolver->embed(d);
- }
- }
- if (skipInlines && o->firstChild())
- o = bidiNext(block, o, resolver, skipInlines);
- else {
- // Never skip empty inlines.
- if (resolver)
- resolver->commitExplicitEmbedding();
- return o;
- }
- }
-
- if (o && !o->isText() && !o->isReplaced() && !o->isFloating() && !o->isPositioned())
- o = bidiNext(block, o, resolver, skipInlines);
-
- if (resolver)
- resolver->commitExplicitEmbedding();
- return o;
-}
-
-inline void InlineIterator::increment(InlineBidiResolver* resolver)
-{
- if (!obj)
- return;
- if (obj->isText()) {
- pos++;
- if (pos >= toRenderText(obj)->textLength()) {
- obj = bidiNext(block, obj, resolver);
- pos = 0;
- nextBreakablePosition = -1;
- }
- } else {
- obj = bidiNext(block, obj, resolver);
- pos = 0;
- nextBreakablePosition = -1;
- }
-}
-
-template<>
-inline void InlineBidiResolver::increment()
-{
- current.increment(this);
-}
-
-inline bool InlineIterator::atEnd() const
-{
- return !obj;
-}
-
-inline UChar InlineIterator::current() const
-{
- if (!obj || !obj->isText())
- return 0;
-
- RenderText* text = toRenderText(obj);
- if (pos >= text->textLength())
- return 0;
-
- return text->characters()[pos];
-}
-
-ALWAYS_INLINE Direction InlineIterator::direction() const
-{
- if (UChar c = current())
- return Unicode::direction(c);
-
- if (obj && obj->isListMarker())
- return obj->style()->direction() == LTR ? LeftToRight : RightToLeft;
-
- return OtherNeutral;
-}
-
-// -------------------------------------------------------------------------------------------------
-
static void chopMidpointsAt(LineMidpointState& lineMidpointState, RenderObject* obj, unsigned pos)
{
if (!lineMidpointState.numMidpoints)
@@ -396,7 +128,7 @@ static void addMidpoint(LineMidpointState& lineMidpointState, const InlineIterat
midpoints[lineMidpointState.numMidpoints++] = midpoint;
}
-static void appendRunsForObject(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
+void RenderBlock::appendRunsForObject(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
{
if (start > end || obj->isFloating() ||
(obj->isPositioned() && !obj->style()->hasStaticX() && !obj->style()->hasStaticY() && !obj->container()->isRenderInline()))
@@ -439,36 +171,6 @@ static void appendRunsForObject(int start, int end, RenderObject* obj, InlineBid
}
}
-template <>
-void InlineBidiResolver::appendRun()
-{
- if (!emptyRun && !eor.atEnd()) {
- int start = sor.pos;
- RenderObject *obj = sor.obj;
- while (obj && obj != eor.obj && obj != endOfLine.obj) {
- appendRunsForObject(start, obj->length(), obj, *this);
- start = 0;
- obj = bidiNext(sor.block, obj);
- }
- if (obj) {
- unsigned pos = obj == eor.obj ? eor.pos : UINT_MAX;
- if (obj == endOfLine.obj && endOfLine.pos <= pos) {
- reachedEndOfLine = true;
- pos = endOfLine.pos;
- }
- // It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
- int end = obj->length() ? pos+1 : 0;
- appendRunsForObject(start, end, obj, *this);
- }
-
- eor.increment();
- sor = eor;
- }
-
- m_direction = OtherNeutral;
- m_status.eor = OtherNeutral;
-}
-
static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
{
if (isRootLineBox)
@@ -823,7 +525,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
// Figure out if we should clear out our line boxes.
// FIXME: Handle resize eventually!
- bool fullLayout = !firstLineBox() || !firstChild() || selfNeedsLayout() || relayoutChildren;
+ bool fullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren;
if (fullLayout)
lineBoxes()->deleteLineBoxes(renderArena());
@@ -843,6 +545,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
bool endOfInline = false;
RenderObject* o = bidiFirst(this, 0, false);
Vector<FloatWithRect> floats;
+ bool hasInlineChild = false;
while (o) {
if (o->isReplaced() || o->isFloating() || o->isPositioned()) {
RenderBox* box = toRenderBox(o);
@@ -865,6 +568,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
o->layoutIfNeeded();
}
} else if (o->isText() || (o->isRenderInline() && !endOfInline)) {
+ hasInlineChild = true;
if (fullLayout || o->selfNeedsLayout())
dirtyLineBoxesForRenderer(o, fullLayout);
o->setNeedsLayout(false);
@@ -881,7 +585,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
bool previousLineBrokeCleanly = true;
RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, previousLineBrokeCleanly, resolver, floats, floatIndex);
- if (fullLayout && !selfNeedsLayout()) {
+ if (fullLayout && hasInlineChild && !selfNeedsLayout()) {
setNeedsLayout(true, false); // Mark ourselves as needing a full layout. This way we'll repaint like
// we're supposed to.
RenderView* v = view();
@@ -942,7 +646,6 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
bool endLineMatched = false;
bool checkForEndLineMatch = endLine;
bool checkForFloatsFromLastLine = false;
- int lastHeight = height();
bool isLineEmpty = true;
@@ -1067,8 +770,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
} else
m_floatingObjects->first();
for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next()) {
- if (f->m_bottom > lastHeight)
- lastRootBox()->floats().append(f->m_renderer);
+ lastRootBox()->floats().append(f->m_renderer);
ASSERT(f->m_renderer == floats[floatIndex].object);
// If a float's geometry has changed, give up on syncing with clean lines.
if (floats[floatIndex].rect != IntRect(f->m_left, f->m_top, f->m_width, f->m_bottom - f->m_top))
@@ -1078,7 +780,6 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
lastFloat = m_floatingObjects->last();
}
- lastHeight = height();
lineMidpointState.reset();
resolver.setPosition(end);
}
@@ -1122,16 +823,24 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
// In case we have a float on the last line, it might not be positioned up to now.
// This has to be done before adding in the bottom border/padding, or the float will
// include the padding incorrectly. -dwh
+ if (checkForFloatsFromLastLine) {
+ int bottomVisualOverflow = lastRootBox()->bottomVisualOverflow();
+ int bottomLayoutOverflow = lastRootBox()->bottomLayoutOverflow();
+ TrailingFloatsRootInlineBox* trailingFloatsLineBox = new (renderArena()) TrailingFloatsRootInlineBox(this);
+ m_lineBoxes.appendLineBox(trailingFloatsLineBox);
+ trailingFloatsLineBox->setConstructed();
+ trailingFloatsLineBox->verticallyAlignBoxes(height());
+ trailingFloatsLineBox->setVerticalOverflowPositions(height(), bottomLayoutOverflow, height(), bottomVisualOverflow, 0);
+ trailingFloatsLineBox->setBlockHeight(height());
+ }
if (lastFloat) {
for (FloatingObject* f = m_floatingObjects->last(); f != lastFloat; f = m_floatingObjects->prev()) {
}
m_floatingObjects->next();
} else
m_floatingObjects->first();
- for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next()) {
- if (f->m_bottom > lastHeight)
- lastRootBox()->floats().append(f->m_renderer);
- }
+ for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next())
+ lastRootBox()->floats().append(f->m_renderer);
lastFloat = m_floatingObjects->last();
}
size_t floatCount = floats.size();
@@ -1184,7 +893,7 @@ RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLa
if (floats[floatIndex].rect.size() != newSize) {
int floatTop = floats[floatIndex].rect.y();
curr->markDirty();
- markLinesDirtyInVerticalRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height()));
+ markLinesDirtyInVerticalRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height()), curr);
floats[floatIndex].rect.setSize(newSize);
dirtiedByFloat = true;
}
@@ -1430,7 +1139,7 @@ static bool inlineFlowRequiresLineBox(RenderInline* flow)
return !flow->firstChild() && flow->hasHorizontalBordersPaddingOrMargin();
}
-static inline bool requiresLineBox(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly)
+bool RenderBlock::requiresLineBox(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly)
{
if (it.obj->isFloatingOrPositioned())
return false;
@@ -1769,10 +1478,10 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
currentCharacterIsSpace = false;
currentCharacterIsWS = false;
trailingSpaceObject = 0;
-
+
// Optimize for a common case. If we can't find whitespace after the list
// item, then this is all moot. -dwh
- if (o->isListMarker() && !toRenderListMarker(o)->isInside()) {
+ if (o->isListMarker()) {
if (style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) {
// Like with inline flows, we start ignoring spaces to make sure that any
// additional spaces we see will be discarded.
@@ -1780,6 +1489,8 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
currentCharacterIsWS = true;
ignoringSpaces = true;
}
+ if (toRenderListMarker(o)->isInside())
+ tmpW += replacedBox->width() + replacedBox->marginLeft() + replacedBox->marginRight() + inlineWidth(o);
} else
tmpW += replacedBox->width() + replacedBox->marginLeft() + replacedBox->marginRight() + inlineWidth(o);
} else if (o->isText()) {
@@ -1799,6 +1510,10 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
int wordSpacing = o->style()->wordSpacing();
int lastSpaceWordSpacing = 0;
+ // Non-zero only when kerning is enabled, in which case we measure words with their trailing
+ // space, then subtract its width.
+ int wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.spaceWidth() + wordSpacing : 0;
+
int wrapW = tmpW + inlineWidth(o, !appliedStartWidth, true);
int charWidth = 0;
bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE;
@@ -1893,7 +1608,11 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
}
}
- int additionalTmpW = textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
+ int additionalTmpW;
+ if (wordTrailingSpaceWidth && currentCharacterIsSpace)
+ additionalTmpW = textWidth(t, lastSpace, pos + 1 - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) - wordTrailingSpaceWidth + lastSpaceWordSpacing;
+ else
+ additionalTmpW = textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
tmpW += additionalTmpW;
if (!appliedStartWidth) {
tmpW += inlineWidth(o, true, false);
@@ -1925,7 +1644,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
}
}
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 (lBreak.obj && shouldPreserveNewline(lBreak.obj) && lBreak.obj->isText() && toRenderText(lBreak.obj)->textLength() && !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(lineMidpointState, InlineIterator(0, o, pos - 1)); // Stop
@@ -2134,19 +1853,12 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
lBreak.nextBreakablePosition = -1;
}
} else if (lBreak.obj) {
- if (last != o && !last->isListMarker()) {
- // better to break between object boundaries than in the middle of a word (except for list markers)
- lBreak.obj = o;
- lBreak.pos = 0;
- lBreak.nextBreakablePosition = -1;
- } else {
- // Don't ever break in the middle of a word if we can help it.
- // There's no room at all. We just have to be on this line,
- // even though we'll spill out.
- lBreak.obj = o;
- lBreak.pos = pos;
- lBreak.nextBreakablePosition = -1;
- }
+ // Don't ever break in the middle of a word if we can help it.
+ // There's no room at all. We just have to be on this line,
+ // even though we'll spill out.
+ lBreak.obj = o;
+ lBreak.pos = pos;
+ lBreak.nextBreakablePosition = -1;
}
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp
index 7ca2ff84fc..1c0e837394 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp
@@ -26,6 +26,7 @@
#include "RenderBox.h"
#include "CachedImage.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
#include "FrameView.h"
@@ -339,12 +340,12 @@ IntRect RenderBox::outlineBoundsForRepaint(RenderBoxModelObject* repaintContaine
return box;
}
-void RenderBox::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
+void RenderBox::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
{
- graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
+ if (width() && height())
+ rects.append(IntRect(tx, ty, width(), height()));
}
-
IntRect RenderBox::reflectionBox() const
{
IntRect result;
@@ -572,13 +573,14 @@ void RenderBox::paintRootBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
{
const FillLayer* bgLayer = style()->backgroundLayers();
Color bgColor = style()->backgroundColor();
+ RenderObject* bodyObject = 0;
if (!style()->hasBackground() && node() && node()->hasTagName(HTMLNames::htmlTag)) {
// Locate the <body> element using the DOM. This is easier than trying
// to crawl around a render tree with potential :before/:after content and
// anonymous blocks created by inline <body> tags etc. We can locate the <body>
// render object very easily via the DOM.
HTMLElement* body = document()->body();
- RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
+ bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
if (bodyObject) {
bgLayer = bodyObject->style()->backgroundLayers();
bgColor = bodyObject->style()->backgroundColor();
@@ -606,7 +608,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);
- paintFillLayers(paintInfo, bgColor, bgLayer, bx, by, bw, bh);
+ paintFillLayers(paintInfo, bgColor, bgLayer, bx, by, bw, bh, CompositeSourceOver, bodyObject);
if (style()->hasBorder() && style()->display() != INLINE)
paintBorder(paintInfo.context, tx, ty, w, h, style());
@@ -674,9 +676,25 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, int tx, int ty, int
bool compositedMask = hasLayer() && layer()->hasCompositedMask();
CompositeOperator compositeOp = CompositeSourceOver;
+ bool allMaskImagesLoaded = true;
+
if (!compositedMask) {
StyleImage* maskBoxImage = style()->maskBoxImage().image();
- if (maskBoxImage && style()->maskLayers()->hasImage()) {
+ const FillLayer* maskLayers = style()->maskLayers();
+
+ // Don't render a masked element until all the mask images have loaded, to prevent a flash of unmasked content.
+ if (maskBoxImage)
+ allMaskImagesLoaded &= maskBoxImage->isLoaded();
+
+ if (maskLayers)
+ allMaskImagesLoaded &= maskLayers->imagesAreLoaded();
+
+ // Before all images have loaded, just use an empty transparency layer as the mask.
+ if (!allMaskImagesLoaded)
+ pushTransparencyLayer = true;
+
+ if (maskBoxImage && maskLayers->hasImage()) {
+ // We have a mask-box-image and mask-image, so need to composite them together before using the result as a mask.
pushTransparencyLayer = true;
} else {
// We have to use an extra image buffer to hold the mask. Multiple mask images need
@@ -686,7 +704,7 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, int tx, int ty, int
// and composite that buffer as the mask.
// We have to check that the mask images to be rendered contain at least one image that can be actually used in rendering
// before pushing the transparency layer.
- for (const FillLayer* fillLayer = style()->maskLayers()->next(); fillLayer; fillLayer = fillLayer->next()) {
+ for (const FillLayer* fillLayer = maskLayers->next(); fillLayer; fillLayer = fillLayer->next()) {
if (fillLayer->hasImage() && fillLayer->image()->canRender(style()->effectiveZoom())) {
pushTransparencyLayer = true;
// We found one image that can be used in rendering, exit the loop
@@ -703,8 +721,10 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, int tx, int ty, int
}
}
- paintFillLayers(paintInfo, Color(), style()->maskLayers(), tx, ty, w, h, compositeOp);
- paintNinePieceImage(paintInfo.context, tx, ty, w, h, style(), style()->maskBoxImage(), compositeOp);
+ if (allMaskImagesLoaded) {
+ paintFillLayers(paintInfo, Color(), style()->maskLayers(), tx, ty, w, h, compositeOp);
+ paintNinePieceImage(paintInfo.context, tx, ty, w, h, style(), style()->maskBoxImage(), compositeOp);
+ }
if (pushTransparencyLayer)
paintInfo.context->endTransparencyLayer();
@@ -729,18 +749,18 @@ IntRect RenderBox::maskClipRect()
return result;
}
-void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, 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, RenderObject* backgroundObject)
{
if (!fillLayer)
return;
- paintFillLayers(paintInfo, c, fillLayer->next(), tx, ty, width, height, op);
- paintFillLayer(paintInfo, c, fillLayer, tx, ty, width, height, op);
+ paintFillLayers(paintInfo, c, fillLayer->next(), tx, ty, width, height, op, backgroundObject);
+ paintFillLayer(paintInfo, c, fillLayer, tx, ty, width, height, op, backgroundObject);
}
-void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, 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, RenderObject* backgroundObject)
{
- paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, width, height, 0, op);
+ paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, width, height, 0, op, backgroundObject);
}
void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*)
@@ -950,19 +970,21 @@ void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool
}
}
- if (style()->position() == FixedPosition)
- fixed = true;
-
bool containerSkipped;
RenderObject* o = container(repaintContainer, &containerSkipped);
if (!o)
return;
+ bool isFixedPos = style()->position() == FixedPosition;
bool hasTransform = hasLayer() && layer()->transform();
- if (hasTransform)
- fixed = false; // Elements with transforms act as a containing block for fixed position descendants
-
- IntSize containerOffset = offsetFromContainer(o);
+ if (hasTransform) {
+ // If this box has a transform, it acts as a fixed position container for fixed descendants,
+ // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
+ fixed &= isFixedPos;
+ } else
+ fixed |= isFixedPos;
+
+ IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -988,12 +1010,14 @@ void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Transfor
// We don't expect absoluteToLocal() to be called during layout (yet)
ASSERT(!view() || !view()->layoutStateEnabled());
- if (style()->position() == FixedPosition)
- fixed = true;
-
+ bool isFixedPos = style()->position() == FixedPosition;
bool hasTransform = hasLayer() && layer()->transform();
- if (hasTransform)
- fixed = false; // Elements with transforms act as a containing block for fixed position descendants
+ if (hasTransform) {
+ // If this box has a transform, it acts as a fixed position container for fixed descendants,
+ // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
+ fixed &= isFixedPos;
+ } else
+ fixed |= isFixedPos;
RenderObject* o = container();
if (!o)
@@ -1001,7 +1025,7 @@ void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Transfor
o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
- IntSize containerOffset = offsetFromContainer(o);
+ IntSize containerOffset = offsetFromContainer(o, IntPoint());
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -1012,7 +1036,7 @@ void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Transfor
transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
}
-IntSize RenderBox::offsetFromContainer(RenderObject* o) const
+IntSize RenderBox::offsetFromContainer(RenderObject* o, const IntPoint& point) const
{
ASSERT(o == container());
@@ -1021,14 +1045,9 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o) const
offset += relativePositionOffset();
if (!isInline() || isReplaced()) {
- RenderBlock* cb;
- if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition
- && (cb = toRenderBlock(o))->hasColumns()) {
- IntRect rect(x(), y(), 1, 1);
- cb->adjustRectForColumns(rect);
- offset.expand(rect.x(), rect.y());
- } else
- offset.expand(x(), y());
+ if (style()->position() != AbsolutePosition && style()->position() != FixedPosition)
+ o->adjustForColumns(offset, IntPoint(point.x() + x(), point.y() + y()));
+ offset.expand(x(), y());
}
if (o->hasOverflowClip())
@@ -1481,7 +1500,7 @@ void RenderBox::calcHeight()
// height since we don't set a height in RenderView when we're printing. So without this quirk, the
// height has nothing to be a percentage of, and it ends up being 0. That is bad.
bool printingNeedsBaseHeight = document()->printing() && h.isPercent()
- && (isRoot() || isBody() && document()->documentElement()->renderer()->style()->height().isPercent());
+ && (isRoot() || (isBody() && document()->documentElement()->renderer()->style()->height().isPercent()));
if (stretchesToViewHeight() || printingNeedsBaseHeight) {
int margins = collapsedMarginTop() + collapsedMarginBottom();
int visHeight = document()->printing() ? view()->frameView()->visibleHeight() : view()->viewHeight();
@@ -1926,7 +1945,7 @@ void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBoxModelO
int& widthValue, int& marginLeftValue, int& marginRightValue, int& xPos)
{
// 'left' and 'right' cannot both be 'auto' because one would of been
- // converted to the static postion already
+ // converted to the static position already
ASSERT(!(left.isAuto() && right.isAuto()));
int leftValue = 0;
@@ -1960,7 +1979,7 @@ void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBoxModelO
if (marginLeft.isAuto() && marginRight.isAuto()) {
// Both margins auto, solve for equality
if (availableSpace >= 0) {
- marginLeftValue = availableSpace / 2; // split the diference
+ marginLeftValue = availableSpace / 2; // split the difference
marginRightValue = availableSpace - marginLeftValue; // account for odd valued differences
} else {
// see FIXME 1
@@ -2245,7 +2264,7 @@ void RenderBox::calcAbsoluteVerticalValues(Length h, const RenderBoxModelObject*
if (marginTop.isAuto() && marginBottom.isAuto()) {
// Both margins auto, solve for equality
// NOTE: This may result in negative values.
- marginTopValue = availableSpace / 2; // split the diference
+ marginTopValue = availableSpace / 2; // split the difference
marginBottomValue = availableSpace - marginTopValue; // account for odd valued differences
} else if (marginTop.isAuto()) {
// Solve for top margin
@@ -2323,7 +2342,7 @@ void RenderBox::calcAbsoluteVerticalValues(Length h, const RenderBoxModelObject*
void RenderBox::calcAbsoluteHorizontalReplaced()
{
// The following is based off of the W3C Working Draft from April 11, 2006 of
- // CSS 2.1: Section 10.3.8 "Absolutly positioned, replaced elements"
+ // CSS 2.1: Section 10.3.8 "Absolutely positioned, replaced elements"
// <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-width>
// (block-style-comments in this function correspond to text from the spec and
// the numbers correspond to numbers in spec)
@@ -2414,7 +2433,7 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
int difference = availableSpace - (leftValue + rightValue);
if (difference > 0) {
- m_marginLeft = difference / 2; // split the diference
+ m_marginLeft = difference / 2; // split the difference
m_marginRight = difference - m_marginLeft; // account for odd valued differences
} else {
// see FIXME 1
@@ -2501,7 +2520,7 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
void RenderBox::calcAbsoluteVerticalReplaced()
{
// The following is based off of the W3C Working Draft from April 11, 2006 of
- // CSS 2.1: Section 10.6.5 "Absolutly positioned, replaced elements"
+ // CSS 2.1: Section 10.6.5 "Absolutely positioned, replaced elements"
// <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-height>
// (block-style-comments in this function correspond to text from the spec and
// the numbers correspond to numbers in spec)
@@ -2565,7 +2584,7 @@ void RenderBox::calcAbsoluteVerticalReplaced()
int bottomValue = 0;
if (marginTop.isAuto() && marginBottom.isAuto()) {
- // 'top' and 'bottom' cannot be 'auto' due to step 2 and 3 combinded.
+ // 'top' and 'bottom' cannot be 'auto' due to step 2 and 3 combined.
ASSERT(!(top.isAuto() || bottom.isAuto()));
topValue = top.calcValue(containerHeight);
@@ -2705,7 +2724,7 @@ VisiblePosition RenderBox::positionForPoint(const IntPoint& point)
{
// no children...return this render object's element, if there is one, and offset 0
if (!firstChild())
- return createVisiblePosition(firstDeepEditingPositionForNode(node()));
+ return createVisiblePosition(node() ? firstDeepEditingPositionForNode(node()) : Position(0, 0));
int xPos = point.x();
int yPos = point.y();
@@ -2885,9 +2904,9 @@ void RenderBox::clearLayoutOverflow()
#if ENABLE(SVG)
-TransformationMatrix RenderBox::localTransform() const
+AffineTransform RenderBox::localTransform() const
{
- return TransformationMatrix(1, 0, 0, 1, x(), y());
+ return AffineTransform(1, 0, 0, 1, x(), y());
}
#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBox.h b/src/3rdparty/webkit/WebCore/rendering/RenderBox.h
index 9050dcbe14..90a17ae0bb 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderBox.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderBox.h
@@ -74,7 +74,7 @@ public:
// Bounds of the outline box in absolute coords. Respects transforms
virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const;
- virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
// Use this with caution! No type checking is done!
RenderBox* previousSiblingBox() const;
@@ -173,7 +173,7 @@ public:
int overrideHeight() const;
virtual void setOverrideSize(int);
- virtual IntSize offsetFromContainer(RenderObject*) const;
+ virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
int calcBorderBoxWidth(int width) const;
int calcBorderBoxHeight(int height) const;
@@ -271,9 +271,9 @@ public:
virtual void paintMask(PaintInfo&, int tx, int ty);
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
- // Called when a positioned object moves but doesn't change size. A simplified layout is done
- // that just updates the object's position.
- virtual void tryLayoutDoingPositionedMovementOnly()
+ // Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted
+ // that just updates the object's position. If the size does change, the object remains dirty.
+ void tryLayoutDoingPositionedMovementOnly()
{
int oldWidth = width();
calcWidth();
@@ -297,7 +297,7 @@ public:
virtual bool avoidsFloats() const;
#if ENABLE(SVG)
- virtual TransformationMatrix localTransform() const;
+ virtual AffineTransform localTransform() const;
#endif
protected:
@@ -305,8 +305,8 @@ protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void updateBoxModelInfoFromStyle();
- 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 paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator op, RenderObject* backgroundObject);
+ void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
void paintMaskImages(const PaintInfo&, int tx, int ty, int width, int height);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp
index 9d0f1edf43..ba4b8dd904 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp
@@ -33,6 +33,7 @@
#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderView.h"
+#include <wtf/CurrentTime.h>
using namespace std;
@@ -44,6 +45,142 @@ bool RenderBoxModelObject::s_wasFloating = false;
bool RenderBoxModelObject::s_hadLayer = false;
bool RenderBoxModelObject::s_layerWasSelfPainting = false;
+static const double cInterpolationCutoff = 800. * 800.;
+static const double cLowQualityTimeThreshold = 0.500; // 500 ms
+
+class RenderBoxModelScaleData : public Noncopyable {
+public:
+ RenderBoxModelScaleData(RenderBoxModelObject* object, const IntSize& size, const AffineTransform& transform, double time, bool lowQualityScale)
+ : m_size(size)
+ , m_transform(transform)
+ , m_lastPaintTime(time)
+ , m_lowQualityScale(lowQualityScale)
+ , m_highQualityRepaintTimer(object, &RenderBoxModelObject::highQualityRepaintTimerFired)
+ {
+ }
+
+ ~RenderBoxModelScaleData()
+ {
+ m_highQualityRepaintTimer.stop();
+ }
+
+ Timer<RenderBoxModelObject>& hiqhQualityRepaintTimer() { return m_highQualityRepaintTimer; }
+
+ const IntSize& size() const { return m_size; }
+ void setSize(const IntSize& s) { m_size = s; }
+ double lastPaintTime() const { return m_lastPaintTime; }
+ void setLastPaintTime(double t) { m_lastPaintTime = t; }
+ bool useLowQualityScale() const { return m_lowQualityScale; }
+ const AffineTransform& transform() const { return m_transform; }
+ void setTransform(const AffineTransform& transform) { m_transform = transform; }
+ void setUseLowQualityScale(bool b)
+ {
+ m_highQualityRepaintTimer.stop();
+ m_lowQualityScale = b;
+ if (b)
+ m_highQualityRepaintTimer.startOneShot(cLowQualityTimeThreshold);
+ }
+
+private:
+ IntSize m_size;
+ AffineTransform m_transform;
+ double m_lastPaintTime;
+ bool m_lowQualityScale;
+ Timer<RenderBoxModelObject> m_highQualityRepaintTimer;
+};
+
+class RenderBoxModelScaleObserver {
+public:
+ static bool shouldPaintBackgroundAtLowQuality(GraphicsContext*, RenderBoxModelObject*, Image*, const IntSize&);
+
+ static void boxModelObjectDestroyed(RenderBoxModelObject* object)
+ {
+ if (gBoxModelObjects) {
+ RenderBoxModelScaleData* data = gBoxModelObjects->take(object);
+ delete data;
+ if (!gBoxModelObjects->size()) {
+ delete gBoxModelObjects;
+ gBoxModelObjects = 0;
+ }
+ }
+ }
+
+ static void highQualityRepaintTimerFired(RenderBoxModelObject* object)
+ {
+ RenderBoxModelScaleObserver::boxModelObjectDestroyed(object);
+ object->repaint();
+ }
+
+ static HashMap<RenderBoxModelObject*, RenderBoxModelScaleData*>* gBoxModelObjects;
+};
+
+bool RenderBoxModelScaleObserver::shouldPaintBackgroundAtLowQuality(GraphicsContext* context, RenderBoxModelObject* object, Image* image, const IntSize& size)
+{
+ // If the image is not a bitmap image, then none of this is relevant and we just paint at high
+ // quality.
+ if (!image || !image->isBitmapImage())
+ return false;
+
+ // Make sure to use the unzoomed image size, since if a full page zoom is in effect, the image
+ // is actually being scaled.
+ IntSize imageSize(image->width(), image->height());
+
+ // Look ourselves up in the hashtable.
+ RenderBoxModelScaleData* data = 0;
+ if (gBoxModelObjects)
+ data = gBoxModelObjects->get(object);
+
+ const AffineTransform& currentTransform = context->getCTM();
+ bool contextIsScaled = !currentTransform.isIdentityOrTranslationOrFlipped();
+ if (!contextIsScaled && imageSize == size) {
+ // There is no scale in effect. If we had a scale in effect before, we can just delete this data.
+ if (data) {
+ gBoxModelObjects->remove(object);
+ delete data;
+ }
+ return false;
+ }
+
+ // There is no need to hash scaled images that always use low quality mode when the page demands it. This is the iChat case.
+ if (object->document()->page()->inLowQualityImageInterpolationMode()) {
+ double totalPixels = static_cast<double>(image->width()) * static_cast<double>(image->height());
+ if (totalPixels > cInterpolationCutoff)
+ return true;
+ }
+
+ // If there is no data yet, we will paint the first scale at high quality and record the paint time in case a second scale happens
+ // very soon.
+ if (!data) {
+ data = new RenderBoxModelScaleData(object, size, currentTransform, currentTime(), false);
+ if (!gBoxModelObjects)
+ gBoxModelObjects = new HashMap<RenderBoxModelObject*, RenderBoxModelScaleData*>;
+ gBoxModelObjects->set(object, data);
+ return false;
+ }
+
+ const AffineTransform& tr = data->transform();
+ bool scaleUnchanged = tr.a() == currentTransform.a() && tr.b() == currentTransform.b() && tr.c() == currentTransform.c() && tr.d() == currentTransform.d();
+ // We are scaled, but we painted already at this size, so just keep using whatever mode we last painted with.
+ if ((!contextIsScaled || scaleUnchanged) && data->size() == size)
+ return data->useLowQualityScale();
+
+ // We have data and our size just changed. If this change happened quickly, go into low quality mode and then set a repaint
+ // timer to paint in high quality mode. Otherwise it is ok to just paint in high quality mode.
+ double newTime = currentTime();
+ data->setUseLowQualityScale(newTime - data->lastPaintTime() < cLowQualityTimeThreshold);
+ data->setLastPaintTime(newTime);
+ data->setTransform(currentTransform);
+ data->setSize(size);
+ return data->useLowQualityScale();
+}
+
+HashMap<RenderBoxModelObject*, RenderBoxModelScaleData*>* RenderBoxModelScaleObserver::gBoxModelObjects = 0;
+
+void RenderBoxModelObject::highQualityRepaintTimerFired(Timer<RenderBoxModelObject>*)
+{
+ RenderBoxModelScaleObserver::highQualityRepaintTimerFired(this);
+}
+
RenderBoxModelObject::RenderBoxModelObject(Node* node)
: RenderObject(node)
, m_layer(0)
@@ -55,6 +192,7 @@ RenderBoxModelObject::~RenderBoxModelObject()
// Our layer should have been destroyed and cleared by now
ASSERT(!hasLayer());
ASSERT(!m_layer);
+ RenderBoxModelScaleObserver::boxModelObjectDestroyed(this);
}
void RenderBoxModelObject::destroyLayer()
@@ -304,9 +442,12 @@ int RenderBoxModelObject::paddingRight(bool) const
}
-void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& c, const FillLayer* bgLayer, 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, RenderObject* backgroundObject)
{
GraphicsContext* context = paintInfo.context;
+ if (context->paintingDisabled())
+ return;
+
bool includeLeftEdge = box ? box->includeLeftEdge() : true;
bool includeRightEdge = box ? box->includeRightEdge() : true;
int bLeft = includeLeftEdge ? borderLeft() : 0;
@@ -340,7 +481,9 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
context->clip(toRenderBox(this)->overflowClipRect(tx, ty));
// Now adjust our tx, ty, w, h to reflect a scrolled content box with borders at the ends.
- layer()->subtractScrolledContentOffset(tx, ty);
+ IntSize offset = layer()->scrolledContentOffset();
+ tx -= offset.width();
+ ty -= offset.height();
w = bLeft + layer()->scrollWidth() + bRight;
h = borderTop() + layer()->scrollHeight() + borderBottom();
}
@@ -441,14 +584,14 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
if (baseColor.alpha() > 0) {
context->save();
context->setCompositeOperation(CompositeCopy);
- context->fillRect(rect, baseColor);
+ context->fillRect(rect, baseColor, style()->colorSpace());
context->restore();
} else
context->clearRect(rect);
}
if (bgColor.isValid() && bgColor.alpha() > 0)
- context->fillRect(rect, bgColor);
+ context->fillRect(rect, bgColor, style()->colorSpace());
}
// no progressive loading of the background image
@@ -463,21 +606,10 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
if (!destRect.isEmpty()) {
phase += destRect.location() - destOrigin;
CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
- RenderObject* clientForBackgroundImage = this;
- // Check if this is the root element painting a background layer propagated from <body>,
- // and pass the body's renderer as the client in that case.
- if (isRoot && !style()->hasBackground()) {
- ASSERT(node()->hasTagName(htmlTag));
- HTMLElement* body = document()->body();
- ASSERT(body);
- ASSERT(body->hasLocalName(bodyTag));
- ASSERT(body->renderer());
- if (body) {
- if (RenderObject* bodyRenderer = body->renderer())
- clientForBackgroundImage = bodyRenderer;
- }
- }
- context->drawTiledImage(bg->image(clientForBackgroundImage, tileSize), destRect, phase, tileSize, compositeOp);
+ RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this;
+ Image* image = bg->image(clientForBackgroundImage, tileSize);
+ bool useLowQualityScaling = RenderBoxModelScaleObserver::shouldPaintBackgroundAtLowQuality(context, this, image, tileSize);
+ context->drawTiledImage(image, style()->colorSpace(), destRect, phase, tileSize, compositeOp, useLowQualityScaling);
}
}
@@ -663,7 +795,8 @@ int RenderBoxModelObject::verticalPosition(bool firstLine) const
vpos += -static_cast<int>(f.xHeight() / 2) - lineHeight(firstLine) / 2 + baselinePosition(firstLine);
else if (va == TEXT_BOTTOM) {
vpos += f.descent();
- if (!isReplaced()) // lineHeight - baselinePosition is always 0 for replaced elements, so don't bother wasting time in that case.
+ // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
+ if (!isReplaced() || style()->display() == INLINE_BLOCK)
vpos -= (lineHeight(firstLine) - baselinePosition(firstLine));
} else if (va == BASELINE_MIDDLE)
vpos += -lineHeight(firstLine) / 2 + baselinePosition(firstLine);
@@ -717,6 +850,7 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
(imageHeight - topSlice - bottomSlice) > 0 && (h - topWidth - bottomWidth) > 0;
Image* image = styleImage->image(this, imageSize);
+ ColorSpace colorSpace = style->colorSpace();
if (drawLeft) {
// Paint the top and bottom left corners.
@@ -724,18 +858,18 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// The top left corner rect is (tx, ty, leftWidth, topWidth)
// The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice)
if (drawTop)
- graphicsContext->drawImage(image, IntRect(tx, ty, leftWidth, topWidth),
+ graphicsContext->drawImage(image, colorSpace, IntRect(tx, ty, leftWidth, topWidth),
IntRect(0, 0, leftSlice, topSlice), op);
// The bottom left corner rect is (tx, ty + h - bottomWidth, leftWidth, bottomWidth)
// The rect to use from within the image is (0, imageHeight - bottomSlice, leftSlice, botomSlice)
if (drawBottom)
- graphicsContext->drawImage(image, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
+ graphicsContext->drawImage(image, colorSpace, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
IntRect(0, imageHeight - bottomSlice, leftSlice, bottomSlice), op);
// Paint the left edge.
// Have to scale and tile into the border rect.
- graphicsContext->drawTiledImage(image, IntRect(tx, ty + topWidth, leftWidth,
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx, ty + topWidth, leftWidth,
h - topWidth - bottomWidth),
IntRect(0, topSlice, leftSlice, imageHeight - topSlice - bottomSlice),
Image::StretchTile, (Image::TileRule)vRule, op);
@@ -746,17 +880,17 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// The top right corner rect is (tx + w - rightWidth, ty, rightWidth, topWidth)
// The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice)
if (drawTop)
- graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
+ graphicsContext->drawImage(image, colorSpace, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
IntRect(imageWidth - rightSlice, 0, rightSlice, topSlice), op);
// The bottom right corner rect is (tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth)
// The rect to use from within the image is (imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice)
if (drawBottom)
- graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
+ graphicsContext->drawImage(image, colorSpace, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
IntRect(imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice), op);
// Paint the right edge.
- graphicsContext->drawTiledImage(image, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
h - topWidth - bottomWidth),
IntRect(imageWidth - rightSlice, topSlice, rightSlice, imageHeight - topSlice - bottomSlice),
Image::StretchTile, (Image::TileRule)vRule, op);
@@ -764,20 +898,20 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// Paint the top edge.
if (drawTop)
- graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
IntRect(leftSlice, 0, imageWidth - rightSlice - leftSlice, topSlice),
(Image::TileRule)hRule, Image::StretchTile, op);
// Paint the bottom edge.
if (drawBottom)
- graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + h - bottomWidth,
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty + h - bottomWidth,
w - leftWidth - rightWidth, bottomWidth),
IntRect(leftSlice, imageHeight - bottomSlice, imageWidth - rightSlice - leftSlice, bottomSlice),
(Image::TileRule)hRule, Image::StretchTile, op);
// Paint the middle.
if (drawMiddle)
- graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
+ graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
h - topWidth - bottomWidth),
IntRect(leftSlice, topSlice, imageWidth - rightSlice - leftSlice, imageHeight - topSlice - bottomSlice),
(Image::TileRule)hRule, (Image::TileRule)vRule, op);
@@ -1209,7 +1343,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
shadowOffset -= extraOffset;
fillRect.move(extraOffset);
- context->setShadow(shadowOffset, shadowBlur, shadowColor);
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
if (hasBorderRadius) {
IntRect rectToClipOut = rect;
IntSize topLeftToClipOut = topLeft;
@@ -1252,7 +1386,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
if (!rectToClipOut.isEmpty())
context->clipOutRoundedRect(rectToClipOut, topLeftToClipOut, topRightToClipOut, bottomLeftToClipOut, bottomRightToClipOut);
- context->fillRoundedRect(fillRect, topLeft, topRight, bottomLeft, bottomRight, Color::black);
+ context->fillRoundedRect(fillRect, topLeft, topRight, bottomLeft, bottomRight, Color::black, s->colorSpace());
} else {
IntRect rectToClipOut = rect;
@@ -1261,7 +1395,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
// edges if they are not pixel-aligned. Those are avoided by insetting the clipping path
// by one pixel.
if (hasOpaqueBackground) {
- TransformationMatrix currentTransformation = context->getCTM();
+ AffineTransform currentTransformation = context->getCTM();
if (currentTransformation.a() != 1 || (currentTransformation.d() != 1 && currentTransformation.d() != -1)
|| currentTransformation.b() || currentTransformation.c())
rectToClipOut.inflate(-1);
@@ -1269,7 +1403,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
if (!rectToClipOut.isEmpty())
context->clipOut(rectToClipOut);
- context->fillRect(fillRect, Color::black);
+ context->fillRect(fillRect, Color::black, s->colorSpace());
}
context->restore();
@@ -1280,9 +1414,9 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
if (holeRect.isEmpty()) {
if (hasBorderRadius)
- context->fillRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, shadowColor);
+ context->fillRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, shadowColor, s->colorSpace());
else
- context->fillRect(rect, shadowColor);
+ context->fillRect(rect, shadowColor, s->colorSpace());
continue;
}
if (!begin) {
@@ -1331,8 +1465,8 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
context->addPath(Path::createRectangle(holeRect));
context->setFillRule(RULE_EVENODD);
- context->setFillColor(fillColor);
- context->setShadow(shadowOffset, shadowBlur, shadowColor);
+ context->setFillColor(fillColor, s->colorSpace());
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
context->fillPath();
context->restore();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h
index c9a4a0a0e1..db7538d9ed 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.h
@@ -90,7 +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*, ShadowStyle, bool begin = true, bool end = true);
- void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, 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, RenderObject* backgroundObject = 0);
// The difference between this inline's baseline position and the line's baseline position.
int verticalPosition(bool firstLine) const;
@@ -98,6 +98,8 @@ public:
// Called by RenderObject::destroy() (and RenderWidget::destroy()) and is the only way layers should ever be destroyed
void destroyLayer();
+ void highQualityRepaintTimerFired(Timer<RenderBoxModelObject>*);
+
protected:
void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderButton.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderButton.cpp
index f3ae5580f3..3ecd38247d 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderButton.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderButton.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the html renderer for KDE.
- *
* Copyright (C) 2005 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderButton.h b/src/3rdparty/webkit/WebCore/rendering/RenderButton.h
index 3a74589677..7fd6ab0437 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderButton.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderButton.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the html renderer for KDE.
- *
* Copyright (C) 2005 Apple Computer
*
* This library is free software; you can redistribute it and/or
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderCounter.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderCounter.cpp
index 17c6dad211..3cb9a078f0 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderCounter.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderCounter.cpp
@@ -38,7 +38,7 @@ using namespace HTMLNames;
typedef HashMap<RefPtr<AtomicStringImpl>, CounterNode*> CounterMap;
typedef HashMap<const RenderObject*, CounterMap*> CounterMaps;
-static CounterNode* counter(RenderObject*, const AtomicString& counterName, bool alwaysCreateCounter);
+static CounterNode* makeCounterNode(RenderObject*, const AtomicString& identifier, bool alwaysCreateCounter);
static CounterMaps& counterMaps()
{
@@ -53,31 +53,7 @@ static inline RenderObject* previousSiblingOrParent(RenderObject* object)
return object->parent();
}
-static CounterNode* lastDescendant(CounterNode* node)
-{
- CounterNode* last = node->lastChild();
- if (!last)
- return 0;
-
- while (CounterNode* lastChild = last->lastChild())
- last = lastChild;
-
- return last;
-}
-
-static CounterNode* previousInPreOrder(CounterNode* node)
-{
- CounterNode* previous = node->previousSibling();
- if (!previous)
- return node->parent();
-
- while (CounterNode* lastChild = previous->lastChild())
- previous = lastChild;
-
- return previous;
-}
-
-static bool planCounter(RenderObject* object, const AtomicString& counterName, bool& isReset, int& value)
+static bool planCounter(RenderObject* object, const AtomicString& identifier, bool& isReset, int& value)
{
ASSERT(object);
@@ -90,7 +66,7 @@ static bool planCounter(RenderObject* object, const AtomicString& counterName, b
ASSERT(style);
if (const CounterDirectiveMap* directivesMap = style->counterDirectives()) {
- CounterDirectives directives = directivesMap->get(counterName.impl());
+ CounterDirectives directives = directivesMap->get(identifier.impl());
if (directives.m_reset) {
value = directives.m_resetValue;
if (directives.m_increment)
@@ -105,7 +81,7 @@ static bool planCounter(RenderObject* object, const AtomicString& counterName, b
}
}
- if (counterName == "list-item") {
+ if (identifier == "list-item") {
if (object->isListItem()) {
if (toRenderListItem(object)->hasExplicitValue()) {
value = toRenderListItem(object)->explicitValue();
@@ -133,83 +109,142 @@ static bool planCounter(RenderObject* object, const AtomicString& counterName, b
return false;
}
-static bool findPlaceForCounter(RenderObject* object, const AtomicString& counterName,
- bool isReset, CounterNode*& parent, CounterNode*& previousSibling)
+// - Finds the insertion point for the counter described by counterOwner, isReset and
+// identifier in the CounterNode tree for identifier and sets parent and
+// previousSibling accordingly.
+// - The function returns true if the counter whose insertion point is searched is NOT
+// the root of the tree.
+// - The root of the tree is a counter reference that is not in the scope of any other
+// counter with the same identifier.
+// - All the counter references with the same identifier as this one that are in
+// children or subsequent siblings of the renderer that owns the root of the tree
+// form the rest of of the nodes of the tree.
+// - The root of the tree is always a reset type reference.
+// - A subtree rooted at any reset node in the tree is equivalent to all counter
+// references that are in the scope of the counter or nested counter defined by that
+// reset node.
+// - Non-reset CounterNodes cannot have descendants.
+
+static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString& identifier, bool isReset, CounterNode*& parent, CounterNode*& previousSibling)
{
- // Find the appropriate previous sibling for insertion into the parent node
- // by searching in render tree order for a child of the counter.
- parent = 0;
+ // We cannot stop searching for counters with the same identifier before we also
+ // check this renderer, because it may affect the positioning in the tree of our counter.
+ RenderObject* searchEndRenderer = previousSiblingOrParent(counterOwner);
+ // We check renderers in preOrder from the renderer that our counter is attached to
+ // towards the begining of the document for counters with the same identifier as the one
+ // we are trying to find a place for. This is the next renderer to be checked.
+ RenderObject* currentRenderer = counterOwner->previousInPreOrder();
previousSibling = 0;
- RenderObject* resetCandidate = isReset ? object->parent() : previousSiblingOrParent(object);
- RenderObject* prevCounterCandidate = object;
- CounterNode* candidateCounter = 0;
- // When a reset counter is chosen as candidateCounter, we'll
- // decide the new node should be a child of the reset node or a
- // sibling or the reset node. This flag controls it.
- bool createChildForReset = true;
- while ((prevCounterCandidate = prevCounterCandidate->previousInPreOrder())) {
- CounterNode* c = counter(prevCounterCandidate, counterName, false);
- if (prevCounterCandidate == resetCandidate) {
- if (!candidateCounter) {
- candidateCounter = c;
- createChildForReset = true;
- }
- if (candidateCounter) {
- if (createChildForReset && candidateCounter->isReset()) {
- parent = candidateCounter;
- previousSibling = 0;
- } else {
- parent = candidateCounter->parent();
- previousSibling = candidateCounter;
+ while (currentRenderer) {
+ CounterNode* currentCounter = makeCounterNode(currentRenderer, identifier, false);
+ if (searchEndRenderer == currentRenderer) {
+ // We may be at the end of our search.
+ if (currentCounter) {
+ // We have a suitable counter on the EndSearchRenderer.
+ if (previousSibling) { // But we already found another counter that we come after.
+ if (currentCounter->actsAsReset()) {
+ // We found a reset counter that is on a renderer that is a sibling of ours or a parent.
+ if (isReset && currentRenderer->parent() == counterOwner->parent()) {
+ // We are also a reset counter and the previous reset was on a sibling renderer
+ // hence we are the next sibling of that counter if that reset is not a root or
+ // we are a root node if that reset is a root.
+ parent = currentCounter->parent();
+ previousSibling = parent ? currentCounter : 0;
+ return parent;
+ }
+ // We are not a reset node or the previous reset must be on an ancestor of our renderer
+ // hence we must be a child of that reset counter.
+ parent = currentCounter;
+ ASSERT(previousSibling->parent() == currentCounter);
+ return true;
+ }
+ // CurrentCounter, the counter at the EndSearchRenderer, is not reset.
+ if (!isReset || currentRenderer->parent() != counterOwner->parent()) {
+ // If the node we are placing is not reset or we have found a counter that is attached
+ // to an ancestor of the placed counter's renderer we know we are a sibling of that node.
+ ASSERT(currentCounter->parent() == previousSibling->parent());
+ parent = currentCounter->parent();
+ return true;
+ }
+ } else {
+ // We are at the potential end of the search, but we had no previous sibling candidate
+ // In this case we follow pretty much the same logic as above but no ASSERTs about
+ // previousSibling, and when we are a sibling of the end counter we must set previousSibling
+ // to currentCounter.
+ if (currentCounter->actsAsReset()) {
+ if (isReset && currentRenderer->parent() == counterOwner->parent()) {
+ parent = currentCounter->parent();
+ previousSibling = currentCounter;
+ return parent;
+ }
+ parent = currentCounter;
+ return true;
+ }
+ if (!isReset || currentRenderer->parent() != counterOwner->parent()) {
+ parent = currentCounter->parent();
+ previousSibling = currentCounter;
+ return true;
+ }
+ previousSibling = currentCounter;
}
- return true;
}
- resetCandidate = previousSiblingOrParent(resetCandidate);
- } else if (c) {
- if (c->isReset()) {
- if (c->parent()) {
- // The new node may be the next sibling of this reset node.
- createChildForReset = false;
- candidateCounter = c;
- } else {
- createChildForReset = true;
- candidateCounter = 0;
- }
- } else if (!candidateCounter) {
- createChildForReset = true;
- candidateCounter = c;
+ // We come here if the previous sibling or parent of our renderer had no
+ // good counter, or we are a reset node and the counter on the previous sibling
+ // of our renderer was not a reset counter.
+ // Set a new goal for the end of the search.
+ searchEndRenderer = previousSiblingOrParent(currentRenderer);
+ } else {
+ // We are searching descendants of a previous sibling of the renderer that the
+ // counter being placed is attached to.
+ if (currentCounter) {
+ // We found a suitable counter.
+ if (previousSibling) {
+ // Since we had a suitable previous counter before, we should only consider this one as our
+ // previousSibling if it is a reset counter and hence the current previousSibling is its child.
+ if (currentCounter->actsAsReset()) {
+ previousSibling = currentCounter;
+ // We are no longer interested in previous siblings of the currentRenderer or their children
+ // as counters they may have attached cannot be the previous sibling of the counter we are placing.
+ currentRenderer = currentRenderer->parent();
+ continue;
+ }
+ } else
+ previousSibling = currentCounter;
+ currentRenderer = previousSiblingOrParent(currentRenderer);
+ continue;
}
}
+ // This function is designed so that the same test is not done twice in an iteration, except for this one
+ // which may be done twice in some cases. Rearranging the decision points though, to accommodate this
+ // performance improvement would create more code duplication than is worthwhile in my oppinion and may further
+ // impede the readability of this already complex algorithm.
+ if (previousSibling)
+ currentRenderer = previousSiblingOrParent(currentRenderer);
+ else
+ currentRenderer = currentRenderer->previousInPreOrder();
}
-
return false;
}
-static CounterNode* counter(RenderObject* object, const AtomicString& counterName, bool alwaysCreateCounter)
+static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& identifier, bool alwaysCreateCounter)
{
ASSERT(object);
if (object->m_hasCounterNodeMap)
if (CounterMap* nodeMap = counterMaps().get(object))
- if (CounterNode* node = nodeMap->get(counterName.impl()))
+ if (CounterNode* node = nodeMap->get(identifier.impl()))
return node;
bool isReset = false;
int value = 0;
- if (!planCounter(object, counterName, isReset, value) && !alwaysCreateCounter)
+ if (!planCounter(object, identifier, isReset, value) && !alwaysCreateCounter)
return 0;
CounterNode* newParent = 0;
CounterNode* newPreviousSibling = 0;
- CounterNode* newNode;
- if (findPlaceForCounter(object, counterName, isReset, newParent, newPreviousSibling)) {
- newNode = new CounterNode(object, isReset, value);
- newParent->insertAfter(newNode, newPreviousSibling);
- } else {
- // Make a reset node for counters that aren't inside an existing reset node.
- newNode = new CounterNode(object, true, value);
- }
-
+ CounterNode* newNode = new CounterNode(object, isReset, value);
+ if (findPlaceForCounter(object, identifier, isReset, newParent, newPreviousSibling))
+ newParent->insertAfter(newNode, newPreviousSibling, identifier);
CounterMap* nodeMap;
if (object->m_hasCounterNodeMap)
nodeMap = counterMaps().get(object);
@@ -218,8 +253,30 @@ static CounterNode* counter(RenderObject* object, const AtomicString& counterNam
counterMaps().set(object, nodeMap);
object->m_hasCounterNodeMap = true;
}
- nodeMap->set(counterName.impl(), newNode);
-
+ nodeMap->set(identifier.impl(), newNode);
+ if (newNode->parent() || !object->nextInPreOrder(object->parent()))
+ return newNode;
+ // Checking if some nodes that were previously counter tree root nodes
+ // should become children of this node now.
+ CounterMaps& maps = counterMaps();
+ RenderObject* stayWithin = object->parent();
+ for (RenderObject* currentRenderer = object->nextInPreOrder(stayWithin); currentRenderer; currentRenderer = currentRenderer->nextInPreOrder(stayWithin)) {
+ if (!currentRenderer->m_hasCounterNodeMap)
+ continue;
+ CounterNode* currentCounter = maps.get(currentRenderer)->get(identifier.impl());
+ if (!currentCounter)
+ continue;
+ if (currentCounter->parent()) {
+ ASSERT(newNode->firstChild());
+ if (currentRenderer->lastChild())
+ currentRenderer = currentRenderer->lastChild();
+ continue;
+ }
+ if (stayWithin != currentRenderer->parent() || !currentCounter->hasResetType())
+ newNode->insertAfter(currentCounter, newNode->lastChild(), identifier);
+ if (currentRenderer->lastChild())
+ currentRenderer = currentRenderer->lastChild();
+ }
return newNode;
}
@@ -246,15 +303,15 @@ PassRefPtr<StringImpl> RenderCounter::originalText() const
return 0;
if (!m_counterNode)
- m_counterNode = counter(parent(), m_counter.identifier(), true);
+ m_counterNode = makeCounterNode(parent(), m_counter.identifier(), true);
CounterNode* child = m_counterNode;
- int value = child->isReset() ? child->value() : child->countInParent();
+ int value = child->actsAsReset() ? child->value() : child->countInParent();
String text = listMarkerText(m_counter.listStyle(), value);
if (!m_counter.separator().isNull()) {
- if (!child->isReset())
+ if (!child->actsAsReset())
child = child->parent();
while (CounterNode* parent = child->parent()) {
text = listMarkerText(m_counter.listStyle(), child->countInParent())
@@ -272,47 +329,156 @@ void RenderCounter::calcPrefWidths(int lead)
RenderText::calcPrefWidths(lead);
}
-void RenderCounter::invalidate()
+void RenderCounter::invalidate(const AtomicString& identifier)
{
+ if (m_counter.identifier() != identifier)
+ return;
m_counterNode = 0;
setNeedsLayoutAndPrefWidthsRecalc();
}
-static void destroyCounterNodeChildren(AtomicStringImpl* identifier, CounterNode* node)
+static void destroyCounterNodeWithoutMapRemoval(const AtomicString& identifier, CounterNode* node)
{
CounterNode* previous;
- for (CounterNode* child = lastDescendant(node); child && child != node; child = previous) {
- previous = previousInPreOrder(child);
- child->parent()->removeChild(child);
- ASSERT(counterMaps().get(child->renderer())->get(identifier) == child);
- counterMaps().get(child->renderer())->remove(identifier);
+ for (CounterNode* child = node->lastDescendant(); child && child != node; child = previous) {
+ previous = child->previousInPreOrder();
+ child->parent()->removeChild(child, identifier);
+ ASSERT(counterMaps().get(child->renderer())->get(identifier.impl()) == child);
+ counterMaps().get(child->renderer())->remove(identifier.impl());
if (!child->renderer()->documentBeingDestroyed()) {
RenderObjectChildList* children = child->renderer()->virtualChildren();
if (children)
- children->invalidateCounters(child->renderer());
+ children->invalidateCounters(child->renderer(), identifier);
}
delete child;
}
+ RenderObject* renderer = node->renderer();
+ if (!renderer->documentBeingDestroyed()) {
+ if (RenderObjectChildList* children = renderer->virtualChildren())
+ children->invalidateCounters(renderer, identifier);
+ }
+ if (CounterNode* parent = node->parent())
+ parent->removeChild(node, identifier);
+ delete node;
}
-void RenderCounter::destroyCounterNodes(RenderObject* object)
+void RenderCounter::destroyCounterNodes(RenderObject* renderer)
{
CounterMaps& maps = counterMaps();
- CounterMap* map = maps.get(object);
- if (!map)
+ CounterMaps::iterator mapsIterator = maps.find(renderer);
+ if (mapsIterator == maps.end())
return;
- maps.remove(object);
-
+ CounterMap* map = mapsIterator->second;
CounterMap::const_iterator end = map->end();
for (CounterMap::const_iterator it = map->begin(); it != end; ++it) {
- CounterNode* node = it->second;
- destroyCounterNodeChildren(it->first.get(), node);
- if (CounterNode* parent = node->parent())
- parent->removeChild(node);
- delete node;
+ AtomicString identifier(it->first.get());
+ destroyCounterNodeWithoutMapRemoval(identifier, it->second);
}
-
+ maps.remove(mapsIterator);
delete map;
+ renderer->m_hasCounterNodeMap = false;
+}
+
+void RenderCounter::destroyCounterNode(RenderObject* renderer, const AtomicString& identifier)
+{
+ CounterMap* map = counterMaps().get(renderer);
+ if (!map)
+ return;
+ CounterMap::iterator mapIterator = map->find(identifier.impl());
+ if (mapIterator == map->end())
+ return;
+ destroyCounterNodeWithoutMapRemoval(identifier, mapIterator->second);
+ map->remove(mapIterator);
+ // We do not delete "map" here even if empty because we expect to reuse
+ // it soon. In order for a renderer to lose all its counters permanently,
+ // a style change for the renderer involving removal of all counter
+ // directives must occur, in which case, RenderCounter::destroyCounterNodes()
+ // must be called.
+ // The destruction of the Renderer (possibly caused by the removal of its
+ // associated DOM node) is the other case that leads to the permanent
+ // destruction of all counters attached to a Renderer. In this case
+ // RenderCounter::destroyCounterNodes() must be and is now called, too.
+ // RenderCounter::destroyCounterNodes() handles destruction of the counter
+ // map associated with a renderer, so there is no risk in leaking the map.
+}
+
+static void updateCounters(RenderObject* renderer)
+{
+ ASSERT(renderer->style());
+ const CounterDirectiveMap* directiveMap = renderer->style()->counterDirectives();
+ if (!directiveMap)
+ return;
+ CounterDirectiveMap::const_iterator end = directiveMap->end();
+ if (!renderer->m_hasCounterNodeMap) {
+ for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); it != end; ++it)
+ makeCounterNode(renderer, AtomicString(it->first.get()), false);
+ return;
+ }
+ CounterMap* counterMap = counterMaps().get(renderer);
+ ASSERT(counterMap);
+ for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); it != end; ++it) {
+ CounterNode* node = counterMap->get(it->first.get());
+ if (!node) {
+ makeCounterNode(renderer, AtomicString(it->first.get()), false);
+ continue;
+ }
+ CounterNode* newParent = 0;
+ CounterNode* newPreviousSibling;
+ findPlaceForCounter(renderer, AtomicString(it->first.get()), node->hasResetType(), newParent, newPreviousSibling);
+ CounterNode* parent = node->parent();
+ if (newParent == parent && newPreviousSibling == node->previousSibling())
+ continue;
+ if (parent)
+ parent->removeChild(node, it->first.get());
+ if (newParent)
+ newParent->insertAfter(node, newPreviousSibling, it->first.get());
+ }
+}
+
+void RenderCounter::rendererSubtreeAttached(RenderObject* renderer)
+{
+ for (RenderObject* descendant = renderer; descendant; descendant = descendant->nextInPreOrder(renderer))
+ updateCounters(descendant);
+}
+
+void RenderCounter::rendererStyleChanged(RenderObject* renderer, const RenderStyle* oldStyle, const RenderStyle* newStyle)
+{
+ const CounterDirectiveMap* newCounterDirectives;
+ const CounterDirectiveMap* oldCounterDirectives;
+ if (oldStyle && (oldCounterDirectives = oldStyle->counterDirectives())) {
+ if (newStyle && (newCounterDirectives = newStyle->counterDirectives())) {
+ CounterDirectiveMap::const_iterator newMapEnd = newCounterDirectives->end();
+ CounterDirectiveMap::const_iterator oldMapEnd = oldCounterDirectives->end();
+ for (CounterDirectiveMap::const_iterator it = newCounterDirectives->begin(); it != newMapEnd; ++it) {
+ CounterDirectiveMap::const_iterator oldMapIt = oldCounterDirectives->find(it->first);
+ if (oldMapIt != oldMapEnd) {
+ if (oldMapIt->second == it->second)
+ continue;
+ RenderCounter::destroyCounterNode(renderer, it->first.get());
+ }
+ // We must create this node here, because the changed node may be a node with no display such as
+ // as those created by the increment or reset directives and the re-layout that will happen will
+ // not catch the change if the node had no children.
+ makeCounterNode(renderer, it->first.get(), false);
+ }
+ // Destroying old counters that do not exist in the new counterDirective map.
+ for (CounterDirectiveMap::const_iterator it = oldCounterDirectives->begin(); it !=oldMapEnd; ++it) {
+ if (!newCounterDirectives->contains(it->first))
+ RenderCounter::destroyCounterNode(renderer, it->first.get());
+ }
+ } else {
+ if (renderer->m_hasCounterNodeMap)
+ RenderCounter::destroyCounterNodes(renderer);
+ }
+ } else if (newStyle && (newCounterDirectives = newStyle->counterDirectives())) {
+ CounterDirectiveMap::const_iterator newMapEnd = newCounterDirectives->end();
+ for (CounterDirectiveMap::const_iterator it = newCounterDirectives->begin(); it != newMapEnd; ++it) {
+ // We must create this node here, because the added node may be a node with no display such as
+ // as those created by the increment or reset directives and the re-layout that will happen will
+ // not catch the change if the node had no children.
+ makeCounterNode(renderer, it->first.get(), false);
+ }
+ }
}
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderCounter.h b/src/3rdparty/webkit/WebCore/rendering/RenderCounter.h
index 961968e16c..10ba1dc574 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderCounter.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderCounter.h
@@ -33,9 +33,16 @@ class RenderCounter : public RenderText {
public:
RenderCounter(Document*, const CounterContent&);
- void invalidate();
+ // Removes the reference to the CounterNode associated with this renderer
+ // if its identifier matches the argument.
+ // This is used to cause a counter display update when the CounterNode
+ // tree for identifier changes.
+ void invalidate(const AtomicString& identifier);
static void destroyCounterNodes(RenderObject*);
+ static void destroyCounterNode(RenderObject*, const AtomicString& identifier);
+ static void rendererSubtreeAttached(RenderObject*);
+ static void rendererStyleChanged(RenderObject*, const RenderStyle* oldStyle, const RenderStyle* newStyle);
private:
virtual const char* renderName() const;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderEmbeddedObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderEmbeddedObject.cpp
new file mode 100644
index 0000000000..d2e9999b78
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * (C) 2000 Stefan Schimanski (1Stein@gmx.de)
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 "RenderEmbeddedObject.h"
+
+#include "CSSValueKeywords.h"
+#include "Font.h"
+#include "FontSelector.h"
+#include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "GraphicsContext.h"
+#include "HTMLEmbedElement.h"
+#include "HTMLIFrameElement.h"
+#include "HTMLNames.h"
+#include "HTMLObjectElement.h"
+#include "HTMLParamElement.h"
+#include "LocalizedStrings.h"
+#include "MIMETypeRegistry.h"
+#include "Page.h"
+#include "Path.h"
+#include "PluginWidget.h"
+#include "RenderTheme.h"
+#include "RenderView.h"
+#include "RenderWidgetProtector.h"
+#include "Text.h"
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "HTMLVideoElement.h"
+#endif
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "PluginWidget.h"
+#endif
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const float missingPluginRoundedRectHeight = 18;
+static const float missingPluginRoundedRectLeftRightTextMargin = 6;
+static const float missingPluginRoundedRectOpacity = 0.20f;
+static const float missingPluginRoundedRectRadius = 5;
+static const float missingPluginTextOpacity = 0.55f;
+
+RenderEmbeddedObject::RenderEmbeddedObject(Element* element)
+ : RenderPartObject(element)
+ , m_showsMissingPluginIndicator(false)
+{
+ view()->frameView()->setIsVisuallyNonEmpty();
+}
+
+RenderEmbeddedObject::~RenderEmbeddedObject()
+{
+ if (frameView())
+ frameView()->removeWidgetToUpdate(this);
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+bool RenderEmbeddedObject::requiresLayer() const
+{
+ if (RenderPartObject::requiresLayer())
+ return true;
+
+ return allowsAcceleratedCompositing();
+}
+
+bool RenderEmbeddedObject::allowsAcceleratedCompositing() const
+{
+ return widget() && widget()->isPluginWidget() && static_cast<PluginWidget*>(widget())->platformLayer();
+}
+#endif
+
+static bool isURLAllowed(Document* doc, const String& url)
+{
+ if (doc->frame()->page()->frameCount() >= 200)
+ return false;
+
+ // We allow one level of self-reference because some sites depend on that.
+ // But we don't allow more than one.
+ KURL completeURL = doc->completeURL(url);
+ bool foundSelfReference = false;
+ for (Frame* frame = doc->frame(); frame; frame = frame->tree()->parent()) {
+ if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) {
+ if (foundSelfReference)
+ return false;
+ foundSelfReference = true;
+ }
+ }
+ return true;
+}
+
+typedef HashMap<String, String, CaseFoldingHash> ClassIdToTypeMap;
+
+static ClassIdToTypeMap* createClassIdToTypeMap()
+{
+ ClassIdToTypeMap* map = new ClassIdToTypeMap;
+ map->add("clsid:D27CDB6E-AE6D-11CF-96B8-444553540000", "application/x-shockwave-flash");
+ map->add("clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA", "audio/x-pn-realaudio-plugin");
+ map->add("clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B", "video/quicktime");
+ map->add("clsid:166B1BCA-3F9C-11CF-8075-444553540000", "application/x-director");
+ map->add("clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6", "application/x-mplayer2");
+ map->add("clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95", "application/x-mplayer2");
+ return map;
+}
+
+static String serviceTypeForClassId(const String& classId)
+{
+ // Return early if classId is empty (since we won't do anything below).
+ // Furthermore, if classId is null, calling get() below will crash.
+ if (classId.isEmpty())
+ return String();
+
+ static ClassIdToTypeMap* map = createClassIdToTypeMap();
+ return map->get(classId);
+}
+
+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 RenderEmbeddedObject::updateWidget(bool onlyCreateNonNetscapePlugins)
+{
+ if (m_showsMissingPluginIndicator)
+ return;
+
+ String url;
+ String serviceType;
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ Frame* frame = frameView()->frame();
+
+ // The calls to FrameLoader::requestObject within this function can result in a plug-in being initialized.
+ // This can run cause arbitrary JavaScript to run and may result in this RenderObject being detached from
+ // the render tree and destroyed, causing a crash like <rdar://problem/6954546>. By extending our lifetime
+ // artifically to ensure that we remain alive for the duration of plug-in initialization.
+ RenderWidgetProtector protector(this);
+
+ if (node()->hasTagName(objectTag)) {
+ HTMLObjectElement* objectElement = static_cast<HTMLObjectElement*>(node());
+
+ objectElement->setNeedWidgetUpdate(false);
+ if (!objectElement->isFinishedParsingChildren())
+ return;
+
+ // Check for a child EMBED tag.
+ HTMLEmbedElement* embed = 0;
+ for (Node* child = objectElement->firstChild(); child; ) {
+ if (child->hasTagName(embedTag)) {
+ embed = static_cast<HTMLEmbedElement*>(child);
+ break;
+ }
+
+ if (child->hasTagName(objectTag))
+ child = child->nextSibling(); // Don't descend into nested OBJECT tags
+ else
+ child = child->traverseNextNode(objectElement); // Otherwise descend (EMBEDs may be inside COMMENT tags)
+ }
+
+ // Use the attributes from the EMBED tag instead of the OBJECT tag including WIDTH and HEIGHT.
+ HTMLElement* embedOrObject;
+ if (embed) {
+ embedOrObject = embed;
+ url = embed->url();
+ serviceType = embed->serviceType();
+ } else
+ embedOrObject = objectElement;
+
+ // If there was no URL or type defined in EMBED, try the OBJECT tag.
+ if (url.isEmpty())
+ url = objectElement->url();
+ if (serviceType.isEmpty())
+ serviceType = objectElement->serviceType();
+
+ HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
+
+ // Scan the PARAM children.
+ // Get the URL and type from the params if we don't already have them.
+ // Get the attributes from the params if there is no EMBED tag.
+ Node* child = objectElement->firstChild();
+ while (child && (url.isEmpty() || serviceType.isEmpty() || !embed)) {
+ if (child->hasTagName(paramTag)) {
+ HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
+ String name = p->name();
+ if (url.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
+ url = p->value();
+ if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
+ serviceType = p->value();
+ int pos = serviceType.find(";");
+ if (pos != -1)
+ serviceType = serviceType.left(pos);
+ }
+ if (!embed && !name.isEmpty()) {
+ uniqueParamNames.add(name.impl());
+ paramNames.append(p->name());
+ paramValues.append(p->value());
+ }
+ }
+ child = child->nextSibling();
+ }
+
+ // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
+ // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
+ // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
+ // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
+ // else our Java plugin will misinterpret it. [4004531]
+ String codebase;
+ if (!embed && MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
+ codebase = "codebase";
+ uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
+ }
+
+ // Turn the attributes of either the EMBED tag or OBJECT tag into arrays, but don't override PARAM values.
+ NamedNodeMap* attributes = embedOrObject->attributes();
+ if (attributes) {
+ for (unsigned i = 0; i < attributes->length(); ++i) {
+ Attribute* it = attributes->attributeItem(i);
+ const AtomicString& name = it->name().localName();
+ if (embed || !uniqueParamNames.contains(name.impl())) {
+ paramNames.append(name.string());
+ paramValues.append(it->value().string());
+ }
+ }
+ }
+
+ mapDataParamToSrc(&paramNames, &paramValues);
+
+ // If we still don't have a type, try to map from a specific CLASSID to a type.
+ if (serviceType.isEmpty())
+ serviceType = serviceTypeForClassId(objectElement->classId());
+
+ if (!isURLAllowed(document(), url))
+ return;
+
+ // Find out if we support fallback content.
+ m_hasFallbackContent = false;
+ for (Node* child = objectElement->firstChild(); child && !m_hasFallbackContent; child = child->nextSibling()) {
+ if ((!child->isTextNode() && !child->hasTagName(embedTag) && !child->hasTagName(paramTag)) // Discount <embed> and <param>
+ || (child->isTextNode() && !static_cast<Text*>(child)->containsOnlyWhitespace()))
+ m_hasFallbackContent = true;
+ }
+
+ if (onlyCreateNonNetscapePlugins) {
+ KURL completedURL;
+ if (!url.isEmpty())
+ completedURL = frame->loader()->completeURL(url);
+
+ if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
+ return;
+ }
+
+ bool success = objectElement->dispatchBeforeLoadEvent(url) && frame->loader()->requestObject(this, url, objectElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
+ if (!success && m_hasFallbackContent)
+ objectElement->renderFallbackContent();
+
+ } else if (node()->hasTagName(embedTag)) {
+ HTMLEmbedElement* embedElement = static_cast<HTMLEmbedElement*>(node());
+ embedElement->setNeedWidgetUpdate(false);
+ url = embedElement->url();
+ serviceType = embedElement->serviceType();
+
+ if (url.isEmpty() && serviceType.isEmpty())
+ return;
+ if (!isURLAllowed(document(), url))
+ return;
+
+ // add all attributes set on the embed object
+ NamedNodeMap* attributes = embedElement->attributes();
+ if (attributes) {
+ for (unsigned i = 0; i < attributes->length(); ++i) {
+ Attribute* it = attributes->attributeItem(i);
+ paramNames.append(it->name().localName().string());
+ paramValues.append(it->value().string());
+ }
+ }
+
+ if (onlyCreateNonNetscapePlugins) {
+ KURL completedURL;
+ if (!url.isEmpty())
+ completedURL = frame->loader()->completeURL(url);
+
+ if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
+ return;
+ }
+
+ if (embedElement->dispatchBeforeLoadEvent(url))
+ frame->loader()->requestObject(this, url, embedElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
+ }
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ else if (node()->hasTagName(videoTag) || node()->hasTagName(audioTag)) {
+ HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node());
+
+ mediaElement->setNeedWidgetUpdate(false);
+ if (node()->hasTagName(videoTag)) {
+ HTMLVideoElement* vid = static_cast<HTMLVideoElement*>(node());
+ String poster = vid->poster();
+ if (!poster.isEmpty()) {
+ paramNames.append("_media_element_poster_");
+ paramValues.append(poster);
+ }
+ }
+
+ url = mediaElement->initialURL();
+ if (!url.isEmpty()) {
+ paramNames.append("_media_element_src_");
+ paramValues.append(url);
+ }
+
+ serviceType = "application/x-media-element-proxy-plugin";
+
+ if (mediaElement->dispatchBeforeLoadEvent(url))
+ frame->loader()->requestObject(this, url, nullAtom, serviceType, paramNames, paramValues);
+ }
+#endif
+}
+
+void RenderEmbeddedObject::paint(PaintInfo& paintInfo, int tx, int ty)
+{
+ if (m_showsMissingPluginIndicator) {
+ RenderReplaced::paint(paintInfo, tx, ty);
+ return;
+ }
+
+ RenderPartObject::paint(paintInfo, tx, ty);
+}
+
+void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
+{
+ if (!m_showsMissingPluginIndicator)
+ return;
+
+ if (paintInfo.phase == PaintPhaseSelection)
+ return;
+
+ GraphicsContext* context = paintInfo.context;
+ if (context->paintingDisabled())
+ return;
+
+ FloatRect pluginRect = contentBoxRect();
+ pluginRect.move(tx, ty);
+
+ FontDescription fontDescription;
+ RenderTheme::defaultTheme()->systemFont(CSSValueWebkitSmallControl, fontDescription);
+ fontDescription.setWeight(FontWeightBold);
+ Font font(fontDescription, 0, 0);
+ font.update(0);
+
+ String label = missingPluginText();
+ TextRun run(label.characters(), label.length());
+ run.disableRoundingHacks();
+ float textWidth = font.floatWidth(run);
+
+ FloatRect missingPluginRect;
+ missingPluginRect.setSize(FloatSize(textWidth + missingPluginRoundedRectLeftRightTextMargin * 2, missingPluginRoundedRectHeight));
+ missingPluginRect.setLocation(FloatPoint((pluginRect.size().width() / 2 - missingPluginRect.size().width() / 2) + pluginRect.location().x(),
+ (pluginRect.size().height() / 2 - missingPluginRect.size().height() / 2) + pluginRect.location().y()));
+
+ Path path = Path::createRoundedRectangle(missingPluginRect, FloatSize(missingPluginRoundedRectRadius, missingPluginRoundedRectRadius));
+ context->save();
+ context->clip(pluginRect);
+ context->beginPath();
+ context->addPath(path);
+ context->setAlpha(missingPluginRoundedRectOpacity);
+ context->setFillColor(Color::white, style()->colorSpace());
+ context->fillPath();
+
+ FloatPoint labelPoint(roundf(missingPluginRect.location().x() + (missingPluginRect.size().width() - textWidth) / 2),
+ roundf(missingPluginRect.location().y()+ (missingPluginRect.size().height() - font.height()) / 2 + font.ascent()));
+ context->setAlpha(missingPluginTextOpacity);
+ context->setFillColor(Color::black, style()->colorSpace());
+ context->drawBidiText(font, run, labelPoint);
+ context->restore();
+}
+
+void RenderEmbeddedObject::layout()
+{
+ ASSERT(needsLayout());
+
+ calcWidth();
+ calcHeight();
+
+ RenderPart::layout();
+
+ m_overflow.clear();
+ addShadowOverflow();
+
+ if (!widget() && frameView())
+ frameView()->addWidgetToUpdate(this);
+
+ setNeedsLayout(false);
+}
+
+}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderEmbeddedObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderEmbeddedObject.h
new file mode 100644
index 0000000000..657701fd23
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderEmbeddedObject.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 RenderEmbeddedObject_h
+#define RenderEmbeddedObject_h
+
+#include "RenderPartObject.h"
+
+namespace WebCore {
+
+// Renderer for embeds and objects.
+class RenderEmbeddedObject : public RenderPartObject {
+public:
+ RenderEmbeddedObject(Element*);
+ virtual ~RenderEmbeddedObject();
+
+ void updateWidget(bool onlyCreateNonNetscapePlugins);
+ void setShowsMissingPluginIndicator(bool showsMissingPluginIndicator) { m_showsMissingPluginIndicator = showsMissingPluginIndicator; }
+ bool showsMissingPluginIndicator() const { return m_showsMissingPluginIndicator; }
+#if USE(ACCELERATED_COMPOSITING)
+ virtual bool allowsAcceleratedCompositing() const;
+#endif
+
+private:
+ virtual const char* renderName() const { return "RenderEmbeddedObject"; }
+ virtual bool isEmbeddedObject() const { return true; }
+
+ virtual void paintReplaced(PaintInfo&, int, int);
+ virtual void paint(PaintInfo& paintInfo, int, int);
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual bool requiresLayer() const;
+#endif
+
+ virtual void layout();
+ bool m_showsMissingPluginIndicator;
+};
+
+inline RenderEmbeddedObject* toRenderEmbeddedObject(RenderObject* object)
+{
+ ASSERT(!object || !strcmp(object->renderName(), "RenderEmbeddedObject"));
+ return static_cast<RenderEmbeddedObject*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderEmbeddedObject(const RenderEmbeddedObject*);
+
+} // namespace WebCore
+
+#endif // RenderEmbeddedObject_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp
index 8618d11c04..889b0bc025 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderFieldset.cpp
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
@@ -121,6 +119,9 @@ RenderBox* RenderFieldset::findLegend() const
void RenderFieldset::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
{
+ if (!shouldPaintWithinRoot(paintInfo))
+ return;
+
int w = width();
int h = height();
RenderBox* legend = findLegend();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.cpp
index 72623f73e4..14d126d247 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "RenderFileUploadControl.h"
+#include "Chrome.h"
#include "FileList.h"
#include "Frame.h"
#include "FrameView.h"
@@ -63,8 +64,13 @@ private:
RenderFileUploadControl::RenderFileUploadControl(HTMLInputElement* input)
: RenderBlock(input)
, m_button(0)
- , m_fileChooser(FileChooser::create(this, input->value()))
{
+ FileList* list = input->files();
+ Vector<String> filenames;
+ unsigned length = list ? list->length() : 0;
+ for (unsigned i = 0; i < length; ++i)
+ filenames.append(list->item(i)->path());
+ m_fileChooser = FileChooser::create(this, filenames);
}
RenderFileUploadControl::~RenderFileUploadControl()
@@ -103,15 +109,32 @@ bool RenderFileUploadControl::allowsMultipleFiles()
return !input->getAttribute(multipleAttr).isNull();
}
+String RenderFileUploadControl::acceptTypes()
+{
+ return static_cast<HTMLInputElement*>(node())->accept();
+}
+
+void RenderFileUploadControl::chooseIconForFiles(const Vector<String>& filenames)
+{
+ if (Chrome* chromePointer = chrome())
+ chromePointer->chooseIconForFiles(filenames, m_fileChooser);
+}
+
void RenderFileUploadControl::click()
{
+ if (Chrome* chromePointer = chrome())
+ chromePointer->runOpenPanel(node()->document()->frame(), m_fileChooser);
+}
+
+Chrome* RenderFileUploadControl::chrome() const
+{
Frame* frame = node()->document()->frame();
if (!frame)
- return;
+ return 0;
Page* page = frame->page();
if (!page)
- return;
- page->chrome()->runOpenPanel(frame, m_fileChooser);
+ return 0;
+ return page->chrome();
}
void RenderFileUploadControl::updateFromElement()
@@ -184,7 +207,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
}
if (paintInfo.phase == PaintPhaseForeground) {
- const String& displayedFilename = m_fileChooser->basenameForWidth(style()->font(), maxFilenameWidth());
+ const String& displayedFilename = fileTextValue();
unsigned length = displayedFilename.length();
const UChar* string = displayedFilename.characters();
TextRun textRun(string, length, false, 0, 0, style()->direction() == RTL, style()->unicodeBidi() == Override);
@@ -204,7 +227,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
+ buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
+ buttonRenderer->baselinePosition(true, false);
- paintInfo.context->setFillColor(style()->color());
+ paintInfo.context->setFillColor(style()->color(), style()->colorSpace());
// Draw the filename
paintInfo.context->drawBidiText(style()->font(), textRun, IntPoint(textX, textY));
@@ -284,7 +307,7 @@ String RenderFileUploadControl::buttonValue()
return m_button->value();
}
-String RenderFileUploadControl::fileTextValue()
+String RenderFileUploadControl::fileTextValue() const
{
return m_fileChooser->basenameForWidth(style()->font(), maxFilenameWidth());
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.h b/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.h
index bd7d62a490..99dd35c365 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderFileUploadControl.h
@@ -26,6 +26,7 @@
namespace WebCore {
+class Chrome;
class HTMLInputElement;
// Each RenderFileUploadControl contains a RenderButton (for opening the file chooser), and
@@ -37,17 +38,15 @@ public:
RenderFileUploadControl(HTMLInputElement*);
virtual ~RenderFileUploadControl();
+ virtual bool isFileUploadControl() const { return true; }
+
void click();
- void valueChanged();
-
void receiveDroppedFiles(const Vector<String>&);
String buttonValue();
- String fileTextValue();
+ String fileTextValue() const;
- bool allowsMultipleFiles();
-
private:
virtual const char* renderName() const { return "RenderFileUploadControl"; }
@@ -57,6 +56,14 @@ private:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ // FileChooserClient methods.
+ void valueChanged();
+ void repaint() { RenderBlock::repaint(); }
+ bool allowsMultipleFiles();
+ String acceptTypes();
+ void chooseIconForFiles(const Vector<String>&);
+
+ Chrome* chrome() const;
int maxFilenameWidth() const;
PassRefPtr<RenderStyle> createButtonStyle(const RenderStyle* parentStyle) const;
@@ -66,10 +73,16 @@ private:
inline RenderFileUploadControl* toRenderFileUploadControl(RenderObject* object)
{
- ASSERT(!object || !strcmp(object->renderName(), "RenderFileUploadControl"));
+ ASSERT(!object || object->isFileUploadControl());
return static_cast<RenderFileUploadControl*>(object);
}
+inline const RenderFileUploadControl* toRenderFileUploadControl(const RenderObject* object)
+{
+ ASSERT(!object || object->isFileUploadControl());
+ return static_cast<const RenderFileUploadControl*>(object);
+}
+
// This will catch anyone doing an unnecessary cast.
void toRenderFileUploadControl(const RenderFileUploadControl*);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFlexibleBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderFlexibleBox.cpp
index 63c72fd0d0..7991b61ce8 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderFlexibleBox.cpp
@@ -410,8 +410,13 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
child->layer()->setStaticX(xPos);
else child->layer()->setStaticX(width() - xPos);
}
- if (child->style()->hasStaticY())
- child->layer()->setStaticY(yPos);
+ if (child->style()->hasStaticY()) {
+ RenderLayer* childLayer = child->layer();
+ if (childLayer->staticY() != yPos) {
+ child->layer()->setStaticY(yPos);
+ child->setChildNeedsLayout(true, false);
+ }
+ }
child = iterator.next();
continue;
}
@@ -640,7 +645,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
// We confine the line clamp ugliness to vertical flexible boxes (thus keeping it out of
// mainstream block layout); this is not really part of the XUL box model.
- bool haveLineClamp = style()->lineClamp() >= 0 && style()->lineClamp() <= 100;
+ bool haveLineClamp = !style()->lineClamp().isNone();
if (haveLineClamp) {
int maxLineCount = 0;
child = iterator.first();
@@ -665,7 +670,8 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
// Get the # of lines and then alter all block flow children with auto height to use the
// specified height. We always try to leave room for at least one line.
- int numVisibleLines = max(1, static_cast<int>((maxLineCount + 1) * style()->lineClamp() / 100.0));
+ LineClampValue lineClamp = style()->lineClamp();
+ int numVisibleLines = lineClamp.isPercentage() ? max(1, (maxLineCount + 1) * lineClamp.value() / 100) : lineClamp.value();
if (numVisibleLines < maxLineCount) {
for (child = iterator.first(); child; child = iterator.next()) {
if (child->isPositioned() || !child->style()->height().isAuto() || !child->isBlockFlow())
@@ -696,28 +702,25 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (!lastLine)
continue;
- // See if the last item is an anchor
- InlineBox* anchorBox = lastLine->lastChild();
- if (!anchorBox)
- continue;
- if (!anchorBox->renderer()->node())
- continue;
- if (!anchorBox->renderer()->node()->isLink())
- continue;
-
RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines-1);
if (!lastVisibleLine)
continue;
const UChar ellipsisAndSpace[2] = { horizontalEllipsis, ' ' };
DEFINE_STATIC_LOCAL(AtomicString, ellipsisAndSpaceStr, (ellipsisAndSpace, 2));
-
+ DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1));
const Font& font = style(numVisibleLines == 1)->font();
- int ellipsisAndSpaceWidth = font.width(TextRun(ellipsisAndSpace, 2));
- // Get ellipsis width + " " + anchor width
- int totalWidth = ellipsisAndSpaceWidth + anchorBox->width();
-
+ // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too
+ int totalWidth;
+ InlineBox* anchorBox = lastLine->lastChild();
+ if (anchorBox && anchorBox->renderer()->node() && anchorBox->renderer()->node()->isLink())
+ totalWidth = anchorBox->width() + font.width(TextRun(ellipsisAndSpace, 2));
+ else {
+ anchorBox = 0;
+ totalWidth = font.width(TextRun(&horizontalEllipsis, 1));
+ }
+
// See if this width can be accommodated on the last visible line
RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer());
RenderBlock* srcBlock = toRenderBlock(lastLine->renderer());
@@ -739,7 +742,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
continue;
// Let the truncation code kick in.
- lastVisibleLine->placeEllipsis(ellipsisAndSpaceStr, ltr, blockLeftEdge, blockRightEdge, totalWidth, anchorBox);
+ lastVisibleLine->placeEllipsis(anchorBox ? ellipsisAndSpaceStr : ellipsisStr, ltr, blockLeftEdge, blockRightEdge, totalWidth, anchorBox);
destBlock->setHasMarkupTruncation(true);
}
}
@@ -769,8 +772,13 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
else
child->layer()->setStaticX(borderRight()+paddingRight());
}
- if (child->style()->hasStaticY())
- child->layer()->setStaticY(height());
+ if (child->style()->hasStaticY()) {
+ RenderLayer* childLayer = child->layer();
+ if (childLayer->staticY() != height()) {
+ child->layer()->setStaticY(height());
+ child->setChildNeedsLayout(true, false);
+ }
+ }
child = iterator.next();
continue;
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.cpp
index b15d55c347..aa28ff08e6 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2009 Google, Inc.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,9 +28,9 @@
#include "GraphicsContext.h"
#include "RenderView.h"
#include "SVGForeignObjectElement.h"
-#include "SVGLength.h"
#include "SVGRenderSupport.h"
-#include "SVGTransformList.h"
+#include "SVGSVGElement.h"
+#include "TransformState.h"
namespace WebCore {
@@ -38,22 +39,18 @@ RenderForeignObject::RenderForeignObject(SVGForeignObjectElement* node)
{
}
-TransformationMatrix RenderForeignObject::translationForAttributes() const
-{
- SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
- return TransformationMatrix().translate(foreign->x().value(foreign), foreign->y().value(foreign));
-}
-
void RenderForeignObject::paint(PaintInfo& paintInfo, int, int)
{
if (paintInfo.context->paintingDisabled())
return;
- // Copy the paint info so that modifications to the damage rect do not affect callers
- PaintInfo childPaintInfo = paintInfo;
+ PaintInfo childPaintInfo(paintInfo);
childPaintInfo.context->save();
- applyTransformToPaintInfo(childPaintInfo, localToParentTransform());
- childPaintInfo.context->clip(clipRect(0, 0));
+
+ applyTransformToPaintInfo(childPaintInfo, localTransform());
+
+ if (SVGRenderBase::isOverflowHidden(this))
+ childPaintInfo.context->clip(m_viewport);
float opacity = style()->opacity();
if (opacity < 1.0f)
@@ -67,29 +64,33 @@ void RenderForeignObject::paint(PaintInfo& paintInfo, int, int)
childPaintInfo.context->restore();
}
-FloatRect RenderForeignObject::objectBoundingBox() const
+IntRect RenderForeignObject::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
- return borderBoxRect();
+ return SVGRenderBase::clippedOverflowRectForRepaint(this, repaintContainer);
}
-FloatRect RenderForeignObject::repaintRectInLocalCoordinates() const
+void RenderForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
- // HACK: to maintain historical LayoutTest results for now.
- // RenderForeignObject is a RenderBlock (not a RenderSVGModelObject) so this
- // should not affect repaint correctness. But it should really be:
- // return borderBoxRect();
- return FloatRect();
+ SVGRenderBase::computeRectForRepaint(this, repaintContainer, repaintRect, fixed);
}
-void RenderForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
+const AffineTransform& RenderForeignObject::localToParentTransform() const
{
- rect = localToParentTransform().mapRect(rect);
- RenderBlock::computeRectForRepaint(repaintContainer, rect, fixed);
+ m_localToParentTransform = localTransform();
+ m_localToParentTransform.translate(m_viewport.x(), m_viewport.y());
+ return m_localToParentTransform;
}
-TransformationMatrix RenderForeignObject::localToParentTransform() const
+void RenderForeignObject::calcWidth()
{
- return localTransform() * translationForAttributes();
+ // FIXME: Investigate in size rounding issues
+ setWidth(static_cast<int>(roundf(m_viewport.width())));
+}
+
+void RenderForeignObject::calcHeight()
+{
+ // FIXME: Investigate in size rounding issues
+ setHeight(static_cast<int>(roundf(m_viewport.height())));
}
void RenderForeignObject::layout()
@@ -98,18 +99,36 @@ void RenderForeignObject::layout()
ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
- m_localTransform = static_cast<SVGForeignObjectElement*>(node())->animatedLocalTransform();
+ SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
+ m_localTransform = foreign->animatedLocalTransform();
+
+ // Cache viewport boundaries
+ FloatPoint viewportLocation(foreign->x().value(foreign), foreign->y().value(foreign));
+ m_viewport = FloatRect(viewportLocation, FloatSize(foreign->width().value(foreign), foreign->height().value(foreign)));
+
+ // Set box origin to the foreignObject x/y translation, so positioned objects in XHTML content get correct
+ // positions. A regular RenderBoxModelObject would pull this information from RenderStyle - in SVG those
+ // properties are ignored for non <svg> elements, so we mimic what happens when specifying them through CSS.
+
+ // FIXME: Investigate in location rounding issues - only affects RenderForeignObject & RenderSVGText
+ setLocation(roundedIntPoint(viewportLocation));
RenderBlock::layout();
- repainter.repaintAfterLayout();
+ repainter.repaintAfterLayout();
setNeedsLayout(false);
}
bool RenderForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
- FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
- return RenderBlock::nodeAtPoint(request, result, static_cast<int>(localPoint.x()), static_cast<int>(localPoint.y()), 0, 0, hitTestAction);
+ FloatPoint localPoint = localTransform().inverse().mapPoint(pointInParent);
+
+ // Early exit if local point is not contained in clipped viewport area
+ if (SVGRenderBase::isOverflowHidden(this) && !m_viewport.contains(localPoint))
+ return false;
+
+ IntPoint roundedLocalPoint = roundedIntPoint(localPoint);
+ return RenderBlock::nodeAtPoint(request, result, roundedLocalPoint.x(), roundedLocalPoint.y(), 0, 0, hitTestAction);
}
bool RenderForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
@@ -118,6 +137,14 @@ bool RenderForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int
return false;
}
-} // namespace WebCore
+void RenderForeignObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
+{
+ // When crawling up the hierachy starting from foreignObject child content, useTransforms may not be set to true.
+ if (!useTransforms)
+ useTransforms = true;
+ SVGRenderBase::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState);
+}
+
+}
-#endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h
index e014f22a5d..bb6b555636 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h
@@ -21,9 +21,10 @@
#ifndef RenderForeignObject_h
#define RenderForeignObject_h
-#if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
-#include "TransformationMatrix.h"
+#if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
+#include "AffineTransform.h"
+#include "FloatPoint.h"
#include "RenderSVGBlock.h"
namespace WebCore {
@@ -38,28 +39,35 @@ public:
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual TransformationMatrix localToParentTransform() const;
-
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
+
virtual bool requiresLayer() const { return false; }
virtual void layout();
- virtual FloatRect objectBoundingBox() const;
- virtual FloatRect repaintRectInLocalCoordinates() const;
+ virtual FloatRect objectBoundingBox() const { return m_viewport; }
+ virtual FloatRect strokeBoundingBox() const { return m_viewport; }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return m_viewport; }
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual bool isSVGForeignObject() const { return true; }
+ virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const;
+
private:
- TransformationMatrix translationForAttributes() const;
+ virtual void calcWidth();
+ virtual void calcHeight();
- virtual TransformationMatrix localTransform() const { return m_localTransform; }
+ virtual const AffineTransform& localToParentTransform() const;
+ virtual AffineTransform localTransform() const { return m_localTransform; }
- TransformationMatrix m_localTransform;
+ FloatRect m_viewport;
+ AffineTransform m_localTransform;
+ mutable AffineTransform m_localToParentTransform;
};
-} // namespace WebCore
+}
-#endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
-#endif // RenderForeignObject_h
+#endif
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFrame.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderFrame.cpp
index a7b131b2b6..5f87417cc6 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderFrame.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderFrame.cpp
@@ -26,6 +26,7 @@
#include "FrameView.h"
#include "HTMLFrameElement.h"
+#include "RenderView.h"
namespace WebCore {
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.cpp
index 2fe1ddbf1f..7855b2d8f7 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the KDE project.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 2000 Simon Hausmann <hausmann@kde.org>
* (C) 2000 Stefan Schimanski (1Stein@gmx.de)
@@ -38,6 +36,7 @@
#include "MouseEvent.h"
#include "RenderFrame.h"
#include "RenderView.h"
+#include "Settings.h"
namespace WebCore {
@@ -87,13 +86,14 @@ void RenderFrameSet::paintColumnBorder(const PaintInfo& paintInfo, const IntRect
// Fill first.
GraphicsContext* context = paintInfo.context;
- context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor());
+ ColorSpace colorSpace = style()->colorSpace();
+ context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor(), colorSpace);
// Now stroke the edges but only if we have enough room to paint both edges with a little
// bit of the fill color showing through.
if (borderRect.width() >= 3) {
- context->fillRect(IntRect(borderRect.topLeft(), IntSize(1, height())), borderStartEdgeColor());
- context->fillRect(IntRect(borderRect.topRight(), IntSize(1, height())), borderEndEdgeColor());
+ context->fillRect(IntRect(borderRect.topLeft(), IntSize(1, height())), borderStartEdgeColor(), colorSpace);
+ context->fillRect(IntRect(borderRect.topRight(), IntSize(1, height())), borderEndEdgeColor(), colorSpace);
}
}
@@ -106,13 +106,14 @@ void RenderFrameSet::paintRowBorder(const PaintInfo& paintInfo, const IntRect& b
// Fill first.
GraphicsContext* context = paintInfo.context;
- context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor());
+ ColorSpace colorSpace = style()->colorSpace();
+ context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor(), colorSpace);
// Now stroke the edges but only if we have enough room to paint both edges with a little
// bit of the fill color showing through.
if (borderRect.height() >= 3) {
- context->fillRect(IntRect(borderRect.topLeft(), IntSize(width(), 1)), borderStartEdgeColor());
- context->fillRect(IntRect(borderRect.bottomLeft(), IntSize(width(), 1)), borderEndEdgeColor());
+ context->fillRect(IntRect(borderRect.topLeft(), IntSize(width(), 1)), borderStartEdgeColor(), colorSpace);
+ context->fillRect(IntRect(borderRect.bottomLeft(), IntSize(width(), 1)), borderEndEdgeColor(), colorSpace);
}
}
@@ -473,7 +474,10 @@ void RenderFrameSet::layout()
layOutAxis(m_rows, frameSet()->rowLengths(), height() - (rows - 1) * borderThickness);
layOutAxis(m_cols, frameSet()->colLengths(), width() - (cols - 1) * borderThickness);
- positionFrames();
+ if (flattenFrameSet())
+ positionFramesWithFlattening();
+ else
+ positionFrames();
RenderBox::layout();
@@ -532,6 +536,119 @@ void RenderFrameSet::positionFrames()
}
}
+void RenderFrameSet::positionFramesWithFlattening()
+{
+ RenderBox* child = firstChildBox();
+ if (!child)
+ return;
+
+ int rows = frameSet()->totalRows();
+ int cols = frameSet()->totalCols();
+
+ int borderThickness = frameSet()->border();
+ bool repaintNeeded = false;
+
+ // calculate frameset height based on actual content height to eliminate scrolling
+ bool out = false;
+ for (int r = 0; r < rows && !out; r++) {
+ int extra = 0;
+ int height = m_rows.m_sizes[r];
+
+ for (int c = 0; c < cols; c++) {
+ IntRect oldFrameRect = child->frameRect();
+
+ int width = m_cols.m_sizes[c];
+
+ bool fixedWidth = frameSet()->colLengths() && frameSet()->colLengths()[c].isFixed();
+ bool fixedHeight = frameSet()->rowLengths() && frameSet()->rowLengths()[r].isFixed();
+
+ // has to be resized and itself resize its contents
+ if (!fixedWidth)
+ child->setWidth(width ? width + extra / (cols - c) : 0);
+ else
+ child->setWidth(width);
+ child->setHeight(height);
+
+ child->setNeedsLayout(true);
+
+ if (child->isFrameSet())
+ toRenderFrameSet(child)->layout();
+ else
+ toRenderFrame(child)->layoutWithFlattening(fixedWidth, fixedHeight);
+
+ if (child->height() > m_rows.m_sizes[r])
+ m_rows.m_sizes[r] = child->height();
+ if (child->width() > m_cols.m_sizes[c])
+ m_cols.m_sizes[c] = child->width();
+
+ if (child->frameRect() != oldFrameRect)
+ repaintNeeded = true;
+
+ // difference between calculated frame width and the width it actually decides to have
+ extra += width - m_cols.m_sizes[c];
+
+ child = child->nextSiblingBox();
+ if (!child) {
+ out = true;
+ break;
+ }
+ }
+ }
+
+ int xPos = 0;
+ int yPos = 0;
+ out = false;
+ child = firstChildBox();
+ for (int r = 0; r < rows && !out; r++) {
+ xPos = 0;
+ for (int c = 0; c < cols; c++) {
+ // ensure the rows and columns are filled
+ IntRect oldRect = child->frameRect();
+
+ child->setLocation(xPos, yPos);
+ child->setHeight(m_rows.m_sizes[r]);
+ child->setWidth(m_cols.m_sizes[c]);
+
+ if (child->frameRect() != oldRect) {
+ repaintNeeded = true;
+
+ // update to final size
+ child->setNeedsLayout(true);
+ if (child->isFrameSet())
+ toRenderFrameSet(child)->layout();
+ else
+ toRenderFrame(child)->layoutWithFlattening(true, true);
+ }
+
+ xPos += m_cols.m_sizes[c] + borderThickness;
+ child = child->nextSiblingBox();
+ if (!child) {
+ out = true;
+ break;
+ }
+ }
+ yPos += m_rows.m_sizes[r] + borderThickness;
+ }
+
+ setWidth(xPos - borderThickness);
+ setHeight(yPos - borderThickness);
+
+ if (repaintNeeded)
+ repaint();
+
+ // all the remaining frames are hidden to avoid ugly spurious unflowed frames
+ for (; child; child = child->nextSiblingBox()) {
+ child->setWidth(0);
+ child->setHeight(0);
+ child->setNeedsLayout(false);
+ }
+}
+
+bool RenderFrameSet::flattenFrameSet() const
+{
+ return document()->frame() && document()->frame()->settings()->frameFlatteningEnabled();
+}
+
void RenderFrameSet::startResizing(GridAxis& axis, int position)
{
int split = hitTestSplit(axis, position);
@@ -560,6 +677,9 @@ void RenderFrameSet::continueResizing(GridAxis& axis, int position)
bool RenderFrameSet::userResize(MouseEvent* evt)
{
+ if (flattenFrameSet())
+ return false;
+
if (!m_isResizing) {
if (needsLayout())
return false;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.h b/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.h
index 26bf73281d..d0ab346be9 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderFrameSet.h
@@ -95,15 +95,18 @@ private:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual void paint(PaintInfo&, int tx, int ty);
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
-
+
inline HTMLFrameSetElement* frameSet() const;
+ bool flattenFrameSet() const;
+
void setIsResizing(bool);
void layOutAxis(GridAxis&, const Length*, int availableSpace);
void computeEdgeInfo();
void fillFromEdgeInfo(const FrameEdgeInfo& edgeInfo, int r, int c);
void positionFrames();
+ void positionFramesWithFlattening();
int splitPosition(const GridAxis&, int split) const;
int hitTestSplit(const GridAxis&, int position) const;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp
index 4206b1cf1c..a14ab2753c 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderImage.cpp
@@ -4,7 +4,7 @@
* (C) 2000 Dirk Mueller (mueller@kde.org)
* (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com)
* (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,14 +26,19 @@
#include "config.h"
#include "RenderImage.h"
+#include "Frame.h"
#include "GraphicsContext.h"
+#include "HTMLAreaElement.h"
+#include "HTMLCollection.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLMapElement.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "Page.h"
+#include "RenderTheme.h"
#include "RenderView.h"
+#include "SelectionController.h"
#include <wtf/CurrentTime.h>
#include <wtf/UnusedParam.h>
@@ -49,7 +54,7 @@ namespace WebCore {
static const double cInterpolationCutoff = 800. * 800.;
static const double cLowQualityTimeThreshold = 0.050; // 50 ms
-class RenderImageScaleData {
+class RenderImageScaleData : public Noncopyable {
public:
RenderImageScaleData(RenderImage* image, const IntSize& size, double time, bool lowQualityScale)
: m_size(size)
@@ -364,8 +369,8 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
if (cWidth > 2 && cHeight > 2) {
// Draw an outline rect where the image should be.
context->setStrokeStyle(SolidStroke);
- context->setStrokeColor(Color::lightGray);
- context->setFillColor(Color::transparent);
+ context->setStrokeColor(Color::lightGray, style()->colorSpace());
+ context->setFillColor(Color::transparent, style()->colorSpace());
context->drawRect(IntRect(tx + leftBorder + leftPad, ty + topBorder + topPad, cWidth, cHeight));
bool errorPictureDrawn = false;
@@ -386,13 +391,13 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
centerY = 0;
imageX = leftBorder + leftPad + centerX + 1;
imageY = topBorder + topPad + centerY + 1;
- context->drawImage(image(), IntPoint(tx + imageX, ty + imageY));
+ context->drawImage(image(), style()->colorSpace(), IntPoint(tx + imageX, ty + imageY));
errorPictureDrawn = true;
}
if (!m_altText.isEmpty()) {
String text = document()->displayStringModifiedByEncoding(m_altText);
- context->setFillColor(style()->color());
+ context->setFillColor(style()->color(), style()->colorSpace());
int ax = tx + leftBorder + leftPad;
int ay = ty + topBorder + topPad;
const Font& font = style()->font();
@@ -420,20 +425,77 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
#endif
IntSize contentSize(cWidth, cHeight);
- bool useLowQualityScaling = RenderImageScaleObserver::shouldImagePaintAtLowQuality(this, contentSize);
IntRect rect(IntPoint(tx + leftBorder + leftPad, ty + topBorder + topPad), contentSize);
- HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
- CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
- context->drawImage(image(cWidth, cHeight), rect, compositeOperator, useLowQualityScaling);
+ paintIntoRect(context, rect);
}
}
+void RenderImage::paint(PaintInfo& paintInfo, int tx, int ty)
+{
+ RenderReplaced::paint(paintInfo, tx, ty);
+
+ if (paintInfo.phase == PaintPhaseOutline)
+ paintFocusRings(paintInfo, style());
+}
+
+void RenderImage::paintFocusRings(PaintInfo& paintInfo, const RenderStyle* style)
+{
+ // Don't draw focus rings if printing.
+ if (document()->printing() || !document()->frame()->selection()->isFocusedAndActive())
+ return;
+
+ if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
+ return;
+
+ HTMLMapElement* mapElement = imageMap();
+ if (!mapElement)
+ return;
+
+ Document* document = mapElement->document();
+ if (!document)
+ return;
+
+ Node* focusedNode = document->focusedNode();
+ if (!focusedNode)
+ return;
+
+ RefPtr<HTMLCollection> areas = mapElement->areas();
+ unsigned numAreas = areas->length();
+
+ // FIXME: Clip the paths to the image bounding box.
+ for (unsigned k = 0; k < numAreas; ++k) {
+ HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(areas->item(k));
+ if (focusedNode != areaElement)
+ continue;
+
+ Vector<Path> focusRingPaths;
+ focusRingPaths.append(areaElement->getPath(this));
+ paintInfo.context->drawFocusRing(focusRingPaths, style->outlineWidth(), style->outlineOffset(), style->outlineColor());
+ break;
+ }
+}
+
+void RenderImage::paintIntoRect(GraphicsContext* context, const IntRect& rect)
+{
+ if (!hasImage() || errorOccurred() || rect.width() <= 0 || rect.height() <= 0)
+ return;
+
+ Image* img = image(rect.width(), rect.height());
+ if (!img || img->isNull())
+ return;
+
+ HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
+ CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
+ bool useLowQualityScaling = RenderImageScaleObserver::shouldImagePaintAtLowQuality(this, rect.size());
+ context->drawImage(image(rect.width(), rect.height()), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
+}
+
int RenderImage::minimumReplacedHeight() const
{
return errorOccurred() ? intrinsicSize().height() : 0;
}
-HTMLMapElement* RenderImage::imageMap()
+HTMLMapElement* RenderImage::imageMap() const
{
HTMLImageElement* i = node() && node()->hasTagName(imgTag) ? static_cast<HTMLImageElement*>(node()) : 0;
return i ? i->document()->getImageMap(i->getAttribute(usemapAttr)) : 0;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderImage.h b/src/3rdparty/webkit/WebCore/rendering/RenderImage.h
index 2224412ae1..b89a65249d 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderImage.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderImage.h
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com)
* (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -43,7 +43,7 @@ public:
void setCachedImage(CachedImage*);
CachedImage* cachedImage() const { return m_cachedImage.get(); }
- HTMLMapElement* imageMap();
+ HTMLMapElement* imageMap() const;
void resetAnimation();
@@ -57,6 +57,15 @@ protected:
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ virtual void paintIntoRect(GraphicsContext*, const IntRect&);
+ void paintFocusRings(PaintInfo&, const RenderStyle*);
+ virtual void paint(PaintInfo&, int tx, int ty);
+
+ bool isWidthSpecified() const;
+ bool isHeightSpecified() const;
+
+ virtual void intrinsicSizeChanged() { imageChanged(imagePtr()); }
+
private:
virtual const char* renderName() const { return "RenderImage"; }
@@ -82,14 +91,9 @@ private:
virtual IntSize imageSize(float multiplier) const { return m_cachedImage ? m_cachedImage->imageSize(multiplier) : IntSize(); }
virtual WrappedImagePtr imagePtr() const { return m_cachedImage.get(); }
- virtual void intrinsicSizeChanged() { imageChanged(imagePtr()); }
-
int calcAspectRatioWidth() const;
int calcAspectRatioHeight() const;
- bool isWidthSpecified() const;
- bool isHeightSpecified() const;
-
protected:
// The image we are rendering.
CachedResourceHandle<CachedImage> m_cachedImage;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderInline.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderInline.cpp
index 2f9a247a5e..1d76742efe 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderInline.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderInline.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "RenderInline.h"
+#include "Chrome.h"
#include "FloatQuad.h"
#include "GraphicsContext.h"
#include "HitTestResult.h"
@@ -79,7 +80,7 @@ void RenderInline::destroy()
// not have a parent that means they are either already disconnected or
// root lines that can just be destroyed without disconnecting.
if (firstLineBox()->parent()) {
- for (InlineRunBox* box = firstLineBox(); box; box = box->nextLineBox())
+ for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox())
box->remove();
}
} else if (isInline() && parent())
@@ -409,7 +410,7 @@ void RenderInline::paint(PaintInfo& paintInfo, int tx, int ty)
void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
{
- if (InlineRunBox* curr = firstLineBox()) {
+ if (InlineFlowBox* curr = firstLineBox()) {
for (; curr; curr = curr->nextLineBox())
rects.append(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height()));
} else
@@ -428,7 +429,7 @@ void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
void RenderInline::absoluteQuads(Vector<FloatQuad>& quads)
{
- if (InlineRunBox* curr = firstLineBox()) {
+ if (InlineFlowBox* curr = firstLineBox()) {
for (; curr; curr = curr->nextLineBox()) {
FloatRect localRect(curr->x(), curr->y(), curr->width(), curr->height());
quads.append(localToAbsoluteQuad(localRect));
@@ -533,7 +534,7 @@ IntRect RenderInline::linesBoundingBox() const
// Return the width of the minimal left side and the maximal right side.
int leftSide = 0;
int rightSide = 0;
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
if (curr == firstLineBox() || curr->x() < leftSide)
leftSide = curr->x();
if (curr == firstLineBox() || curr->x() + curr->width() > rightSide)
@@ -556,7 +557,7 @@ IntRect RenderInline::linesVisibleOverflowBoundingBox() const
// Return the width of the minimal left side and the maximal right side.
int leftSide = numeric_limits<int>::max();
int rightSide = numeric_limits<int>::min();
- for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextFlowBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
leftSide = min(leftSide, curr->leftVisibleOverflow());
rightSide = max(rightSide, curr->rightVisibleOverflow());
}
@@ -598,11 +599,10 @@ IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repain
// cb->height() is inaccurate if we're in the middle of a layout of |cb|, so use the
// layer's size instead. Even if the layer's size is wrong, the layer itself will repaint
// anyway if its size does change.
- int x = r.x();
- int y = r.y();
+ IntRect repaintRect(r);
+ repaintRect.move(-cb->layer()->scrolledContentOffset()); // For overflow:auto/scroll/hidden.
+
IntRect boxRect(0, 0, cb->layer()->width(), cb->layer()->height());
- cb->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.
- IntRect repaintRect(x, y, r.width(), r.height());
r = intersection(repaintRect, boxRect);
}
@@ -709,7 +709,7 @@ void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer,
o->computeRectForRepaint(repaintContainer, rect, fixed);
}
-IntSize RenderInline::offsetFromContainer(RenderObject* container) const
+IntSize RenderInline::offsetFromContainer(RenderObject* container, const IntPoint& point) const
{
ASSERT(container == this->container());
@@ -717,13 +717,7 @@ IntSize RenderInline::offsetFromContainer(RenderObject* container) const
if (isRelPositioned())
offset += relativePositionOffset();
- if (!isInline() || isReplaced()) {
- RenderBlock* cb;
- if (container->isBlockFlow() && (cb = toRenderBlock(container))->hasColumns()) {
- IntRect rect(0, 0, 1, 1);
- cb->adjustRectForColumns(rect);
- }
- }
+ container->adjustForColumns(offset, point);
if (container->hasOverflowClip())
offset -= toRenderBox(container)->layer()->scrolledContentOffset();
@@ -752,7 +746,7 @@ void RenderInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b
if (!o)
return;
- IntSize containerOffset = offsetFromContainer(o);
+ IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -784,7 +778,7 @@ void RenderInline::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Trans
o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
- IntSize containerOffset = offsetFromContainer(o);
+ IntSize containerOffset = offsetFromContainer(o, IntPoint());
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -931,13 +925,15 @@ void RenderInline::imageChanged(WrappedImagePtr, const IntRect*)
repaint();
}
-void RenderInline::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
+void RenderInline::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
{
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
RootInlineBox* root = curr->root();
int top = max(root->lineTop(), curr->y());
int bottom = min(root->lineBottom(), curr->y() + curr->height());
- graphicsContext->addFocusRingRect(IntRect(tx + curr->x(), ty + top, curr->width(), bottom - top));
+ IntRect rect(tx + curr->x(), ty + top, curr->width(), bottom - top);
+ if (!rect.isEmpty())
+ rects.append(rect);
}
for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
@@ -948,17 +944,17 @@ void RenderInline::addFocusRingRects(GraphicsContext* graphicsContext, int tx, i
pos = curr->localToAbsolute();
else if (curr->isBox())
pos.move(toRenderBox(curr)->x(), toRenderBox(curr)->y());
- curr->addFocusRingRects(graphicsContext, pos.x(), pos.y());
+ curr->addFocusRingRects(rects, pos.x(), pos.y());
}
}
if (continuation()) {
if (continuation()->isInline())
- continuation()->addFocusRingRects(graphicsContext,
+ continuation()->addFocusRingRects(rects,
tx - containingBlock()->x() + continuation()->containingBlock()->x(),
ty - containingBlock()->y() + continuation()->containingBlock()->y());
else
- continuation()->addFocusRingRects(graphicsContext,
+ continuation()->addFocusRingRects(rects,
tx - containingBlock()->x() + toRenderBox(continuation())->x(),
ty - containingBlock()->y() + toRenderBox(continuation())->y());
}
@@ -975,13 +971,12 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
if (!oc.isValid())
oc = style()->color();
- graphicsContext->initFocusRing(ow, style()->outlineOffset());
- addFocusRingRects(graphicsContext, tx, ty);
+ Vector<IntRect> focusRingRects;
+ addFocusRingRects(focusRingRects, tx, ty);
if (style()->outlineStyleIsAuto())
- graphicsContext->drawFocusRing(oc);
+ graphicsContext->drawFocusRing(focusRingRects, ow, style()->outlineOffset(), oc);
else
- addPDFURLRect(graphicsContext, graphicsContext->focusRingBoundingRect());
- graphicsContext->clearFocusRing();
+ addPDFURLRect(graphicsContext, unionRect(focusRingRects));
}
if (style()->outlineStyleIsAuto() || style()->outlineStyle() == BNONE)
@@ -990,7 +985,7 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
Vector<IntRect> rects;
rects.append(IntRect());
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
RootInlineBox* root = curr->root();
int top = max(root->lineTop(), curr->y());
int bottom = min(root->lineBottom(), curr->y() + curr->height());
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderInline.h b/src/3rdparty/webkit/WebCore/rendering/RenderInline.h
index 8e9715ccbd..7fcb5161bc 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderInline.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderInline.h
@@ -44,7 +44,7 @@ public:
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
- virtual IntSize offsetFromContainer(RenderObject*) const;
+ virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
IntRect linesBoundingBox() const;
IntRect linesVisibleOverflowBoundingBox() const;
@@ -65,7 +65,7 @@ public:
IntSize relativePositionedInlineOffset(const RenderBox* child) const;
- virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
void paintOutline(GraphicsContext*, int tx, int ty);
int verticalPositionFromCache(bool firstLine) const;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp
index fea61c9feb..15ffb64b49 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Portions are Copyright (C) 1998 Netscape Communications Corporation.
*
@@ -73,11 +73,13 @@
#include "RenderScrollbar.h"
#include "RenderScrollbarPart.h"
#include "RenderTheme.h"
+#include "RenderTreeAsText.h"
#include "RenderView.h"
#include "ScaleTransformOperation.h"
#include "Scrollbar.h"
#include "ScrollbarTheme.h"
#include "SelectionController.h"
+#include "TextStream.h"
#include "TransformationMatrix.h"
#include "TransformState.h"
#include "TranslateTransformOperation.h"
@@ -243,14 +245,6 @@ bool RenderLayer::hasAcceleratedCompositing() const
#endif
}
-void RenderLayer::setStaticY(int staticY)
-{
- if (m_staticY == staticY)
- return;
- m_staticY = staticY;
- renderer()->setChildNeedsLayout(true, false);
-}
-
void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
{
if (flags & DoFullRepaint) {
@@ -295,7 +289,7 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
if (newRect != m_repaintRect)
renderer()->repaintUsingContainer(repaintContainer, newRect);
} else
- renderer()->repaintAfterLayoutIfNeeded(repaintContainer, m_repaintRect, m_outlineBox);
+ renderer()->repaintAfterLayoutIfNeeded(repaintContainer, m_repaintRect, m_outlineBox, &newRect, &newOutlineBox);
}
}
m_repaintRect = newRect;
@@ -383,6 +377,20 @@ TransformationMatrix RenderLayer::currentTransform() const
return *m_transform;
}
+TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
+{
+ if (!m_transform)
+ return TransformationMatrix();
+
+ if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
+ TransformationMatrix matrix = *m_transform;
+ makeMatrixRenderable(matrix, false /* flatten 3d */);
+ return matrix;
+ }
+
+ return *m_transform;
+}
+
void RenderLayer::setHasVisibleContent(bool b)
{
if (m_hasVisibleContent == b && !m_visibleContentStatusDirty)
@@ -563,15 +571,20 @@ void RenderLayer::updateLayerPosition()
RenderLayer* positionedParent = enclosingPositionedAncestor();
// For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
- positionedParent->subtractScrolledContentOffset(x, y);
+ IntSize offset = positionedParent->scrolledContentOffset();
+ x -= offset.width();
+ y -= offset.height();
if (renderer()->isPositioned() && positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) {
IntSize offset = toRenderInline(positionedParent->renderer())->relativePositionedInlineOffset(toRenderBox(renderer()));
x += offset.width();
y += offset.height();
}
- } else if (parent())
- parent()->subtractScrolledContentOffset(x, y);
+ } else if (parent()) {
+ IntSize offset = parent()->scrolledContentOffset();
+ x -= offset.width();
+ y -= offset.height();
+ }
// FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
@@ -651,6 +664,12 @@ static inline bool isPositionedContainer(RenderLayer* layer)
return o->isRenderView() || o->isPositioned() || o->isRelPositioned() || layer->hasTransform();
}
+static inline bool isFixedPositionedContainer(RenderLayer* layer)
+{
+ RenderObject* o = layer->renderer();
+ return o->isRenderView() || layer->hasTransform();
+}
+
RenderLayer* RenderLayer::enclosingPositionedAncestor() const
{
RenderLayer* curr = parent();
@@ -689,6 +708,32 @@ RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const
}
#endif
+RenderLayer* RenderLayer::clippingRoot() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (isComposited())
+ return const_cast<RenderLayer*>(this);
+#endif
+
+ const RenderLayer* current = this;
+ while (current) {
+ if (current->renderer()->isRenderView())
+ return const_cast<RenderLayer*>(current);
+
+ current = compositingContainer(current);
+ ASSERT(current);
+ if (current->transform()
+#if USE(ACCELERATED_COMPOSITING)
+ || current->isComposited()
+#endif
+ )
+ return const_cast<RenderLayer*>(current);
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
IntPoint RenderLayer::absoluteToContents(const IntPoint& absolutePoint) const
{
// We don't use convertToLayerCoords because it doesn't know about transforms
@@ -727,46 +772,18 @@ RenderLayer* RenderLayer::transparentPaintingAncestor()
return 0;
}
-static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransform, const RenderLayer* l, const RenderLayer* rootLayer)
-{
- // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
- // paintDirtyRect, and that should cut down on the amount we have to paint. Still it
- // would be better to respect clips.
-
- if (rootLayer != l && l->paintsWithTransform()) {
- // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
- // the transformed layer and all of its children.
- int x = 0;
- int y = 0;
- l->convertToLayerCoords(rootLayer, x, y);
-
- TransformationMatrix transform;
- transform.translate(x, y);
- transform = *l->transform() * transform;
- transform = transform * enclosingTransform;
+static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior);
- // We now have a transform that will produce a rectangle in our view's space.
- IntRect clipRect = transform.mapRect(l->boundingBox(l));
-
- // Now shift the root layer to be us and pass down the new enclosing transform.
- for (RenderLayer* curr = l->firstChild(); curr; curr = curr->nextSibling()) {
- if (!l->reflection() || l->reflectionLayer() != curr)
- clipRect.unite(transparencyClipBox(transform, curr, l));
- }
-
- return clipRect;
- }
-
- // Note: we don't have to walk z-order lists since transparent elements always establish
- // a stacking context. This means we can just walk the layer tree directly.
- IntRect clipRect = l->boundingBox(rootLayer);
-
+static void expandClipRectForDescendantsAndReflection(IntRect& clipRect, const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
+{
// If we have a mask, then the clip is limited to the border box area (and there is
// no need to examine child layers).
if (!l->renderer()->hasMask()) {
+ // Note: we don't have to walk z-order lists since transparent elements always establish
+ // a stacking context. This means we can just walk the layer tree directly.
for (RenderLayer* curr = l->firstChild(); curr; curr = curr->nextSibling()) {
if (!l->reflection() || l->reflectionLayer() != curr)
- clipRect.unite(transparencyClipBox(enclosingTransform, curr, rootLayer));
+ clipRect.unite(transparencyClipBox(curr, rootLayer, paintBehavior));
}
}
@@ -782,25 +799,54 @@ static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransfor
clipRect.unite(l->renderBox()->reflectedRect(clipRect));
clipRect.move(deltaX, deltaY);
}
+}
+
+static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
+{
+ // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
+ // paintDirtyRect, and that should cut down on the amount we have to paint. Still it
+ // would be better to respect clips.
+
+ if (rootLayer != l && l->paintsWithTransform(paintBehavior)) {
+ // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
+ // the transformed layer and all of its children.
+ int x = 0;
+ int y = 0;
+ l->convertToLayerCoords(rootLayer, x, y);
- // Now map the clipRect via the enclosing transform
- return enclosingTransform.mapRect(clipRect);
+ TransformationMatrix transform;
+ transform.translate(x, y);
+ transform = *l->transform() * transform;
+
+ IntRect clipRect = l->boundingBox(l);
+ expandClipRectForDescendantsAndReflection(clipRect, l, l, paintBehavior);
+ return transform.mapRect(clipRect);
+ }
+
+ IntRect clipRect = l->boundingBox(rootLayer);
+ expandClipRectForDescendantsAndReflection(clipRect, l, rootLayer, paintBehavior);
+ return clipRect;
}
-void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer* rootLayer)
+void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
{
- if (p->paintingDisabled() || (paintsWithTransparency() && m_usedTransparency))
+ if (p->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency))
return;
RenderLayer* ancestor = transparentPaintingAncestor();
if (ancestor)
- ancestor->beginTransparencyLayers(p, rootLayer);
+ ancestor->beginTransparencyLayers(p, rootLayer, paintBehavior);
- if (paintsWithTransparency()) {
+ if (paintsWithTransparency(paintBehavior)) {
m_usedTransparency = true;
p->save();
- p->clip(transparencyClipBox(TransformationMatrix(), this, rootLayer));
+ IntRect clipRect = transparencyClipBox(this, rootLayer, paintBehavior);
+ p->clip(clipRect);
p->beginTransparencyLayer(renderer()->opacity());
+#ifdef REVEAL_TRANSPARENCY_LAYERS
+ p->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f), DeviceColorSpace);
+ p->fillRect(clipRect);
+#endif
}
}
@@ -958,9 +1004,10 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
{
if (ancestorLayer == this)
return;
-
- if (renderer()->style()->position() == FixedPosition) {
- // Add in the offset of the view. We can obtain this by calling
+
+ EPosition position = renderer()->style()->position();
+ if (position == FixedPosition && (!ancestorLayer || ancestorLayer == renderer()->view()->layer())) {
+ // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
// localToAbsolute() on the RenderView.
FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
xPos += absPos.x();
@@ -968,9 +1015,43 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
return;
}
+ if (position == FixedPosition) {
+ // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
+ // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
+ // so we should always find the ancestor at or before we find the fixed position container.
+ RenderLayer* fixedPositionContainerLayer = 0;
+ bool foundAncestor = false;
+ for (RenderLayer* currLayer = parent(); currLayer; currLayer = currLayer->parent()) {
+ if (currLayer == ancestorLayer)
+ foundAncestor = true;
+
+ if (isFixedPositionedContainer(currLayer)) {
+ fixedPositionContainerLayer = currLayer;
+ ASSERT(foundAncestor);
+ break;
+ }
+ }
+
+ ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
+
+ if (fixedPositionContainerLayer != ancestorLayer) {
+ int fixedContainerX = 0;
+ int fixedContainerY = 0;
+ convertToLayerCoords(fixedPositionContainerLayer, fixedContainerX, fixedContainerY);
+
+ int ancestorX = 0;
+ int ancestorY = 0;
+ ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorX, ancestorY);
+
+ xPos += (fixedContainerX - ancestorX);
+ yPos += (fixedContainerY - ancestorY);
+ return;
+ }
+ }
+
RenderLayer* parentLayer;
- if (renderer()->style()->position() == AbsolutePosition) {
- // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way
+ if (position == AbsolutePosition || position == FixedPosition) {
+ // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
parentLayer = parent();
bool foundAncestorFirst = false;
while (parentLayer) {
@@ -1061,7 +1142,7 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
bool restrictedByLineClamp = false;
if (renderer()->parent())
- restrictedByLineClamp = renderer()->parent()->style()->lineClamp() >= 0;
+ restrictedByLineClamp = !renderer()->parent()->style()->lineClamp().isNone();
if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
int newOffsetX = scrollXOffset() + xDelta;
@@ -1086,7 +1167,7 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
frame->eventHandler()->updateAutoscrollRenderer();
}
} else if (renderer()->view()->frameView()) {
- // If we are here, we were called on a renderer that can be programatically scrolled, but doesn't
+ // If we are here, we were called on a renderer that can be programmatically scrolled, but doesn't
// have an overflow clip. Which means that it is a document node that can be scrolled.
renderer()->view()->frameView()->scrollBy(IntSize(xDelta, yDelta));
// FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement?
@@ -1094,21 +1175,6 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
}
}
-
-void
-RenderLayer::addScrolledContentOffset(int& x, int& y) const
-{
- x += scrollXOffset() + m_scrollLeftOverflow;
- y += scrollYOffset();
-}
-
-void
-RenderLayer::subtractScrolledContentOffset(int& x, int& y) const
-{
- x -= scrollXOffset() + m_scrollLeftOverflow;
- y -= scrollYOffset();
-}
-
void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repaint)
{
RenderBox* box = renderBox();
@@ -1146,7 +1212,9 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
#if USE(ACCELERATED_COMPOSITING)
if (compositor()->inCompositingMode()) {
- if (RenderLayer* compositingAncestor = ancestorCompositingLayer()) {
+ // Our stacking context is guaranteed to contain all of our descendants that may need
+ // repositioning, so update compositing layers from there.
+ if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
bool isUpdateRoot = true;
compositingAncestor->backing()->updateAfterLayout(RenderLayerBacking::AllDescendants, isUpdateRoot);
}
@@ -1167,15 +1235,24 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
view->updateWidgetPositions();
}
- // The caret rect needs to be invalidated after scrolling
+ RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
+ IntRect rectForRepaint = renderer()->clippedOverflowRectForRepaint(repaintContainer);
+
Frame* frame = renderer()->document()->frame();
- if (frame)
- frame->invalidateSelection();
+ if (frame) {
+ // The caret rect needs to be invalidated after scrolling
+ frame->selection()->setNeedsLayout();
+
+ FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint);
+ if (repaintContainer)
+ quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
+ frame->eventHandler()->dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
+ }
// Just schedule a full repaint of our object.
- if (repaint)
- renderer()->repaint();
-
+ if (view && repaint)
+ renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
+
if (updateScrollbars) {
if (m_hBar)
m_hBar->setValue(scrollXOffset());
@@ -1205,7 +1282,7 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor,
bool restrictedByLineClamp = false;
if (renderer()->parent()) {
parentLayer = renderer()->parent()->enclosingLayer();
- restrictedByLineClamp = renderer()->parent()->style()->lineClamp() >= 0;
+ restrictedByLineClamp = !renderer()->parent()->style()->lineClamp().isNone();
}
if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
@@ -1673,6 +1750,11 @@ IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
return localPoint - bottomRight;
}
+bool RenderLayer::hasOverflowControls() const
+{
+ return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE;
+}
+
void RenderLayer::positionOverflowControls(int tx, int ty)
{
if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
@@ -1858,17 +1940,23 @@ RenderLayer::updateScrollInfoAfterLayout()
// Set up the range (and page step/line step).
if (m_hBar) {
int clientWidth = box->clientWidth();
- int pageStep = (clientWidth - cAmountToKeepWhenPaging);
- if (pageStep < 0) pageStep = clientWidth;
- m_hBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
+ int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
+ m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_hBar->setProportion(clientWidth, m_scrollWidth);
+ // Explicitly set the horizontal scroll value. This ensures that when a
+ // right-to-left scrollable area's width (or content width) changes, the
+ // top right corner of the content doesn't shift with respect to the top
+ // right corner of the area. Conceptually, right-to-left areas have
+ // their origin at the top-right, but RenderLayer is top-left oriented,
+ // so this is needed to keep everything working (see how scrollXOffset()
+ // differs from scrollYOffset() to get an idea of why the horizontal and
+ // vertical scrollbars need to be treated differently).
m_hBar->setValue(scrollXOffset());
}
if (m_vBar) {
int clientHeight = box->clientHeight();
- int pageStep = (clientHeight - cAmountToKeepWhenPaging);
- if (pageStep < 0) pageStep = clientHeight;
- m_vBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
+ int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
+ m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_vBar->setProportion(clientHeight, m_scrollHeight);
}
@@ -1921,7 +2009,7 @@ void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, co
return;
}
- context->fillRect(absRect, Color::white);
+ context->fillRect(absRect, Color::white, box->style()->colorSpace());
}
void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
@@ -1950,7 +2038,7 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
// Paint the resizer control.
DEFINE_STATIC_LOCAL(RefPtr<Image>, resizeCornerImage, (Image::loadPlatformResource("textAreaResizeCorner")));
IntPoint imagePoint(absRect.right() - resizeCornerImage->width(), absRect.bottom() - resizeCornerImage->height());
- context->drawImage(resizeCornerImage.get(), imagePoint);
+ context->drawImage(resizeCornerImage.get(), box->style()->colorSpace(), imagePoint);
// Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
// Clipping will exclude the right and bottom edges of this frame.
@@ -1959,9 +2047,9 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
context->clip(absRect);
IntRect largerCorner = absRect;
largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.height() + 1));
- context->setStrokeColor(Color(makeRGB(217, 217, 217)));
+ context->setStrokeColor(Color(makeRGB(217, 217, 217)), DeviceColorSpace);
context->setStrokeThickness(1.0f);
- context->setFillColor(Color::transparent);
+ context->setFillColor(Color::transparent, DeviceColorSpace);
context->drawRect(largerCorner);
context->restore();
}
@@ -2044,10 +2132,10 @@ bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularit
return (didHorizontalScroll || didVerticalScroll);
}
-void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintRestriction paintRestriction, RenderObject *paintingRoot)
+void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot)
{
RenderObject::OverlapTestRequestMap overlapTestRequests;
- paintLayer(this, p, damageRect, paintRestriction, paintingRoot, &overlapTestRequests);
+ paintLayer(this, p, damageRect, paintBehavior, paintingRoot, &overlapTestRequests);
RenderObject::OverlapTestRequestMap::iterator end = overlapTestRequests.end();
for (RenderObject::OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
it->first->setOverlapTestResult(false);
@@ -2091,7 +2179,7 @@ static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflect
#endif
void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
- const IntRect& paintDirtyRect, PaintRestriction paintRestriction,
+ const IntRect& paintDirtyRect, PaintBehavior paintBehavior,
RenderObject* paintingRoot, RenderObject::OverlapTestRequestMap* overlapTestRequests,
PaintLayerFlags paintFlags)
{
@@ -2099,7 +2187,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (isComposited()) {
// The updatingControlTints() painting pass goes through compositing layers,
// but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
- if (p->updatingControlTints())
+ if (p->updatingControlTints() || (paintBehavior & PaintBehaviorFlattenCompositingLayers))
paintFlags |= PaintLayerTemporaryClipRects;
else if (!backing()->paintingGoesToWindow() && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)) {
// If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer().
@@ -2118,19 +2206,20 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (!renderer()->opacity())
return;
- if (paintsWithTransparency())
+ if (paintsWithTransparency(paintBehavior))
paintFlags |= PaintLayerHaveTransparency;
// Apply a transform if we have one. A reflection is considered to be a transform, since it is a flip and a translate.
- if (paintsWithTransform() && !(paintFlags & PaintLayerAppliedTransform)) {
+ if (paintsWithTransform(paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) {
+ TransformationMatrix layerTransform = renderableTransform(paintBehavior);
// If the transform can't be inverted, then don't paint anything.
- if (!m_transform->isInvertible())
+ if (!layerTransform.isInvertible())
return;
// If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
// layer from the parent now.
if (paintFlags & PaintLayerHaveTransparency)
- parent()->beginTransparencyLayers(p, rootLayer);
+ parent()->beginTransparencyLayers(p, rootLayer, paintBehavior);
// Make sure the parent's clip rects have been calculated.
IntRect clipRect = paintDirtyRect;
@@ -2147,16 +2236,15 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
int x = 0;
int y = 0;
convertToLayerCoords(rootLayer, x, y);
- TransformationMatrix transform;
- transform.translate(x, y);
- transform = *m_transform * transform;
+ TransformationMatrix transform(layerTransform);
+ transform.translateRight(x, y);
// Apply the transform.
p->save();
- p->concatCTM(transform);
+ p->concatCTM(transform.toAffineTransform());
// Now do a paint with the root layer shifted to be us.
- paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintRestriction, paintingRoot, overlapTestRequests, paintFlags | PaintLayerAppliedTransform);
+ paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, overlapTestRequests, paintFlags | PaintLayerAppliedTransform);
p->restore();
@@ -2173,7 +2261,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (m_reflection && !m_paintingInsideReflection) {
// Mark that we are now inside replica painting.
m_paintingInsideReflection = true;
- reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags | PaintLayerPaintingReflection);
+ reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags | PaintLayerPaintingReflection);
m_paintingInsideReflection = false;
}
@@ -2188,13 +2276,13 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Ensure our lists are up-to-date.
updateCompositingAndLayerListsIfNeeded();
- bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText;
- bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText;
+ bool forceBlackText = paintBehavior & PaintBehaviorForceBlackText;
+ bool selectionOnly = paintBehavior & PaintBehaviorSelectionOnly;
// If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
// is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
// Else, our renderer tree may or may not contain the painting root, so we pass that root along
- // so it will be tested against as we decend through the renderers.
+ // so it will be tested against as we descend through the renderers.
RenderObject* paintingRootForRenderer = 0;
if (paintingRoot && !renderer()->isDescendantOf(paintingRoot))
paintingRootForRenderer = paintingRoot;
@@ -2207,7 +2295,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
// Begin transparency layers lazily now that we know we have to paint something.
if (haveTransparency)
- beginTransparencyLayers(p, rootLayer);
+ beginTransparencyLayers(p, rootLayer, paintBehavior);
// Paint our background first, before painting any child layers.
// Establish the clip used to paint our background.
@@ -2224,13 +2312,13 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Now walk the sorted list of children with negative z-indices.
if (m_negZOrderList)
for (Vector<RenderLayer*>::iterator it = m_negZOrderList->begin(); it != m_negZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags);
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
// Now establish the appropriate clip and paint our child RenderObjects.
if (shouldPaint && !clipRectToApply.isEmpty()) {
// Begin transparency layers lazily now that we know we have to paint something.
if (haveTransparency)
- beginTransparencyLayers(p, rootLayer);
+ beginTransparencyLayers(p, rootLayer, paintBehavior);
// Set up the clip used when painting our children.
setClip(p, paintDirtyRect, clipRectToApply);
@@ -2263,12 +2351,12 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Paint any child layers that have overflow.
if (m_normalFlowList)
for (Vector<RenderLayer*>::iterator it = m_normalFlowList->begin(); it != m_normalFlowList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags);
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
// Now walk the sorted list of children with positive z-indices.
if (m_posZOrderList)
for (Vector<RenderLayer*>::iterator it = m_posZOrderList->begin(); it != m_posZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags);
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
if (renderer()->hasMask() && shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
setClip(p, paintDirtyRect, damageRect);
@@ -2317,15 +2405,10 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
}
}
- // Now determine if the result is inside an anchor; make sure an image map wins if
- // it already set URLElement and only use the innermost.
+ // Now determine if the result is inside an anchor - if the urlElement isn't already set.
Node* node = result.innerNode();
- while (node) {
- // for imagemaps, URLElement is the associated area element not the image itself
- if (node->isLink() && !result.URLElement() && !node->hasTagName(imgTag))
- result.setURLElement(static_cast<Element*>(node));
- node = node->eventParentNode();
- }
+ if (node && !result.URLElement())
+ result.setURLElement(static_cast<Element*>(node->enclosingLinkEventParentOrSelf()));
// Next set up the correct :hover/:active state along the new chain.
updateHoverActiveState(request, result);
@@ -2569,7 +2652,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
// Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
if (fgRect.contains(hitTestPoint) && isSelfPaintingLayer()) {
- // Hit test with a temporary HitTestResult, because we onlyl want to commit to 'result' if we know we're frontmost.
+ // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
HitTestResult tempResult(result.point());
if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestDescendants) &&
isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
@@ -2808,17 +2891,49 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa
IntRect RenderLayer::childrenClipRect() const
{
RenderLayer* rootLayer = renderer()->view()->layer();
+ RenderLayer* clippingRootLayer = clippingRoot();
IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
- calculateRects(rootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
- return foregroundRect;
+ calculateRects(clippingRootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
+ return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect)).enclosingBoundingBox();
}
IntRect RenderLayer::selfClipRect() const
{
RenderLayer* rootLayer = renderer()->view()->layer();
+ RenderLayer* clippingRootLayer = clippingRoot();
IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
- calculateRects(rootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
- return backgroundRect;
+ calculateRects(clippingRootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
+ return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect)).enclosingBoundingBox();
+}
+
+void RenderLayer::addBlockSelectionGapsBounds(const IntRect& bounds)
+{
+ m_blockSelectionGapsBounds.unite(bounds);
+}
+
+void RenderLayer::clearBlockSelectionGapsBounds()
+{
+ m_blockSelectionGapsBounds = IntRect();
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+ child->clearBlockSelectionGapsBounds();
+}
+
+void RenderLayer::repaintBlockSelectionGaps()
+{
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+ child->repaintBlockSelectionGaps();
+
+ if (m_blockSelectionGapsBounds.isEmpty())
+ return;
+
+ IntRect rect = m_blockSelectionGapsBounds;
+ rect.move(-scrolledContentOffset());
+ if (renderer()->hasOverflowClip())
+ rect.intersect(toRenderBox(renderer())->overflowClipRect(0, 0));
+ if (renderer()->hasClip())
+ rect.intersect(toRenderBox(renderer())->clipRect(0, 0));
+ if (!rect.isEmpty())
+ renderer()->repaintRectangle(rect);
}
bool RenderLayer::intersectsDamageRect(const IntRect& layerBounds, const IntRect& damageRect, const RenderLayer* rootLayer) const
@@ -2866,7 +2981,7 @@ IntRect RenderLayer::localBoundingBox() const
int top = firstBox->topVisibleOverflow();
int bottom = inlineFlow->lastLineBox()->bottomVisibleOverflow();
int left = firstBox->x();
- for (InlineRunBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
left = min(left, curr->x());
result = IntRect(left, top, width(), bottom - top);
} else if (renderer()->isTableRow()) {
@@ -3172,7 +3287,7 @@ void RenderLayer::updateCompositingAndLayerListsIfNeeded()
#if USE(ACCELERATED_COMPOSITING)
if (compositor()->inCompositingMode()) {
if ((isStackingContext() && m_zOrderListsDirty) || m_normalFlowListDirty)
- compositor()->updateCompositingLayers(this);
+ compositor()->updateCompositingLayers(CompositingUpdateOnPaitingOrHitTest, this);
return;
}
#endif
@@ -3233,7 +3348,7 @@ void RenderLayer::repaintIncludingNonCompositingDescendants(RenderBoxModelObject
bool RenderLayer::shouldBeNormalFlowOnly() const
{
- return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isVideo()) &&
+ return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isVideo() || renderer()->isEmbeddedObject()) &&
!renderer()->isPositioned() &&
!renderer()->isRelPositioned() &&
!renderer()->hasTransform() &&
@@ -3242,7 +3357,7 @@ bool RenderLayer::shouldBeNormalFlowOnly() const
bool RenderLayer::isSelfPaintingLayer() const
{
- return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo();
+ return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo() || renderer()->isEmbeddedObject();
}
void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
@@ -3256,7 +3371,7 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
dirtyStackingContextZOrderLists();
}
- if (renderer()->style()->overflowX() == OMARQUEE && renderer()->style()->marqueeBehavior() != MNONE) {
+ if (renderer()->style()->overflowX() == OMARQUEE && renderer()->style()->marqueeBehavior() != MNONE && renderer()->isBox()) {
if (!m_marquee)
m_marquee = new RenderMarquee(this);
m_marquee->updateMarqueeStyle();
@@ -3390,3 +3505,16 @@ void RenderLayer::updateReflectionStyle()
}
} // namespace WebCore
+
+#ifndef NDEBUG
+void showLayerTree(const WebCore::RenderLayer* layer)
+{
+ if (!layer)
+ return;
+
+ if (WebCore::Frame* frame = layer->renderer()->document()->frame()) {
+ WebCore::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers);
+ fprintf(stderr, "%s\n", output.utf8().data());
+ }
+}
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h
index a274638586..9210e95c92 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h
@@ -202,9 +202,10 @@ public:
bool isTransparent() const;
RenderLayer* transparentPaintingAncestor();
- void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer);
+ void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, PaintBehavior);
bool hasReflection() const { return renderer()->hasReflection(); }
+ bool isReflection() const { return renderer()->isReplica(); }
RenderReplica* reflection() const { return m_reflection; }
RenderLayer* reflectionLayer() const;
@@ -226,6 +227,8 @@ public:
int width() const { return m_width; }
int height() const { return m_height; }
+ IntSize size() const { return IntSize(m_width, m_height); }
+
void setWidth(int w) { m_width = w; }
void setHeight(int h) { m_height = h; }
@@ -236,8 +239,7 @@ public:
// Scrolling methods for layers that can scroll their overflow.
void scrollByRecursively(int xDelta, int yDelta);
- void addScrolledContentOffset(int& x, int& y) const;
- void subtractScrolledContentOffset(int& x, int& y) const;
+
IntSize scrolledContentOffset() const { return IntSize(scrollXOffset() + m_scrollLeftOverflow, scrollYOffset()); }
int scrollXOffset() const { return m_scrollX + m_scrollOriginX; }
@@ -262,6 +264,7 @@ public:
int verticalScrollbarWidth() const;
int horizontalScrollbarHeight() const;
+ bool hasOverflowControls() const;
void positionOverflowControls(int tx, int ty);
bool isPointInResizeControl(const IntPoint& absolutePoint) const;
bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint);
@@ -312,6 +315,10 @@ public:
void clearClipRectsIncludingDescendants();
void clearClipRects();
+ void addBlockSelectionGapsBounds(const IntRect&);
+ void clearBlockSelectionGapsBounds();
+ void repaintBlockSelectionGaps();
+
// Get the enclosing stacking context for this layer. A stacking context is a layer
// that has a non-auto z-index.
RenderLayer* stackingContext() const;
@@ -336,6 +343,9 @@ public:
// the <html> layer and the root layer).
RenderLayer* enclosingPositionedAncestor() const;
+ // The layer relative to which clipping rects for this layer are computed.
+ RenderLayer* clippingRoot() const;
+
#if USE(ACCELERATED_COMPOSITING)
// Enclosing compositing layer; if includeSelf is true, may return this.
RenderLayer* enclosingCompositingLayer(bool includeSelf = true) const;
@@ -352,7 +362,7 @@ public:
// paints the layers that intersect the damage rect from back to
// front. The hitTest method looks for mouse events by walking
// layers that intersect the point from front to back.
- void paint(GraphicsContext*, const IntRect& damageRect, PaintRestriction = PaintRestrictionNone, RenderObject* paintingRoot = 0);
+ void paint(GraphicsContext*, const IntRect& damageRect, PaintBehavior = PaintBehaviorNormal, RenderObject* paintingRoot = 0);
bool hitTest(const HitTestRequest&, HitTestResult&);
// This method figures out our layerBounds in coordinates relative to
@@ -390,7 +400,7 @@ public:
int staticX() const { return m_staticX; }
int staticY() const { return m_staticY; }
void setStaticX(int staticX) { m_staticX = staticX; }
- void setStaticY(int staticY);
+ void setStaticY(int staticY) { m_staticY = staticY; }
bool hasTransform() const { return renderer()->hasTransform(); }
// Note that this transform has the transform-origin baked in.
@@ -399,6 +409,7 @@ public:
// resulting transform has transform-origin baked in. If the layer does not have a transform,
// returns the identity matrix.
TransformationMatrix currentTransform() const;
+ TransformationMatrix renderableTransform(PaintBehavior) const;
// Get the perspective transform, which is applied to transformed sublayers.
// Returns true if the layer has a -webkit-perspective.
@@ -426,14 +437,14 @@ public:
bool hasCompositedMask() const { return false; }
#endif
- bool paintsWithTransparency() const
+ bool paintsWithTransparency(PaintBehavior paintBehavior) const
{
- return isTransparent() && !isComposited();
+ return isTransparent() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || !isComposited());
}
- bool paintsWithTransform() const
+ bool paintsWithTransform(PaintBehavior paintBehavior) const
{
- return transform() && !isComposited();
+ return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || !isComposited());
}
private:
@@ -465,7 +476,7 @@ private:
typedef unsigned PaintLayerFlags;
void paintLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect,
- PaintRestriction, RenderObject* paintingRoot, RenderObject::OverlapTestRequestMap* = 0,
+ PaintBehavior, RenderObject* paintingRoot, RenderObject::OverlapTestRequestMap* = 0,
PaintLayerFlags paintFlags = 0);
RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
@@ -644,6 +655,9 @@ protected:
RenderScrollbarPart* m_scrollCorner;
RenderScrollbarPart* m_resizer;
+private:
+ IntRect m_blockSelectionGapsBounds;
+
#if USE(ACCELERATED_COMPOSITING)
OwnPtr<RenderLayerBacking> m_backing;
#endif
@@ -651,4 +665,9 @@ protected:
} // namespace WebCore
+#ifndef NDEBUG
+// Outside the WebCore namespace for ease of invocation from gdb.
+void showLayerTree(const WebCore::RenderLayer* layer);
+#endif
+
#endif // RenderLayer_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp
index d7248d49f0..b5f74c6710 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp
@@ -28,7 +28,9 @@
#if USE(ACCELERATED_COMPOSITING)
#include "AnimationController.h"
-#include "CanvasRenderingContext3D.h"
+#if ENABLE(3D_CANVAS)
+#include "WebGLRenderingContext.h"
+#endif
#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
#include "FrameView.h"
@@ -36,12 +38,18 @@
#include "GraphicsLayer.h"
#include "HTMLCanvasElement.h"
#include "HTMLElement.h"
+#include "HTMLMediaElement.h"
#include "HTMLNames.h"
+#include "InspectorTimelineAgent.h"
+#include "KeyframeList.h"
+#include "PluginWidget.h"
#include "RenderBox.h"
#include "RenderImage.h"
#include "RenderLayerCompositor.h"
+#include "RenderEmbeddedObject.h"
#include "RenderVideo.h"
#include "RenderView.h"
+#include "Settings.h"
#include "RenderLayerBacking.h"
@@ -52,12 +60,22 @@ namespace WebCore {
using namespace HTMLNames;
static bool hasBorderOutlineOrShadow(const RenderStyle*);
-static bool hasBoxDecorations(const RenderStyle*);
-static bool hasBoxDecorationsWithBackgroundImage(const RenderStyle*);
+static bool hasBoxDecorationsOrBackground(const RenderStyle*);
+static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
+
+static inline bool is3DCanvas(RenderObject* renderer)
+{
+#if ENABLE(3D_CANVAS)
+ if (renderer->isCanvas())
+ return static_cast<HTMLCanvasElement*>(renderer->node())->is3D();
+#else
+ UNUSED_PARAM(renderer);
+#endif
+ return false;
+}
RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
: m_owningLayer(layer)
- , m_hasDirectlyCompositedContent(false)
, m_artificiallyInflatedBounds(false)
{
createGraphicsLayer();
@@ -81,11 +99,13 @@ void RenderLayerBacking::createGraphicsLayer()
m_graphicsLayer->setName("Document Node");
else {
if (renderer()->node()->isHTMLElement() && renderer()->node()->hasID())
- m_graphicsLayer->setName(renderer()->renderName() + String(" ") + static_cast<HTMLElement*>(renderer()->node())->getAttribute(idAttr));
+ m_graphicsLayer->setName(renderer()->renderName() + String(" ") + static_cast<HTMLElement*>(renderer()->node())->getIDAttribute());
else
m_graphicsLayer->setName(renderer()->renderName());
}
- } else
+ } else if (m_owningLayer->isReflection())
+ m_graphicsLayer->setName("Reflection");
+ else
m_graphicsLayer->setName("Anonymous Node");
#endif // NDEBUG
@@ -181,29 +201,35 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
if (updateMaskLayer(m_owningLayer->renderer()->hasMask()))
m_graphicsLayer->setMaskLayer(m_maskLayer.get());
- m_hasDirectlyCompositedContent = false;
- if (canUseDirectCompositing()) {
- if (renderer()->isImage()) {
- updateImageContents();
- m_hasDirectlyCompositedContent = true;
- m_graphicsLayer->setDrawsContent(false);
- }
-#if ENABLE(3D_CANVAS)
- else if (renderer()->isCanvas()) {
- HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
- if (canvas->is3D()) {
- CanvasRenderingContext3D* context = static_cast<CanvasRenderingContext3D*>(canvas->renderingContext());
- if (context->graphicsContext3D()->platformGraphicsContext3D())
- m_graphicsLayer->setContentsToGraphicsContext3D(context->graphicsContext3D());
- }
+ if (m_owningLayer->hasReflection()) {
+ if (m_owningLayer->reflectionLayer()->backing()) {
+ GraphicsLayer* reflectionLayer = m_owningLayer->reflectionLayer()->backing()->graphicsLayer();
+ m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
}
-#endif
+ } else
+ m_graphicsLayer->setReplicatedByLayer(0);
+
+ if (isDirectlyCompositedImage())
+ updateImageContents();
- if (rendererHasBackground())
- m_graphicsLayer->setBackgroundColor(rendererBackgroundColor());
- else
- m_graphicsLayer->clearBackgroundColor();
+ if (renderer()->isEmbeddedObject() && toRenderEmbeddedObject(renderer())->allowsAcceleratedCompositing()) {
+ PluginWidget* pluginWidget = static_cast<PluginWidget*>(toRenderEmbeddedObject(renderer())->widget());
+ m_graphicsLayer->setContentsToMedia(pluginWidget->platformLayer());
+ }
+#if ENABLE(VIDEO)
+ else if (renderer()->isVideo()) {
+ HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(renderer()->node());
+ m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
}
+#endif
+#if ENABLE(3D_CANVAS)
+ else if (is3DCanvas(renderer())) {
+ HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
+ WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(canvas->renderingContext());
+ if (context->graphicsContext3D()->platformGraphicsContext3D())
+ m_graphicsLayer->setContentsToGraphicsContext3D(context->graphicsContext3D());
+ }
+#endif
return layerConfigChanged;
}
@@ -224,7 +250,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
updateLayerOpacity(renderer()->style());
RenderStyle* style = renderer()->style();
- m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D);
+ m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection());
m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
@@ -345,9 +371,19 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
}
+ if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) {
+ RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing();
+ reflectionBacking->updateGraphicsLayerGeometry();
+
+ // The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
+ // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
+ FloatRect layerBounds = compositedBounds();
+ FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
+ reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint() + (layerBounds.location() - reflectionLayerBounds.location()));
+ }
+
m_graphicsLayer->setContentsRect(contentsBox());
- if (!m_hasDirectlyCompositedContent)
- m_graphicsLayer->setDrawsContent(!isSimpleContainerCompositingLayer() && !paintingGoesToWindow() && !m_artificiallyInflatedBounds);
+ m_graphicsLayer->setDrawsContent(containsPaintedContent());
}
void RenderLayerBacking::updateInternalHierarchy()
@@ -388,7 +424,7 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs
if (needsDescendantClip) {
if (!m_clippingLayer) {
- m_clippingLayer = GraphicsLayer::create(0);
+ m_clippingLayer = GraphicsLayer::create(this);
#ifndef NDEBUG
m_clippingLayer->setName("Child clipping Layer");
#endif
@@ -493,12 +529,12 @@ static bool hasBorderOutlineOrShadow(const RenderStyle* style)
return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow();
}
-static bool hasBoxDecorations(const RenderStyle* style)
+static bool hasBoxDecorationsOrBackground(const RenderStyle* style)
{
return hasBorderOutlineOrShadow(style) || style->hasBackground();
}
-static bool hasBoxDecorationsWithBackgroundImage(const RenderStyle* style)
+static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
{
return hasBorderOutlineOrShadow(style) || style->hasBackgroundImage();
}
@@ -558,7 +594,7 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
// Reject anything that has a border, a border-radius or outline,
// or any background (color or image).
// FIXME: we could optimize layers for simple backgrounds.
- if (hasBoxDecorations(style))
+ if (hasBoxDecorationsOrBackground(style))
return false;
// If we have got this far and the renderer has no children, then we're ok.
@@ -575,7 +611,7 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
// Reject anything that has a border, a border-radius or outline,
// or is not a simple background (no background, or solid color).
- if (hasBoxDecorationsWithBackgroundImage(style))
+ if (hasBoxDecorationsOrBackgroundImage(style))
return false;
// Now look at the body's renderer.
@@ -586,7 +622,7 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
style = bodyObject->style();
- if (hasBoxDecorationsWithBackgroundImage(style))
+ if (hasBoxDecorationsOrBackgroundImage(style))
return false;
// Ceck to see if all the body's children are compositing layers.
@@ -603,9 +639,11 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
return true;
}
+// Conservative test for having no rendered children.
bool RenderLayerBacking::hasNonCompositingContent() const
{
- // Conservative test for having no rendered children.
+ if (m_owningLayer->hasOverflowControls())
+ return true;
// Some HTML can cause whitespace text nodes to have renderers, like:
// <div>
@@ -622,7 +660,6 @@ bool RenderLayerBacking::hasNonCompositingContent() const
}
}
- // FIXME: test for overflow controls.
if (m_owningLayer->isStackingContext()) {
// Use the m_hasCompositingDescendant bit to optimize?
if (Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList()) {
@@ -656,51 +693,43 @@ bool RenderLayerBacking::hasNonCompositingContent() const
return false;
}
-// A layer can use direct compositing if the render layer's object is a replaced object and has no children.
-// This allows the GraphicsLayer to display the RenderLayer contents directly; it's used for images.
-bool RenderLayerBacking::canUseDirectCompositing() const
+bool RenderLayerBacking::containsPaintedContent() const
{
- RenderObject* renderObject = renderer();
-
- // Canvas3D is always direct composited
-#if ENABLE(3D_CANVAS)
- if (renderer()->isCanvas()) {
- HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
- return canvas->is3D();
- }
-#endif
-
- // Reject anything that isn't an image
- if (!renderObject->isImage() && !renderObject->isVideo())
+ if (isSimpleContainerCompositingLayer() || paintingGoesToWindow() || m_artificiallyInflatedBounds || m_owningLayer->isReflection())
return false;
-
- if (renderObject->hasMask() || renderObject->hasReflection())
+
+ if (isDirectlyCompositedImage())
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.
- return !hasBoxDecorationsWithBackgroundImage(renderObject->style());
+ // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
+ // and set background color on the layer in that case, instead of allocating backing store and painting.
+ if (renderer()->isVideo() || is3DCanvas(renderer()))
+ return hasBoxDecorationsOrBackground(renderer()->style());
+
+ return true;
}
-
+
+// An image can be directly compositing if it's the sole content of the layer, and has no box decorations
+// that require painting. Direct compositing saves backing store.
+bool RenderLayerBacking::isDirectlyCompositedImage() const
+{
+ RenderObject* renderObject = renderer();
+ return renderObject->isImage() && !hasBoxDecorationsOrBackground(renderObject->style());
+}
+
void RenderLayerBacking::rendererContentChanged()
{
- if (canUseDirectCompositing()) {
- if (renderer()->isImage())
- updateImageContents();
- else {
+ if (isDirectlyCompositedImage()) {
+ updateImageContents();
+ return;
+ }
+
#if ENABLE(3D_CANVAS)
- if (renderer()->isCanvas()) {
- HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
- if (canvas->is3D())
- m_graphicsLayer->setGraphicsContext3DNeedsDisplay();
- }
-#endif
- }
+ if (is3DCanvas(renderer())) {
+ m_graphicsLayer->setGraphicsContext3DNeedsDisplay();
+ return;
}
+#endif
}
void RenderLayerBacking::updateImageContents()
@@ -849,7 +878,7 @@ static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const
// Share this with RenderLayer::paintLayer, which would have to be educated about GraphicsLayerPaintingPhase?
void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* context,
const IntRect& paintDirtyRect, // in the coords of rootLayer
- PaintRestriction paintRestriction, GraphicsLayerPaintingPhase paintingPhase,
+ PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase,
RenderObject* paintingRoot)
{
if (paintingGoesToWindow()) {
@@ -859,14 +888,6 @@ 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);
@@ -899,9 +920,9 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
int rw;
int rh;
- if (box->view()->frameView()) {
- rw = box->view()->frameView()->contentsWidth();
- rh = box->view()->frameView()->contentsHeight();
+ if (FrameView* frameView = box->view()->frameView()) {
+ rw = frameView->contentsWidth();
+ rh = frameView->contentsHeight();
} else {
rw = box->view()->width();
rh = box->view()->height();
@@ -930,8 +951,8 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
restoreClip(context, paintDirtyRect, damageRect);
}
- bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText;
- bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText;
+ bool forceBlackText = paintBehavior & PaintBehaviorForceBlackText;
+ bool selectionOnly = paintBehavior & PaintBehaviorSelectionOnly;
if (shouldPaint && (paintingPhase & GraphicsLayerPaintForeground)) {
// Now walk the sorted list of children with negative z-indices. Only RenderLayers without compositing layers will paint.
@@ -939,7 +960,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList();
if (negZOrderList) {
for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot);
+ it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot);
}
// Set up the clip used when painting our children.
@@ -975,14 +996,14 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList();
if (normalFlowList) {
for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it)
- it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot);
+ it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot);
}
// Now walk the sorted list of children with positive z-indices.
Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList();
if (posZOrderList) {
for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintRestriction, paintingRoot);
+ it[0]->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot);
}
}
@@ -1002,9 +1023,27 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
ASSERT(!m_owningLayer->m_usedTransparency);
}
+#if ENABLE(INSPECTOR)
+static InspectorTimelineAgent* inspectorTimelineAgent(RenderObject* renderer)
+{
+ Frame* frame = renderer->document()->frame();
+ if (!frame)
+ return 0;
+ Page* page = frame->page();
+ if (!page)
+ return 0;
+ return page->inspectorTimelineAgent();
+}
+#endif
+
// Up-call from compositing layer drawing callback.
void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
{
+#if ENABLE(INSPECTOR)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent(m_owningLayer->renderer()))
+ timelineAgent->willPaint(clip);
+#endif
+
// We have to use the same root as for hit testing, because both methods
// can compute and cache clipRects.
IntRect enclosingBBox = compositedBounds();
@@ -1021,10 +1060,25 @@ void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& co
IntRect dirtyRect = enclosingBBox;
dirtyRect.intersect(clipRect);
- paintIntoLayer(m_owningLayer, &context, dirtyRect, PaintRestrictionNone, paintingPhase, renderer());
+ paintIntoLayer(m_owningLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase, renderer());
+
+#if ENABLE(INSPECTOR)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent(m_owningLayer->renderer()))
+ timelineAgent->didPaint();
+#endif
+}
+
+bool RenderLayerBacking::showDebugBorders() const
+{
+ return compositor() ? compositor()->showDebugBorders() : false;
+}
+
+bool RenderLayerBacking::showRepaintCounter() const
+{
+ return compositor() ? compositor()->showRepaintCounter() : false;
}
-bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes)
+bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
{
bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
bool hasTransform = keyframes.containsProperty(CSSPropertyWebkitTransform);
@@ -1055,10 +1109,10 @@ bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim,
bool didAnimateTransform = !hasTransform;
bool didAnimateOpacity = !hasOpacity;
- if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), beginTime))
+ if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), timeOffset))
didAnimateTransform = true;
- if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), beginTime))
+ if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
didAnimateOpacity = true;
bool runningAcceleratedAnimation = didAnimateTransform && didAnimateOpacity;
@@ -1068,7 +1122,7 @@ bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim,
return runningAcceleratedAnimation;
}
-bool RenderLayerBacking::startTransition(double beginTime, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
+bool RenderLayerBacking::startTransition(double timeOffset, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
{
bool didAnimate = false;
ASSERT(property != cAnimateAll);
@@ -1080,7 +1134,7 @@ bool RenderLayerBacking::startTransition(double beginTime, int property, const R
opacityVector.insert(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity())));
opacityVector.insert(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity())));
// The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
- if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, String(), beginTime)) {
+ if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, String(), timeOffset)) {
// To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
updateLayerOpacity(toStyle);
didAnimate = true;
@@ -1094,7 +1148,7 @@ bool RenderLayerBacking::startTransition(double beginTime, int property, const R
KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
transformVector.insert(new TransformAnimationValue(0, &fromStyle->transform()));
transformVector.insert(new TransformAnimationValue(1, &toStyle->transform()));
- if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, String(), beginTime)) {
+ if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, String(), timeOffset)) {
// To ensure that the correct transform is visible when the animation ends, also set the final opacity.
updateLayerTransform(toStyle);
didAnimate = true;
@@ -1124,9 +1178,9 @@ void RenderLayerBacking::animationFinished(const String& animationName)
m_graphicsLayer->removeAnimationsForKeyframes(animationName);
}
-void RenderLayerBacking::animationPaused(const String& animationName)
+void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
{
- m_graphicsLayer->pauseAnimation(animationName);
+ m_graphicsLayer->pauseAnimation(animationName, timeOffset);
}
void RenderLayerBacking::transitionFinished(int property)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h
index 17bcaf707f..a6907e7f5e 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h
@@ -46,7 +46,7 @@ class RenderLayerCompositor;
//
// There is one RenderLayerBacking for each RenderLayer that is composited.
-class RenderLayerBacking : public GraphicsLayerClient {
+class RenderLayerBacking : public GraphicsLayerClient, public Noncopyable {
public:
RenderLayerBacking(RenderLayer*);
~RenderLayerBacking();
@@ -97,10 +97,10 @@ public:
void rendererContentChanged();
// Interface to start, finish, suspend and resume animations and transitions
- bool startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes);
- bool startTransition(double beginTime, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle);
+ bool startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes);
+ bool startTransition(double timeOffset, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle);
void animationFinished(const String& name);
- void animationPaused(const String& name);
+ void animationPaused(double timeOffset, const String& name);
void transitionFinished(int property);
void suspendAnimations(double time = 0);
@@ -119,6 +119,9 @@ public:
virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip);
+ virtual bool showDebugBorders() const;
+ virtual bool showRepaintCounter() const;
+
IntRect contentsBox() const;
private:
@@ -146,12 +149,12 @@ private:
// Return the opacity value that this layer should use for compositing.
float compositingOpacity(float rendererOpacity) const;
- // Returns true if this RenderLayer only has content that can be rendered directly
- // by the compositing layer, without drawing (e.g. solid background color).
+ // Returns true if this compositing layer has no visible content.
bool isSimpleContainerCompositingLayer() const;
- // Returns true if we can optimize the RenderLayer to draw the replaced content
- // directly into a compositing buffer
- bool canUseDirectCompositing() const;
+ // Returns true if this layer has content that needs to be rendered by painting into the backing store.
+ bool containsPaintedContent() const;
+ // Returns true if the RenderLayer just contains an image that we can composite directly.
+ bool isDirectlyCompositedImage() const;
void updateImageContents();
bool rendererHasBackground() const;
@@ -160,7 +163,7 @@ private:
bool hasNonCompositingContent() const;
void paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect,
- PaintRestriction paintRestriction, GraphicsLayerPaintingPhase, RenderObject* paintingRoot);
+ PaintBehavior paintBehavior, GraphicsLayerPaintingPhase, RenderObject* paintingRoot);
static int graphicsLayerToCSSProperty(AnimatedPropertyID);
static AnimatedPropertyID cssToGraphicsLayerProperty(int);
@@ -176,7 +179,6 @@ private:
IntRect m_compositedBounds;
- bool m_hasDirectlyCompositedContent;
bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work
};
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp
index 5201287eb9..93af664778 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp
@@ -29,6 +29,7 @@
#include "RenderLayerCompositor.h"
#include "AnimationController.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "CSSPropertyNames.h"
#include "Frame.h"
@@ -37,7 +38,9 @@
#include "HitTestResult.h"
#include "HTMLCanvasElement.h"
#include "Page.h"
+#include "RenderEmbeddedObject.h"
#include "RenderLayerBacking.h"
+#include "RenderReplica.h"
#include "RenderVideo.h"
#include "RenderView.h"
#include "Settings.h"
@@ -58,6 +61,8 @@ bool WebCoreHas3DRendering = true;
namespace WebCore {
+using namespace HTMLNames;
+
struct CompositingState {
CompositingState(RenderLayer* compAncestor)
: m_compositingAncestor(compAncestor)
@@ -79,6 +84,8 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
: m_renderView(renderView)
, m_rootPlatformLayer(0)
, m_hasAcceleratedCompositing(true)
+ , m_showDebugBorders(false)
+ , m_showRepaintCounter(false)
, m_compositingConsultsOverlap(true)
, m_compositing(false)
, m_rootLayerAttached(false)
@@ -109,16 +116,24 @@ void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
}
}
-void RenderLayerCompositor::cacheAcceleratedCompositingEnabledFlag()
+void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
{
bool hasAcceleratedCompositing = false;
- if (Settings* settings = m_renderView->document()->settings())
+ bool showDebugBorders = false;
+ bool showRepaintCounter = false;
+
+ if (Settings* settings = m_renderView->document()->settings()) {
hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
+ showDebugBorders = settings->showDebugBorders();
+ showRepaintCounter = settings->showRepaintCounter();
+ }
- if (hasAcceleratedCompositing != m_hasAcceleratedCompositing)
+ if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter)
setCompositingLayersNeedRebuild();
m_hasAcceleratedCompositing = hasAcceleratedCompositing;
+ m_showDebugBorders = showDebugBorders;
+ m_showRepaintCounter = showRepaintCounter;
}
void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
@@ -137,16 +152,30 @@ void RenderLayerCompositor::scheduleSync()
page->chrome()->client()->scheduleCompositingLayerSync();
}
-void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot)
+void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
{
- // When m_compositingConsultsOverlap is true, then layer positions affect compositing,
- // so we can only bail here when we're not looking at overlap.
- if (!m_compositingLayersNeedRebuild && !m_compositingConsultsOverlap)
+ bool checkForHierarchyUpdate = false;
+ bool needGeometryUpdate = false;
+
+ switch (updateType) {
+ case CompositingUpdateAfterLayoutOrStyleChange:
+ case CompositingUpdateOnPaitingOrHitTest:
+ checkForHierarchyUpdate = true;
+ break;
+ case CompositingUpdateOnScroll:
+ if (m_compositingConsultsOverlap)
+ checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
+
+ needGeometryUpdate = true;
+ break;
+ }
+
+ if (!checkForHierarchyUpdate && !needGeometryUpdate)
return;
ASSERT(inCompositingMode());
- bool needLayerRebuild = m_compositingLayersNeedRebuild;
+ bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
if (!updateRoot) {
// Only clear the flag if we're updating the entire hierarchy.
m_compositingLayersNeedRebuild = false;
@@ -159,26 +188,38 @@ void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot)
double startTime = WTF::currentTime();
#endif
- // Go through the layers in presentation order, so that we can compute which
- // RLs need compositing layers.
- // FIXME: we could maybe do this in one pass, but the parenting logic would be more
- // complex.
- {
+ if (checkForHierarchyUpdate) {
+ // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
+ // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
CompositingState compState(updateRoot);
- bool layersChanged;
+ bool layersChanged = false;
if (m_compositingConsultsOverlap) {
OverlapMap overlapTestRequestMap;
computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged);
} else
computeCompositingRequirements(updateRoot, 0, compState, layersChanged);
- needLayerRebuild |= layersChanged;
+ needHierarchyUpdate |= layersChanged;
}
- // Now create and parent the compositing layers.
- {
+ if (needHierarchyUpdate) {
+ // Update the hierarchy of the compositing layers.
CompositingState compState(updateRoot);
- rebuildCompositingLayerTree(updateRoot, compState, needLayerRebuild);
+ Vector<GraphicsLayer*> childList;
+ rebuildCompositingLayerTree(updateRoot, compState, childList);
+
+ // Host the document layer in the RenderView's root layer.
+ if (updateRoot == rootRenderLayer()) {
+ if (childList.isEmpty()) {
+ willMoveOffscreen();
+ m_rootPlatformLayer = 0;
+ } else
+ m_rootPlatformLayer->setChildren(childList);
+ }
+ } else if (needGeometryUpdate) {
+ // We just need to do a geometry update. This is only used for position:fixed scrolling;
+ // most of the time, geometry is updated via RenderLayer::styleChanged().
+ updateLayerTreeGeometry(updateRoot);
}
#if PROFILE_LAYER_REBUILD
@@ -215,6 +256,17 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR
}
} else {
if (layer->backing()) {
+ // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
+ // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
+ // are both either composited, or not composited.
+ if (layer->isReflection()) {
+ RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer();
+ if (RenderLayerBacking* backing = sourceLayer->backing()) {
+ ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer());
+ backing->graphicsLayer()->setReplicatedByLayer(0);
+ }
+ }
+
layer->clearBacking();
layerChanged = true;
@@ -328,7 +380,7 @@ IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* laye
}
}
- if (layer->paintsWithTransform()) {
+ if (layer->paintsWithTransform(PaintBehaviorNormal)) {
TransformationMatrix* affineTrans = layer->transform();
boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
unionBounds = affineTrans->mapRect(unionBounds);
@@ -391,6 +443,9 @@ void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer*
if (!boundsComputed) {
layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
+ // Empty rects never intersect, but we need them to for the purposes of overlap testing.
+ if (layerBounds.isEmpty())
+ layerBounds.setSize(IntSize(1, 1));
boundsComputed = true;
}
@@ -434,6 +489,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (overlapMap && !overlapMap->isEmpty()) {
// If we're testing for overlap, we only need to composite if we overlap something that is already composited.
absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
+ // Empty rects never intersect, but we need them to for the purposes of overlap testing.
+ if (absBounds.isEmpty())
+ absBounds.setSize(IntSize(1, 1));
haveComputedBounds = true;
mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
}
@@ -448,7 +506,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
++childState.m_depth;
#endif
- const bool willBeComposited = needsToBeComposited(layer);
+ bool willBeComposited = needsToBeComposited(layer);
if (willBeComposited) {
// Tell the parent it has compositing descendants.
compositingState.m_subtreeIsCompositing = true;
@@ -476,7 +534,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
// If we have to make a layer for this child, make one now so we can have a contents layer
// (since we need to ensure that the -ve z-order child renders underneath our contents).
- if (childState.m_subtreeIsCompositing) {
+ if (!willBeComposited && childState.m_subtreeIsCompositing) {
// make layer compositing
layer->setMustOverlapCompositedLayers(true);
childState.m_compositingAncestor = layer;
@@ -509,28 +567,50 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
// If we have a software transform, and we have layers under us, we need to also
// be composited. Also, if we have opacity < 1, then we need to be a layer so that
// the child layers are opaque, then rendered with opacity on this layer.
- if (childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
+ if (!willBeComposited && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
layer->setMustOverlapCompositedLayers(true);
if (overlapMap)
addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
+ willBeComposited = true;
}
+ ASSERT(willBeComposited == needsToBeComposited(layer));
+ if (layer->reflectionLayer())
+ layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
+
// Subsequent layers in the parent stacking context also need to composite.
if (childState.m_subtreeIsCompositing)
compositingState.m_subtreeIsCompositing = true;
- // If the layer is going into compositing mode, repaint its old location.
- if (!layer->isComposited() && needsToBeComposited(layer))
- repaintOnCompositingChange(layer);
-
// Set the flag to say that this SC has compositing children.
- // this can affect the answer to needsToBeComposited() when clipping,
- // but that's ok here.
layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
+ // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
+ // so test that again.
+ if (!willBeComposited && clipsCompositingDescendants(layer)) {
+ if (overlapMap)
+ addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
+ willBeComposited = true;
+ }
+
+ // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
+ // to be composited, then we can drop out of compositing mode altogether.
+ if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer)) {
+ m_compositing = false;
+ willBeComposited = false;
+ }
+
+ // If the layer is going into compositing mode, repaint its old location.
+ ASSERT(willBeComposited == needsToBeComposited(layer));
+ if (!layer->isComposited() && willBeComposited)
+ repaintOnCompositingChange(layer);
+
// Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
if (updateBacking(layer, CompositingChangeRepaintNow))
layersChanged = true;
+
+ if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
+ layersChanged = true;
}
void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
@@ -577,39 +657,41 @@ void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer)
#if ENABLE(VIDEO)
bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
{
- // FIXME: ideally we need to look at all ancestors for mask or video. But for now,
- // just bail on the obvious cases.
- if (o->hasReflection() || !m_hasAcceleratedCompositing)
+ if (!m_hasAcceleratedCompositing)
return false;
return o->supportsAcceleratedRendering();
}
#endif
-void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, struct CompositingState& compositingState, bool updateHierarchy)
+void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer)
{
// Make the layer compositing if necessary, and set up clipping and content layers.
// Note that we can only do work here that is independent of whether the descendant layers
// have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
+
RenderLayerBacking* layerBacking = layer->backing();
if (layerBacking) {
// The compositing state of all our children has been updated already, so now
// we can compute and cache the composited bounds for this layer.
layerBacking->updateCompositedBounds();
+
+ if (RenderLayer* reflection = layer->reflectionLayer()) {
+ if (reflection->backing())
+ reflection->backing()->updateCompositedBounds();
+ }
+
layerBacking->updateGraphicsLayerConfiguration();
layerBacking->updateGraphicsLayerGeometry();
if (!layer->parent())
updateRootLayerPosition();
-
- // FIXME: make this more incremental
- if (updateHierarchy)
- layerBacking->parentForSublayers()->removeAllChildren();
}
- // host the document layer in the RenderView's root layer
- if (updateHierarchy && layer->isRootLayer() && layer->isComposited())
- parentInRootLayer(layer);
+ // If this layer has backing, then we are collecting its children, otherwise appending
+ // to the compositing child list of an enclosing layer.
+ Vector<GraphicsLayer*> layerChildren;
+ Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
CompositingState childState = compositingState;
if (layer->isComposited())
@@ -630,19 +712,13 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru
size_t listSize = negZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
- rebuildCompositingLayerTree(curLayer, childState, updateHierarchy);
- if (updateHierarchy && curLayer->isComposited())
- setCompositingParent(curLayer, childState.m_compositingAncestor);
+ rebuildCompositingLayerTree(curLayer, childState, childList);
}
}
- if (updateHierarchy && layerBacking && layerBacking->foregroundLayer()) {
- layerBacking->foregroundLayer()->removeFromParent();
-
- // The foreground layer has to be correctly sorted with child layers, so needs to become a child of the clipping layer.
- GraphicsLayer* hostingLayer = layerBacking->parentForSublayers();
- hostingLayer->addChild(layerBacking->foregroundLayer());
- }
+ // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
+ if (layerBacking && layerBacking->foregroundLayer())
+ childList.append(layerBacking->foregroundLayer());
}
ASSERT(!layer->m_normalFlowListDirty);
@@ -650,9 +726,7 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru
size_t listSize = normalFlowList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
- rebuildCompositingLayerTree(curLayer, childState, updateHierarchy);
- if (updateHierarchy && curLayer->isComposited())
- setCompositingParent(curLayer, childState.m_compositingAncestor);
+ rebuildCompositingLayerTree(curLayer, childState, childList);
}
}
@@ -661,14 +735,62 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru
size_t listSize = posZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
- rebuildCompositingLayerTree(curLayer, childState, updateHierarchy);
- if (updateHierarchy && curLayer->isComposited())
- setCompositingParent(curLayer, childState.m_compositingAncestor);
+ rebuildCompositingLayerTree(curLayer, childState, childList);
}
}
}
+
+ if (layerBacking) {
+ layerBacking->parentForSublayers()->setChildren(layerChildren);
+ childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
+ }
}
+// This just updates layer geometry without changing the hierarchy.
+void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
+{
+ if (RenderLayerBacking* layerBacking = layer->backing()) {
+ // The compositing state of all our children has been updated already, so now
+ // we can compute and cache the composited bounds for this layer.
+ layerBacking->updateCompositedBounds();
+
+ if (RenderLayer* reflection = layer->reflectionLayer()) {
+ if (reflection->backing())
+ reflection->backing()->updateCompositedBounds();
+ }
+
+ layerBacking->updateGraphicsLayerConfiguration();
+ layerBacking->updateGraphicsLayerGeometry();
+
+ if (!layer->parent())
+ updateRootLayerPosition();
+ }
+
+ if (layer->isStackingContext()) {
+ ASSERT(!layer->m_zOrderListsDirty);
+
+ if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
+ size_t listSize = negZOrderList->size();
+ for (size_t i = 0; i < listSize; ++i)
+ updateLayerTreeGeometry(negZOrderList->at(i));
+ }
+ }
+
+ ASSERT(!layer->m_normalFlowListDirty);
+ if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
+ size_t listSize = normalFlowList->size();
+ for (size_t i = 0; i < listSize; ++i)
+ updateLayerTreeGeometry(normalFlowList->at(i));
+ }
+
+ if (layer->isStackingContext()) {
+ if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
+ size_t listSize = posZOrderList->size();
+ for (size_t i = 0; i < listSize; ++i)
+ updateLayerTreeGeometry(posZOrderList->at(i));
+ }
+ }
+}
// Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth)
@@ -676,12 +798,21 @@ void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* com
if (layer != compositingAncestor) {
if (RenderLayerBacking* layerBacking = layer->backing()) {
layerBacking->updateCompositedBounds();
+
+ if (RenderLayer* reflection = layer->reflectionLayer()) {
+ if (reflection->backing())
+ reflection->backing()->updateCompositedBounds();
+ }
+
layerBacking->updateGraphicsLayerGeometry();
if (updateDepth == RenderLayerBacking::CompositingChildren)
return;
}
}
+ if (layer->reflectionLayer())
+ updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth);
+
if (!layer->hasCompositingDescendant())
return;
@@ -716,6 +847,7 @@ void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& a
void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
{
+ // FIXME: This method does not work correctly with transforms.
if (layer->isComposited())
layer->setBackingNeedsRepaintInRect(rect);
@@ -724,7 +856,8 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const
size_t listSize = negZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
- int x = 0, y = 0;
+ int x = 0;
+ int y = 0;
curLayer->convertToLayerCoords(layer, x, y);
IntRect childRect(rect);
childRect.move(-x, -y);
@@ -736,7 +869,8 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const
size_t listSize = posZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
- int x = 0, y = 0;
+ int x = 0;
+ int y = 0;
curLayer->convertToLayerCoords(layer, x, y);
IntRect childRect(rect);
childRect.move(-x, -y);
@@ -748,7 +882,8 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const
size_t listSize = normalFlowList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
- int x = 0, y = 0;
+ int x = 0;
+ int y = 0;
curLayer->convertToLayerCoords(layer, x, y);
IntRect childRect(rect);
childRect.move(-x, -y);
@@ -819,22 +954,28 @@ bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
if (!m_hasAcceleratedCompositing || !layer->isSelfPaintingLayer())
return false;
- return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers();
+ return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
}
// 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
-{
+{
+ RenderObject* renderer = layer->renderer();
+ // The compositing state of a reflection should match that of its reflected layer.
+ if (layer->isReflection()) {
+ renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
+ layer = toRenderBoxModelObject(renderer)->layer();
+ }
// The root layer always has a compositing layer, but it may not have backing.
- return (inCompositingMode() && layer->isRootLayer()) ||
- requiresCompositingForTransform(layer->renderer()) ||
- requiresCompositingForVideo(layer->renderer()) ||
- requiresCompositingForCanvas(layer->renderer()) ||
- layer->renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden ||
- clipsCompositingDescendants(layer) ||
- requiresCompositingForAnimation(layer->renderer());
+ return requiresCompositingForTransform(renderer)
+ || requiresCompositingForVideo(renderer)
+ || requiresCompositingForCanvas(renderer)
+ || requiresCompositingForPlugin(renderer)
+ || renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden
+ || clipsCompositingDescendants(layer)
+ || requiresCompositingForAnimation(renderer);
}
// Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
@@ -897,6 +1038,8 @@ bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer)
RenderVideo* video = toRenderVideo(renderer);
return canAccelerateVideoRendering(video);
}
+#else
+ UNUSED_PARAM(renderer);
#endif
return false;
}
@@ -914,6 +1057,11 @@ bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer)
return false;
}
+bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
+{
+ return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
+}
+
bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
{
if (AnimationController* animController = renderer->animation()) {
@@ -925,7 +1073,7 @@ bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* render
bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
{
- return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask();
+ return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection();
}
// If an element has negative z-index children, those children render in front of the
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h
index a809a7077a..5f1a178e21 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.h
@@ -38,6 +38,12 @@ class GraphicsLayer;
class RenderVideo;
#endif
+enum CompositingUpdateType {
+ CompositingUpdateAfterLayoutOrStyleChange,
+ CompositingUpdateOnPaitingOrHitTest,
+ CompositingUpdateOnScroll
+};
+
// RenderLayerCompositor manages the hierarchy of
// composited RenderLayers. It determines which RenderLayers
// become compositing, and creates and maintains a hierarchy of
@@ -47,7 +53,6 @@ class RenderVideo;
class RenderLayerCompositor {
public:
-
RenderLayerCompositor(RenderView*);
~RenderLayerCompositor();
@@ -61,8 +66,11 @@ public:
// Returns true if the accelerated compositing is enabled
bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; }
- // Copy the acceleratedCompositingEnabledFlag from Settings
- void cacheAcceleratedCompositingEnabledFlag();
+ bool showDebugBorders() const { return m_showDebugBorders; }
+ bool showRepaintCounter() const { return m_showRepaintCounter; }
+
+ // Copy the accelerated compositing related flags from Settings
+ void cacheAcceleratedCompositingFlags();
// Called when the layer hierarchy needs to be updated (compositing layers have been
// created, destroyed or re-parented).
@@ -77,7 +85,7 @@ public:
void scheduleSync();
// Rebuild the tree of compositing layers
- void updateCompositingLayers(RenderLayer* updateRoot = 0);
+ void updateCompositingLayers(CompositingUpdateType = CompositingUpdateAfterLayoutOrStyleChange, RenderLayer* updateRoot = 0);
// Update the compositing state of the given layer. Returns true if that state changed.
enum CompositingChangeRepaint { CompositingChangeRepaintNow, CompositingChangeWillRepaintLater };
@@ -147,8 +155,13 @@ private:
// Returns true if any layer's compositing changed
void computeCompositingRequirements(RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged);
- void rebuildCompositingLayerTree(RenderLayer* layer, struct CompositingState&, bool updateHierarchy);
+
+ // Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer.
+ void rebuildCompositingLayerTree(RenderLayer* layer, const struct CompositingState&, Vector<GraphicsLayer*>& childGraphicsLayersOfEnclosingLayer);
+ // Recurses down the tree, updating layer geometry only.
+ void updateLayerTreeGeometry(RenderLayer*);
+
// Hook compositing layers together
void setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer);
void removeCompositedChildren(RenderLayer*);
@@ -165,12 +178,15 @@ private:
bool requiresCompositingForTransform(RenderObject*) const;
bool requiresCompositingForVideo(RenderObject*) const;
bool requiresCompositingForCanvas(RenderObject*) const;
+ bool requiresCompositingForPlugin(RenderObject*) const;
bool requiresCompositingWhenDescendantsAreCompositing(RenderObject*) const;
private:
RenderView* m_renderView;
OwnPtr<GraphicsLayer> m_rootPlatformLayer;
bool m_hasAcceleratedCompositing;
+ bool m_showDebugBorders;
+ bool m_showRepaintCounter;
bool m_compositingConsultsOverlap;
bool m_compositing;
bool m_rootLayerAttached;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLineBoxList.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLineBoxList.cpp
index 76a2e2f4ed..9736874983 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderLineBoxList.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderLineBoxList.cpp
@@ -67,7 +67,7 @@ void RenderLineBoxList::deleteLineBoxTree(RenderArena* arena)
InlineFlowBox* line = m_firstLineBox;
InlineFlowBox* nextLine;
while (line) {
- nextLine = line->nextFlowBox();
+ nextLine = line->nextLineBox();
line->deleteLine(arena);
line = nextLine;
}
@@ -78,13 +78,13 @@ void RenderLineBoxList::extractLineBox(InlineFlowBox* box)
{
checkConsistency();
- m_lastLineBox = box->prevFlowBox();
+ m_lastLineBox = box->prevLineBox();
if (box == m_firstLineBox)
m_firstLineBox = 0;
if (box->prevLineBox())
box->prevLineBox()->setNextLineBox(0);
box->setPreviousLineBox(0);
- for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = box; curr; curr = curr->nextLineBox())
curr->setExtracted();
checkConsistency();
@@ -100,7 +100,7 @@ void RenderLineBoxList::attachLineBox(InlineFlowBox* box)
} else
m_firstLineBox = box;
InlineFlowBox* last = box;
- for (InlineFlowBox* curr = box; curr; curr = curr->nextFlowBox()) {
+ for (InlineFlowBox* curr = box; curr; curr = curr->nextLineBox()) {
curr->setExtracted(false);
last = curr;
}
@@ -114,9 +114,9 @@ void RenderLineBoxList::removeLineBox(InlineFlowBox* box)
checkConsistency();
if (box == m_firstLineBox)
- m_firstLineBox = box->nextFlowBox();
+ m_firstLineBox = box->nextLineBox();
if (box == m_lastLineBox)
- m_lastLineBox = box->prevFlowBox();
+ m_lastLineBox = box->prevLineBox();
if (box->nextLineBox())
box->nextLineBox()->setPreviousLineBox(box->prevLineBox());
if (box->prevLineBox())
@@ -128,8 +128,8 @@ void RenderLineBoxList::removeLineBox(InlineFlowBox* box)
void RenderLineBoxList::deleteLineBoxes(RenderArena* arena)
{
if (m_firstLineBox) {
- InlineRunBox* next;
- for (InlineRunBox* curr = m_firstLineBox; curr; curr = next) {
+ InlineFlowBox* next;
+ for (InlineFlowBox* curr = m_firstLineBox; curr; curr = next) {
next = curr->nextLineBox();
curr->destroy(arena);
}
@@ -140,7 +140,7 @@ void RenderLineBoxList::deleteLineBoxes(RenderArena* arena)
void RenderLineBoxList::dirtyLineBoxes()
{
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
curr->dirtyLineBoxes();
}
@@ -177,7 +177,7 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::Pain
// based off positions of our first line box or our last line box.
RenderView* v = renderer->view();
bool usePrintRect = !v->printRect().isEmpty();
- for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextFlowBox()) {
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
if (usePrintRect) {
// FIXME: This is a feeble effort to avoid splitting a line across two pages.
// It is utterly inadequate, and this should not be done at paint time at all.
@@ -199,6 +199,7 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::Pain
int bottom = curr->bottomVisibleOverflow() + renderer->maximalOutlineSize(info.phase);
h = bottom - top;
yPos = ty + top;
+ v->setMinimumColumnHeight(h);
if (yPos < info.rect.bottom() && yPos + h > info.rect.y())
curr->paint(info, tx, ty);
}
@@ -235,7 +236,7 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq
// See if our root lines contain the point. If so, then we hit test
// them further. Note that boxes can easily overlap, so we can't make any assumptions
// based off positions of our first line box or our last line box.
- for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevFlowBox()) {
+ for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) {
if (y >= ty + curr->root()->topVisibleOverflow() && y < ty + curr->root()->bottomVisibleOverflow()) {
bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty);
if (inside) {
@@ -280,9 +281,9 @@ void RenderLineBoxList::dirtyLinesFromChangedChild(RenderObject* container, Rend
if (textBox)
box = textBox->root();
} else if (curr->isRenderInline()) {
- InlineRunBox* runBox = toRenderInline(curr)->lastLineBox();
- if (runBox)
- box = runBox->root();
+ InlineFlowBox* flowBox = toRenderInline(curr)->lastLineBox();
+ if (flowBox)
+ box = flowBox->root();
}
if (box)
@@ -320,8 +321,8 @@ void RenderLineBoxList::checkConsistency() const
{
#ifdef CHECK_CONSISTENCY
const InlineFlowBox* prev = 0;
- for (const InlineFlowBox* child = m_firstLineBox; child != 0; child = child->nextFlowBox()) {
- ASSERT(child->prevFlowBox() == prev);
+ for (const InlineFlowBox* child = m_firstLineBox; child != 0; child = child->nextLineBox()) {
+ ASSERT(child->prevLineBox() == prev);
prev = child;
}
ASSERT(prev == m_lastLineBox);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp
index 0edfdef31b..15c652ca32 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp
@@ -321,7 +321,8 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, in
textColor = theme()->inactiveListBoxSelectionForegroundColor();
}
- paintInfo.context->setFillColor(textColor);
+ ColorSpace colorSpace = itemStyle->colorSpace();
+ paintInfo.context->setFillColor(textColor, colorSpace);
Font itemFont = style()->font();
if (isOptionGroupElement(element)) {
@@ -358,9 +359,10 @@ void RenderListBox::paintItemBackground(PaintInfo& paintInfo, int tx, int ty, in
// Draw the background for this list box item
if (!element->renderStyle() || element->renderStyle()->visibility() != HIDDEN) {
+ ColorSpace colorSpace = element->renderStyle() ? element->renderStyle()->colorSpace() : style()->colorSpace();
IntRect itemRect = itemBoundingBoxRect(tx, ty, listIndex);
itemRect.intersect(controlClipRect(tx, ty));
- paintInfo.context->fillRect(itemRect, backColor);
+ paintInfo.context->fillRect(itemRect, backColor, colorSpace);
}
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListItem.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderListItem.cpp
index e487c603e5..54a7dd2908 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderListItem.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderListItem.cpp
@@ -1,9 +1,7 @@
/**
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
*
* This library is free software; you can redistribute it and/or
@@ -53,8 +51,8 @@ void RenderListItem::styleDidChange(StyleDifference diff, const RenderStyle* old
{
RenderBlock::styleDidChange(diff, oldStyle);
- if (style()->listStyleType() != LNONE ||
- (style()->listStyleImage() && !style()->listStyleImage()->errorOccurred())) {
+ if (style()->listStyleType() != NoneListStyle
+ || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurred())) {
RefPtr<RenderStyle> newStyle = RenderStyle::create();
// The marker always inherits from the list item, regardless of where it might end
// up (e.g., in some deeply nested line box). See CSS3 spec.
@@ -77,11 +75,16 @@ void RenderListItem::destroy()
RenderBlock::destroy();
}
+static bool isList(Node* node)
+{
+ return (node->hasTagName(ulTag) || node->hasTagName(olTag));
+}
+
static Node* enclosingList(Node* node)
{
Node* parent = node->parentNode();
for (Node* n = parent; n; n = n->parentNode())
- if (n->hasTagName(ulTag) || n->hasTagName(olTag))
+ if (isList(n))
return n;
// If there's no actual <ul> or <ol> list element, then our parent acts as
// our list for purposes of determining what other list items should be
@@ -89,22 +92,38 @@ static Node* enclosingList(Node* node)
return parent;
}
+static Node* enclosingList(const RenderObject* renderer)
+{
+ Node* node = renderer->node();
+ if (node)
+ return enclosingList(node);
+
+ renderer = renderer->parent();
+ while (renderer && !renderer->node())
+ renderer = renderer->parent();
+
+ node = renderer->node();
+ if (isList(node))
+ return node;
+
+ return enclosingList(node);
+}
+
static RenderListItem* previousListItem(Node* list, const RenderListItem* item)
{
- for (Node* node = item->node()->traversePreviousNode(); node != list; node = node->traversePreviousNode()) {
- RenderObject* renderer = node->renderer();
- if (!renderer || !renderer->isListItem())
+ for (RenderObject* renderer = item->previousInPreOrder(); renderer != list->renderer(); renderer = renderer->previousInPreOrder()) {
+ if (!renderer->isListItem())
continue;
- Node* otherList = enclosingList(node);
+ Node* otherList = enclosingList(renderer);
// This item is part of our current list, so it's what we're looking for.
if (list == otherList)
return toRenderListItem(renderer);
// We found ourself inside another list; lets skip the rest of it.
- // Use traverseNextNode() here because the other list itself may actually
+ // Use nextInPreOrder() here because the other list itself may actually
// be a list item itself. We need to examine it, so we do this to counteract
- // the traversePreviousNode() that will be done by the loop.
+ // the previousInPreOrder() that will be done by the loop.
if (otherList)
- node = otherList->traverseNextNode();
+ renderer = otherList->renderer()->nextInPreOrder();
}
return 0;
}
@@ -113,7 +132,7 @@ inline int RenderListItem::calcValue() const
{
if (m_hasExplicitValue)
return m_explicitValue;
- Node* list = enclosingList(node());
+ Node* list = enclosingList(this);
// FIXME: This recurses to a possible depth of the length of the list.
// That's not good -- we need to change this to an iterative algorithm.
if (RenderListItem* previousItem = previousListItem(list, this))
@@ -324,6 +343,8 @@ void RenderListItem::explicitValueChanged()
void RenderListItem::setExplicitValue(int value)
{
+ ASSERT(node());
+
if (m_hasExplicitValue && m_explicitValue == value)
return;
m_explicitValue = value;
@@ -334,6 +355,8 @@ void RenderListItem::setExplicitValue(int value)
void RenderListItem::clearExplicitValue()
{
+ ASSERT(node());
+
if (!m_hasExplicitValue)
return;
m_hasExplicitValue = false;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.cpp
index 9627711780..d0353ee091 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.cpp
@@ -3,6 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
+ * Copyright (C) 2010 Daniel Bates (dbates@intudata.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -40,6 +41,8 @@ namespace WebCore {
const int cMarkerPadding = 7;
+enum SequenceType { NumericSequence, AlphabeticSequence };
+
static String toRoman(int number, bool upper)
{
// FIXME: CSS3 describes how to make this work for much larger numbers,
@@ -48,7 +51,9 @@ static String toRoman(int number, bool upper)
if (number < 1 || number > 3999)
return String::number(number);
- const int lettersSize = 12; // big enough for three each of I, X, C, and M
+ // Big enough to store largest roman number less than 3999 which
+ // is 3888 (MMMDCCCLXXXVIII)
+ const int lettersSize = 15;
UChar letters[lettersSize];
int length = 0;
@@ -75,26 +80,63 @@ static String toRoman(int number, bool upper)
return String(&letters[lettersSize - length], length);
}
-static String toAlphabetic(int number, const UChar* alphabet, int alphabetSize)
+static inline String toAlphabeticOrNumeric(int number, const UChar* sequence, int sequenceSize, SequenceType type)
{
- ASSERT(alphabetSize >= 10);
+ ASSERT(sequenceSize >= 2);
- if (number < 1)
- return String::number(number);
+ const int lettersSize = sizeof(number) * 8 + 1; // Binary is the worst case; requires one character per bit plus a minus sign.
- const int lettersSize = 10; // big enough for a 32-bit int, with a 10-letter alphabet
UChar letters[lettersSize];
- --number;
- letters[lettersSize - 1] = alphabet[number % alphabetSize];
+ bool isNegativeNumber = false;
+ unsigned numberShadow = number;
+ if (type == AlphabeticSequence) {
+ ASSERT(number > 0);
+ --numberShadow;
+ } else if (number < 0) {
+ numberShadow = -number;
+ isNegativeNumber = true;
+ }
+ letters[lettersSize - 1] = sequence[numberShadow % sequenceSize];
int length = 1;
- while ((number /= alphabetSize) > 0)
- letters[lettersSize - ++length] = alphabet[number % alphabetSize - 1];
+
+ if (type == AlphabeticSequence) {
+ while ((numberShadow /= sequenceSize) > 0)
+ letters[lettersSize - ++length] = sequence[numberShadow % sequenceSize - 1];
+ } else {
+ while ((numberShadow /= sequenceSize) > 0)
+ letters[lettersSize - ++length] = sequence[numberShadow % sequenceSize];
+ }
+ if (isNegativeNumber)
+ letters[lettersSize - ++length] = hyphenMinus;
ASSERT(length <= lettersSize);
return String(&letters[lettersSize - length], length);
}
+static String toAlphabetic(int number, const UChar* alphabet, int alphabetSize)
+{
+ if (number < 1)
+ return String::number(number);
+
+ return toAlphabeticOrNumeric(number, alphabet, alphabetSize, AlphabeticSequence);
+}
+
+static String toNumeric(int number, const UChar* numerals, int numeralsSize)
+{
+ return toAlphabeticOrNumeric(number, numerals, numeralsSize, NumericSequence);
+}
+
+template <size_t size> static inline String toAlphabetic(int number, const UChar(&alphabet)[size])
+{
+ return toAlphabetic(number, alphabet, size);
+}
+
+template <size_t size> static inline String toNumeric(int number, const UChar(&alphabet)[size])
+{
+ return toNumeric(number, alphabet, size);
+}
+
static int toHebrewUnder1000(int number, UChar letters[5])
{
// FIXME: CSS3 mentions various refinements not implemented here.
@@ -335,58 +377,273 @@ static String toCJKIdeographic(int number, const UChar table[16])
return String(characters, length);
}
+static UChar listMarkerSuffix(EListStyleType type)
+{
+ // Note, the following switch statement has been explicitly
+ // grouped by list-style-type suffix.
+ switch (type) {
+ case NoneListStyle:
+ case Disc:
+ case Circle:
+ case Square:
+ ASSERT_NOT_REACHED();
+ return ' ';
+ case Afar:
+ case Amharic:
+ case AmharicAbegede:
+ case Ethiopic:
+ case EthiopicAbegede:
+ case EthiopicAbegedeAmEt:
+ case EthiopicAbegedeGez:
+ case EthiopicAbegedeTiEr:
+ case EthiopicAbegedeTiEt:
+ case EthiopicHalehameAaEr:
+ case EthiopicHalehameAaEt:
+ case EthiopicHalehameAmEt:
+ case EthiopicHalehameGez:
+ case EthiopicHalehameOmEt:
+ case EthiopicHalehameSidEt:
+ case EthiopicHalehameSoEt:
+ case EthiopicHalehameTiEr:
+ case EthiopicHalehameTiEt:
+ case EthiopicHalehameTig:
+ case Oromo:
+ case Sidama:
+ case Somali:
+ case Tigre:
+ case TigrinyaEr:
+ case TigrinyaErAbegede:
+ case TigrinyaEt:
+ case TigrinyaEtAbegede:
+ return ethiopicPrefaceColon;
+ case Armenian:
+ case ArabicIndic:
+ case Bengali:
+ case BinaryListStyle:
+ case Cambodian:
+ case CJKIdeographic:
+ case CjkEarthlyBranch:
+ case CjkHeavenlyStem:
+ case DecimalLeadingZero:
+ case DecimalListStyle:
+ case Devanagari:
+ case Georgian:
+ case Gujarati:
+ case Gurmukhi:
+ case Hangul:
+ case HangulConsonant:
+ case Hebrew:
+ case Hiragana:
+ case HiraganaIroha:
+ case Kannada:
+ case Katakana:
+ case KatakanaIroha:
+ case Khmer:
+ case Lao:
+ case LowerAlpha:
+ case LowerGreek:
+ case LowerHexadecimal:
+ case LowerLatin:
+ case LowerNorwegian:
+ case LowerRoman:
+ case Malayalam:
+ case Mongolian:
+ case Myanmar:
+ case Octal:
+ case Oriya:
+ case Persian:
+ case Telugu:
+ case Thai:
+ case Tibetan:
+ case UpperAlpha:
+ case UpperGreek:
+ case UpperHexadecimal:
+ case UpperLatin:
+ case UpperNorwegian:
+ case UpperRoman:
+ case Urdu:
+ return '.';
+ }
+
+ ASSERT_NOT_REACHED();
+ return '.';
+}
+
String listMarkerText(EListStyleType type, int value)
{
switch (type) {
- case LNONE:
+ case NoneListStyle:
return "";
// We use the same characters for text security.
// See RenderText::setInternalString.
- case CIRCLE:
+ case Circle:
return String(&whiteBullet, 1);
- case DISC:
+ case Disc:
return String(&bullet, 1);
- case SQUARE:
+ case Square:
// The CSS 2.1 test suite uses U+25EE BLACK MEDIUM SMALL SQUARE
// instead, but I think this looks better.
return String(&blackSquare, 1);
- case LDECIMAL:
+ case DecimalListStyle:
return String::number(value);
- case DECIMAL_LEADING_ZERO:
+ case DecimalLeadingZero:
if (value < -9 || value > 9)
return String::number(value);
if (value < 0)
return "-0" + String::number(-value); // -01 to -09
return "0" + String::number(value); // 00 to 09
- case LOWER_ALPHA:
- case LOWER_LATIN: {
+ case ArabicIndic: {
+ static const UChar arabicIndicNumerals[10] = {
+ 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669
+ };
+ return toNumeric(value, arabicIndicNumerals);
+ }
+ case BinaryListStyle: {
+ static const UChar binaryNumerals[2] = {
+ '0', '1'
+ };
+ return toNumeric(value, binaryNumerals);
+ }
+ case Bengali: {
+ static const UChar bengaliNumerals[10] = {
+ 0x09E6, 0x09E7, 0x09E8, 0x09E9, 0x09EA, 0x09EB, 0x09EC, 0x09ED, 0x09EE, 0x09EF
+ };
+ return toNumeric(value, bengaliNumerals);
+ }
+ case Cambodian:
+ case Khmer: {
+ static const UChar khmerNumerals[10] = {
+ 0x17E0, 0x17E1, 0x17E2, 0x17E3, 0x17E4, 0x17E5, 0x17E6, 0x17E7, 0x17E8, 0x17E9
+ };
+ return toNumeric(value, khmerNumerals);
+ }
+ case Devanagari: {
+ static const UChar devanagariNumerals[10] = {
+ 0x0966, 0x0967, 0x0968, 0x0969, 0x096A, 0x096B, 0x096C, 0x096D, 0x096E, 0x096F
+ };
+ return toNumeric(value, devanagariNumerals);
+ }
+ case Gujarati: {
+ static const UChar gujaratiNumerals[10] = {
+ 0x0AE6, 0x0AE7, 0x0AE8, 0x0AE9, 0x0AEA, 0x0AEB, 0x0AEC, 0x0AED, 0x0AEE, 0x0AEF
+ };
+ return toNumeric(value, gujaratiNumerals);
+ }
+ case Gurmukhi: {
+ static const UChar gurmukhiNumerals[10] = {
+ 0x0A66, 0x0A67, 0x0A68, 0x0A69, 0x0A6A, 0x0A6B, 0x0A6C, 0x0A6D, 0x0A6E, 0x0A6F
+ };
+ return toNumeric(value, gurmukhiNumerals);
+ }
+ case Kannada: {
+ static const UChar kannadaNumerals[10] = {
+ 0x0CE6, 0x0CE7, 0x0CE8, 0x0CE9, 0x0CEA, 0x0CEB, 0x0CEC, 0x0CED, 0x0CEE, 0x0CEF
+ };
+ return toNumeric(value, kannadaNumerals);
+ }
+ case LowerHexadecimal: {
+ static const UChar lowerHexadecimalNumerals[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+ return toNumeric(value, lowerHexadecimalNumerals);
+ }
+ case Lao: {
+ static const UChar laoNumerals[10] = {
+ 0x0ED0, 0x0ED1, 0x0ED2, 0x0ED3, 0x0ED4, 0x0ED5, 0x0ED6, 0x0ED7, 0x0ED8, 0x0ED9
+ };
+ return toNumeric(value, laoNumerals);
+ }
+ case Malayalam: {
+ static const UChar malayalamNumerals[10] = {
+ 0x0D66, 0x0D67, 0x0D68, 0x0D69, 0x0D6A, 0x0D6B, 0x0D6C, 0x0D6D, 0x0D6E, 0x0D6F
+ };
+ return toNumeric(value, malayalamNumerals);
+ }
+ case Mongolian: {
+ static const UChar mongolianNumerals[10] = {
+ 0x1810, 0x1811, 0x1812, 0x1813, 0x1814, 0x1815, 0x1816, 0x1817, 0x1818, 0x1819
+ };
+ return toNumeric(value, mongolianNumerals);
+ }
+ case Myanmar: {
+ static const UChar myanmarNumerals[10] = {
+ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, 0x1049
+ };
+ return toNumeric(value, myanmarNumerals);
+ }
+ case Octal: {
+ static const UChar octalNumerals[8] = {
+ '0', '1', '2', '3', '4', '5', '6', '7'
+ };
+ return toNumeric(value, octalNumerals);
+ }
+ case Oriya: {
+ static const UChar oriyaNumerals[10] = {
+ 0x0B66, 0x0B67, 0x0B68, 0x0B69, 0x0B6A, 0x0B6B, 0x0B6C, 0x0B6D, 0x0B6E, 0x0B6F
+ };
+ return toNumeric(value, oriyaNumerals);
+ }
+ case Persian:
+ case Urdu: {
+ static const UChar urduNumerals[10] = {
+ 0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, 0x06F5, 0x06F6, 0x06F7, 0x06F8, 0x06F9
+ };
+ return toNumeric(value, urduNumerals);
+ }
+ case Telugu: {
+ static const UChar teluguNumerals[10] = {
+ 0x0C66, 0x0C67, 0x0C68, 0x0C69, 0x0C6A, 0x0C6B, 0x0C6C, 0x0C6D, 0x0C6E, 0x0C6F
+ };
+ return toNumeric(value, teluguNumerals);
+ }
+ case Tibetan: {
+ static const UChar tibetanNumerals[10] = {
+ 0x0F20, 0x0F21, 0x0F22, 0x0F23, 0x0F24, 0x0F25, 0x0F26, 0x0F27, 0x0F28, 0x0F29
+ };
+ return toNumeric(value, tibetanNumerals);
+ }
+ case Thai: {
+ static const UChar thaiNumerals[10] = {
+ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59
+ };
+ return toNumeric(value, thaiNumerals);
+ }
+ case UpperHexadecimal: {
+ static const UChar upperHexadecimalNumerals[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+ return toNumeric(value, upperHexadecimalNumerals);
+ }
+
+ case LowerAlpha:
+ case LowerLatin: {
static const UChar lowerLatinAlphabet[26] = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
};
- return toAlphabetic(value, lowerLatinAlphabet, 26);
+ return toAlphabetic(value, lowerLatinAlphabet);
}
- case UPPER_ALPHA:
- case UPPER_LATIN: {
+ case UpperAlpha:
+ case UpperLatin: {
static const UChar upperLatinAlphabet[26] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
};
- return toAlphabetic(value, upperLatinAlphabet, 26);
+ return toAlphabetic(value, upperLatinAlphabet);
}
- case LOWER_GREEK: {
+ case LowerGreek: {
static const UChar lowerGreekAlphabet[24] = {
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9
};
- return toAlphabetic(value, lowerGreekAlphabet, 24);
+ return toAlphabetic(value, lowerGreekAlphabet);
}
- case HIRAGANA: {
+ case Hiragana: {
// FIXME: This table comes from the CSS3 draft, and is probably
// incorrect, given the comments in that draft.
static const UChar hiraganaAlphabet[48] = {
@@ -397,9 +654,9 @@ String listMarkerText(EListStyleType type, int value)
0x3080, 0x3081, 0x3082, 0x3084, 0x3086, 0x3088, 0x3089, 0x308A,
0x308B, 0x308C, 0x308D, 0x308F, 0x3090, 0x3091, 0x3092, 0x3093
};
- return toAlphabetic(value, hiraganaAlphabet, 48);
+ return toAlphabetic(value, hiraganaAlphabet);
}
- case HIRAGANA_IROHA: {
+ case HiraganaIroha: {
// FIXME: This table comes from the CSS3 draft, and is probably
// incorrect, given the comments in that draft.
static const UChar hiraganaIrohaAlphabet[47] = {
@@ -410,9 +667,9 @@ String listMarkerText(EListStyleType type, int value)
0x3053, 0x3048, 0x3066, 0x3042, 0x3055, 0x304D, 0x3086, 0x3081,
0x307F, 0x3057, 0x3091, 0x3072, 0x3082, 0x305B, 0x3059
};
- return toAlphabetic(value, hiraganaIrohaAlphabet, 47);
+ return toAlphabetic(value, hiraganaIrohaAlphabet);
}
- case KATAKANA: {
+ case Katakana: {
// FIXME: This table comes from the CSS3 draft, and is probably
// incorrect, given the comments in that draft.
static const UChar katakanaAlphabet[48] = {
@@ -423,9 +680,9 @@ String listMarkerText(EListStyleType type, int value)
0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9, 0x30EA,
0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F0, 0x30F1, 0x30F2, 0x30F3
};
- return toAlphabetic(value, katakanaAlphabet, 48);
+ return toAlphabetic(value, katakanaAlphabet);
}
- case KATAKANA_IROHA: {
+ case KatakanaIroha: {
// FIXME: This table comes from the CSS3 draft, and is probably
// incorrect, given the comments in that draft.
static const UChar katakanaIrohaAlphabet[47] = {
@@ -436,10 +693,187 @@ String listMarkerText(EListStyleType type, int value)
0x30B3, 0x30A8, 0x30C6, 0x30A2, 0x30B5, 0x30AD, 0x30E6, 0x30E1,
0x30DF, 0x30B7, 0x30F1, 0x30D2, 0x30E2, 0x30BB, 0x30B9
};
- return toAlphabetic(value, katakanaIrohaAlphabet, 47);
+ return toAlphabetic(value, katakanaIrohaAlphabet);
}
- case CJK_IDEOGRAPHIC: {
+ case Afar:
+ case EthiopicHalehameAaEt:
+ case EthiopicHalehameAaEr: {
+ static const UChar ethiopicHalehameAaErAlphabet[18] = {
+ 0x1200, 0x1208, 0x1210, 0x1218, 0x1228, 0x1230, 0x1260, 0x1270, 0x1290,
+ 0x12A0, 0x12A8, 0x12C8, 0x12D0, 0x12E8, 0x12F0, 0x1308, 0x1338, 0x1348
+ };
+ return toAlphabetic(value, ethiopicHalehameAaErAlphabet);
+ }
+ case Amharic:
+ case EthiopicHalehameAmEt: {
+ static const UChar ethiopicHalehameAmEtAlphabet[33] = {
+ 0x1200, 0x1208, 0x1210, 0x1218, 0x1220, 0x1228, 0x1230, 0x1238, 0x1240,
+ 0x1260, 0x1270, 0x1278, 0x1280, 0x1290, 0x1298, 0x12A0, 0x12A8, 0x12B8,
+ 0x12C8, 0x12D0, 0x12D8, 0x12E0, 0x12E8, 0x12F0, 0x1300, 0x1308, 0x1320,
+ 0x1328, 0x1330, 0x1338, 0x1340, 0x1348, 0x1350
+ };
+ return toAlphabetic(value, ethiopicHalehameAmEtAlphabet);
+ }
+ case AmharicAbegede:
+ case EthiopicAbegedeAmEt: {
+ static const UChar ethiopicAbegedeAmEtAlphabet[33] = {
+ 0x12A0, 0x1260, 0x1308, 0x12F0, 0x1300, 0x1200, 0x12C8, 0x12D8, 0x12E0,
+ 0x1210, 0x1320, 0x1328, 0x12E8, 0x12A8, 0x12B8, 0x1208, 0x1218, 0x1290,
+ 0x1298, 0x1220, 0x12D0, 0x1348, 0x1338, 0x1240, 0x1228, 0x1230, 0x1238,
+ 0x1270, 0x1278, 0x1280, 0x1340, 0x1330, 0x1350
+ };
+ return toAlphabetic(value, ethiopicAbegedeAmEtAlphabet);
+ }
+ case CjkEarthlyBranch: {
+ static const UChar cjkEarthlyBranchAlphabet[12] = {
+ 0x5B50, 0x4E11, 0x5BC5, 0x536F, 0x8FB0, 0x5DF3, 0x5348, 0x672A, 0x7533,
+ 0x9149, 0x620C, 0x4EA5
+ };
+ return toAlphabetic(value, cjkEarthlyBranchAlphabet);
+ }
+ case CjkHeavenlyStem: {
+ static const UChar cjkHeavenlyStemAlphabet[10] = {
+ 0x7532, 0x4E59, 0x4E19, 0x4E01, 0x620A, 0x5DF1, 0x5E9A, 0x8F9B, 0x58EC,
+ 0x7678
+ };
+ return toAlphabetic(value, cjkHeavenlyStemAlphabet);
+ }
+ case Ethiopic:
+ case EthiopicHalehameGez: {
+ static const UChar ethiopicHalehameGezAlphabet[26] = {
+ 0x1200, 0x1208, 0x1210, 0x1218, 0x1220, 0x1228, 0x1230, 0x1240, 0x1260,
+ 0x1270, 0x1280, 0x1290, 0x12A0, 0x12A8, 0x12C8, 0x12D0, 0x12D8, 0x12E8,
+ 0x12F0, 0x1308, 0x1320, 0x1330, 0x1338, 0x1340, 0x1348, 0x1350
+ };
+ return toAlphabetic(value, ethiopicHalehameGezAlphabet);
+ }
+ case EthiopicAbegede:
+ case EthiopicAbegedeGez: {
+ static const UChar ethiopicAbegedeGezAlphabet[26] = {
+ 0x12A0, 0x1260, 0x1308, 0x12F0, 0x1200, 0x12C8, 0x12D8, 0x1210, 0x1320,
+ 0x12E8, 0x12A8, 0x1208, 0x1218, 0x1290, 0x1220, 0x12D0, 0x1348, 0x1338,
+ 0x1240, 0x1228, 0x1230, 0x1270, 0x1280, 0x1340, 0x1330, 0x1350
+ };
+ return toAlphabetic(value, ethiopicAbegedeGezAlphabet);
+ }
+ case HangulConsonant: {
+ static const UChar hangulConsonantAlphabet[14] = {
+ 0x3131, 0x3134, 0x3137, 0x3139, 0x3141, 0x3142, 0x3145, 0x3147, 0x3148,
+ 0x314A, 0x314B, 0x314C, 0x314D, 0x314E
+ };
+ return toAlphabetic(value, hangulConsonantAlphabet);
+ }
+ case Hangul: {
+ static const UChar hangulAlphabet[14] = {
+ 0xAC00, 0xB098, 0xB2E4, 0xB77C, 0xB9C8, 0xBC14, 0xC0AC, 0xC544, 0xC790,
+ 0xCC28, 0xCE74, 0xD0C0, 0xD30C, 0xD558
+ };
+ return toAlphabetic(value, hangulAlphabet);
+ }
+ case Oromo:
+ case EthiopicHalehameOmEt: {
+ static const UChar ethiopicHalehameOmEtAlphabet[25] = {
+ 0x1200, 0x1208, 0x1218, 0x1228, 0x1230, 0x1238, 0x1240, 0x1260, 0x1270,
+ 0x1278, 0x1290, 0x1298, 0x12A0, 0x12A8, 0x12C8, 0x12E8, 0x12F0, 0x12F8,
+ 0x1300, 0x1308, 0x1320, 0x1328, 0x1338, 0x1330, 0x1348
+ };
+ return toAlphabetic(value, ethiopicHalehameOmEtAlphabet);
+ }
+ case Sidama:
+ case EthiopicHalehameSidEt: {
+ static const UChar ethiopicHalehameSidEtAlphabet[26] = {
+ 0x1200, 0x1208, 0x1210, 0x1218, 0x1228, 0x1230, 0x1238, 0x1240, 0x1260,
+ 0x1270, 0x1278, 0x1290, 0x1298, 0x12A0, 0x12A8, 0x12C8, 0x12E8, 0x12F0,
+ 0x12F8, 0x1300, 0x1308, 0x1320, 0x1328, 0x1338, 0x1330, 0x1348
+ };
+ return toAlphabetic(value, ethiopicHalehameSidEtAlphabet);
+ }
+ case Somali:
+ case EthiopicHalehameSoEt: {
+ static const UChar ethiopicHalehameSoEtAlphabet[22] = {
+ 0x1200, 0x1208, 0x1210, 0x1218, 0x1228, 0x1230, 0x1238, 0x1240, 0x1260,
+ 0x1270, 0x1290, 0x12A0, 0x12A8, 0x12B8, 0x12C8, 0x12D0, 0x12E8, 0x12F0,
+ 0x1300, 0x1308, 0x1338, 0x1348
+ };
+ return toAlphabetic(value, ethiopicHalehameSoEtAlphabet);
+ }
+ case Tigre:
+ case EthiopicHalehameTig: {
+ static const UChar ethiopicHalehameTigAlphabet[27] = {
+ 0x1200, 0x1208, 0x1210, 0x1218, 0x1228, 0x1230, 0x1238, 0x1240, 0x1260,
+ 0x1270, 0x1278, 0x1290, 0x12A0, 0x12A8, 0x12C8, 0x12D0, 0x12D8, 0x12E8,
+ 0x12F0, 0x1300, 0x1308, 0x1320, 0x1328, 0x1338, 0x1330, 0x1348, 0x1350
+ };
+ return toAlphabetic(value, ethiopicHalehameTigAlphabet);
+ }
+ case TigrinyaEr:
+ case EthiopicHalehameTiEr: {
+ static const UChar ethiopicHalehameTiErAlphabet[31] = {
+ 0x1200, 0x1208, 0x1210, 0x1218, 0x1228, 0x1230, 0x1238, 0x1240, 0x1250,
+ 0x1260, 0x1270, 0x1278, 0x1290, 0x1298, 0x12A0, 0x12A8, 0x12B8, 0x12C8,
+ 0x12D0, 0x12D8, 0x12E0, 0x12E8, 0x12F0, 0x1300, 0x1308, 0x1320, 0x1328,
+ 0x1330, 0x1338, 0x1348, 0x1350
+ };
+ return toAlphabetic(value, ethiopicHalehameTiErAlphabet);
+ }
+ case TigrinyaErAbegede:
+ case EthiopicAbegedeTiEr: {
+ static const UChar ethiopicAbegedeTiErAlphabet[31] = {
+ 0x12A0, 0x1260, 0x1308, 0x12F0, 0x1300, 0x1200, 0x12C8, 0x12D8, 0x12E0,
+ 0x1210, 0x1320, 0x1328, 0x12E8, 0x12A8, 0x12B8, 0x1208, 0x1218, 0x1290,
+ 0x1298, 0x12D0, 0x1348, 0x1338, 0x1240, 0x1250, 0x1228, 0x1230, 0x1238,
+ 0x1270, 0x1278, 0x1330, 0x1350
+ };
+ return toAlphabetic(value, ethiopicAbegedeTiErAlphabet);
+ }
+ case TigrinyaEt:
+ case EthiopicHalehameTiEt: {
+ static const UChar ethiopicHalehameTiEtAlphabet[34] = {
+ 0x1200, 0x1208, 0x1210, 0x1218, 0x1220, 0x1228, 0x1230, 0x1238, 0x1240,
+ 0x1250, 0x1260, 0x1270, 0x1278, 0x1280, 0x1290, 0x1298, 0x12A0, 0x12A8,
+ 0x12B8, 0x12C8, 0x12D0, 0x12D8, 0x12E0, 0x12E8, 0x12F0, 0x1300, 0x1308,
+ 0x1320, 0x1328, 0x1330, 0x1338, 0x1340, 0x1348, 0x1350
+ };
+ return toAlphabetic(value, ethiopicHalehameTiEtAlphabet);
+ }
+ case TigrinyaEtAbegede:
+ case EthiopicAbegedeTiEt: {
+ static const UChar ethiopicAbegedeTiEtAlphabet[34] = {
+ 0x12A0, 0x1260, 0x1308, 0x12F0, 0x1300, 0x1200, 0x12C8, 0x12D8, 0x12E0,
+ 0x1210, 0x1320, 0x1328, 0x12E8, 0x12A8, 0x12B8, 0x1208, 0x1218, 0x1290,
+ 0x1298, 0x1220, 0x12D0, 0x1348, 0x1338, 0x1240, 0x1250, 0x1228, 0x1230,
+ 0x1238, 0x1270, 0x1278, 0x1280, 0x1340, 0x1330, 0x1350
+ };
+ return toAlphabetic(value, ethiopicAbegedeTiEtAlphabet);
+ }
+ case UpperGreek: {
+ static const UChar upperGreekAlphabet[24] = {
+ 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399,
+ 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3,
+ 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9
+ };
+ return toAlphabetic(value, upperGreekAlphabet);
+ }
+ case LowerNorwegian: {
+ static const UChar lowerNorwegianAlphabet[29] = {
+ 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069,
+ 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072,
+ 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x00E6,
+ 0x00F8, 0x00E5
+ };
+ return toAlphabetic(value, lowerNorwegianAlphabet);
+ }
+ case UpperNorwegian: {
+ static const UChar upperNorwegianAlphabet[29] = {
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049,
+ 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052,
+ 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00C6,
+ 0x00D8, 0x00C5
+ };
+ return toAlphabetic(value, upperNorwegianAlphabet);
+ }
+ case CJKIdeographic: {
static const UChar traditionalChineseInformalTable[16] = {
0x842C, 0x5104, 0x5146,
0x5341, 0x767E, 0x5343,
@@ -449,19 +883,19 @@ String listMarkerText(EListStyleType type, int value)
return toCJKIdeographic(value, traditionalChineseInformalTable);
}
- case LOWER_ROMAN:
+ case LowerRoman:
return toRoman(value, false);
- case UPPER_ROMAN:
+ case UpperRoman:
return toRoman(value, true);
- case ARMENIAN:
+ case Armenian:
// CSS3 says "armenian" means "lower-armenian".
// But the CSS2.1 test suite contains uppercase test results for "armenian",
// so we'll match the test suite.
return toArmenian(value, true);
- case GEORGIAN:
+ case Georgian:
return toGeorgian(value);
- case HEBREW:
+ case Hebrew:
return toHebrew(value);
}
@@ -517,6 +951,15 @@ bool RenderListMarker::isImage() const
return m_image && !m_image->errorOccurred();
}
+IntRect RenderListMarker::localSelectionRect()
+{
+ InlineBox* box = inlineBoxWrapper();
+ if (!box)
+ return IntRect();
+ RootInlineBox* root = box->root();
+ return IntRect(x(), root->selectionTop() - y(), width(), root->selectionHeight());
+}
+
void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
{
if (paintInfo.phase != PaintPhaseForeground)
@@ -543,10 +986,11 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
if (style()->highlight() != nullAtom && !paintInfo.context->paintingDisabled())
paintCustomHighlight(tx, ty, style()->highlight(), true);
#endif
- context->drawImage(m_image->image(this, marker.size()), marker.location());
+ context->drawImage(m_image->image(this, marker.size()), style()->colorSpace(), marker.location());
if (selectionState() != SelectionNone) {
- // FIXME: selectionRect() is in absolute, not painting coordinates.
- context->fillRect(selectionRect(), selectionBackgroundColor());
+ IntRect selRect = localSelectionRect();
+ selRect.move(tx, ty);
+ context->fillRect(selRect, selectionBackgroundColor(), style()->colorSpace());
}
return;
}
@@ -558,46 +1002,104 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
#endif
if (selectionState() != SelectionNone) {
- // FIXME: selectionRect() is in absolute, not painting coordinates.
- context->fillRect(selectionRect(), selectionBackgroundColor());
+ IntRect selRect = localSelectionRect();
+ selRect.move(tx, ty);
+ context->fillRect(selRect, selectionBackgroundColor(), style()->colorSpace());
}
const Color color(style()->color());
- context->setStrokeColor(color);
+ context->setStrokeColor(color, style()->colorSpace());
context->setStrokeStyle(SolidStroke);
context->setStrokeThickness(1.0f);
- context->setFillColor(color);
+ context->setFillColor(color, style()->colorSpace());
- switch (style()->listStyleType()) {
- case DISC:
+ EListStyleType type = style()->listStyleType();
+ switch (type) {
+ case Disc:
context->drawEllipse(marker);
return;
- case CIRCLE:
- context->setFillColor(Color::transparent);
+ case Circle:
+ context->setFillColor(Color::transparent, DeviceColorSpace);
context->drawEllipse(marker);
return;
- case SQUARE:
+ case Square:
context->drawRect(marker);
return;
- case LNONE:
+ case NoneListStyle:
return;
- case ARMENIAN:
- case CJK_IDEOGRAPHIC:
- case DECIMAL_LEADING_ZERO:
- case GEORGIAN:
- case HEBREW:
- case HIRAGANA:
- case HIRAGANA_IROHA:
- case KATAKANA:
- case KATAKANA_IROHA:
- case LDECIMAL:
- case LOWER_ALPHA:
- case LOWER_GREEK:
- case LOWER_LATIN:
- case LOWER_ROMAN:
- case UPPER_ALPHA:
- case UPPER_LATIN:
- case UPPER_ROMAN:
+ case Afar:
+ case Amharic:
+ case AmharicAbegede:
+ case ArabicIndic:
+ case Armenian:
+ case BinaryListStyle:
+ case Bengali:
+ case Cambodian:
+ case CJKIdeographic:
+ case CjkEarthlyBranch:
+ case CjkHeavenlyStem:
+ case DecimalLeadingZero:
+ case DecimalListStyle:
+ case Devanagari:
+ case Ethiopic:
+ case EthiopicAbegede:
+ case EthiopicAbegedeAmEt:
+ case EthiopicAbegedeGez:
+ case EthiopicAbegedeTiEr:
+ case EthiopicAbegedeTiEt:
+ case EthiopicHalehameAaEr:
+ case EthiopicHalehameAaEt:
+ case EthiopicHalehameAmEt:
+ case EthiopicHalehameGez:
+ case EthiopicHalehameOmEt:
+ case EthiopicHalehameSidEt:
+ case EthiopicHalehameSoEt:
+ case EthiopicHalehameTiEr:
+ case EthiopicHalehameTiEt:
+ case EthiopicHalehameTig:
+ case Georgian:
+ case Gujarati:
+ case Gurmukhi:
+ case Hangul:
+ case HangulConsonant:
+ case Hebrew:
+ case Hiragana:
+ case HiraganaIroha:
+ case Kannada:
+ case Katakana:
+ case KatakanaIroha:
+ case Khmer:
+ case Lao:
+ case LowerAlpha:
+ case LowerGreek:
+ case LowerHexadecimal:
+ case LowerLatin:
+ case LowerNorwegian:
+ case LowerRoman:
+ case Malayalam:
+ case Mongolian:
+ case Myanmar:
+ case Octal:
+ case Oriya:
+ case Oromo:
+ case Persian:
+ case Sidama:
+ case Somali:
+ case Telugu:
+ case Thai:
+ case Tibetan:
+ case Tigre:
+ case TigrinyaEr:
+ case TigrinyaErAbegede:
+ case TigrinyaEt:
+ case TigrinyaEtAbegede:
+ case UpperAlpha:
+ case UpperGreek:
+ case UpperHexadecimal:
+ case UpperLatin:
+ case UpperNorwegian:
+ case UpperRoman:
+ case Urdu:
break;
}
if (m_text.isEmpty())
@@ -618,16 +1120,17 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
}
const Font& font = style()->font();
+ const UChar suffix = listMarkerSuffix(type);
if (style()->direction() == LTR) {
int width = font.width(textRun);
context->drawText(style()->font(), textRun, marker.location());
- const UChar periodSpace[2] = { '.', ' ' };
- context->drawText(style()->font(), TextRun(periodSpace, 2), marker.location() + IntSize(width, 0));
+ UChar suffixSpace[2] = { suffix, ' ' };
+ context->drawText(style()->font(), TextRun(suffixSpace, 2), marker.location() + IntSize(width, 0));
} else {
- const UChar spacePeriod[2] = { ' ', '.' };
- TextRun spacePeriodRun(spacePeriod, 2);
- int width = font.width(spacePeriodRun);
- context->drawText(style()->font(), spacePeriodRun, marker.location());
+ UChar spaceSuffix[2] = { ' ', suffix };
+ TextRun spaceSuffixRun(spaceSuffix, 2);
+ int width = font.width(spaceSuffixRun);
+ context->drawText(style()->font(), spaceSuffixRun, marker.location());
context->drawText(style()->font(), textRun, marker.location() + IntSize(width, 0));
}
}
@@ -691,39 +1194,95 @@ void RenderListMarker::calcPrefWidths()
int width = 0;
EListStyleType type = style()->listStyleType();
switch (type) {
- case LNONE:
+ case NoneListStyle:
break;
- case CIRCLE:
- case DISC:
- case SQUARE:
+ case Circle:
+ case Disc:
+ case Square:
m_text = listMarkerText(type, 0); // value is ignored for these types
width = (font.ascent() * 2 / 3 + 1) / 2 + 2;
break;
- case ARMENIAN:
- case CJK_IDEOGRAPHIC:
- case DECIMAL_LEADING_ZERO:
- case GEORGIAN:
- case HEBREW:
- case HIRAGANA:
- case HIRAGANA_IROHA:
- case KATAKANA:
- case KATAKANA_IROHA:
- case LDECIMAL:
- case LOWER_ALPHA:
- case LOWER_GREEK:
- case LOWER_LATIN:
- case LOWER_ROMAN:
- case UPPER_ALPHA:
- case UPPER_LATIN:
- case UPPER_ROMAN:
+ case Afar:
+ case Amharic:
+ case AmharicAbegede:
+ case ArabicIndic:
+ case Armenian:
+ case BinaryListStyle:
+ case Bengali:
+ case Cambodian:
+ case CJKIdeographic:
+ case CjkEarthlyBranch:
+ case CjkHeavenlyStem:
+ case DecimalLeadingZero:
+ case DecimalListStyle:
+ case Devanagari:
+ case Ethiopic:
+ case EthiopicAbegede:
+ case EthiopicAbegedeAmEt:
+ case EthiopicAbegedeGez:
+ case EthiopicAbegedeTiEr:
+ case EthiopicAbegedeTiEt:
+ case EthiopicHalehameAaEr:
+ case EthiopicHalehameAaEt:
+ case EthiopicHalehameAmEt:
+ case EthiopicHalehameGez:
+ case EthiopicHalehameOmEt:
+ case EthiopicHalehameSidEt:
+ case EthiopicHalehameSoEt:
+ case EthiopicHalehameTiEr:
+ case EthiopicHalehameTiEt:
+ case EthiopicHalehameTig:
+ case Georgian:
+ case Gujarati:
+ case Gurmukhi:
+ case Hangul:
+ case HangulConsonant:
+ case Hebrew:
+ case Hiragana:
+ case HiraganaIroha:
+ case Kannada:
+ case Katakana:
+ case KatakanaIroha:
+ case Khmer:
+ case Lao:
+ case LowerAlpha:
+ case LowerGreek:
+ case LowerHexadecimal:
+ case LowerLatin:
+ case LowerNorwegian:
+ case LowerRoman:
+ case Malayalam:
+ case Mongolian:
+ case Myanmar:
+ case Octal:
+ case Oriya:
+ case Oromo:
+ case Persian:
+ case Sidama:
+ case Somali:
+ case Telugu:
+ case Thai:
+ case Tibetan:
+ case Tigre:
+ case TigrinyaEr:
+ case TigrinyaErAbegede:
+ case TigrinyaEt:
+ case TigrinyaEtAbegede:
+ case UpperAlpha:
+ case UpperGreek:
+ case UpperHexadecimal:
+ case UpperLatin:
+ case UpperNorwegian:
+ case UpperRoman:
+ case Urdu:
m_text = listMarkerText(type, m_listItem->value());
if (m_text.isEmpty())
width = 0;
else {
int itemWidth = font.width(m_text);
- const UChar periodSpace[2] = { '.', ' ' };
- int periodSpaceWidth = font.width(TextRun(periodSpace, 2));
- width = itemWidth + periodSpaceWidth;
+ UChar suffixSpace[2] = { listMarkerSuffix(type), ' ' };
+ int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
+ width = itemWidth + suffixSpaceWidth;
}
break;
}
@@ -750,9 +1309,9 @@ void RenderListMarker::updateMargins()
else
marginLeft = cMarkerPadding;
} else switch (style()->listStyleType()) {
- case DISC:
- case CIRCLE:
- case SQUARE:
+ case Disc:
+ case Circle:
+ case Square:
if (style()->direction() == LTR) {
marginLeft = -1;
marginRight = font.ascent() - minPrefWidth() + 1;
@@ -771,12 +1330,12 @@ void RenderListMarker::updateMargins()
else {
int offset = font.ascent() * 2 / 3;
switch (style()->listStyleType()) {
- case DISC:
- case CIRCLE:
- case SQUARE:
+ case Disc:
+ case Circle:
+ case Square:
marginLeft = -offset - cMarkerPadding - 1;
break;
- case LNONE:
+ case NoneListStyle:
break;
default:
marginLeft = m_text.isEmpty() ? 0 : -minPrefWidth() - offset / 2;
@@ -788,12 +1347,12 @@ void RenderListMarker::updateMargins()
else {
int offset = font.ascent() * 2 / 3;
switch (style()->listStyleType()) {
- case DISC:
- case CIRCLE:
- case SQUARE:
+ case Disc:
+ case Circle:
+ case Square:
marginLeft = offset + cMarkerPadding + 1 - minPrefWidth();
break;
- case LNONE:
+ case NoneListStyle:
break;
default:
marginLeft = m_text.isEmpty() ? 0 : offset / 2;
@@ -833,42 +1392,99 @@ IntRect RenderListMarker::getRelativeMarkerRect()
if (isImage())
return IntRect(x(), y(), m_image->imageSize(this, style()->effectiveZoom()).width(), m_image->imageSize(this, style()->effectiveZoom()).height());
- switch (style()->listStyleType()) {
- case DISC:
- case CIRCLE:
- case SQUARE: {
+ EListStyleType type = style()->listStyleType();
+ switch (type) {
+ case Disc:
+ case Circle:
+ case Square: {
// FIXME: Are these particular rounding rules necessary?
const Font& font = style()->font();
int ascent = font.ascent();
int bulletWidth = (ascent * 2 / 3 + 1) / 2;
return IntRect(x() + 1, y() + 3 * (ascent - ascent * 2 / 3) / 2, bulletWidth, bulletWidth);
}
- case LNONE:
+ case NoneListStyle:
return IntRect();
- case ARMENIAN:
- case CJK_IDEOGRAPHIC:
- case DECIMAL_LEADING_ZERO:
- case GEORGIAN:
- case HEBREW:
- case HIRAGANA:
- case HIRAGANA_IROHA:
- case KATAKANA:
- case KATAKANA_IROHA:
- case LDECIMAL:
- case LOWER_ALPHA:
- case LOWER_GREEK:
- case LOWER_LATIN:
- case LOWER_ROMAN:
- case UPPER_ALPHA:
- case UPPER_LATIN:
- case UPPER_ROMAN:
+ case Afar:
+ case Amharic:
+ case AmharicAbegede:
+ case ArabicIndic:
+ case Armenian:
+ case BinaryListStyle:
+ case Bengali:
+ case Cambodian:
+ case CJKIdeographic:
+ case CjkEarthlyBranch:
+ case CjkHeavenlyStem:
+ case DecimalLeadingZero:
+ case DecimalListStyle:
+ case Devanagari:
+ case Ethiopic:
+ case EthiopicAbegede:
+ case EthiopicAbegedeAmEt:
+ case EthiopicAbegedeGez:
+ case EthiopicAbegedeTiEr:
+ case EthiopicAbegedeTiEt:
+ case EthiopicHalehameAaEr:
+ case EthiopicHalehameAaEt:
+ case EthiopicHalehameAmEt:
+ case EthiopicHalehameGez:
+ case EthiopicHalehameOmEt:
+ case EthiopicHalehameSidEt:
+ case EthiopicHalehameSoEt:
+ case EthiopicHalehameTiEr:
+ case EthiopicHalehameTiEt:
+ case EthiopicHalehameTig:
+ case Georgian:
+ case Gujarati:
+ case Gurmukhi:
+ case Hangul:
+ case HangulConsonant:
+ case Hebrew:
+ case Hiragana:
+ case HiraganaIroha:
+ case Kannada:
+ case Katakana:
+ case KatakanaIroha:
+ case Khmer:
+ case Lao:
+ case LowerAlpha:
+ case LowerGreek:
+ case LowerHexadecimal:
+ case LowerLatin:
+ case LowerNorwegian:
+ case LowerRoman:
+ case Malayalam:
+ case Mongolian:
+ case Myanmar:
+ case Octal:
+ case Oriya:
+ case Oromo:
+ case Persian:
+ case Sidama:
+ case Somali:
+ case Telugu:
+ case Thai:
+ case Tibetan:
+ case Tigre:
+ case TigrinyaEr:
+ case TigrinyaErAbegede:
+ case TigrinyaEt:
+ case TigrinyaEtAbegede:
+ case UpperAlpha:
+ case UpperGreek:
+ case UpperHexadecimal:
+ case UpperLatin:
+ case UpperNorwegian:
+ case UpperRoman:
+ case Urdu:
if (m_text.isEmpty())
return IntRect();
const Font& font = style()->font();
int itemWidth = font.width(m_text);
- const UChar periodSpace[2] = { '.', ' ' };
- int periodSpaceWidth = font.width(TextRun(periodSpace, 2));
- return IntRect(x(), y() + font.ascent(), itemWidth + periodSpaceWidth, font.height());
+ UChar suffixSpace[2] = { listMarkerSuffix(type), ' ' };
+ int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
+ return IntRect(x(), y() + font.ascent(), itemWidth + suffixSpaceWidth, font.height());
}
return IntRect();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.h b/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.h
index 5b46278daa..971877b41f 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderListMarker.h
@@ -73,6 +73,7 @@ private:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
IntRect getRelativeMarkerRect();
+ IntRect localSelectionRect();
String m_text;
RefPtr<StyleImage> m_image;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMarquee.h b/src/3rdparty/webkit/WebCore/rendering/RenderMarquee.h
index 886c3431b1..1651454df5 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderMarquee.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderMarquee.h
@@ -53,7 +53,7 @@ namespace WebCore {
class RenderLayer;
// This class handles the auto-scrolling of layers with overflow: marquee.
-class RenderMarquee {
+class RenderMarquee : public Noncopyable {
public:
RenderMarquee(RenderLayer*);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp
index 1d4da23381..7100435a96 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -45,32 +45,30 @@ using namespace HTMLNames;
static const double cTimeUpdateRepeatDelay = 0.2;
static const double cOpacityAnimationRepeatDelay = 0.05;
-// FIXME get this from style
-static const double cOpacityAnimationDurationFadeIn = 0.1;
-static const double cOpacityAnimationDurationFadeOut = 0.3;
RenderMedia::RenderMedia(HTMLMediaElement* video)
- : RenderReplaced(video)
+ : RenderImage(video)
, m_timeUpdateTimer(this, &RenderMedia::timeUpdateTimerFired)
, m_opacityAnimationTimer(this, &RenderMedia::opacityAnimationTimerFired)
, m_mouseOver(false)
, m_opacityAnimationStartTime(0)
- , m_opacityAnimationDuration(cOpacityAnimationDurationFadeIn)
+ , m_opacityAnimationDuration(0)
, m_opacityAnimationFrom(0)
, m_opacityAnimationTo(1.0f)
{
}
RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
- : RenderReplaced(video, intrinsicSize)
+ : RenderImage(video)
, m_timeUpdateTimer(this, &RenderMedia::timeUpdateTimerFired)
, m_opacityAnimationTimer(this, &RenderMedia::opacityAnimationTimerFired)
, m_mouseOver(false)
, m_opacityAnimationStartTime(0)
- , m_opacityAnimationDuration(cOpacityAnimationDurationFadeIn)
+ , m_opacityAnimationDuration(0)
, m_opacityAnimationFrom(0)
, m_opacityAnimationTo(1.0f)
{
+ setIntrinsicSize(intrinsicSize);
}
RenderMedia::~RenderMedia()
@@ -89,7 +87,7 @@ void RenderMedia::destroy()
m_controlsShadowRoot->detach();
m_controlsShadowRoot = 0;
}
- RenderReplaced::destroy();
+ RenderImage::destroy();
}
HTMLMediaElement* RenderMedia::mediaElement() const
@@ -104,7 +102,7 @@ MediaPlayer* RenderMedia::player() const
void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- RenderReplaced::styleDidChange(diff, oldStyle);
+ RenderImage::styleDidChange(diff, oldStyle);
if (m_controlsShadowRoot) {
if (m_panel)
@@ -121,6 +119,8 @@ void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
m_rewindButton->updateStyle();
if (m_returnToRealtimeButton)
m_returnToRealtimeButton->updateStyle();
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->updateStyle();
if (m_statusDisplay)
m_statusDisplay->updateStyle();
if (m_timelineContainer)
@@ -144,7 +144,7 @@ void RenderMedia::layout()
{
IntSize oldSize = contentBoxRect().size();
- RenderReplaced::layout();
+ RenderImage::layout();
RenderBox* controlsRenderer = m_controlsShadowRoot ? m_controlsShadowRoot->renderBox() : 0;
if (!controlsRenderer)
@@ -223,6 +223,13 @@ void RenderMedia::createReturnToRealtimeButton()
m_returnToRealtimeButton->attachToParent(m_panel.get());
}
+void RenderMedia::createToggleClosedCaptionsButton()
+{
+ ASSERT(!m_toggleClosedCaptionsButton);
+ m_toggleClosedCaptionsButton = new MediaControlToggleClosedCaptionsButtonElement(document(), mediaElement());
+ m_toggleClosedCaptionsButton->attachToParent(m_panel.get());
+}
+
void RenderMedia::createStatusDisplay()
{
ASSERT(!m_statusDisplay);
@@ -310,6 +317,7 @@ void RenderMedia::updateControls()
m_volumeSliderContainer = 0;
m_volumeSlider = 0;
m_controlsShadowRoot = 0;
+ m_toggleClosedCaptionsButton = 0;
}
m_opacityAnimationTo = 1.0f;
m_opacityAnimationTimer.stop();
@@ -333,6 +341,7 @@ void RenderMedia::updateControls()
}
createSeekBackButton();
createSeekForwardButton();
+ createToggleClosedCaptionsButton();
createFullscreenButton();
createMuteButton();
createVolumeSliderContainer();
@@ -379,6 +388,8 @@ void RenderMedia::updateControls()
m_rewindButton->update();
if (m_returnToRealtimeButton)
m_returnToRealtimeButton->update();
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->update();
if (m_statusDisplay)
m_statusDisplay->update();
if (m_fullscreenButton)
@@ -401,10 +412,15 @@ void RenderMedia::updateTimeDisplay()
{
if (!m_currentTimeDisplay || !m_currentTimeDisplay->renderer() || m_currentTimeDisplay->renderer()->style()->display() == NONE || style()->visibility() != VISIBLE)
return;
+
float now = mediaElement()->currentTime();
float duration = mediaElement()->duration();
+ // Allow the theme to format the time
+ ExceptionCode ec;
+ m_currentTimeDisplay->setInnerText(theme()->formatMediaControlsCurrentTime(now, duration), ec);
m_currentTimeDisplay->setCurrentValue(now);
+ m_timeRemainingDisplay->setInnerText(theme()->formatMediaControlsRemainingTime(now, duration), ec);
m_timeRemainingDisplay->setCurrentValue(now - duration);
}
@@ -439,9 +455,9 @@ void RenderMedia::updateControlVisibility()
}
if (animateFrom < animateTo)
- m_opacityAnimationDuration = cOpacityAnimationDurationFadeIn;
+ m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeInDuration();
else
- m_opacityAnimationDuration = cOpacityAnimationDurationFadeOut;
+ m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeOutDuration();
m_opacityAnimationFrom = animateFrom;
m_opacityAnimationTo = animateTo;
@@ -535,6 +551,9 @@ void RenderMedia::forwardEvent(Event* event)
if (m_returnToRealtimeButton && m_returnToRealtimeButton->hitTest(point))
m_returnToRealtimeButton->defaultEventHandler(event);
+ if (m_toggleClosedCaptionsButton && m_toggleClosedCaptionsButton->hitTest(point))
+ m_toggleClosedCaptionsButton->defaultEventHandler(event);
+
if (m_timeline && m_timeline->hitTest(point))
m_timeline->defaultEventHandler(event);
@@ -557,7 +576,7 @@ void RenderMedia::forwardEvent(Event* event)
int RenderMedia::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
{
- int bottom = RenderReplaced::lowestPosition(includeOverflowInterior, includeSelf);
+ int bottom = RenderImage::lowestPosition(includeOverflowInterior, includeSelf);
if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
return bottom;
@@ -566,7 +585,7 @@ int RenderMedia::lowestPosition(bool includeOverflowInterior, bool includeSelf)
int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const
{
- int right = RenderReplaced::rightmostPosition(includeOverflowInterior, includeSelf);
+ int right = RenderImage::rightmostPosition(includeOverflowInterior, includeSelf);
if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
return right;
@@ -575,7 +594,7 @@ int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSel
int RenderMedia::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const
{
- int left = RenderReplaced::leftmostPosition(includeOverflowInterior, includeSelf);
+ int left = RenderImage::leftmostPosition(includeOverflowInterior, includeSelf);
if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
return left;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.h b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.h
index 602cd2648a..0d24c4c596 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,7 +28,7 @@
#if ENABLE(VIDEO)
-#include "RenderReplaced.h"
+#include "RenderImage.h"
#include "Timer.h"
namespace WebCore {
@@ -40,6 +40,7 @@ class MediaControlPlayButtonElement;
class MediaControlSeekButtonElement;
class MediaControlRewindButtonElement;
class MediaControlReturnToRealtimeButtonElement;
+class MediaControlToggleClosedCaptionsButtonElement;
class MediaControlTimelineElement;
class MediaControlVolumeSliderElement;
class MediaControlFullscreenButtonElement;
@@ -50,12 +51,12 @@ class MediaControlVolumeSliderContainerElement;
class MediaControlElement;
class MediaPlayer;
-class RenderMedia : public RenderReplaced {
+class RenderMedia : public RenderImage {
public:
RenderMedia(HTMLMediaElement*);
RenderMedia(HTMLMediaElement*, const IntSize& intrinsicSize);
virtual ~RenderMedia();
-
+
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
@@ -82,6 +83,7 @@ private:
virtual const char* renderName() const { return "RenderMedia"; }
virtual bool isMedia() const { return true; }
+ virtual bool isImage() const { return false; }
virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
@@ -96,6 +98,7 @@ private:
void createSeekForwardButton();
void createRewindButton();
void createReturnToRealtimeButton();
+ void createToggleClosedCaptionsButton();
void createStatusDisplay();
void createTimelineContainer();
void createTimeline();
@@ -123,6 +126,7 @@ private:
RefPtr<MediaControlSeekButtonElement> m_seekForwardButton;
RefPtr<MediaControlRewindButtonElement> m_rewindButton;
RefPtr<MediaControlReturnToRealtimeButtonElement> m_returnToRealtimeButton;
+ RefPtr<MediaControlToggleClosedCaptionsButtonElement> m_toggleClosedCaptionsButton;
RefPtr<MediaControlTimelineElement> m_timeline;
RefPtr<MediaControlVolumeSliderElement> m_volumeSlider;
RefPtr<MediaControlFullscreenButtonElement> m_fullscreenButton;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp
index 9cc1493f52..17576ae06b 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControls.cpp
@@ -90,6 +90,15 @@ bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, R
case MediaFullscreenButton:
paintThemePart(SafariTheme::MediaFullscreenButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o));
break;
+ case MediaShowClosedCaptionsButton:
+ case MediaHideClosedCaptionsButton:
+#if SAFARI_THEME_VERSION >= 4
+ if (MediaControlToggleClosedCaptionsButtonElement* btn = static_cast<MediaControlToggleClosedCaptionsButtonElement*>(o->node())) {
+ bool captionsVisible = btn->displayType() == MediaHideClosedCaptionsButton;
+ paintThemePart(captionsVisible ? SafariTheme::MediaHideClosedCaptionsButtonPart : SafariTheme::MediaShowClosedCaptionsButtonPart, paintInfo.context->platformContext(), r, NSRegularControlSize, determineState(o));
+ }
+#endif
+ break;
case MediaMuteButton:
case MediaUnMuteButton:
if (MediaControlMuteButtonElement* btn = static_cast<MediaControlMuteButtonElement*>(o->node())) {
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.cpp
index 56fbec43c2..50feb4604e 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderMediaControlsChromium.cpp
@@ -63,7 +63,7 @@ static bool hasSource(const HTMLMediaElement* mediaElement)
static bool paintMediaButton(GraphicsContext* context, const IntRect& rect, Image* image)
{
IntRect imageRect = image->rect();
- context->drawImage(image, rect);
+ context->drawImage(image, DeviceColorSpace, rect);
return true;
}
@@ -114,9 +114,9 @@ static bool paintMediaSlider(RenderObject* object, const RenderObject::PaintInfo
context->save();
context->setShouldAntialias(true);
context->setStrokeStyle(SolidStroke);
- context->setStrokeColor(style->borderLeftColor());
+ context->setStrokeColor(style->borderLeftColor(), DeviceColorSpace);
context->setStrokeThickness(style->borderLeftWidth());
- context->setFillColor(style->backgroundColor());
+ context->setFillColor(style->backgroundColor(), DeviceColorSpace);
context->drawRect(rect);
context->restore();
@@ -172,13 +172,13 @@ static bool paintMediaVolumeSlider(RenderObject* object, const RenderObject::Pai
GraphicsContext* context = paintInfo.context;
Color originalColor = context->strokeColor();
if (originalColor != Color::white)
- context->setStrokeColor(Color::white);
+ context->setStrokeColor(Color::white, DeviceColorSpace);
int x = rect.x() + rect.width() / 2;
context->drawLine(IntPoint(x, rect.y()), IntPoint(x, rect.y() + rect.height()));
if (originalColor != Color::white)
- context->setStrokeColor(originalColor);
+ context->setStrokeColor(originalColor, DeviceColorSpace);
return true;
}
@@ -207,17 +207,17 @@ static bool paintMediaTimelineContainer(RenderObject* object, const RenderObject
// Draw the left border using CSS defined width and color.
context->setStrokeThickness(object->style()->borderLeftWidth());
- context->setStrokeColor(object->style()->borderLeftColor().rgb());
+ context->setStrokeColor(object->style()->borderLeftColor().rgb(), DeviceColorSpace);
context->drawLine(IntPoint(rect.x() + 1, rect.y()),
IntPoint(rect.x() + 1, rect.y() + rect.height()));
// Draw the right border using CSS defined width and color.
context->setStrokeThickness(object->style()->borderRightWidth());
- context->setStrokeColor(object->style()->borderRightColor().rgb());
+ context->setStrokeColor(object->style()->borderRightColor().rgb(), DeviceColorSpace);
context->drawLine(IntPoint(rect.x() + rect.width() - 1, rect.y()),
IntPoint(rect.x() + rect.width() - 1, rect.y() + rect.height()));
- context->setStrokeColor(originalColor);
+ context->setStrokeColor(originalColor, DeviceColorSpace);
context->setStrokeThickness(originalThickness);
context->setStrokeStyle(originalStyle);
}
@@ -275,6 +275,8 @@ bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType
case MediaRewindButton:
case MediaReturnToRealtimeButton:
case MediaStatusDisplay:
+ case MediaShowClosedCaptionsButton:
+ case MediaHideClosedCaptionsButton:
ASSERT_NOT_REACHED();
break;
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp
index cbbc7cbad9..518925af56 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.cpp
@@ -1,7 +1,8 @@
/*
* This file is part of the select element renderer in WebCore.
*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -24,6 +25,8 @@
#include "config.h"
#include "RenderMenuList.h"
+#include "AXObjectCache.h"
+#include "AccessibilityObject.h"
#include "CSSStyleSelector.h"
#include "Frame.h"
#include "FrameView.h"
@@ -50,6 +53,7 @@ RenderMenuList::RenderMenuList(Element* element)
, m_innerBlock(0)
, m_optionsChanged(true)
, m_optionsWidth(0)
+ , m_lastSelectedIndex(-1)
, m_popup(0)
, m_popupIsVisible(false)
{
@@ -306,10 +310,39 @@ void RenderMenuList::valueChanged(unsigned listIndex, bool fireOnChange)
select->setSelectedIndexByUser(select->listToOptionIndex(listIndex), true, fireOnChange);
}
+#if ENABLE(NO_LISTBOX_RENDERING)
+void RenderMenuList::listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow)
+{
+ SelectElement* select = toSelectElement(static_cast<Element*>(node()));
+ select->listBoxSelectItem(select->listToOptionIndex(listIndex), allowMultiplySelections, shift, fireOnChangeNow);
+}
+
+bool RenderMenuList::multiple()
+{
+ SelectElement* select = toSelectElement(static_cast<Element*>(node()));
+ return select->multiple();
+}
+#endif
+
+void RenderMenuList::didSetSelectedIndex()
+{
+ int index = selectedIndex();
+ if (m_lastSelectedIndex == index)
+ return;
+
+ m_lastSelectedIndex = index;
+
+ if (AXObjectCache::accessibilityEnabled())
+ document()->axObjectCache()->postNotification(this, AXObjectCache::AXMenuListValueChanged, true, PostSynchronously);
+}
+
String RenderMenuList::itemText(unsigned listIndex) const
{
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
- Element* element = select->listItems()[listIndex];
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size())
+ return String();
+ Element* element = listItems[listIndex];
if (OptionGroupElement* optionGroupElement = toOptionGroupElement(element))
return optionGroupElement->groupLabelText();
else if (OptionElement* optionElement = toOptionElement(element))
@@ -317,17 +350,34 @@ String RenderMenuList::itemText(unsigned listIndex) const
return String();
}
+String RenderMenuList::itemAccessibilityText(unsigned listIndex) const
+{
+ // Allow the accessible name be changed if necessary.
+ SelectElement* select = toSelectElement(static_cast<Element*>(node()));
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size())
+ return String();
+
+ return AccessibilityObject::getAttribute(listItems[listIndex], aria_labelAttr);
+}
+
String RenderMenuList::itemToolTip(unsigned listIndex) const
{
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
- Element* element = select->listItems()[listIndex];
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size())
+ return String();
+ Element* element = listItems[listIndex];
return element->title();
}
bool RenderMenuList::itemIsEnabled(unsigned listIndex) const
{
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
- Element* element = select->listItems()[listIndex];
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size())
+ return false;
+ Element* element = listItems[listIndex];
if (!isOptionElement(element))
return false;
@@ -345,7 +395,18 @@ bool RenderMenuList::itemIsEnabled(unsigned listIndex) const
PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
{
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
- Element* element = select->listItems()[listIndex];
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size()) {
+ // If we are making an out of bounds access, then we want to use the style
+ // of a different option element (index 0). However, if there isn't an option element
+ // before at index 0, we fall back to the menu's style.
+ if (!listIndex)
+ return menuStyle();
+
+ // Try to retrieve the style of an option element we know exists (index 0).
+ listIndex = 0;
+ }
+ Element* element = listItems[listIndex];
RenderStyle* style = element->renderStyle() ? element->renderStyle() : element->computedStyle();
return style ? PopupMenuStyle(style->color(), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->textIndent(), style->direction()) : menuStyle();
@@ -354,7 +415,10 @@ PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
{
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
- Element* element = select->listItems()[listIndex];
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size())
+ return style()->backgroundColor();
+ Element* element = listItems[listIndex];
Color backgroundColor;
if (element->renderStyle())
@@ -374,7 +438,6 @@ Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
PopupMenuStyle RenderMenuList::menuStyle() const
{
-
RenderStyle* s = m_innerBlock ? m_innerBlock->style() : style();
return PopupMenuStyle(s->color(), s->backgroundColor(), s->font(), s->visibility() == VISIBLE, s->textIndent(), s->direction());
}
@@ -410,8 +473,19 @@ int RenderMenuList::clientPaddingLeft() const
return paddingLeft();
}
+const int endOfLinePadding = 2;
int RenderMenuList::clientPaddingRight() const
{
+ if (style()->appearance() == MenulistPart || style()->appearance() == MenulistButtonPart) {
+ // For these appearance values, the theme applies padding to leave room for the
+ // drop-down button. But leaving room for the button inside the popup menu itself
+ // looks strange, so we return a small default padding to avoid having a large empty
+ // space appear on the side of the popup menu.
+ return endOfLinePadding;
+ }
+
+ // If the appearance isn't MenulistPart, then the select is styled (non-native), so
+ // we want to return the user specified padding.
return paddingRight();
}
@@ -435,21 +509,30 @@ void RenderMenuList::popupDidHide()
bool RenderMenuList::itemIsSeparator(unsigned listIndex) const
{
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
- Element* element = select->listItems()[listIndex];
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size())
+ return false;
+ Element* element = listItems[listIndex];
return element->hasTagName(hrTag);
}
bool RenderMenuList::itemIsLabel(unsigned listIndex) const
{
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
- Element* element = select->listItems()[listIndex];
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size())
+ return false;
+ Element* element = listItems[listIndex];
return isOptionGroupElement(element);
}
bool RenderMenuList::itemIsSelected(unsigned listIndex) const
{
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
- Element* element = select->listItems()[listIndex];
+ const Vector<Element*>& listItems = select->listItems();
+ if (listIndex >= listItems.size())
+ return false;
+ Element* element = listItems[listIndex];
if (OptionElement* optionElement = toOptionElement(element))
return optionElement->selected();
return false;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.h b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.h
index 2d617c115d..aeb62058b6 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderMenuList.h
@@ -1,7 +1,8 @@
/*
* This file is part of the select element renderer in WebCore.
*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -37,7 +38,12 @@ namespace WebCore {
class PopupMenu;
class RenderText;
+#if ENABLE(NO_LISTBOX_RENDERING)
+class RenderMenuList : public RenderFlexibleBox, private ListPopupMenuClient {
+#else
class RenderMenuList : public RenderFlexibleBox, private PopupMenuClient {
+#endif
+
public:
RenderMenuList(Element*);
virtual ~RenderMenuList();
@@ -49,6 +55,8 @@ public:
void setOptionsChanged(bool changed) { m_optionsChanged = changed; }
+ void didSetSelectedIndex();
+
String text() const;
private:
@@ -73,6 +81,7 @@ private:
// PopupMenuClient methods
virtual String itemText(unsigned listIndex) const;
virtual String itemToolTip(unsigned listIndex) const;
+ virtual String itemAccessibilityText(unsigned listIndex) const;
virtual bool itemIsEnabled(unsigned listIndex) const;
virtual PopupMenuStyle itemStyle(unsigned listIndex) const;
virtual PopupMenuStyle menuStyle() const;
@@ -94,6 +103,11 @@ private:
virtual HostWindow* hostWindow() const;
virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize);
+#if ENABLE(NO_LISTBOX_RENDERING)
+ virtual void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
+ virtual bool multiple();
+#endif
+
virtual bool hasLineIfEmpty() const { return true; }
Color itemBackgroundColor(unsigned listIndex) const;
@@ -110,6 +124,8 @@ private:
bool m_optionsChanged;
int m_optionsWidth;
+ int m_lastSelectedIndex;
+
RefPtr<PopupMenu> m_popup;
bool m_popupIsVisible;
};
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp
index 199de4a224..8212dcad32 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp
@@ -4,6 +4,7 @@
* (C) 2000 Dirk Mueller (mueller@kde.org)
* (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -27,6 +28,7 @@
#include "RenderObject.h"
#include "AXObjectCache.h"
+#include "Chrome.h"
#include "CSSStyleSelector.h"
#include "FloatQuad.h"
#include "Frame.h"
@@ -41,6 +43,8 @@
#include "RenderImageGeneratedContent.h"
#include "RenderInline.h"
#include "RenderListItem.h"
+#include "RenderRuby.h"
+#include "RenderRubyText.h"
#include "RenderTableCell.h"
#include "RenderTableCol.h"
#include "RenderTableRow.h"
@@ -61,6 +65,11 @@
#include "WMLNames.h"
#endif
+#if ENABLE(SVG)
+#include "RenderSVGResource.h"
+#include "SVGRenderSupport.h"
+#endif
+
using namespace std;
namespace WebCore {
@@ -103,46 +112,44 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
return image;
}
- RenderObject* o = 0;
+#if ENABLE(RUBY)
+ if (node->hasTagName(rubyTag)) {
+ if (style->display() == INLINE)
+ return new (arena) RenderRubyAsInline(node);
+ else
+ return new (arena) RenderRubyAsBlock(node);
+ }
+ // treat <rt> as ruby text ONLY if it still has its default treatment of block
+ if (node->hasTagName(rtTag) && style->display() == BLOCK)
+ return new (arena) RenderRubyText(node);
+#endif
switch (style->display()) {
case NONE:
- break;
+ return 0;
case INLINE:
- o = new (arena) RenderInline(node);
- break;
+ return new (arena) RenderInline(node);
case BLOCK:
- o = new (arena) RenderBlock(node);
- break;
case INLINE_BLOCK:
- o = new (arena) RenderBlock(node);
- break;
- case LIST_ITEM:
- o = new (arena) RenderListItem(node);
- break;
case RUN_IN:
case COMPACT:
- o = new (arena) RenderBlock(node);
- break;
+ return new (arena) RenderBlock(node);
+ case LIST_ITEM:
+ return new (arena) RenderListItem(node);
case TABLE:
case INLINE_TABLE:
- o = new (arena) RenderTable(node);
- break;
+ return new (arena) RenderTable(node);
case TABLE_ROW_GROUP:
case TABLE_HEADER_GROUP:
case TABLE_FOOTER_GROUP:
- o = new (arena) RenderTableSection(node);
- break;
+ return new (arena) RenderTableSection(node);
case TABLE_ROW:
- o = new (arena) RenderTableRow(node);
- break;
+ return new (arena) RenderTableRow(node);
case TABLE_COLUMN_GROUP:
case TABLE_COLUMN:
- o = new (arena) RenderTableCol(node);
- break;
+ return new (arena) RenderTableCol(node);
case TABLE_CELL:
- o = new (arena) RenderTableCell(node);
- break;
+ return new (arena) RenderTableCell(node);
case TABLE_CAPTION:
#if ENABLE(WCSS)
// As per the section 17.1 of the spec WAP-239-WCSS-20011026-a.pdf,
@@ -150,15 +157,13 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
// principal block box ([CSS2] section 9.2.1).
case WAP_MARQUEE:
#endif
- o = new (arena) RenderBlock(node);
- break;
+ return new (arena) RenderBlock(node);
case BOX:
case INLINE_BOX:
- o = new (arena) RenderFlexibleBox(node);
- break;
+ return new (arena) RenderFlexibleBox(node);
}
- return o;
+ return 0;
}
#ifndef NDEBUG
@@ -307,7 +312,7 @@ void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
// Just add it...
children->insertChildNode(this, newChild, beforeChild);
}
-
+ RenderCounter::rendererSubtreeAttached(newChild);
if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) {
RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalText();
if (textToTransform)
@@ -366,19 +371,14 @@ RenderObject* RenderObject::nextInPreOrderAfterChildren(RenderObject* stayWithin
if (this == stayWithin)
return 0;
- RenderObject* o;
- if (!(o = nextSibling())) {
- o = parent();
- while (o && !o->nextSibling()) {
- if (o == stayWithin)
- return 0;
- o = o->parent();
- }
- if (o)
- o = o->nextSibling();
+ const RenderObject* current = this;
+ RenderObject* next;
+ while (!(next = current->nextSibling())) {
+ current = current->parent();
+ if (!current || current == stayWithin)
+ return 0;
}
-
- return o;
+ return next;
}
RenderObject* RenderObject::previousInPreOrder() const
@@ -643,7 +643,7 @@ RenderBlock* RenderObject::containingBlock() const
}
if (!o || !o->isRenderBlock())
- return 0; // Probably doesn't happen any more, but leave just in case. -dwh
+ return 0; // This can still happen in case of an orphaned tree
return toRenderBlock(o);
}
@@ -719,7 +719,7 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
return;
case DOTTED:
case DASHED:
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeThickness(width);
graphicsContext->setStrokeStyle(style == DASHED ? DashedStroke : DottedStroke);
@@ -740,7 +740,7 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
if (adjbw1 == 0 && adjbw2 == 0) {
graphicsContext->setStrokeStyle(NoStroke);
- graphicsContext->setFillColor(c);
+ graphicsContext->setFillColor(c, m_style->colorSpace());
switch (s) {
case BSTop:
case BSBottom:
@@ -853,7 +853,7 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
// fall through
case SOLID: {
graphicsContext->setStrokeStyle(NoStroke);
- graphicsContext->setFillColor(c);
+ graphicsContext->setFillColor(c, m_style->colorSpace());
ASSERT(x2 >= x1);
ASSERT(y2 >= y1);
if (!adjbw1 && !adjbw2) {
@@ -913,7 +913,7 @@ void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, in
return;
case DOTTED:
case DASHED:
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeStyle(style == DOTTED ? DottedStroke : DashedStroke);
graphicsContext->setStrokeThickness(thickness);
graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
@@ -935,7 +935,7 @@ void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, in
}
graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeThickness(third);
graphicsContext->strokeArc(IntRect(x, outerY, radius.width() * 2, outerHeight), angleStart, angleSpan);
graphicsContext->setStrokeThickness(innerThird > 2 ? innerThird - 1 : innerThird);
@@ -954,13 +954,13 @@ void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, in
}
graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeThickness(thickness);
graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
float halfThickness = (thickness + 1.0f) / 4.0f;
int shiftForInner = static_cast<int>(halfThickness * 1.5f);
- graphicsContext->setStrokeColor(c2);
+ graphicsContext->setStrokeColor(c2, m_style->colorSpace());
graphicsContext->setStrokeThickness(halfThickness > 2 ? halfThickness - 1 : halfThickness);
graphicsContext->strokeArc(IntRect(x + shiftForInner, y + shiftForInner, (radius.width() - shiftForInner) * 2,
(radius.height() - shiftForInner) * 2), angleStart, angleSpan);
@@ -974,7 +974,7 @@ void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, in
c = c.dark();
case SOLID:
graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeColor(c, m_style->colorSpace());
graphicsContext->setStrokeThickness(thickness);
graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
break;
@@ -1011,13 +1011,12 @@ void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
if (style->outlineStyleIsAuto() || hasOutlineAnnotation()) {
if (!theme()->supportsFocusRing(style)) {
// Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
- graphicsContext->initFocusRing(ow, offset);
- addFocusRingRects(graphicsContext, tx, ty);
+ Vector<IntRect> focusRingRects;
+ addFocusRingRects(focusRingRects, tx, ty);
if (style->outlineStyleIsAuto())
- graphicsContext->drawFocusRing(oc);
+ graphicsContext->drawFocusRing(focusRingRects, ow, offset, oc);
else
- addPDFURLRect(graphicsContext, graphicsContext->focusRingBoundingRect());
- graphicsContext->clearFocusRing();
+ addPDFURLRect(graphicsContext, unionRect(focusRingRects));
}
}
@@ -1075,6 +1074,23 @@ IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms)
return result;
}
+void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
+{
+ Vector<IntRect> rects;
+ // FIXME: addFocusRingRects() needs to be passed this transform-unaware
+ // localToAbsolute() offset here because RenderInline::addFocusRingRects()
+ // implicitly assumes that. This doesn't work correctly with transformed
+ // descendants.
+ FloatPoint absolutePoint = localToAbsolute();
+ addFocusRingRects(rects, absolutePoint.x(), absolutePoint.y());
+ size_t count = rects.size();
+ for (size_t i = 0; i < count; ++i) {
+ IntRect rect = rects[i];
+ rect.move(-absolutePoint.x(), -absolutePoint.y());
+ quads.append(localToAbsoluteQuad(FloatQuad(rect)));
+ }
+}
+
void RenderObject::addAbsoluteRectForLayer(IntRect& result)
{
if (hasLayer())
@@ -1163,13 +1179,14 @@ void RenderObject::repaintRectangle(const IntRect& r, bool immediate)
repaintUsingContainer(repaintContainer ? repaintContainer : view, dirtyRect, immediate);
}
-bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox)
+bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox, const IntRect* newBoundsPtr, const IntRect* newOutlineBoxRectPtr)
{
RenderView* v = view();
if (v->printing())
return false; // Don't repaint if we're printing.
- IntRect newBounds = clippedOverflowRectForRepaint(repaintContainer);
+ ASSERT(!newBoundsPtr || *newBoundsPtr == clippedOverflowRectForRepaint(repaintContainer));
+ IntRect newBounds = newBoundsPtr ? *newBoundsPtr : clippedOverflowRectForRepaint(repaintContainer);
IntRect newOutlineBox;
bool fullRepaint = selfNeedsLayout();
@@ -1177,7 +1194,8 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta
if (!fullRepaint && style()->borderFit() == BorderFitLines)
fullRepaint = true;
if (!fullRepaint) {
- newOutlineBox = outlineBoundsForRepaint(repaintContainer);
+ ASSERT(!newOutlineBoxRectPtr || *newOutlineBoxRectPtr == outlineBoundsForRepaint(repaintContainer));
+ newOutlineBox = newOutlineBoxRectPtr ? *newOutlineBoxRectPtr : outlineBoundsForRepaint(repaintContainer);
if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox)))
fullRepaint = true;
}
@@ -1312,11 +1330,10 @@ void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer,
// anyway if its size does change.
RenderBox* boxParent = toRenderBox(o);
+ IntRect repaintRect(rect);
+ repaintRect.move(-boxParent->layer()->scrolledContentOffset()); // For overflow:auto/scroll/hidden.
+
IntRect boxRect(0, 0, boxParent->layer()->width(), boxParent->layer()->height());
- int x = rect.x();
- int y = rect.y();
- boxParent->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.
- IntRect repaintRect(x, y, rect.width(), rect.height());
rect = intersection(repaintRect, boxRect);
if (rect.isEmpty())
return;
@@ -1338,6 +1355,50 @@ void RenderObject::showTreeForThis() const
node()->showTreeForThis();
}
+void RenderObject::showRenderObject() const
+{
+ showRenderObject(0);
+}
+
+void RenderObject::showRenderObject(int printedCharacters) const
+{
+ // As this function is intended to be used when debugging, the
+ // this pointer may be 0.
+ if (!this) {
+ fputs("(null)\n", stderr);
+ return;
+ }
+
+ printedCharacters += fprintf(stderr, "%s %p", renderName(), this);
+
+ if (node()) {
+ if (printedCharacters)
+ for (; printedCharacters < 39; printedCharacters++)
+ fputc(' ', stderr);
+ fputc('\t', stderr);
+ node()->showNode();
+ } else
+ fputc('\n', stderr);
+}
+
+void RenderObject::showRenderTreeAndMark(const RenderObject* markedObject1, const char* markedLabel1, const RenderObject* markedObject2, const char* markedLabel2, int depth) const
+{
+ int printedCharacters = 0;
+ if (markedObject1 == this && markedLabel1)
+ printedCharacters += fprintf(stderr, "%s", markedLabel1);
+ if (markedObject2 == this && markedLabel2)
+ printedCharacters += fprintf(stderr, "%s", markedLabel2);
+ for (; printedCharacters < depth * 2; printedCharacters++)
+ fputc(' ', stderr);
+
+ showRenderObject(printedCharacters);
+ if (!this)
+ return;
+
+ for (const RenderObject* child = firstChild(); child; child = child->nextSibling())
+ child->showRenderTreeAndMark(markedObject1, markedLabel1, markedObject2, markedLabel2, depth + 1);
+}
+
#endif // NDEBUG
Color RenderObject::selectionBackgroundColor() const
@@ -1611,7 +1672,7 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
}
}
-void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle*)
+void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
if (s_affectsParentBlock)
handleDynamicFloatPositionChange();
@@ -1619,9 +1680,19 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle*)
if (!m_parent)
return;
- if (diff == StyleDifferenceLayout)
+ if (diff == StyleDifferenceLayout) {
+ RenderCounter::rendererStyleChanged(this, oldStyle, m_style.get());
+
+ // If the object already needs layout, then setNeedsLayout won't do
+ // any work. But if the containing block has changed, then we may need
+ // to mark the new containing blocks for layout. The change that can
+ // directly affect the containing block of this object is a change to
+ // the position style.
+ if (m_needsLayout && oldStyle->position() != m_style->position())
+ markContainingBlocksForLayout();
+
setNeedsLayoutAndPrefWidthsRecalc();
- else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
+ } else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
setNeedsPositionedMovementLayout();
// Don't check for repaint here; we need to wait until the layer has been
@@ -1688,6 +1759,11 @@ void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b
if (!o)
return;
+ IntSize columnOffset;
+ o->adjustForColumns(columnOffset, roundedIntPoint(transformState.mappedPoint()));
+ if (!columnOffset.isZero())
+ transformState.move(columnOffset);
+
if (o->hasOverflowClip())
transformState.move(-toRenderBox(o)->layer()->scrolledContentOffset());
@@ -1744,18 +1820,23 @@ void RenderObject::getTransformFromContainer(const RenderObject* containerObject
FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBoxModelObject* repaintContainer, bool fixed) const
{
- TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint(), &localQuad);
+ // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
+ // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
+ TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), &localQuad);
mapLocalToContainer(repaintContainer, fixed, true, transformState);
transformState.flatten();
return transformState.lastPlanarQuad();
}
-IntSize RenderObject::offsetFromContainer(RenderObject* o) const
+IntSize RenderObject::offsetFromContainer(RenderObject* o, const IntPoint& point) const
{
ASSERT(o == container());
IntSize offset;
+
+ o->adjustForColumns(offset, point);
+
if (o->hasOverflowClip())
offset -= toRenderBox(o)->layer()->scrolledContentOffset();
@@ -1765,6 +1846,7 @@ IntSize RenderObject::offsetFromContainer(RenderObject* o) const
IntSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
{
IntSize offset;
+ IntPoint referencePoint;
const RenderObject* currContainer = this;
do {
RenderObject* nextContainer = currContainer->container();
@@ -1772,7 +1854,9 @@ IntSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
if (!nextContainer)
break;
ASSERT(!currContainer->hasTransform());
- offset += currContainer->offsetFromContainer(nextContainer);
+ IntSize currentOffset = currContainer->offsetFromContainer(nextContainer, referencePoint);
+ offset += currentOffset;
+ referencePoint.move(currentOffset);
currContainer = nextContainer;
} while (currContainer != container);
@@ -1875,7 +1959,7 @@ void RenderObject::destroy()
// If this renderer is being autoscrolled, stop the autoscroll timer
- // FIXME: RenderObject::destroy should not get called with a renderar whose document
+ // FIXME: RenderObject::destroy should not get called with a renderer whose document
// has a null frame, so we assert this. However, we don't want release builds to crash which is why we
// check that the frame is not null.
ASSERT(document()->frame());
@@ -2376,9 +2460,20 @@ RenderBoxModelObject* RenderObject::offsetParent() const
VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity)
{
- // If this is a non-anonymous renderer, then it's simple.
- if (Node* node = this->node())
+ // If this is a non-anonymous renderer in an editable area, then it's simple.
+ if (Node* node = this->node()) {
+ if (!node->isContentEditable()) {
+ // If it can be found, we prefer a visually equivalent position that is editable.
+ Position position(node, offset);
+ Position candidate = position.downstream(Position::CanCrossEditingBoundary);
+ if (candidate.node()->isContentEditable())
+ return VisiblePosition(candidate, affinity);
+ candidate = position.upstream(Position::CanCrossEditingBoundary);
+ if (candidate.node()->isContentEditable())
+ return VisiblePosition(candidate, affinity);
+ }
return VisiblePosition(node, offset, affinity);
+ }
// We don't want to cross the boundary between editable and non-editable
// regions of the document, but that is either impossible or at least
@@ -2426,6 +2521,17 @@ VisiblePosition RenderObject::createVisiblePosition(const Position& position)
}
#if ENABLE(SVG)
+const SVGRenderBase* RenderObject::toSVGRenderBase() const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+RenderSVGResource* RenderObject::toRenderSVGResource()
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
FloatRect RenderObject::objectBoundingBox() const
{
@@ -2441,25 +2547,16 @@ FloatRect RenderObject::repaintRectInLocalCoordinates() const
return FloatRect();
}
-TransformationMatrix RenderObject::localTransform() const
+AffineTransform RenderObject::localTransform() const
{
- return TransformationMatrix();
+ static const AffineTransform identity;
+ return identity;
}
-TransformationMatrix RenderObject::localToParentTransform() const
+const AffineTransform& RenderObject::localToParentTransform() const
{
- // FIXME: This double virtual call indirection is temporary until I can land the
- // rest of the of the localToParentTransform() support for SVG.
- return localTransform();
-}
-
-TransformationMatrix RenderObject::absoluteTransform() const
-{
- // FIXME: This should use localToParentTransform(), but much of the SVG code
- // depends on RenderBox::absoluteTransform() being the sum of the localTransform()s of all parent renderers.
- if (parent())
- return localTransform() * parent()->absoluteTransform();
- return localTransform();
+ static const AffineTransform identity;
+ return identity;
}
bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
@@ -2480,4 +2577,19 @@ void showTree(const WebCore::RenderObject* ro)
ro->showTreeForThis();
}
+void showRenderTree(const WebCore::RenderObject* object1)
+{
+ showRenderTree(object1, 0);
+}
+
+void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2)
+{
+ if (object1) {
+ const WebCore::RenderObject* root = object1;
+ while (root->parent())
+ root = root->parent();
+ root->showRenderTreeAndMark(object1, "*", object2, "-", 0);
+ }
+}
+
#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderObject.h
index e358c981ac..d928521d54 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderObject.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderObject.h
@@ -4,6 +4,7 @@
* (C) 2000 Dirk Mueller (mueller@kde.org)
* (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,6 +26,7 @@
#ifndef RenderObject_h
#define RenderObject_h
+#include "AffineTransform.h"
#include "CachedResourceClient.h"
#include "Document.h"
#include "Element.h"
@@ -51,6 +53,10 @@ class RenderLayer;
class RenderTheme;
class TransformState;
class VisiblePosition;
+#if ENABLE(SVG)
+class RenderSVGResource;
+class SVGRenderBase;
+#endif
/*
* The painting of a layer occurs in three distinct phases. Each phase involves
@@ -76,11 +82,13 @@ enum PaintPhase {
PaintPhaseMask
};
-enum PaintRestriction {
- PaintRestrictionNone,
- PaintRestrictionSelectionOnly,
- PaintRestrictionSelectionOnlyBlackText
+enum PaintBehaviorFlags {
+ PaintBehaviorNormal = 0,
+ PaintBehaviorSelectionOnly = 1 << 0,
+ PaintBehaviorForceBlackText = 1 << 1,
+ PaintBehaviorFlattenCompositingLayers = 1 << 2
};
+typedef unsigned PaintBehavior;
enum HitTestFilter {
HitTestAll,
@@ -228,6 +236,12 @@ private:
public:
#ifndef NDEBUG
void showTreeForThis() const;
+
+ void showRenderObject() const;
+ // We don't make printedCharacters an optional parameter so that
+ // showRenderObject can be called from gdb easily.
+ void showRenderObject(int printedCharacters) const;
+ void showRenderTreeAndMark(const RenderObject* markedObject1 = 0, const char* markedLabel1 = 0, const RenderObject* markedObject2 = 0, const char* markedLabel2 = 0, int depth = 0) const;
#endif
static RenderObject* createObject(Node*, RenderStyle*);
@@ -251,7 +265,9 @@ public:
virtual bool isBlockFlow() const { return false; }
virtual bool isBoxModelObject() const { return false; }
virtual bool isCounter() const { return false; }
+ virtual bool isEmbeddedObject() const { return false; }
virtual bool isFieldset() const { return false; }
+ virtual bool isFileUploadControl() const { return false; }
virtual bool isFrame() const { return false; }
virtual bool isFrameSet() const { return false; }
virtual bool isImage() const { return false; }
@@ -261,12 +277,22 @@ public:
virtual bool isListMarker() const { return false; }
virtual bool isMedia() const { return false; }
virtual bool isMenuList() const { return false; }
+#if ENABLE(PROGRESS_TAG)
+ virtual bool isProgress() const { return false; }
+#endif
virtual bool isRenderBlock() const { return false; }
virtual bool isRenderButton() const { return false; }
virtual bool isRenderImage() const { return false; }
virtual bool isRenderInline() const { return false; }
virtual bool isRenderPart() const { return false; }
virtual bool isRenderView() const { return false; }
+ virtual bool isReplica() const { return false; }
+#if ENABLE(RUBY)
+ virtual bool isRuby() const { return false; }
+ virtual bool isRubyBase() const { return false; }
+ virtual bool isRubyRun() const { return false; }
+ virtual bool isRubyText() const { return false; }
+#endif
virtual bool isSlider() const { return false; }
virtual bool isTable() const { return false; }
virtual bool isTableCell() const { return false; }
@@ -296,6 +322,10 @@ public:
bool cellWidthChanged() const { return m_cellWidthChanged; }
void setCellWidthChanged(bool b = true) { m_cellWidthChanged = b; }
+#if ENABLE(MATHML)
+ virtual bool isRenderMathMLBlock() const { return false; }
+#endif // ENABLE(MATHML)
+
#if ENABLE(SVG)
// FIXME: Until all SVG renders can be subclasses of RenderSVGModelObject we have
// to add SVG renderer methods to RenderObject with an ASSERT_NOT_REACHED() default implementation.
@@ -306,6 +336,10 @@ public:
virtual bool isSVGText() const { return false; }
virtual bool isSVGImage() const { return false; }
virtual bool isSVGForeignObject() const { return false; }
+ virtual bool isSVGResource() const { return false; }
+
+ virtual const SVGRenderBase* toSVGRenderBase() const;
+ virtual RenderSVGResource* toRenderSVGResource();
// Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects, opacity and stroke-width.
// This is used for all computation of objectBoundingBox relative units and by SVGLocateable::getBBox().
@@ -322,16 +356,11 @@ public:
// FIXME: This accessor is deprecated and mostly around for SVGRenderTreeAsText.
// This only returns the transform="" value from the element
// most callsites want localToParentTransform() instead.
- virtual TransformationMatrix localTransform() const;
+ virtual AffineTransform localTransform() const;
// Returns the full transform mapping from local coordinates to local coords for the parent SVG renderer
// This includes any viewport transforms and x/y offsets as well as the transform="" value off the element.
- virtual TransformationMatrix localToParentTransform() const;
-
- // Walks up the parent chain to create a transform which maps from local to document coords
- // NOTE: This method is deprecated! It doesn't respect scroll offsets or repaint containers.
- // FIXME: This is only virtual so that RenderSVGHiddenContainer can override it to match old LayoutTest results.
- virtual TransformationMatrix absoluteTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
// SVG uses FloatPoint precise hit testing, and passes the point in parent
// coordinates instead of in repaint container coordinates. Eventually the
@@ -486,10 +515,6 @@ public:
/* This function performs a layout only if one is needed. */
void layoutIfNeeded() { if (needsLayout()) layout(); }
-
- // Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted
- // that just updates the object's position. If the size does change, the object remains dirty.
- virtual void tryLayoutDoingPositionedMovementOnly() { }
// used for element state updates that cannot be fixed with a
// repaint and do not need a relayout
@@ -539,8 +564,9 @@ public:
// Convert a local quad into the coordinate system of container, taking transforms into account.
FloatQuad localToContainerQuad(const FloatQuad&, RenderBoxModelObject* repaintContainer, bool fixed = false) const;
- // Return the offset from the container() renderer (excluding transforms)
- virtual IntSize offsetFromContainer(RenderObject*) const;
+ // Return the offset from the container() renderer (excluding transforms). In multi-column layout,
+ // different offsets apply at different points, so return the offset that applies to the given point.
+ virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
// Return the offset from an object up the container() chain. Asserts that none of the intermediate objects have transforms.
IntSize offsetFromAncestorContainer(RenderObject*) const;
@@ -551,6 +577,8 @@ public:
// Build an array of quads in absolute coords for line boxes
virtual void absoluteQuads(Vector<FloatQuad>&) { }
+ void absoluteFocusRingQuads(Vector<FloatQuad>&);
+
// the rect that will be painted if this object is passed as the paintingRoot
IntRect paintingRootRect(IntRect& topLevelRect);
@@ -587,8 +615,8 @@ public:
// Repaint a specific subrectangle within a given object. The rect |r| is in the object's coordinate space.
void repaintRectangle(const IntRect&, bool immediate = false);
- // Repaint only if our old bounds and new bounds are different.
- bool repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox);
+ // Repaint only if our old bounds and new bounds are different. The caller may pass in newBounds and newOutlineBox if they are known.
+ bool repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox, const IntRect* newBoundsPtr = 0, const IntRect* newOutlineBoxPtr = 0);
// Repaint only if the object moved.
virtual void repaintDuringLayoutIfMoved(const IntRect& rect);
@@ -617,6 +645,10 @@ public:
// that rect in the coordinate space of repaintContainer.
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
+ // If multiple-column layout results in applying an offset to the given point, add the same
+ // offset to the given size.
+ virtual void adjustForColumns(IntSize&, const IntPoint&) const { }
+
virtual unsigned int length() const { return 1; }
bool isFloatingOrPositioned() const { return (isFloating() || isPositioned()); }
@@ -736,7 +768,7 @@ public:
bool shouldUseTransformFromContainer(const RenderObject* container) const;
void getTransformFromContainer(const RenderObject* container, const IntSize& offsetInContainer, TransformationMatrix&) const;
- virtual void addFocusRingRects(GraphicsContext*, int /*tx*/, int /*ty*/) { };
+ virtual void addFocusRingRects(Vector<IntRect>&, int /*tx*/, int /*ty*/) { };
IntRect absoluteOutlineBounds() const
{
@@ -1028,6 +1060,10 @@ inline void adjustFloatQuadForAbsoluteZoom(FloatQuad& quad, RenderObject* render
#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
void showTree(const WebCore::RenderObject*);
+void showRenderTree(const WebCore::RenderObject* object1);
+// We don't make object2 an optional parameter so that showRenderTree
+// can be called from gdb easily.
+void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2);
#endif
#endif // RenderObject_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.cpp
index 23ab98f277..d56a015f76 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.cpp
@@ -271,24 +271,29 @@ static RenderObject* findBeforeAfterParent(RenderObject* object)
return beforeAfterParent;
}
-static void invalidateCountersInContainer(RenderObject* container)
+static void invalidateCountersInContainer(RenderObject* container, const AtomicString& identifier)
{
if (!container)
return;
container = findBeforeAfterParent(container);
if (!container)
return;
+ // Sometimes the counter is attached directly on the container.
+ if (container->isCounter()) {
+ toRenderCounter(container)->invalidate(identifier);
+ return;
+ }
for (RenderObject* content = container->firstChild(); content; content = content->nextSibling()) {
if (content->isCounter())
- toRenderCounter(content)->invalidate();
+ toRenderCounter(content)->invalidate(identifier);
}
}
-void RenderObjectChildList::invalidateCounters(RenderObject* owner)
+void RenderObjectChildList::invalidateCounters(RenderObject* owner, const AtomicString& identifier)
{
ASSERT(!owner->documentBeingDestroyed());
- invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE));
- invalidateCountersInContainer(beforeAfterContainer(owner, AFTER));
+ invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE), identifier);
+ invalidateCountersInContainer(beforeAfterContainer(owner, AFTER), identifier);
}
void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject)
@@ -369,9 +374,11 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
RefPtr<RenderStyle> style = RenderStyle::create();
style->inheritFrom(pseudoElementStyle);
genChild->setStyle(style.release());
- } else
- // Must be a first-letter container. updateFirstLetter() will take care of it.
- ASSERT(genChild->style()->styleType() == FIRST_LETTER);
+ } else {
+ // RenderListItem may insert a list marker here. We do not need to care about this case.
+ // Otherwise, genChild must be a first-letter container. updateFirstLetter() will take care of it.
+ ASSERT(genChild->isListMarker() || genChild->style()->styleType() == FIRST_LETTER);
+ }
}
}
return; // We've updated the generated content. That's all we needed to do.
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.h b/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.h
index bf8800a2d8..ba73c50cb4 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderObjectChildList.h
@@ -30,6 +30,7 @@
namespace WebCore {
+class AtomicString;
class RenderObject;
class RenderObjectChildList {
@@ -55,7 +56,7 @@ public:
void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool fullInsert = true);
void updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject = 0);
- void invalidateCounters(RenderObject* owner);
+ void invalidateCounters(RenderObject* owner, const AtomicString& identifier);
private:
RenderObject* m_firstChild;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderOverflow.h b/src/3rdparty/webkit/WebCore/rendering/RenderOverflow.h
index ed8976a5b7..253a672231 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderOverflow.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderOverflow.h
@@ -37,7 +37,7 @@ namespace WebCore
// Examples of visual overflow are shadows, text stroke (and eventually outline and border-image).
// This object is allocated only when some of these fields have non-default values in the owning box.
-class RenderOverflow {
+class RenderOverflow : public Noncopyable {
public:
RenderOverflow(const IntRect& defaultRect = IntRect())
: m_topLayoutOverflow(defaultRect.y())
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPart.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderPart.cpp
index cb56c0c310..74b467f238 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderPart.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderPart.cpp
@@ -24,13 +24,16 @@
#include "config.h"
#include "RenderPart.h"
+#include "RenderView.h"
#include "Frame.h"
#include "FrameView.h"
+#include "HTMLFrameElementBase.h"
namespace WebCore {
RenderPart::RenderPart(Element* node)
: RenderWidget(node)
+ , m_hasFallbackContent(false)
{
// init RenderObject attributes
setInline(false);
@@ -53,6 +56,60 @@ void RenderPart::setWidget(PassRefPtr<Widget> widget)
viewCleared();
}
+void RenderPart::layoutWithFlattening(bool fixedWidth, bool fixedHeight)
+{
+ FrameView* childFrameView = static_cast<FrameView*>(widget());
+ RenderView* childRoot = childFrameView ? static_cast<RenderView*>(childFrameView->frame()->contentRenderer()) : 0;
+
+ // Do not expand frames which has zero width or height
+ if (!width() || !height() || !childRoot) {
+ updateWidgetPosition();
+ if (childFrameView)
+ childFrameView->layout();
+ setNeedsLayout(false);
+ return;
+ }
+
+ // need to update to calculate min/max correctly
+ updateWidgetPosition();
+ if (childRoot->prefWidthsDirty())
+ childRoot->calcPrefWidths();
+
+ // if scrollbars are off, and the width or height are fixed
+ // we obey them and do not expand. With frame flattening
+ // no subframe much ever become scrollable.
+
+ HTMLFrameElementBase* element = static_cast<HTMLFrameElementBase*>(node());
+ bool isScrollable = element->scrollingMode() != ScrollbarAlwaysOff;
+
+ // consider iframe inset border
+ int hBorder = borderLeft() + borderRight();
+ int vBorder = borderTop() + borderBottom();
+
+ // make sure minimum preferred width is enforced
+ if (isScrollable || !fixedWidth) {
+ setWidth(max(width(), childRoot->minPrefWidth() + hBorder));
+ // update again to pass the new width to the child frame
+ updateWidgetPosition();
+ childFrameView->layout();
+ }
+
+ // expand the frame by setting frame height = content height
+ if (isScrollable || !fixedHeight || childRoot->isFrameSet())
+ setHeight(max(height(), childFrameView->contentsHeight() + vBorder));
+ if (isScrollable || !fixedWidth || childRoot->isFrameSet())
+ setWidth(max(width(), childFrameView->contentsWidth() + hBorder));
+
+ updateWidgetPosition();
+
+ ASSERT(!childFrameView->layoutPending());
+ ASSERT(!childRoot->needsLayout());
+ ASSERT(!childRoot->firstChild() || !childRoot->firstChild()->firstChild() || !childRoot->firstChild()->firstChild()->needsLayout());
+
+ setNeedsLayout(false);
+}
+
+
void RenderPart::viewCleared()
{
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPart.h b/src/3rdparty/webkit/WebCore/rendering/RenderPart.h
index 08abf99049..ef4b5e1b83 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderPart.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderPart.h
@@ -27,16 +27,22 @@
namespace WebCore {
+// Renderer for frames via RenderPartObject, and plug-ins via RenderEmbeddedObject.
+
+// FIXME: This class is subclassed in RenderPartObject for iframes, which is in turn
+// subclassed in RenderEmbeddedObject for object and embed. This class itself could be removed.
class RenderPart : public RenderWidget {
public:
RenderPart(Element*);
virtual ~RenderPart();
-
+
bool hasFallbackContent() const { return m_hasFallbackContent; }
virtual void setWidget(PassRefPtr<Widget>);
virtual void viewCleared();
+ void layoutWithFlattening(bool fixedWidth, bool fixedHeight);
+
protected:
bool m_hasFallbackContent;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp
index e2c8e7d8af..c4c515ede4 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.cpp
@@ -35,6 +35,7 @@
#include "Page.h"
#include "RenderView.h"
#include "RenderWidgetProtector.h"
+#include "Settings.h"
#include "Text.h"
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
@@ -48,288 +49,72 @@ using namespace HTMLNames;
RenderPartObject::RenderPartObject(Element* element)
: RenderPart(element)
{
- // init RenderObject attributes
- setInline(true);
- m_hasFallbackContent = false;
-
- if (element->hasTagName(embedTag) || element->hasTagName(objectTag))
- view()->frameView()->setIsVisuallyNonEmpty();
}
-RenderPartObject::~RenderPartObject()
+bool RenderPartObject::flattenFrame() const
{
- if (frameView())
- frameView()->removeWidgetToUpdate(this);
-}
-
-static bool isURLAllowed(Document* doc, const String& url)
-{
- if (doc->frame()->page()->frameCount() >= 200)
+ if (!node() || !node()->hasTagName(iframeTag))
return false;
- // We allow one level of self-reference because some sites depend on that.
- // But we don't allow more than one.
- KURL completeURL = doc->completeURL(url);
- bool foundSelfReference = false;
- for (Frame* frame = doc->frame(); frame; frame = frame->tree()->parent()) {
- if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) {
- if (foundSelfReference)
- return false;
- foundSelfReference = true;
- }
- }
- return true;
-}
+ HTMLIFrameElement* frame = static_cast<HTMLIFrameElement*>(node());
+ bool isScrollable = frame->scrollingMode() != ScrollbarAlwaysOff;
-typedef HashMap<String, String, CaseFoldingHash> ClassIdToTypeMap;
+ if (!isScrollable && style()->width().isFixed()
+ && style()->height().isFixed())
+ return false;
-static ClassIdToTypeMap* createClassIdToTypeMap()
-{
- ClassIdToTypeMap* map = new ClassIdToTypeMap;
- map->add("clsid:D27CDB6E-AE6D-11CF-96B8-444553540000", "application/x-shockwave-flash");
- map->add("clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA", "audio/x-pn-realaudio-plugin");
- map->add("clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B", "video/quicktime");
- map->add("clsid:166B1BCA-3F9C-11CF-8075-444553540000", "application/x-director");
- map->add("clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6", "application/x-mplayer2");
- map->add("clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95", "application/x-mplayer2");
- return map;
+ return frame->document()->frame() && frame->document()->frame()->settings()->frameFlatteningEnabled();
}
-static String serviceTypeForClassId(const String& classId)
+void RenderPartObject::calcHeight()
{
- // Return early if classId is empty (since we won't do anything below).
- // Furthermore, if classId is null, calling get() below will crash.
- if (classId.isEmpty())
- return String();
-
- static ClassIdToTypeMap* map = createClassIdToTypeMap();
- return map->get(classId);
-}
+ RenderPart::calcHeight();
+ if (!flattenFrame())
+ return;
-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;
- }
+ HTMLIFrameElement* frame = static_cast<HTMLIFrameElement*>(node());
+ bool isScrollable = frame->scrollingMode() != ScrollbarAlwaysOff;
- if (srcIndex == -1 && dataIndex != -1) {
- paramNames->append("src");
- paramValues->append((*paramValues)[dataIndex]);
+ if (isScrollable || !style()->height().isFixed()) {
+ FrameView* view = static_cast<FrameView*>(widget());
+ int border = borderTop() + borderBottom();
+ setHeight(max(height(), view->contentsHeight() + border));
}
}
-void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins)
+void RenderPartObject::calcWidth()
{
- String url;
- String serviceType;
- Vector<String> paramNames;
- Vector<String> paramValues;
- Frame* frame = frameView()->frame();
-
- // The calls to FrameLoader::requestObject within this function can result in a plug-in being initialized.
- // This can run cause arbitrary JavaScript to run and may result in this RenderObject being detached from
- // the render tree and destroyed, causing a crash like <rdar://problem/6954546>. By extending our lifetime
- // artifically to ensure that we remain alive for the duration of plug-in initialization.
- RenderWidgetProtector protector(this);
-
- if (node()->hasTagName(objectTag)) {
- HTMLObjectElement* o = static_cast<HTMLObjectElement*>(node());
-
- o->setNeedWidgetUpdate(false);
- if (!o->isFinishedParsingChildren())
- return;
-
- // Check for a child EMBED tag.
- HTMLEmbedElement* embed = 0;
- for (Node* child = o->firstChild(); child; ) {
- if (child->hasTagName(embedTag)) {
- embed = static_cast<HTMLEmbedElement*>(child);
- break;
- } else if (child->hasTagName(objectTag))
- child = child->nextSibling(); // Don't descend into nested OBJECT tags
- else
- child = child->traverseNextNode(o); // Otherwise descend (EMBEDs may be inside COMMENT tags)
- }
-
- // Use the attributes from the EMBED tag instead of the OBJECT tag including WIDTH and HEIGHT.
- HTMLElement *embedOrObject;
- if (embed) {
- embedOrObject = (HTMLElement *)embed;
- url = embed->url();
- serviceType = embed->serviceType();
- } else
- embedOrObject = (HTMLElement *)o;
-
- // If there was no URL or type defined in EMBED, try the OBJECT tag.
- if (url.isEmpty())
- url = o->url();
- if (serviceType.isEmpty())
- serviceType = o->serviceType();
-
- HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
-
- // Scan the PARAM children.
- // Get the URL and type from the params if we don't already have them.
- // Get the attributes from the params if there is no EMBED tag.
- Node *child = o->firstChild();
- while (child && (url.isEmpty() || serviceType.isEmpty() || !embed)) {
- if (child->hasTagName(paramTag)) {
- HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
- String name = p->name();
- if (url.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
- url = p->value();
- if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
- serviceType = p->value();
- int pos = serviceType.find(";");
- if (pos != -1)
- serviceType = serviceType.left(pos);
- }
- if (!embed && !name.isEmpty()) {
- uniqueParamNames.add(name.impl());
- paramNames.append(p->name());
- paramValues.append(p->value());
- }
- }
- child = child->nextSibling();
- }
-
- // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
- // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
- // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
- // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
- // else our Java plugin will misinterpret it. [4004531]
- String codebase;
- if (!embed && MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
- codebase = "codebase";
- uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
- }
-
- // Turn the attributes of either the EMBED tag or OBJECT tag into arrays, but don't override PARAM values.
- NamedNodeMap* attributes = embedOrObject->attributes();
- if (attributes) {
- for (unsigned i = 0; i < attributes->length(); ++i) {
- Attribute* it = attributes->attributeItem(i);
- const AtomicString& name = it->name().localName();
- if (embed || !uniqueParamNames.contains(name.impl())) {
- paramNames.append(name.string());
- paramValues.append(it->value().string());
- }
- }
- }
+ RenderPart::calcWidth();
+ if (!flattenFrame())
+ return;
- mapDataParamToSrc(&paramNames, &paramValues);
+ HTMLIFrameElement* frame = static_cast<HTMLIFrameElement*>(node());
+ bool isScrollable = frame->scrollingMode() != ScrollbarAlwaysOff;
- // 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());
-
- if (!isURLAllowed(document(), url))
- return;
-
- // Find out if we support fallback content.
- m_hasFallbackContent = false;
- for (Node *child = o->firstChild(); child && !m_hasFallbackContent; child = child->nextSibling()) {
- if ((!child->isTextNode() && !child->hasTagName(embedTag) && !child->hasTagName(paramTag)) || // Discount <embed> and <param>
- (child->isTextNode() && !static_cast<Text*>(child)->containsOnlyWhitespace()))
- m_hasFallbackContent = true;
- }
-
- if (onlyCreateNonNetscapePlugins) {
- KURL completedURL;
- if (!url.isEmpty())
- completedURL = frame->loader()->completeURL(url);
-
- if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
- return;
- }
-
- bool success = o->dispatchBeforeLoadEvent(url) &&
- frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues);
- if (!success && m_hasFallbackContent)
- o->renderFallbackContent();
- } else if (node()->hasTagName(embedTag)) {
- HTMLEmbedElement *o = static_cast<HTMLEmbedElement*>(node());
- o->setNeedWidgetUpdate(false);
- url = o->url();
- serviceType = o->serviceType();
-
- if (url.isEmpty() && serviceType.isEmpty())
- return;
- if (!isURLAllowed(document(), url))
- return;
-
- // add all attributes set on the embed object
- NamedNodeMap* a = o->attributes();
- if (a) {
- for (unsigned i = 0; i < a->length(); ++i) {
- Attribute* it = a->attributeItem(i);
- paramNames.append(it->name().localName().string());
- paramValues.append(it->value().string());
- }
- }
-
- if (onlyCreateNonNetscapePlugins) {
- KURL completedURL;
- if (!url.isEmpty())
- completedURL = frame->loader()->completeURL(url);
-
- if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
- return;
-
- }
-
- if (o->dispatchBeforeLoadEvent(url))
- frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues);
- }
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
- else if (node()->hasTagName(videoTag) || node()->hasTagName(audioTag)) {
- HTMLMediaElement* o = static_cast<HTMLMediaElement*>(node());
-
- o->setNeedWidgetUpdate(false);
- if (node()->hasTagName(videoTag)) {
- HTMLVideoElement* vid = static_cast<HTMLVideoElement*>(node());
- String poster = vid->poster();
- if (!poster.isEmpty()) {
- paramNames.append("_media_element_poster_");
- paramValues.append(poster);
- }
- }
-
- url = o->initialURL();
- if (!url.isEmpty()) {
- paramNames.append("_media_element_src_");
- paramValues.append(url);
- }
-
- serviceType = "application/x-media-element-proxy-plugin";
-
- if (o->dispatchBeforeLoadEvent(url))
- frame->loader()->requestObject(this, url, nullAtom, serviceType, paramNames, paramValues);
+ if (isScrollable || !style()->width().isFixed()) {
+ FrameView* view = static_cast<FrameView*>(widget());
+ int border = borderLeft() + borderRight();
+ setWidth(max(width(), view->contentsWidth() + border));
}
-#endif
}
void RenderPartObject::layout()
{
ASSERT(needsLayout());
- calcWidth();
- calcHeight();
+ RenderPart::calcWidth();
+ RenderPart::calcHeight();
+
+ if (flattenFrame()) {
+ layoutWithFlattening(style()->width().isFixed(), style()->height().isFixed());
+ return;
+ }
RenderPart::layout();
m_overflow.clear();
addShadowOverflow();
- if (!widget() && frameView())
- frameView()->addWidgetToUpdate(this);
-
setNeedsLayout(false);
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.h
index ad956bd1ea..5c7277e44e 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderPartObject.h
@@ -27,12 +27,13 @@
namespace WebCore {
+// Renderer for iframes. Is subclassed in RenderEmbeddedObject for object and embed.
class RenderPartObject : public RenderPart {
public:
RenderPartObject(Element*);
- virtual ~RenderPartObject();
- void updateWidget(bool onlyCreateNonNetscapePlugins);
+ virtual void calcHeight();
+ virtual void calcWidth();
private:
virtual const char* renderName() const { return "RenderPartObject"; }
@@ -40,6 +41,8 @@ private:
virtual void layout();
virtual void viewCleared();
+
+ bool flattenFrame() const;
};
inline RenderPartObject* toRenderPartObject(RenderObject* object)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPath.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderPath.cpp
index 4a7662f23f..bcedd38088 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderPath.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderPath.cpp
@@ -3,6 +3,7 @@
2004, 2005, 2008 Rob Buis <buis@kde.org>
2005, 2007 Eric Seidel <eric@webkit.org>
2009 Google, Inc.
+ 2009 Dirk Schulze <krit@webkit.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -33,9 +34,7 @@
#include "StrokeStyleApplier.h"
#include "SVGPaintServer.h"
#include "SVGRenderSupport.h"
-#include "SVGResourceFilter.h"
#include "SVGResourceMarker.h"
-#include "SVGResourceMasker.h"
#include "SVGStyledTransformableElement.h"
#include "SVGTransformList.h"
#include "SVGURIReference.h"
@@ -68,12 +67,12 @@ RenderPath::RenderPath(SVGStyledTransformableElement* node)
{
}
-TransformationMatrix RenderPath::localToParentTransform() const
+const AffineTransform& RenderPath::localToParentTransform() const
{
return m_localTransform;
}
-TransformationMatrix RenderPath::localTransform() const
+AffineTransform RenderPath::localTransform() const
{
return m_localTransform;
}
@@ -112,6 +111,34 @@ FloatRect RenderPath::objectBoundingBox() const
return m_cachedLocalFillBBox;
}
+FloatRect RenderPath::strokeBoundingBox() const
+{
+ if (m_path.isEmpty())
+ return FloatRect();
+
+ if (!m_cachedLocalStrokeBBox.isEmpty())
+ return m_cachedLocalStrokeBBox;
+
+ m_cachedLocalStrokeBBox = objectBoundingBox();
+ if (style()->svgStyle()->hasStroke()) {
+ BoundingRectStrokeStyleApplier strokeStyle(this, style());
+ m_cachedLocalStrokeBBox.unite(m_path.strokeBoundingRect(&strokeStyle));
+ }
+
+ return m_cachedLocalStrokeBBox;
+}
+
+FloatRect RenderPath::markerBoundingBox() const
+{
+ if (m_path.isEmpty())
+ return FloatRect();
+
+ if (m_cachedLocalMarkerBBox.isEmpty())
+ calculateMarkerBoundsIfNeeded();
+
+ return m_cachedLocalMarkerBBox;
+}
+
FloatRect RenderPath::repaintRectInLocalCoordinates() const
{
if (m_path.isEmpty())
@@ -121,16 +148,25 @@ FloatRect RenderPath::repaintRectInLocalCoordinates() const
if (!m_cachedLocalRepaintRect.isEmpty())
return m_cachedLocalRepaintRect;
- if (!style()->svgStyle()->hasStroke())
- m_cachedLocalRepaintRect = objectBoundingBox();
+ // FIXME: We need to be careful here. We assume that there is no filter,
+ // clipper, marker or masker if the rects are empty.
+ FloatRect rect = filterBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ m_cachedLocalRepaintRect = rect;
else {
- BoundingRectStrokeStyleApplier strokeStyle(this, style());
- m_cachedLocalRepaintRect = m_path.strokeBoundingRect(&strokeStyle);
+ m_cachedLocalRepaintRect = strokeBoundingBox();
+ m_cachedLocalRepaintRect.unite(markerBoundingBox());
}
- // Markers and filters can paint outside of the stroke path
- m_cachedLocalRepaintRect.unite(m_markerBounds);
- m_cachedLocalRepaintRect.unite(filterBoundingBoxForRenderer(this));
+ rect = clipperBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ m_cachedLocalRepaintRect.intersect(rect);
+
+ rect = maskerBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ m_cachedLocalRepaintRect.intersect(rect);
+
+ style()->svgStyle()->inflateForShadow(m_cachedLocalRepaintRect);
return m_cachedLocalRepaintRect;
}
@@ -139,12 +175,9 @@ void RenderPath::setPath(const Path& newPath)
{
m_path = newPath;
m_cachedLocalRepaintRect = FloatRect();
+ m_cachedLocalStrokeBBox = FloatRect();
m_cachedLocalFillBBox = FloatRect();
-}
-
-const Path& RenderPath::path() const
-{
- return m_path;
+ m_cachedLocalMarkerBBox = FloatRect();
}
void RenderPath::layout()
@@ -180,39 +213,48 @@ void RenderPath::paint(PaintInfo& paintInfo, int, int)
{
if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || m_path.isEmpty())
return;
-
- paintInfo.context->save();
- paintInfo.context->concatCTM(localToParentTransform());
-
- SVGResourceFilter* filter = 0;
FloatRect boundingBox = repaintRectInLocalCoordinates();
- if (paintInfo.phase == PaintPhaseForeground) {
- PaintInfo savedInfo(paintInfo);
+ FloatRect nonLocalBoundingBox = m_localTransform.mapRect(boundingBox);
+ // FIXME: The empty rect check is to deal with incorrect initial clip in renderSubtreeToImage
+ // unfortunately fixing that problem is fairly complex unless we were willing to just futz the
+ // rect to something "close enough"
+ if (!nonLocalBoundingBox.intersects(paintInfo.rect) && !paintInfo.rect.isEmpty())
+ return;
+
+ PaintInfo childPaintInfo(paintInfo);
+ childPaintInfo.context->save();
+ applyTransformToPaintInfo(childPaintInfo, m_localTransform);
+ SVGResourceFilter* filter = 0;
- prepareToRenderSVGContent(this, paintInfo, boundingBox, filter);
- if (style()->svgStyle()->shapeRendering() == SR_CRISPEDGES)
- paintInfo.context->setShouldAntialias(false);
- fillAndStrokePath(m_path, paintInfo.context, style(), this);
+ if (childPaintInfo.phase == PaintPhaseForeground) {
+ PaintInfo savedInfo(childPaintInfo);
- if (static_cast<SVGStyledElement*>(node())->supportsMarkers())
- m_markerBounds = drawMarkersIfNeeded(paintInfo.context, paintInfo.rect, m_path);
+ if (prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter)) {
+ if (style()->svgStyle()->shapeRendering() == SR_CRISPEDGES)
+ childPaintInfo.context->setShouldAntialias(false);
+ fillAndStrokePath(m_path, childPaintInfo.context, style(), this);
- finishRenderSVGContent(this, paintInfo, filter, savedInfo.context);
+ if (static_cast<SVGStyledElement*>(node())->supportsMarkers())
+ m_markerLayoutInfo.drawMarkers(childPaintInfo);
+ }
+ finishRenderSVGContent(this, childPaintInfo, filter, savedInfo.context);
}
- if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
- paintOutline(paintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()),
+ if ((childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
+ paintOutline(childPaintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()),
static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height()), style());
- paintInfo.context->restore();
+ childPaintInfo.context->restore();
}
// This method is called from inside paintOutline() since we call paintOutline()
// while transformed to our coord system, return local coords
-void RenderPath::addFocusRingRects(GraphicsContext* graphicsContext, int, int)
+void RenderPath::addFocusRingRects(Vector<IntRect>& rects, int, int)
{
- graphicsContext->addFocusRingRect(enclosingIntRect(repaintRectInLocalCoordinates()));
+ IntRect rect = enclosingIntRect(repaintRectInLocalCoordinates());
+ if (!rect.isEmpty())
+ rects.append(rect);
}
bool RenderPath::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
@@ -221,7 +263,7 @@ bool RenderPath::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result,
if (hitTestAction != HitTestForeground)
return false;
- FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
+ FloatPoint localPoint = m_localTransform.inverse().mapPoint(pointInParent);
PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_PATH_HITTESTING, style()->pointerEvents());
@@ -237,143 +279,27 @@ bool RenderPath::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result,
return false;
}
-enum MarkerType {
- Start,
- Mid,
- End
-};
-
-struct MarkerData {
- FloatPoint origin;
- FloatPoint subpathStart;
- double strokeWidth;
- FloatPoint inslopePoints[2];
- FloatPoint outslopePoints[2];
- MarkerType type;
- SVGResourceMarker* marker;
-};
-
-struct DrawMarkersData {
- DrawMarkersData(GraphicsContext*, SVGResourceMarker* startMarker, SVGResourceMarker* midMarker, double strokeWidth);
- GraphicsContext* context;
- int elementIndex;
- MarkerData previousMarkerData;
- SVGResourceMarker* midMarker;
-};
-
-DrawMarkersData::DrawMarkersData(GraphicsContext* c, SVGResourceMarker *start, SVGResourceMarker *mid, double strokeWidth)
- : context(c)
- , elementIndex(0)
- , midMarker(mid)
-{
- previousMarkerData.origin = FloatPoint();
- previousMarkerData.subpathStart = FloatPoint();
- previousMarkerData.strokeWidth = strokeWidth;
- previousMarkerData.marker = start;
- previousMarkerData.type = Start;
-}
-
-static void drawMarkerWithData(GraphicsContext* context, MarkerData &data)
-{
- if (!data.marker)
- return;
-
- FloatPoint inslopeChange = data.inslopePoints[1] - FloatSize(data.inslopePoints[0].x(), data.inslopePoints[0].y());
- FloatPoint outslopeChange = data.outslopePoints[1] - FloatSize(data.outslopePoints[0].x(), data.outslopePoints[0].y());
-
- double inslope = rad2deg(atan2(inslopeChange.y(), inslopeChange.x()));
- double outslope = rad2deg(atan2(outslopeChange.y(), outslopeChange.x()));
-
- double angle = 0.0;
- switch (data.type) {
- case Start:
- angle = outslope;
- break;
- case Mid:
- angle = (inslope + outslope) / 2;
- break;
- case End:
- angle = inslope;
- }
-
- data.marker->draw(context, FloatRect(), data.origin.x(), data.origin.y(), data.strokeWidth, angle);
-}
-
-static inline void updateMarkerDataForElement(MarkerData& previousMarkerData, const PathElement* element)
-{
- FloatPoint* points = element->points;
-
- switch (element->type) {
- case PathElementAddQuadCurveToPoint:
- // TODO
- previousMarkerData.origin = points[1];
- break;
- case PathElementAddCurveToPoint:
- previousMarkerData.inslopePoints[0] = points[1];
- previousMarkerData.inslopePoints[1] = points[2];
- previousMarkerData.origin = points[2];
- break;
- case PathElementMoveToPoint:
- previousMarkerData.subpathStart = points[0];
- case PathElementAddLineToPoint:
- previousMarkerData.inslopePoints[0] = previousMarkerData.origin;
- previousMarkerData.inslopePoints[1] = points[0];
- previousMarkerData.origin = points[0];
- break;
- case PathElementCloseSubpath:
- previousMarkerData.inslopePoints[0] = previousMarkerData.origin;
- previousMarkerData.inslopePoints[1] = points[0];
- previousMarkerData.origin = previousMarkerData.subpathStart;
- previousMarkerData.subpathStart = FloatPoint();
- }
-}
-
-static void drawStartAndMidMarkers(void* info, const PathElement* element)
-{
- DrawMarkersData& data = *reinterpret_cast<DrawMarkersData*>(info);
-
- int elementIndex = data.elementIndex;
- MarkerData& previousMarkerData = data.previousMarkerData;
-
- FloatPoint* points = element->points;
-
- // First update the outslope for the previous element
- previousMarkerData.outslopePoints[0] = previousMarkerData.origin;
- previousMarkerData.outslopePoints[1] = points[0];
-
- // Draw the marker for the previous element
- if (elementIndex != 0)
- drawMarkerWithData(data.context, previousMarkerData);
-
- // Update our marker data for this element
- updateMarkerDataForElement(previousMarkerData, element);
-
- if (elementIndex == 1) {
- // After drawing the start marker, switch to drawing mid markers
- previousMarkerData.marker = data.midMarker;
- previousMarkerData.type = Mid;
- }
-
- data.elementIndex++;
-}
-
-FloatRect RenderPath::drawMarkersIfNeeded(GraphicsContext* context, const FloatRect&, const Path& path) const
+void RenderPath::calculateMarkerBoundsIfNeeded() const
{
Document* doc = document();
SVGElement* svgElement = static_cast<SVGElement*>(node());
- ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
+ ASSERT(svgElement && svgElement->document());
+ if (!svgElement->isStyled())
+ return;
SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
- const SVGRenderStyle* svgStyle = style()->svgStyle();
+ if (!styledElement->supportsMarkers())
+ return;
+ const SVGRenderStyle* svgStyle = style()->svgStyle();
AtomicString startMarkerId(svgStyle->startMarker());
AtomicString midMarkerId(svgStyle->midMarker());
AtomicString endMarkerId(svgStyle->endMarker());
- SVGResourceMarker* startMarker = getMarkerById(doc, startMarkerId);
- SVGResourceMarker* midMarker = getMarkerById(doc, midMarkerId);
- SVGResourceMarker* endMarker = getMarkerById(doc, endMarkerId);
+ SVGResourceMarker* startMarker = getMarkerById(doc, startMarkerId, this);
+ SVGResourceMarker* midMarker = getMarkerById(doc, midMarkerId, this);
+ SVGResourceMarker* endMarker = getMarkerById(doc, endMarkerId, this);
if (!startMarker && !startMarkerId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(startMarkerId, styledElement);
@@ -391,32 +317,10 @@ FloatRect RenderPath::drawMarkersIfNeeded(GraphicsContext* context, const FloatR
endMarker->addClient(styledElement);
if (!startMarker && !midMarker && !endMarker)
- return FloatRect();
-
- double strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, svgStyle->strokeWidth(), 1.0f);
- DrawMarkersData data(context, startMarker, midMarker, strokeWidth);
-
- path.apply(&data, drawStartAndMidMarkers);
-
- data.previousMarkerData.marker = endMarker;
- data.previousMarkerData.type = End;
- drawMarkerWithData(context, data.previousMarkerData);
-
- // We know the marker boundaries, only after they're drawn!
- // Otherwhise we'd need to do all the marker calculation twice
- // once here (through paint()) and once in absoluteClippedOverflowRect().
- FloatRect bounds;
-
- if (startMarker)
- bounds.unite(startMarker->cachedBounds());
-
- if (midMarker)
- bounds.unite(midMarker->cachedBounds());
-
- if (endMarker)
- bounds.unite(endMarker->cachedBounds());
+ return;
- return bounds;
+ float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, svgStyle->strokeWidth(), 1.0f);
+ m_cachedLocalMarkerBBox = m_markerLayoutInfo.calculateBoundaries(startMarker, midMarker, endMarker, strokeWidth, m_path);
}
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderPath.h b/src/3rdparty/webkit/WebCore/rendering/RenderPath.h
index 2ff179e243..d530f3cdaa 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderPath.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderPath.h
@@ -25,10 +25,10 @@
#define RenderPath_h
#if ENABLE(SVG)
-
+#include "AffineTransform.h"
#include "FloatRect.h"
#include "RenderSVGModelObject.h"
-#include "TransformationMatrix.h"
+#include "SVGMarkerLayoutInfo.h"
namespace WebCore {
@@ -40,7 +40,7 @@ class RenderPath : public RenderSVGModelObject {
public:
RenderPath(SVGStyledTransformableElement*);
- const Path& path() const;
+ const Path& path() const { return m_path; }
private:
// Hit-detection seperated for the fill and the stroke
@@ -48,9 +48,11 @@ private:
bool strokeContains(const FloatPoint&, bool requiresStroke = true) const;
virtual FloatRect objectBoundingBox() const;
+ virtual FloatRect strokeBoundingBox() const;
+ virtual FloatRect markerBoundingBox() const;
virtual FloatRect repaintRectInLocalCoordinates() const;
- virtual TransformationMatrix localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
void setPath(const Path&);
@@ -59,20 +61,22 @@ private:
virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
- FloatRect drawMarkersIfNeeded(GraphicsContext*, const FloatRect&, const Path&) const;
+ void calculateMarkerBoundsIfNeeded() const;
private:
- virtual TransformationMatrix localTransform() const;
+ virtual AffineTransform localTransform() const;
mutable Path m_path;
mutable FloatRect m_cachedLocalFillBBox;
+ mutable FloatRect m_cachedLocalStrokeBBox;
mutable FloatRect m_cachedLocalRepaintRect;
- FloatRect m_markerBounds;
- TransformationMatrix m_localTransform;
+ mutable FloatRect m_cachedLocalMarkerBBox;
+ mutable SVGMarkerLayoutInfo m_markerLayoutInfo;
+ AffineTransform m_localTransform;
};
inline RenderPath* toRenderPath(RenderObject* object)
@@ -94,5 +98,3 @@ void toRenderPath(const RenderPath*);
#endif // ENABLE(SVG)
#endif
-
-// vim:ts=4:noet
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderProgress.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderProgress.cpp
new file mode 100644
index 0000000000..8a57612f29
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderProgress.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#if ENABLE(PROGRESS_TAG)
+
+#include "RenderProgress.h"
+
+#include "HTMLProgressElement.h"
+#include "RenderTheme.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const int defaultProgressWidth = 120;
+static const int defaultProgressHeight = 20;
+
+RenderProgress::RenderProgress(HTMLProgressElement* element)
+ : RenderBlock(element)
+ , m_position(-1)
+{
+ setSize(IntSize(defaultProgressWidth, defaultProgressHeight));
+ setReplaced(true);
+}
+
+int RenderProgress::baselinePosition(bool, bool) const
+{
+ return height() + marginTop();
+}
+
+void RenderProgress::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 = defaultProgressWidth * style()->effectiveZoom();
+
+ 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 RenderProgress::layout()
+{
+ ASSERT(needsLayout());
+
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+
+ calcWidth();
+ calcHeight();
+
+ m_overflow.clear();
+
+ repainter.repaintAfterLayout();
+
+ setNeedsLayout(false);
+}
+
+void RenderProgress::updateFromElement()
+{
+ HTMLProgressElement* element = static_cast<HTMLProgressElement*>(node());
+ double position = element->position();
+ int oldPosition = m_position;
+ bool canOptimize = theme()->getNumberOfPixelsForProgressPosition(position, m_position);
+ if (oldPosition == m_position)
+ return;
+
+ IntRect paintRect = contentBoxRect();
+ if (canOptimize) {
+ // FIXME: Need to handle indeterminate progress bar and RTL
+ int adjustedPosition = (m_position >= 0) ? m_position : 0;
+ int adjustedOldPosition = (oldPosition >= 0) ? oldPosition : 0;
+ paintRect.setX(std::min(adjustedPosition, adjustedOldPosition));
+ paintRect.setWidth(std::max(adjustedPosition, adjustedOldPosition) - paintRect.x());
+ }
+ repaintRectangle(paintRect);
+}
+
+} // namespace WebCore
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderProgress.h b/src/3rdparty/webkit/WebCore/rendering/RenderProgress.h
new file mode 100644
index 0000000000..0a90fde54a
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderProgress.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderProgress_h
+#define RenderProgress_h
+
+#if ENABLE(PROGRESS_TAG)
+#include "RenderBlock.h"
+
+namespace WebCore {
+
+class HTMLProgressElement;
+
+class RenderProgress : public RenderBlock {
+public:
+ RenderProgress(HTMLProgressElement*);
+ int position() { return m_position; }
+
+private:
+ virtual const char* renderName() const { return "RenderProgress"; }
+ virtual bool isProgress() const { return true; }
+ virtual int baselinePosition(bool, bool) const;
+ virtual void calcPrefWidths();
+ virtual void layout();
+ virtual void updateFromElement();
+ int m_position;
+};
+
+inline RenderProgress* toRenderProgress(RenderObject* object)
+{
+ ASSERT(!object || object->isProgress());
+ return static_cast<RenderProgress*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderProgress(const RenderProgress*);
+
+} // namespace WebCore
+
+#endif
+
+#endif // RenderProgress_h
+
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp
index 27d2e72af7..ba579dfcea 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp
@@ -153,7 +153,7 @@ void RenderReplaced::paint(PaintInfo& paintInfo, int tx, int ty)
if (drawSelectionTint) {
IntRect selectionPaintingRect = localSelectionRect();
selectionPaintingRect.move(tx, ty);
- paintInfo.context->fillRect(selectionPaintingRect, selectionBackgroundColor());
+ paintInfo.context->fillRect(selectionPaintingRect, selectionBackgroundColor(), style()->colorSpace());
}
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.h b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.h
index 0ba6b8abc2..b5c61791b6 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.h
@@ -46,8 +46,8 @@ protected:
void setIntrinsicSize(const IntSize&);
virtual void intrinsicSizeChanged();
+ virtual void paint(PaintInfo&, int tx, int ty);
bool shouldPaint(PaintInfo&, int& tx, int& ty);
- void adjustOverflowForBoxShadowAndReflect();
IntRect localSelectionRect(bool checkWhetherSelected = true) const;
private:
@@ -62,7 +62,6 @@ private:
virtual int minimumReplacedHeight() const { return 0; }
- virtual void paint(PaintInfo&, int tx, int ty);
virtual void paintReplaced(PaintInfo&, int /*tx*/, int /*ty*/) { }
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderReplica.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderReplica.cpp
index 5fa3c620cc..1d589ae725 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderReplica.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderReplica.cpp
@@ -72,7 +72,7 @@ void RenderReplica::paint(PaintInfo& paintInfo, int tx, int ty)
// computing using the wrong rootLayer
layer()->parent()->paintLayer(layer()->transform() ? layer()->parent() : layer()->enclosingTransformedAncestor(),
paintInfo.context, paintInfo.rect,
- PaintRestrictionNone, 0, 0,
+ PaintBehaviorNormal, 0, 0,
RenderLayer::PaintLayerHaveTransparency | RenderLayer::PaintLayerAppliedTransform | RenderLayer::PaintLayerTemporaryClipRects | RenderLayer::PaintLayerPaintingReflection);
else if (paintInfo.phase == PaintPhaseMask)
paintMask(paintInfo, tx, ty);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderReplica.h b/src/3rdparty/webkit/WebCore/rendering/RenderReplica.h
index d5db3b742f..48c64e4aa5 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderReplica.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderReplica.h
@@ -46,6 +46,10 @@ public:
virtual void calcPrefWidths();
virtual void paint(PaintInfo&, int tx, int ty);
+
+private:
+ virtual bool isReplica() const { return true; }
+
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderRuby.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderRuby.cpp
new file mode 100644
index 0000000000..4ab9d735e6
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderRuby.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(RUBY)
+#include "RenderRuby.h"
+
+#include "RenderRubyRun.h"
+
+namespace WebCore {
+
+//=== generic helper functions to avoid excessive code duplication ===
+
+static RenderRubyRun* lastRubyRun(const RenderObject* ruby)
+{
+ RenderObject* child = ruby->lastChild();
+ if (child && ruby->isAfterContent(child))
+ child = child->previousSibling();
+ ASSERT(!child || child->isRubyRun());
+ return static_cast<RenderRubyRun*>(child);
+}
+
+static inline RenderRubyRun* findRubyRunParent(RenderObject* child)
+{
+ while (child && !child->isRubyRun())
+ child = child->parent();
+ return static_cast<RenderRubyRun*>(child);
+}
+
+//=== ruby as inline object ===
+
+RenderRubyAsInline::RenderRubyAsInline(Node* node)
+ : RenderInline(node)
+{
+}
+
+RenderRubyAsInline::~RenderRubyAsInline()
+{
+}
+
+bool RenderRubyAsInline::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isRubyText()
+ || child->isRubyRun()
+ || child->isInline();
+}
+
+void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+ // Note: ':after' content is handled implicitely below
+
+ // if child is a ruby run, just add it normally
+ if (child->isRubyRun()) {
+ RenderInline::addChild(child, beforeChild);
+ return;
+ }
+
+ if (beforeChild && !isAfterContent(beforeChild)) {
+ // insert child into run
+ ASSERT(!beforeChild->isRubyRun());
+ RenderRubyRun* run = findRubyRunParent(beforeChild);
+ ASSERT(run); // beforeChild should always have a run as parent
+ if (run) {
+ run->addChild(child, beforeChild);
+ return;
+ }
+ ASSERT(false); // beforeChild should always have a run as parent!
+ // Emergency fallback: fall through and just append.
+ }
+
+ // If the new child would be appended, try to add the child to the previous run
+ // if possible, or create a new run otherwise.
+ // (The RenderRubyRun object will handle the details)
+ RenderRubyRun* lastRun = lastRubyRun(this);
+ if (!lastRun || lastRun->hasRubyText()) {
+ lastRun = RenderRubyRun::staticCreateRubyRun(this);
+ RenderInline::addChild(lastRun);
+ }
+ lastRun->addChild(child);
+}
+
+void RenderRubyAsInline::removeChild(RenderObject* child)
+{
+ // If the child's parent is *this, i.e. a ruby run or ':after' content,
+ // just use the normal remove method.
+ if (child->parent() == this) {
+ ASSERT(child->isRubyRun() || child->isAfterContent());
+ RenderInline::removeChild(child);
+ return;
+ }
+
+ // Find the containing run
+ RenderRubyRun* run = findRubyRunParent(child);
+ ASSERT(run);
+ run->removeChild(child);
+}
+
+
+//=== ruby as block object ===
+
+RenderRubyAsBlock::RenderRubyAsBlock(Node* node)
+ : RenderBlock(node)
+{
+}
+
+RenderRubyAsBlock::~RenderRubyAsBlock()
+{
+}
+
+bool RenderRubyAsBlock::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isRubyText()
+ || child->isRubyRun()
+ || child->isInline();
+}
+
+void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+ // Note: ':after' content is handled implicitely below
+
+ // if child is a ruby run, just add it normally
+ if (child->isRubyRun()) {
+ RenderBlock::addChild(child, beforeChild);
+ return;
+ }
+
+ if (beforeChild && !isAfterContent(beforeChild)) {
+ // insert child into run
+ ASSERT(!beforeChild->isRubyRun());
+ RenderObject* run = beforeChild;
+ while (run && !run->isRubyRun())
+ run = run->parent();
+ if (run) {
+ run->addChild(child, beforeChild);
+ return;
+ }
+ ASSERT(false); // beforeChild should always have a run as parent!
+ // Emergency fallback: fall through and just append.
+ }
+
+ // If the new child would be appended, try to add the child to the previous run
+ // if possible, or create a new run otherwise.
+ // (The RenderRubyRun object will handle the details)
+ RenderRubyRun* lastRun = lastRubyRun(this);
+ if (!lastRun || lastRun->hasRubyText()) {
+ lastRun = RenderRubyRun::staticCreateRubyRun(this);
+ RenderBlock::addChild(lastRun);
+ }
+ lastRun->addChild(child);
+}
+
+void RenderRubyAsBlock::removeChild(RenderObject* child)
+{
+ // If the child's parent is *this, just use the normal remove method.
+ if (child->parent() == this) {
+ // This should happen only during destruction of the whole ruby element, though.
+ RenderBlock::removeChild(child);
+ return;
+ }
+
+ // Find the containing run
+ RenderRubyRun* run = findRubyRunParent(child);
+ ASSERT(run);
+ run->removeChild(child);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(RUBY)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderRuby.h b/src/3rdparty/webkit/WebCore/rendering/RenderRuby.h
new file mode 100644
index 0000000000..a5dafe981d
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderRuby.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderRuby_h
+#define RenderRuby_h
+
+#if ENABLE(RUBY)
+
+#include "RenderBlock.h"
+#include "RenderInline.h"
+
+namespace WebCore {
+
+// Following the HTML 5 spec, the box object model for a <ruby> element allows several runs of ruby
+// bases with their respective ruby texts looks as follows:
+//
+// 1 RenderRuby object, corresponding to the whole <ruby> HTML element
+// 1+ RenderRubyRun (anonymous)
+// 0 or 1 RenderRubyText - shuffled to the front in order to re-use existing block layouting
+// 0-n inline object(s)
+// 0 or 1 RenderRubyBase - contains the inline objects that make up the ruby base
+// 1-n inline object(s)
+//
+// Note: <rp> elements are defined as having 'display:none' and thus normally are not assigned a renderer.
+
+// <ruby> when used as 'display:inline'
+class RenderRubyAsInline : public RenderInline {
+public:
+ RenderRubyAsInline(Node*);
+ virtual ~RenderRubyAsInline();
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void removeChild(RenderObject* child);
+
+private:
+ virtual bool isRuby() const { return true; }
+ virtual const char* renderName() const { return "RenderRuby (inline)"; }
+ virtual bool createsAnonymousWrapper() const { return true; }
+ virtual void removeLeftoverAnonymousBlock(RenderBlock*) { ASSERT_NOT_REACHED(); }
+};
+
+// <ruby> when used as 'display:block' or 'display:inline-block'
+class RenderRubyAsBlock : public RenderBlock {
+public:
+ RenderRubyAsBlock(Node*);
+ virtual ~RenderRubyAsBlock();
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void removeChild(RenderObject* child);
+
+private:
+ virtual bool isRuby() const { return true; }
+ virtual const char* renderName() const { return "RenderRuby (block)"; }
+ virtual bool createsAnonymousWrapper() const { return true; }
+ virtual void removeLeftoverAnonymousBlock(RenderBlock*) { ASSERT_NOT_REACHED(); }
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // RenderRuby_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderRubyBase.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderRubyBase.cpp
new file mode 100644
index 0000000000..9b2dc9ef6f
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderRubyBase.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(RUBY)
+#include "RenderRubyBase.h"
+
+namespace WebCore {
+
+RenderRubyBase::RenderRubyBase(Node* node)
+ : RenderBlock(node)
+{
+ setInline(false);
+}
+
+RenderRubyBase::~RenderRubyBase()
+{
+}
+
+bool RenderRubyBase::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isInline();
+}
+
+bool RenderRubyBase::hasOnlyWrappedInlineChildren(RenderObject* beforeChild) const
+{
+ // Tests whether all children in the base before beforeChild are either floated/positioned,
+ // or inline objects wrapped in anonymous blocks.
+ // Note that beforeChild may be 0, in which case all children are looked at.
+ for (RenderObject* child = firstChild(); child != beforeChild; child = child->nextSibling()) {
+ if (!child->isFloatingOrPositioned() && !(child->isAnonymousBlock() && child->childrenInline()))
+ return false;
+ }
+ return true;
+}
+
+void RenderRubyBase::moveChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
+{
+ // This function removes all children that are before (!) beforeChild
+ // and appends them to toBase.
+ ASSERT(toBase);
+
+ // First make sure that beforeChild (if set) is indeed a direct child of this.
+ // Inline children might be wrapped in an anonymous block if there's a continuation.
+ // Theoretically, in ruby bases, this can happen with only the first such a child,
+ // so it should be OK to just climb the tree.
+ while (fromBeforeChild && fromBeforeChild->parent() != this)
+ fromBeforeChild = fromBeforeChild->parent();
+
+ if (childrenInline())
+ moveInlineChildren(toBase, fromBeforeChild);
+ else
+ moveBlockChildren(toBase, fromBeforeChild);
+
+ setNeedsLayoutAndPrefWidthsRecalc();
+ toBase->setNeedsLayoutAndPrefWidthsRecalc();
+}
+
+void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
+{
+ RenderBlock* toBlock;
+
+ if (toBase->childrenInline()) {
+ // The standard and easy case: move the children into the target base
+ toBlock = toBase;
+ } else {
+ // We need to wrap the inline objects into an anonymous block.
+ // If toBase has a suitable block, we re-use it, otherwise create a new one.
+ RenderObject* lastChild = toBase->lastChild();
+ if (lastChild && lastChild->isAnonymousBlock() && lastChild->childrenInline())
+ toBlock = toRenderBlock(lastChild);
+ else {
+ toBlock = toBase->createAnonymousBlock();
+ toBase->children()->appendChildNode(toBase, toBlock);
+ }
+ }
+ // Move our inline children into the target block we determined above.
+ for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild())
+ moveChildTo(toBlock, toBlock->children(), child);
+}
+
+void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
+{
+ if (toBase->childrenInline()) {
+ // First check whether we move only wrapped inline objects.
+ if (hasOnlyWrappedInlineChildren(fromBeforeChild)) {
+ // The reason why the base is in block flow must be after beforeChild.
+ // We therefore can extract the inline objects and move them to toBase.
+ for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild()) {
+ if (child->isAnonymousBlock()) {
+ RenderBlock* anonBlock = toRenderBlock(child);
+ ASSERT(anonBlock->childrenInline());
+ ASSERT(!anonBlock->inlineContinuation());
+ anonBlock->moveAllChildrenTo(toBase, toBase->children());
+ anonBlock->deleteLineBoxTree();
+ anonBlock->destroy();
+ } else {
+ ASSERT(child->isFloatingOrPositioned());
+ moveChildTo(toBase, toBase->children(), child);
+ }
+ }
+ } else {
+ // Moving block children -> have to set toBase as block flow
+ toBase->makeChildrenNonInline();
+ // Move children, potentially collapsing anonymous block wrappers.
+ mergeBlockChildren(toBase, fromBeforeChild);
+
+ // Now we need to check if the leftover children are all inline.
+ // If so, make this base inline again.
+ if (hasOnlyWrappedInlineChildren()) {
+ RenderObject* next = 0;
+ for (RenderObject* child = firstChild(); child; child = next) {
+ next = child->nextSibling();
+ if (child->isFloatingOrPositioned())
+ continue;
+ ASSERT(child->isAnonymousBlock());
+
+ RenderBlock* anonBlock = toRenderBlock(child);
+ ASSERT(anonBlock->childrenInline());
+ ASSERT(!anonBlock->inlineContinuation());
+ // Move inline children out of anonymous block.
+ anonBlock->moveAllChildrenTo(this, children(), anonBlock);
+ anonBlock->deleteLineBoxTree();
+ anonBlock->destroy();
+ }
+ setChildrenInline(true);
+ }
+ }
+ } else
+ mergeBlockChildren(toBase, fromBeforeChild);
+}
+
+void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
+{
+ // This function removes all children that are before fromBeforeChild and appends them to toBase.
+ ASSERT(!childrenInline());
+ ASSERT(toBase);
+ ASSERT(!toBase->childrenInline());
+
+ // Quick check whether we have anything to do, to simplify the following code.
+ if (fromBeforeChild != firstChild())
+ return;
+
+ // If an anonymous block would be put next to another such block, then merge those.
+ RenderObject* firstChildHere = firstChild();
+ RenderObject* lastChildThere = toBase->lastChild();
+ if (firstChildHere && firstChildHere->isAnonymousBlock() && firstChildHere->childrenInline()
+ && lastChildThere && lastChildThere->isAnonymousBlock() && lastChildThere->childrenInline()) {
+ RenderBlock* anonBlockHere = toRenderBlock(firstChildHere);
+ RenderBlock* anonBlockThere = toRenderBlock(lastChildThere);
+ anonBlockHere->moveAllChildrenTo(anonBlockThere, anonBlockThere->children());
+ anonBlockHere->deleteLineBoxTree();
+ anonBlockHere->destroy();
+ }
+ // Move all remaining children normally.
+ for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild())
+ moveChildTo(toBase, toBase->children(), child);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(RUBY)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderRubyBase.h b/src/3rdparty/webkit/WebCore/rendering/RenderRubyBase.h
new file mode 100644
index 0000000000..29c4858f57
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderRubyBase.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderRubyBase_h
+#define RenderRubyBase_h
+
+#if ENABLE(RUBY)
+
+#include "RenderBlock.h"
+
+namespace WebCore {
+
+class RenderRubyBase : public RenderBlock {
+public:
+ RenderRubyBase(Node*);
+ virtual ~RenderRubyBase();
+
+ virtual const char* renderName() const { return "RenderRubyBase (anonymous)"; }
+
+ virtual bool isRubyBase() const { return true; }
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+
+private:
+ bool hasOnlyWrappedInlineChildren(RenderObject* beforeChild = 0) const;
+
+ void moveChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
+ void moveInlineChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
+ void moveBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
+ void mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
+
+ // Allow RenderRubyRun to manipulate the children within ruby bases.
+ friend class RenderRubyRun;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // RenderRubyBase_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderRubyRun.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderRubyRun.cpp
new file mode 100644
index 0000000000..d91c625eef
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderRubyRun.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(RUBY)
+#include "RenderRubyRun.h"
+
+#include "RenderRubyBase.h"
+#include "RenderRubyText.h"
+#include "RenderView.h"
+
+using namespace std;
+
+namespace WebCore {
+
+RenderRubyRun::RenderRubyRun(Node* node)
+ : RenderBlock(node)
+ , m_beingDestroyed(false)
+{
+ setReplaced(true);
+ setInline(true);
+}
+
+RenderRubyRun::~RenderRubyRun()
+{
+}
+
+void RenderRubyRun::destroy()
+{
+ // Mark if the run is being destroyed to avoid trouble in removeChild().
+ m_beingDestroyed = true;
+ RenderBlock::destroy();
+}
+
+bool RenderRubyRun::hasRubyText() const
+{
+ // The only place where a ruby text can be is in the first position
+ // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' content themselves.
+ return firstChild() && firstChild()->isRubyText();
+}
+
+bool RenderRubyRun::hasRubyBase() const
+{
+ // The only place where a ruby base can be is in the last position
+ // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' content themselves.
+ return lastChild() && lastChild()->isRubyBase();
+}
+
+bool RenderRubyRun::isEmpty() const
+{
+ return !hasRubyText() && !hasRubyBase();
+}
+
+RenderRubyText* RenderRubyRun::rubyText() const
+{
+ RenderObject* child = firstChild();
+ return child && child->isRubyText() ? static_cast<RenderRubyText*>(child) : 0;
+}
+
+RenderRubyBase* RenderRubyRun::rubyBase() const
+{
+ RenderObject* child = lastChild();
+ return child && child->isRubyBase() ? static_cast<RenderRubyBase*>(child) : 0;
+}
+
+RenderRubyBase* RenderRubyRun::rubyBaseSafe()
+{
+ RenderRubyBase* base = rubyBase();
+ if (!base) {
+ base = createRubyBase();
+ RenderBlock::addChild(base);
+ }
+ return base;
+}
+
+RenderBlock* RenderRubyRun::firstLineBlock() const
+{
+ return 0;
+}
+
+void RenderRubyRun::updateFirstLetter()
+{
+}
+
+bool RenderRubyRun::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isRubyText() || child->isInline();
+}
+
+void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+ ASSERT(child);
+
+ // If child is a ruby text
+ if (child->isRubyText()) {
+ if (!beforeChild) {
+ // RenderRuby has already ascertained that we can add the child here.
+ ASSERT(!hasRubyText());
+ // prepend ruby texts as first child
+ RenderBlock::addChild(child, firstChild());
+ } else if (beforeChild->isRubyText()) {
+ // New text is inserted just before another.
+ // In this case the new text takes the place of the old one, and
+ // the old text goes into a new run that is inserted as next sibling.
+ ASSERT(beforeChild->parent() == this);
+ RenderObject* ruby = parent();
+ ASSERT(ruby->isRuby());
+ RenderBlock* newRun = staticCreateRubyRun(ruby);
+ ruby->addChild(newRun, nextSibling());
+ // Add the new ruby text and move the old one to the new run
+ // Note: Doing it in this order and not using RenderRubyRun's methods,
+ // in order to avoid automatic removal of the ruby run in case there is no
+ // other child besides the old ruby text.
+ RenderBlock::addChild(child, beforeChild);
+ RenderBlock::removeChild(beforeChild);
+ newRun->addChild(beforeChild);
+ } else {
+ ASSERT(hasRubyBase()); // Otherwise beforeChild would be borked.
+ // Insertion before a ruby base object.
+ // In this case we need insert a new run before the current one and split the base.
+ RenderObject* ruby = parent();
+ RenderRubyRun* newRun = staticCreateRubyRun(ruby);
+ ruby->addChild(newRun, this);
+ newRun->addChild(child);
+ rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild);
+ }
+ } else {
+ // child is not a text -> insert it into the base
+ // (append it instead if beforeChild is the ruby text)
+ if (beforeChild && beforeChild->isRubyText())
+ beforeChild = 0;
+ rubyBaseSafe()->addChild(child, beforeChild);
+ }
+}
+
+void RenderRubyRun::removeChild(RenderObject* child)
+{
+ // If the child is a ruby text, then merge the ruby base with the base of
+ // the right sibling run, if possible.
+ if (!m_beingDestroyed && !documentBeingDestroyed() && child->isRubyText()) {
+ RenderRubyBase* base = rubyBase();
+ RenderObject* rightNeighbour = nextSibling();
+ if (base && rightNeighbour && rightNeighbour->isRubyRun()) {
+ // Ruby run without a base can happen only at the first run.
+ RenderRubyRun* rightRun = static_cast<RenderRubyRun*>(rightNeighbour);
+ ASSERT(rightRun->hasRubyBase());
+ RenderRubyBase* rightBase = rightRun->rubyBaseSafe();
+ // Collect all children in a single base, then swap the bases.
+ rightBase->moveChildren(base);
+ moveChildTo(rightRun, rightRun->children(), base);
+ rightRun->moveChildTo(this, children(), rightBase);
+ // The now empty ruby base will be removed below.
+ }
+ }
+
+ RenderBlock::removeChild(child);
+
+ if (!m_beingDestroyed && !documentBeingDestroyed()) {
+ // Check if our base (if any) is now empty. If so, destroy it.
+ RenderBlock* base = rubyBase();
+ if (base && !base->firstChild()) {
+ RenderBlock::removeChild(base);
+ base->deleteLineBoxTree();
+ base->destroy();
+ }
+
+ // If any of the above leaves the run empty, destroy it as well.
+ if (isEmpty()) {
+ parent()->removeChild(this);
+ deleteLineBoxTree();
+ destroy();
+ }
+ }
+}
+
+RenderRubyBase* RenderRubyRun::createRubyBase() const
+{
+ RenderRubyBase* rb = new (renderArena()) RenderRubyBase(document() /* anonymous */);
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(BLOCK);
+ newStyle->setTextAlign(CENTER); // FIXME: use WEBKIT_CENTER?
+ rb->setStyle(newStyle.release());
+ return rb;
+}
+
+RenderRubyRun* RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby)
+{
+ ASSERT(parentRuby && parentRuby->isRuby());
+ RenderRubyRun* rr = new (parentRuby->renderArena()) RenderRubyRun(parentRuby->document() /* anonymous */);
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(parentRuby->style());
+ newStyle->setDisplay(INLINE_BLOCK);
+ rr->setStyle(newStyle.release());
+ return rr;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(RUBY)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderRubyRun.h b/src/3rdparty/webkit/WebCore/rendering/RenderRubyRun.h
new file mode 100644
index 0000000000..acf359bb01
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderRubyRun.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderRubyRun_h
+#define RenderRubyRun_h
+
+#if ENABLE(RUBY)
+
+#include "RenderBlock.h"
+
+namespace WebCore {
+
+class RenderRubyBase;
+class RenderRubyText;
+
+// RenderRubyRun are 'inline-block/table' like objects,and wrap a single pairing of a ruby base with its ruby text(s).
+// See RenderRuby.h for further comments on the structure
+
+class RenderRubyRun : public RenderBlock {
+public:
+ RenderRubyRun(Node*);
+ virtual ~RenderRubyRun();
+
+ virtual void destroy();
+
+ bool hasRubyText() const;
+ bool hasRubyBase() const;
+ bool isEmpty() const;
+ RenderRubyText* rubyText() const;
+ RenderRubyBase* rubyBase() const;
+ RenderRubyBase* rubyBaseSafe(); // creates the base if it doesn't already exist
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void removeChild(RenderObject* child);
+
+ virtual RenderBlock* firstLineBlock() const;
+ virtual void updateFirstLetter();
+
+ static RenderRubyRun* staticCreateRubyRun(const RenderObject* parentRuby);
+
+protected:
+ RenderRubyBase* createRubyBase() const;
+
+private:
+ virtual bool isRubyRun() const { return true; }
+ virtual const char* renderName() const { return "RenderRubyRun (anonymous)"; }
+ virtual bool createsAnonymousWrapper() const { return true; }
+ virtual void removeLeftoverAnonymousBlock(RenderBlock*) { }
+
+ bool m_beingDestroyed;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // RenderRubyRun_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderRubyText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderRubyText.cpp
new file mode 100644
index 0000000000..12e8feace3
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderRubyText.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(RUBY)
+#include "RenderRubyText.h"
+
+namespace WebCore {
+
+RenderRubyText::RenderRubyText(Node* node)
+ : RenderBlock(node)
+{
+}
+
+RenderRubyText::~RenderRubyText()
+{
+}
+
+bool RenderRubyText::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isInline();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(RUBY)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderRubyText.h b/src/3rdparty/webkit/WebCore/rendering/RenderRubyText.h
new file mode 100644
index 0000000000..865d1798bd
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderRubyText.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderRubyText_h
+#define RenderRubyText_h
+
+#if ENABLE(RUBY)
+
+#include "RenderBlock.h"
+
+namespace WebCore {
+
+class RenderRubyText : public RenderBlock {
+public:
+ RenderRubyText(Node*);
+ virtual ~RenderRubyText();
+
+ virtual const char* renderName() const { return "RenderRubyText"; }
+
+ virtual bool isRubyText() const { return true; }
+
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // RenderRubyText_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.cpp
index f065c44b07..99725d618c 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.cpp
@@ -1,8 +1,7 @@
/*
- * This file is part of the WebKit project.
- *
* Copyright (C) 2006 Apple Computer, Inc.
- * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -40,9 +39,7 @@ void RenderSVGBlock::setStyle(PassRefPtr<RenderStyle> style)
RefPtr<RenderStyle> useStyle = style;
// SVG text layout code expects us to be a block-level style element.
- if (useStyle->display() == NONE)
- setChildrenInline(false);
- else if (useStyle->isDisplayInlineType()) {
+ if (useStyle->isDisplayInlineType()) {
RefPtr<RenderStyle> newStyle = RenderStyle::create();
newStyle->inheritFrom(useStyle.get());
newStyle->setDisplay(BLOCK);
@@ -50,14 +47,27 @@ void RenderSVGBlock::setStyle(PassRefPtr<RenderStyle> style)
}
RenderBlock::setStyle(useStyle.release());
- setReplaced(false);
+}
+
+void RenderSVGBlock::updateBoxModelInfoFromStyle()
+{
+ RenderBlock::updateBoxModelInfoFromStyle();
- //FIXME: Once overflow rules are supported by SVG we should
- //probably map the CSS overflow rules rather than just ignoring
- //them
+ // RenderSVGlock, used by Render(SVGText|ForeignObject), is not allowed to call setHasOverflowClip(true).
+ // RenderBlock assumes a layer to be present when the overflow clip functionality is requested. Both
+ // Render(SVGText|ForeignObject) return 'false' on 'requiresLayer'. Fine for RenderSVGText.
+ //
+ // If we want to support overflow rules for <foreignObject> we can choose between two solutions:
+ // a) make RenderForeignObject require layers and SVG layer aware
+ // b) reactor overflow logic out of RenderLayer (as suggested by dhyatt), which is a large task
+ //
+ // Until this is resolved, disable overflow support. Opera/FF don't support it as well at the moment (Feb 2010).
+ //
+ // Note: This does NOT affect overflow handling on outer/inner <svg> elements - this is handled
+ // manually by RenderSVGRoot - which owns the documents enclosing root layer and thus works fine.
setHasOverflowClip(false);
}
}
-#endif // ENABLE(SVG)
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.h
index a4ececb3cd..19cac62720 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGBlock.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the WebKit project.
- *
* Copyright (C) 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -22,8 +20,8 @@
#ifndef RenderSVGBlock_h
#define RenderSVGBlock_h
-#if ENABLE(SVG)
+#if ENABLE(SVG)
#include "RenderBlock.h"
#include "SVGRenderSupport.h"
@@ -35,10 +33,13 @@ class RenderSVGBlock : public RenderBlock, protected SVGRenderBase {
public:
RenderSVGBlock(SVGElement*);
+ virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
+
private:
virtual void setStyle(PassRefPtr<RenderStyle>);
+ virtual void updateBoxModelInfoFromStyle();
};
}
-#endif // ENABLE(SVG)
-#endif // !RenderSVGBlock_h
+#endif
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.cpp
index d7aec99dfe..6d1b965682 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.cpp
@@ -3,6 +3,7 @@
2004, 2005, 2007, 2008 Rob Buis <buis@kde.org>
2007 Eric Seidel <eric@webkit.org>
Copyright (C) 2009 Google, Inc. All rights reserved.
+ 2009 Dirk Schulze <krit@webkit.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -25,14 +26,11 @@
#if ENABLE(SVG)
#include "RenderSVGContainer.h"
-#include "AXObjectCache.h"
-#include "FloatQuad.h"
#include "GraphicsContext.h"
#include "RenderView.h"
#include "SVGRenderSupport.h"
#include "SVGResourceFilter.h"
#include "SVGStyledElement.h"
-#include "SVGURIReference.h"
namespace WebCore {
@@ -62,17 +60,7 @@ void RenderSVGContainer::layout()
LayoutRepainter repainter(*this, checkForRepaintDuringLayout() || selfWillPaint());
calculateLocalTransform(); // Allow RenderSVGTransformableContainer to update its transform
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- // Only force our kids to layout if we're being asked to relayout as a result of a parent changing
- // FIXME: We should be able to skip relayout of non-relative kids when only bounds size has changed
- // that's a possible future optimization using LayoutState
- // http://bugs.webkit.org/show_bug.cgi?id=15391
- if (selfNeedsLayout())
- child->setNeedsLayout(true);
-
- child->layoutIfNeeded();
- ASSERT(!child->needsLayout());
- }
+ layoutChildren(this, selfNeedsLayout());
repainter.repaintAfterLayout();
setNeedsLayout(false);
@@ -82,7 +70,7 @@ bool RenderSVGContainer::selfWillPaint() const
{
#if ENABLE(FILTERS)
const SVGRenderStyle* svgStyle = style()->svgStyle();
- SVGResourceFilter* filter = getFilterById(document(), svgStyle->filter());
+ SVGResourceFilter* filter = getFilterById(document(), svgStyle->filter(), this);
if (filter)
return true;
#endif
@@ -94,7 +82,7 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int)
if (paintInfo.context->paintingDisabled() || !drawsContents())
return;
- // Spec: groups w/o children still may render filter content.
+ // Spec: groups w/o children still may render filter content.
if (!firstChild() && !selfWillPaint())
return;
@@ -109,12 +97,16 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int)
SVGResourceFilter* filter = 0;
FloatRect boundingBox = repaintRectInLocalCoordinates();
+
+ bool continueRendering = true;
if (childPaintInfo.phase == PaintPhaseForeground)
- prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter);
+ continueRendering = prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter);
- childPaintInfo.paintingRoot = paintingRootForChildren(childPaintInfo);
- for (RenderObject* child = firstChild(); child; child = child->nextSibling())
- child->paint(childPaintInfo, 0, 0);
+ if (continueRendering) {
+ childPaintInfo.paintingRoot = paintingRootForChildren(childPaintInfo);
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling())
+ child->paint(childPaintInfo, 0, 0);
+ }
if (paintInfo.phase == PaintPhaseForeground)
finishRenderSVGContent(this, childPaintInfo, filter, paintInfo.context);
@@ -132,10 +124,11 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int)
}
// addFocusRingRects is called from paintOutline and needs to be in the same coordinates as the paintOuline call
-void RenderSVGContainer::addFocusRingRects(GraphicsContext* graphicsContext, int, int)
+void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, int, int)
{
IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRectInLocalCoordinates()));
- graphicsContext->addFocusRingRect(paintRectInParent);
+ if (!paintRectInParent.isEmpty())
+ rects.append(paintRectInParent);
}
FloatRect RenderSVGContainer::objectBoundingBox() const
@@ -143,14 +136,30 @@ FloatRect RenderSVGContainer::objectBoundingBox() const
return computeContainerBoundingBox(this, false);
}
+FloatRect RenderSVGContainer::strokeBoundingBox() const
+{
+ return computeContainerBoundingBox(this, true);
+}
+
// RenderSVGContainer is used for <g> elements which do not themselves have a
// width or height, so we union all of our child rects as our repaint rect.
FloatRect RenderSVGContainer::repaintRectInLocalCoordinates() const
{
FloatRect repaintRect = computeContainerBoundingBox(this, true);
- // A filter on this container can paint outside of the union of the child repaint rects
- repaintRect.unite(filterBoundingBoxForRenderer(this));
+ FloatRect rect = filterBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ repaintRect = rect;
+
+ rect = clipperBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ repaintRect.intersect(rect);
+
+ rect = maskerBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ repaintRect.intersect(rect);
+
+ style()->svgStyle()->inflateForShadow(repaintRect);
return repaintRect;
}
@@ -178,5 +187,3 @@ bool RenderSVGContainer::nodeAtFloatPoint(const HitTestRequest& request, HitTest
}
#endif // ENABLE(SVG)
-
-// vim:ts=4:noet
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.h
index f2195e3faf..f681e505f7 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGContainer.h
@@ -42,10 +42,9 @@ public:
void setDrawsContents(bool);
bool drawsContents() const;
-protected:
virtual void paint(PaintInfo&, int parentX, int parentY);
-private:
+protected:
virtual RenderObjectChildList* virtualChildren() { return children(); }
virtual const RenderObjectChildList* virtualChildren() const { return children(); }
@@ -54,9 +53,10 @@ private:
virtual void layout();
- virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
virtual FloatRect objectBoundingBox() const;
+ virtual FloatRect strokeBoundingBox() const;
virtual FloatRect repaintRectInLocalCoordinates() const;
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
@@ -71,6 +71,7 @@ private:
bool selfWillPaint() const;
+private:
RenderObjectChildList m_children;
bool m_drawsContents : 1;
};
@@ -78,14 +79,14 @@ private:
inline RenderSVGContainer* toRenderSVGContainer(RenderObject* object)
{
// Note: isSVGContainer is also true for RenderSVGViewportContainer, which is not derived from this.
- ASSERT(!object || object->isSVGContainer() && strcmp(object->renderName(), "RenderSVGViewportContainer"));
+ ASSERT(!object || (object->isSVGContainer() && strcmp(object->renderName(), "RenderSVGViewportContainer")));
return static_cast<RenderSVGContainer*>(object);
}
inline const RenderSVGContainer* toRenderSVGContainer(const RenderObject* object)
{
// Note: isSVGContainer is also true for RenderSVGViewportContainer, which is not derived from this.
- ASSERT(!object || object->isSVGContainer() && strcmp(object->renderName(), "RenderSVGViewportContainer"));
+ ASSERT(!object || (object->isSVGContainer() && strcmp(object->renderName(), "RenderSVGViewportContainer")));
return static_cast<const RenderSVGContainer*>(object);
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGGradientStop.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGGradientStop.cpp
index b81e7f41ff..66391c82c6 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGGradientStop.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGGradientStop.cpp
@@ -49,7 +49,7 @@ void RenderSVGGradientStop::styleDidChange(StyleDifference diff, const RenderSty
// <stop> elements should only be allowed to make renderers under gradient elements
// but I can imagine a few cases we might not be catching, so let's not crash if our parent isn't a gradient.
if (SVGGradientElement* gradient = gradientElement()) {
- if (SVGResource* resource = gradient->canvasResource())
+ if (SVGResource* resource = gradient->canvasResource(this))
resource->invalidate();
}
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.cpp
index d4b39d3a74..bb0a15d344 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.cpp
@@ -38,17 +38,7 @@ RenderSVGHiddenContainer::RenderSVGHiddenContainer(SVGStyledElement* element)
void RenderSVGHiddenContainer::layout()
{
ASSERT(needsLayout());
-
- // Layout our kids to prevent a kid from being marked as needing layout
- // then never being asked to layout.
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (selfNeedsLayout())
- child->setNeedsLayout(true);
-
- child->layoutIfNeeded();
- ASSERT(!child->needsLayout());
- }
-
+ layoutChildren(this, selfNeedsLayout());
setNeedsLayout(false);
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.h
index 0ef0a430e7..fdbd2bcfa3 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGHiddenContainer.h
@@ -51,9 +51,6 @@ namespace WebCore {
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
- // FIXME: This override only exists to match existing LayoutTest results.
- virtual TransformationMatrix absoluteTransform() const { return TransformationMatrix(); }
-
virtual FloatRect objectBoundingBox() const;
virtual FloatRect repaintRectInLocalCoordinates() const;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.cpp
index 7e0b40d539..6fb9501674 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.cpp
@@ -4,6 +4,7 @@
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
Copyright (C) 2007, 2008, 2009 Rob Buis <buis@kde.org>
Copyright (C) 2009, Google, Inc.
+ Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -36,9 +37,6 @@
#include "SVGLength.h"
#include "SVGPreserveAspectRatio.h"
#include "SVGRenderSupport.h"
-#include "SVGResourceClipper.h"
-#include "SVGResourceFilter.h"
-#include "SVGResourceMasker.h"
namespace WebCore {
@@ -47,81 +45,6 @@ RenderSVGImage::RenderSVGImage(SVGImageElement* impl)
{
}
-void RenderSVGImage::adjustRectsForAspectRatio(FloatRect& destRect, FloatRect& srcRect, SVGPreserveAspectRatio* aspectRatio)
-{
- float origDestWidth = destRect.width();
- float origDestHeight = destRect.height();
- if (aspectRatio->meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET) {
- float widthToHeightMultiplier = srcRect.height() / srcRect.width();
- if (origDestHeight > (origDestWidth * widthToHeightMultiplier)) {
- destRect.setHeight(origDestWidth * widthToHeightMultiplier);
- switch (aspectRatio->align()) {
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
- destRect.setY(destRect.y() + origDestHeight / 2.0f - destRect.height() / 2.0f);
- break;
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
- destRect.setY(destRect.y() + origDestHeight - destRect.height());
- break;
- }
- }
- if (origDestWidth > (origDestHeight / widthToHeightMultiplier)) {
- destRect.setWidth(origDestHeight / widthToHeightMultiplier);
- switch (aspectRatio->align()) {
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
- destRect.setX(destRect.x() + origDestWidth / 2.0f - destRect.width() / 2.0f);
- break;
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
- destRect.setX(destRect.x() + origDestWidth - destRect.width());
- break;
- }
- }
- } else if (aspectRatio->meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE) {
- float widthToHeightMultiplier = srcRect.height() / srcRect.width();
- // if the destination height is less than the height of the image we'll be drawing
- if (origDestHeight < (origDestWidth * widthToHeightMultiplier)) {
- float destToSrcMultiplier = srcRect.width() / destRect.width();
- srcRect.setHeight(destRect.height() * destToSrcMultiplier);
- switch (aspectRatio->align()) {
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
- srcRect.setY(destRect.y() + image()->height() / 2.0f - srcRect.height() / 2.0f);
- break;
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
- srcRect.setY(destRect.y() + image()->height() - srcRect.height());
- break;
- }
- }
- // if the destination width is less than the width of the image we'll be drawing
- if (origDestWidth < (origDestHeight / widthToHeightMultiplier)) {
- float destToSrcMultiplier = srcRect.height() / destRect.height();
- srcRect.setWidth(destRect.width() * destToSrcMultiplier);
- switch (aspectRatio->align()) {
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
- srcRect.setX(destRect.x() + image()->width() / 2.0f - srcRect.width() / 2.0f);
- break;
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
- case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
- srcRect.setX(destRect.x() + image()->width() - srcRect.width());
- break;
- }
- }
- }
-}
-
void RenderSVGImage::layout()
{
ASSERT(needsLayout());
@@ -138,6 +61,7 @@ void RenderSVGImage::layout()
calcHeight();
m_localBounds = FloatRect(image->x().value(image), image->y().value(image), image->width().value(image), image->height().value(image));
+ m_cachedLocalRepaintRect = FloatRect();
repainter.repaintAfterLayout();
@@ -157,16 +81,16 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
PaintInfo savedInfo(paintInfo);
- prepareToRenderSVGContent(this, paintInfo, m_localBounds, filter);
-
- FloatRect destRect = m_localBounds;
- FloatRect srcRect(0, 0, image()->width(), image()->height());
+ if (prepareToRenderSVGContent(this, paintInfo, m_localBounds, filter)) {
+ FloatRect destRect = m_localBounds;
+ FloatRect srcRect(0, 0, image()->width(), image()->height());
- SVGImageElement* imageElt = static_cast<SVGImageElement*>(node());
- if (imageElt->preserveAspectRatio()->align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
- adjustRectsForAspectRatio(destRect, srcRect, imageElt->preserveAspectRatio());
+ SVGImageElement* imageElt = static_cast<SVGImageElement*>(node());
+ if (imageElt->preserveAspectRatio().align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
+ imageElt->preserveAspectRatio().transformRect(destRect, srcRect);
- paintInfo.context->drawImage(image(), destRect, srcRect);
+ paintInfo.context->drawImage(image(), DeviceColorSpace, destRect, srcRect);
+ }
finishRenderSVGContent(this, paintInfo, filter, savedInfo.context);
}
@@ -176,6 +100,12 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
paintInfo.context->restore();
}
+void RenderSVGImage::destroy()
+{
+ SVGRenderBase::deregisterFromResources(this);
+ RenderImage::destroy();
+}
+
bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
// We only draw in the forground phase, so we only hit-test then.
@@ -212,12 +142,29 @@ FloatRect RenderSVGImage::objectBoundingBox() const
FloatRect RenderSVGImage::repaintRectInLocalCoordinates() const
{
- FloatRect repaintRect = m_localBounds;
+ // If we already have a cached repaint rect, return that
+ if (!m_cachedLocalRepaintRect.isEmpty())
+ return m_cachedLocalRepaintRect;
+
+ m_cachedLocalRepaintRect = m_localBounds;
+
+ // FIXME: We need to be careful here. We assume that there is no filter,
+ // clipper or masker if the rects are empty.
+ FloatRect rect = filterBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ m_cachedLocalRepaintRect = rect;
+
+ rect = clipperBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ m_cachedLocalRepaintRect.intersect(rect);
+
+ rect = maskerBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ m_cachedLocalRepaintRect.intersect(rect);
- // Filters can paint outside the image content
- repaintRect.unite(filterBoundingBoxForRenderer(this));
+ style()->svgStyle()->inflateForShadow(m_cachedLocalRepaintRect);
- return repaintRect;
+ return m_cachedLocalRepaintRect;
}
void RenderSVGImage::imageChanged(WrappedImagePtr image, const IntRect* rect)
@@ -241,11 +188,12 @@ void RenderSVGImage::mapLocalToContainer(RenderBoxModelObject* repaintContainer,
SVGRenderBase::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState);
}
-void RenderSVGImage::addFocusRingRects(GraphicsContext* graphicsContext, int, int)
+void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, int, int)
{
// this is called from paint() after the localTransform has already been applied
IntRect contentRect = enclosingIntRect(repaintRectInLocalCoordinates());
- graphicsContext->addFocusRingRect(contentRect);
+ if (!contentRect.isEmpty())
+ rects.append(contentRect);
}
void RenderSVGImage::absoluteRects(Vector<IntRect>& rects, int, int)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.h
index ef117191d9..f48b9dd9f1 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGImage.h
@@ -24,55 +24,58 @@
#define RenderSVGImage_h
#if ENABLE(SVG)
-
-#include "TransformationMatrix.h"
+#include "AffineTransform.h"
#include "FloatRect.h"
#include "RenderImage.h"
+#include "SVGPreserveAspectRatio.h"
#include "SVGRenderSupport.h"
namespace WebCore {
- class SVGImageElement;
- class SVGPreserveAspectRatio;
+class SVGImageElement;
+
+class RenderSVGImage : public RenderImage, protected SVGRenderBase {
+public:
+ RenderSVGImage(SVGImageElement*);
- class RenderSVGImage : public RenderImage, SVGRenderBase {
- public:
- RenderSVGImage(SVGImageElement*);
+private:
+ virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
+ virtual const char* renderName() const { return "RenderSVGImage"; }
+ virtual bool isSVGImage() const { return true; }
- private:
- virtual const char* renderName() const { return "RenderSVGImage"; }
- virtual bool isSVGImage() const { return true; }
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
- virtual TransformationMatrix localToParentTransform() const { return m_localTransform; }
+ virtual FloatRect objectBoundingBox() const;
+ virtual FloatRect strokeBoundingBox() const { return m_localBounds; }
+ virtual FloatRect repaintRectInLocalCoordinates() const;
- virtual FloatRect objectBoundingBox() const;
- virtual FloatRect repaintRectInLocalCoordinates() const;
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
+ virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
- virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
- virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
+ virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
- virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
+ virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
+ virtual void absoluteQuads(Vector<FloatQuad>&);
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
- virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
- virtual void absoluteQuads(Vector<FloatQuad>&);
- virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+
+ virtual void layout();
+ virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
- void adjustRectsForAspectRatio(FloatRect& destRect, FloatRect& srcRect, SVGPreserveAspectRatio*);
-
- virtual void layout();
- virtual void paint(PaintInfo&, int parentX, int parentY);
+ virtual void destroy();
- virtual bool requiresLayer() const { return false; }
+ virtual bool requiresLayer() const { return false; }
- virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
- virtual TransformationMatrix localTransform() const { return m_localTransform; }
+ virtual AffineTransform localTransform() const { return m_localTransform; }
- TransformationMatrix m_localTransform;
- FloatRect m_localBounds;
- };
+ AffineTransform m_localTransform;
+ FloatRect m_localBounds;
+ mutable FloatRect m_cachedLocalRepaintRect;
+};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.cpp
index cf97b52add..33459ce93c 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.cpp
@@ -48,9 +48,9 @@ InlineFlowBox* RenderSVGInline::createInlineFlowBox()
void RenderSVGInline::absoluteRects(Vector<IntRect>& rects, int, int)
{
- InlineRunBox* firstBox = firstLineBox();
+ InlineFlowBox* firstBox = firstLineBox();
- SVGRootInlineBox* rootBox = firstBox ? static_cast<SVGInlineTextBox*>(firstBox)->svgRootInlineBox() : 0;
+ RootInlineBox* rootBox = firstBox ? firstBox->root() : 0;
RenderBox* object = rootBox ? rootBox->block() : 0;
if (!object)
@@ -59,17 +59,45 @@ void RenderSVGInline::absoluteRects(Vector<IntRect>& rects, int, int)
int xRef = object->x();
int yRef = object->y();
- for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
FloatRect rect(xRef + curr->x(), yRef + curr->y(), curr->width(), curr->height());
rects.append(enclosingIntRect(localToAbsoluteQuad(rect).boundingBox()));
}
}
+FloatRect RenderSVGInline::objectBoundingBox() const
+{
+ if (const RenderObject* object = findTextRootObject(this))
+ return object->objectBoundingBox();
+
+ return FloatRect();
+}
+
+FloatRect RenderSVGInline::strokeBoundingBox() const
+{
+ const RenderObject* object = findTextRootObject(this);
+ ASSERT(object);
+
+ const SVGRenderBase* renderer = object->toSVGRenderBase();
+ if (!renderer)
+ return FloatRect();
+
+ return renderer->strokeBoundingBox();
+}
+
+FloatRect RenderSVGInline::repaintRectInLocalCoordinates() const
+{
+ if (const RenderObject* object = findTextRootObject(this))
+ return object->repaintRectInLocalCoordinates();
+
+ return FloatRect();
+}
+
void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads)
{
- InlineRunBox* firstBox = firstLineBox();
+ InlineFlowBox* firstBox = firstLineBox();
- SVGRootInlineBox* rootBox = firstBox ? static_cast<SVGInlineTextBox*>(firstBox)->svgRootInlineBox() : 0;
+ RootInlineBox* rootBox = firstBox ? firstBox->root() : 0;
RenderBox* object = rootBox ? rootBox->block() : 0;
if (!object)
@@ -78,7 +106,7 @@ void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads)
int xRef = object->x();
int yRef = object->y();
- for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
+ for (InlineFlowBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
FloatRect rect(xRef + curr->x(), yRef + curr->y(), curr->width(), curr->height());
quads.append(localToAbsoluteQuad(rect));
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.h
index 9f9f3f5f2e..e57b93605d 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInline.h
@@ -27,17 +27,31 @@
#if ENABLE(SVG)
#include "RenderInline.h"
+#include "SVGRenderSupport.h"
+
namespace WebCore {
-class RenderSVGInline : public RenderInline {
+class RenderSVGInline : public RenderInline, protected SVGRenderBase {
public:
RenderSVGInline(Node*);
+
+ virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
+
virtual const char* renderName() const { return "RenderSVGInline"; }
virtual bool requiresLayer() const { return false; }
// These are shared between RenderSVGTSpan and RenderSVGTextPath
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
+
+ // Chapter 10.4 of the SVG Specification say that we should use the
+ // object bounding box of the parent text element.
+ // We search for the root text element and take it's bounding box.
+ // It is also necessary to take the stroke and repaint rect of
+ // this element, since we need it for filters.
+ virtual FloatRect objectBoundingBox() const;
+ virtual FloatRect strokeBoundingBox() const;
+ virtual FloatRect repaintRectInLocalCoordinates() const;
private:
virtual InlineFlowBox* createInlineFlowBox();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.h
index e9c5d6e190..b475067909 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.h
@@ -39,6 +39,10 @@ private:
virtual void styleDidChange(StyleDifference, const RenderStyle*);
+ // FIXME: We need objectBoundingBox for DRT results and filters at the moment.
+ // This should be fixed to give back the objectBoundingBox of the text root.
+ virtual FloatRect objectBoundingBox() const { return FloatRect(); }
+
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.cpp
index 3fab5a6bab..c163dc6363 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.cpp
@@ -38,10 +38,6 @@
#include "RenderView.h"
#include "SVGStyledElement.h"
-#if ENABLE(FILTERS)
-#include "SVGResourceFilter.h"
-#endif
-
namespace WebCore {
RenderSVGModelObject::RenderSVGModelObject(SVGStyledElement* node)
@@ -86,6 +82,12 @@ void RenderSVGModelObject::absoluteQuads(Vector<FloatQuad>& quads)
quads.append(absoluteClippedOverflowRect());
}
+void RenderSVGModelObject::destroy()
+{
+ deregisterFromResources(this);
+ RenderObject::destroy();
+}
+
bool RenderSVGModelObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
{
ASSERT_NOT_REACHED();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.h
index 0aa13adc8f..c04c5900a2 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGModelObject.h
@@ -49,6 +49,8 @@ class RenderSVGModelObject : public RenderObject, protected SVGRenderBase {
public:
RenderSVGModelObject(SVGStyledElement*);
+ virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
+
virtual bool requiresLayer() const { return false; }
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
@@ -58,6 +60,8 @@ public:
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
+ virtual void destroy();
+
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
private:
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGResource.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResource.h
new file mode 100644
index 0000000000..184ffe3954
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResource.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderSVGResource_h
+#define RenderSVGResource_h
+
+#if ENABLE(SVG)
+#include "FloatRect.h"
+#include "RenderSVGHiddenContainer.h"
+
+namespace WebCore {
+
+enum RenderSVGResourceType {
+ MaskerResourceType,
+ ClipperResourceType
+};
+
+class RenderSVGResource : public RenderSVGHiddenContainer {
+public:
+ RenderSVGResource(SVGStyledElement* node) : RenderSVGHiddenContainer(node) { }
+
+ template<class Renderer>
+ Renderer* cast()
+ {
+ if (Renderer::s_resourceType == resourceType())
+ return static_cast<Renderer*>(this);
+
+ return 0;
+ }
+
+ virtual RenderSVGResource* toRenderSVGResource() { return this; }
+ virtual bool isSVGResource() const { return true; }
+ virtual bool drawsContents() { return false; }
+
+ virtual void invalidateClients() = 0;
+ virtual void invalidateClient(RenderObject*) = 0;
+
+ virtual bool applyResource(RenderObject*, GraphicsContext*) = 0;
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const = 0;
+
+ virtual RenderSVGResourceType resourceType() const = 0;
+};
+
+template<typename Renderer>
+Renderer* getRenderSVGResourceById(Document* document, const AtomicString& id)
+{
+ if (id.isEmpty())
+ return 0;
+
+ Element* element = document->getElementById(id);
+ if (!element || !element->isSVGElement())
+ return 0;
+
+ RenderObject* renderer = element->renderer();
+ if (!renderer)
+ return 0;
+
+ RenderSVGResource* renderResource = renderer->toRenderSVGResource();
+ if (!renderResource)
+ return 0;
+
+ return renderResource->cast<Renderer>();
+}
+
+}
+
+#endif
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceClipper.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceClipper.cpp
new file mode 100644
index 0000000000..dfc4b1e9bb
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
+ * 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org>
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderSVGResourceClipper.h"
+
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "RenderSVGResource.h"
+#include "SVGClipPathElement.h"
+#include "SVGElement.h"
+#include "SVGRenderSupport.h"
+#include "SVGStyledElement.h"
+#include "SVGStyledTransformableElement.h"
+#include "SVGUnitTypes.h"
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourceClipper::s_resourceType = ClipperResourceType;
+
+RenderSVGResourceClipper::RenderSVGResourceClipper(SVGStyledElement* node)
+ : RenderSVGResource(node)
+{
+}
+
+RenderSVGResourceClipper::~RenderSVGResourceClipper()
+{
+ m_clipper.clear();
+}
+
+void RenderSVGResourceClipper::invalidateClients()
+{
+ HashSet<RenderObject*>::const_iterator end = m_clipper.end();
+ for (HashSet<RenderObject*>::const_iterator it = m_clipper.begin(); it != end; ++it)
+ (*it)->setNeedsLayout(true);
+ m_clipper.clear();
+}
+
+void RenderSVGResourceClipper::invalidateClient(RenderObject* object)
+{
+ ASSERT(object);
+
+ // FIXME: The HashSet should always contain the object on calling invalidateClient. A race condition
+ // during the parsing can causes a call of invalidateClient right before the call of applyResource.
+ // We return earlier for the moment. This bug should be fixed in:
+ // https://bugs.webkit.org/show_bug.cgi?id=35181
+ if (!m_clipper.contains(object))
+ return;
+
+ m_clipper.remove(object);
+}
+
+bool RenderSVGResourceClipper::applyResource(RenderObject* object, GraphicsContext* context)
+{
+ ASSERT(object);
+ ASSERT(context);
+
+ m_clipper.add(object);
+
+ context->beginPath();
+
+ AffineTransform obbTransform;
+ FloatRect objectBoundingBox = object->objectBoundingBox();
+ bool bbox = static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
+ if (bbox) {
+ obbTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ obbTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ }
+
+ bool hasClipPath = false;
+ WindRule clipRule = RULE_EVENODD;
+ for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
+ if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyledTransformable())
+ continue;
+ SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(childNode);
+ RenderStyle* style = styled->renderer() ? styled->renderer()->style() : 0;
+ if (!style || style->display() == NONE)
+ continue;
+ Path pathData = styled->toClipPath();
+ if (pathData.isEmpty())
+ continue;
+ if (bbox)
+ pathData.transform(obbTransform);
+ hasClipPath = true;
+ context->addPath(pathData);
+ clipRule = style->svgStyle()->clipRule();
+ }
+
+ if (!hasClipPath) {
+ Path clipPath;
+ clipPath.addRect(FloatRect());
+ context->addPath(clipPath);
+ }
+
+ // FIXME!
+ // We don't currently allow for heterogenous clip rules.
+ // we would have to detect such, draw to a mask, and then clip
+ // to that mask
+ context->clipPath(clipRule);
+
+ return true;
+}
+
+FloatRect RenderSVGResourceClipper::resourceBoundingBox(const FloatRect& objectBoundingBox) const
+{
+ FloatRect clipRect;
+ for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
+ if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyledTransformable())
+ continue;
+ SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(childNode);
+ RenderStyle* style = styled->renderer() ? styled->renderer()->style() : 0;
+ if (!style || style->display() == NONE || styled->toClipPath().isEmpty())
+ continue;
+ clipRect.unite(styled->renderer()->objectBoundingBox());
+ }
+
+ if (clipRect.isEmpty())
+ return FloatRect();
+
+ if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ AffineTransform obbTransform;
+ obbTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ obbTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ return obbTransform.mapRect(clipRect);
+ }
+
+ return clipRect;
+}
+
+}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceClipper.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceClipper.h
new file mode 100644
index 0000000000..0e1d2b5ce9
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceClipper.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderSVGResourceClipper_h
+#define RenderSVGResourceClipper_h
+
+#if ENABLE(SVG)
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "RenderSVGResource.h"
+#include "SVGClipPathElement.h"
+#include "SVGUnitTypes.h"
+
+#include <wtf/HashSet.h>
+
+namespace WebCore {
+
+class RenderSVGResourceClipper : public RenderSVGResource {
+
+public:
+ RenderSVGResourceClipper(SVGStyledElement*);
+ virtual ~RenderSVGResourceClipper();
+
+ virtual const char* renderName() const { return "RenderSVGResourceClipper"; }
+
+ virtual void invalidateClients();
+ virtual void invalidateClient(RenderObject*);
+
+ virtual bool applyResource(RenderObject*, GraphicsContext*);
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const;
+
+ virtual RenderSVGResourceType resourceType() const { return ClipperResourceType; }
+
+ SVGUnitTypes::SVGUnitType clipPathUnits() const { return toUnitType(static_cast<SVGClipPathElement*>(node())->clipPathUnits()); }
+
+ static RenderSVGResourceType s_resourceType;
+private:
+ HashSet<RenderObject*> m_clipper;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceMasker.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceMasker.cpp
new file mode 100644
index 0000000000..2923c6e2d1
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderSVGResourceMasker.h"
+
+#include "AffineTransform.h"
+#include "CanvasPixelArray.h"
+#include "Element.h"
+#include "FloatPoint.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "IntRect.h"
+#include "SVGElement.h"
+#include "SVGMaskElement.h"
+#include "SVGStyledElement.h"
+#include "SVGUnitTypes.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+RenderSVGResourceType RenderSVGResourceMasker::s_resourceType = MaskerResourceType;
+
+RenderSVGResourceMasker::RenderSVGResourceMasker(SVGStyledElement* node)
+ : RenderSVGResource(node)
+{
+}
+
+RenderSVGResourceMasker::~RenderSVGResourceMasker()
+{
+ deleteAllValues(m_masker);
+ m_masker.clear();
+}
+
+void RenderSVGResourceMasker::invalidateClients()
+{
+ HashMap<RenderObject*, MaskerData*>::const_iterator end = m_masker.end();
+ for (HashMap<RenderObject*, MaskerData*>::const_iterator it = m_masker.begin(); it != end; ++it)
+ it->first->setNeedsLayout(true);
+ deleteAllValues(m_masker);
+ m_masker.clear();
+}
+
+void RenderSVGResourceMasker::invalidateClient(RenderObject* object)
+{
+ ASSERT(object);
+
+ // FIXME: The HashMap should always contain the object on calling invalidateClient. A race condition
+ // during the parsing can causes a call of invalidateClient right before the call of applyResource.
+ // We return earlier for the moment. This bug should be fixed in:
+ // https://bugs.webkit.org/show_bug.cgi?id=35181
+ if (!m_masker.contains(object))
+ return;
+
+ delete m_masker.take(object);
+}
+
+bool RenderSVGResourceMasker::applyResource(RenderObject* object, GraphicsContext* context)
+{
+ ASSERT(object);
+ ASSERT(context);
+
+ if (!m_masker.contains(object))
+ m_masker.set(object, new MaskerData);
+
+ MaskerData* maskerData = m_masker.get(object);
+ if (!maskerData->maskImage && !maskerData->emptyMask) {
+ SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
+ if (!maskElement)
+ return false;
+
+ createMaskImage(maskerData, maskElement, object);
+ }
+
+ if (!maskerData->maskImage)
+ return false;
+
+ context->clipToImageBuffer(maskerData->maskRect, maskerData->maskImage.get());
+ return true;
+}
+
+FloatRect RenderSVGResourceMasker::resourceBoundingBox(const FloatRect& objectBoundingBox) const
+{
+ if (SVGMaskElement* element = static_cast<SVGMaskElement*>(node()))
+ return element->maskBoundingBox(objectBoundingBox);
+
+ return FloatRect();
+}
+
+void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
+{
+ FloatRect objectBoundingBox = object->objectBoundingBox();
+
+ // Mask rect clipped with clippingBoundingBox and filterBoundingBox as long as they are present.
+ maskerData->maskRect = object->repaintRectInLocalCoordinates();
+ if (maskerData->maskRect.isEmpty()) {
+ maskerData->emptyMask = true;
+ return;
+ }
+
+ // Calculate the smallest rect for the mask ImageBuffer.
+ FloatRect repaintRect;
+ Vector<RenderObject*> rendererList;
+ for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
+ RenderObject* renderer = node->renderer();
+ if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !renderer)
+ continue;
+
+ rendererList.append(renderer);
+ repaintRect.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
+ }
+
+ AffineTransform contextTransform;
+ // We need to scale repaintRect for objectBoundingBox to get the drawing area.
+ if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ contextTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ FloatPoint contextAdjustment = repaintRect.location();
+ repaintRect = contextTransform.mapRect(repaintRect);
+ repaintRect.move(objectBoundingBox.x(), objectBoundingBox.y());
+ contextTransform.translate(-contextAdjustment.x(), -contextAdjustment.y());
+ }
+ repaintRect.intersect(maskerData->maskRect);
+ maskerData->maskRect = repaintRect;
+ IntRect maskImageRect = enclosingIntRect(maskerData->maskRect);
+
+ maskImageRect.setLocation(IntPoint());
+
+ // Don't create ImageBuffers with image size of 0
+ if (!maskImageRect.width() || !maskImageRect.height()) {
+ maskerData->emptyMask = true;
+ return;
+ }
+
+ // FIXME: This changes color space to linearRGB, the default color space
+ // for masking operations in SVG. We need a switch for the other color-space
+ // attribute values sRGB, inherit and auto.
+ maskerData->maskImage = ImageBuffer::create(maskImageRect.size(), LinearRGB);
+ if (!maskerData->maskImage)
+ return;
+
+ GraphicsContext* maskImageContext = maskerData->maskImage->context();
+ ASSERT(maskImageContext);
+
+ maskImageContext->save();
+
+ if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
+ maskImageContext->translate(-maskerData->maskRect.x(), -maskerData->maskRect.y());
+ maskImageContext->concatCTM(contextTransform);
+
+ // draw the content into the ImageBuffer
+ Vector<RenderObject*>::iterator end = rendererList.end();
+ for (Vector<RenderObject*>::iterator it = rendererList.begin(); it != end; it++)
+ renderSubtreeToImage(maskerData->maskImage.get(), *it);
+
+ maskImageContext->restore();
+
+ // create the luminance mask
+ RefPtr<ImageData> imageData(maskerData->maskImage->getUnmultipliedImageData(maskImageRect));
+ CanvasPixelArray* srcPixelArray(imageData->data());
+
+ for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset += 4) {
+ unsigned char a = srcPixelArray->get(pixelOffset + 3);
+ if (!a)
+ continue;
+ unsigned char r = srcPixelArray->get(pixelOffset);
+ unsigned char g = srcPixelArray->get(pixelOffset + 1);
+ unsigned char b = srcPixelArray->get(pixelOffset + 2);
+
+ double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0);
+ srcPixelArray->set(pixelOffset + 3, luma);
+ }
+
+ maskerData->maskImage->putUnmultipliedImageData(imageData.get(), maskImageRect, IntPoint());
+}
+
+}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceMasker.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceMasker.h
new file mode 100644
index 0000000000..6c73c84dc6
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGResourceMasker.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderSVGResourceMasker_h
+#define RenderSVGResourceMasker_h
+
+#if ENABLE(SVG)
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "IntSize.h"
+#include "RenderSVGResource.h"
+#include "SVGMaskElement.h"
+#include "SVGUnitTypes.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+struct MaskerData {
+ MaskerData(FloatRect rect = FloatRect(), bool emptyObject = false)
+ : maskRect(rect)
+ , emptyMask(emptyObject)
+ {
+ }
+
+ OwnPtr<ImageBuffer> maskImage;
+ FloatRect maskRect;
+ bool emptyMask;
+};
+
+class RenderSVGResourceMasker : public RenderSVGResource {
+
+public:
+ RenderSVGResourceMasker(SVGStyledElement*);
+ virtual ~RenderSVGResourceMasker();
+
+ virtual const char* renderName() const { return "RenderSVGResourceMasker"; }
+
+ virtual void invalidateClients();
+ virtual void invalidateClient(RenderObject*);
+
+ virtual bool applyResource(RenderObject*, GraphicsContext*);
+ virtual FloatRect resourceBoundingBox(const FloatRect&) const;
+
+ SVGUnitTypes::SVGUnitType maskUnits() const { return toUnitType(static_cast<SVGMaskElement*>(node())->maskUnits()); }
+ SVGUnitTypes::SVGUnitType maskContentUnits() const { return toUnitType(static_cast<SVGMaskElement*>(node())->maskContentUnits()); }
+
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
+
+private:
+ void createMaskImage(MaskerData*, const SVGMaskElement*, RenderObject*);
+
+ HashMap<RenderObject*, MaskerData*> m_masker;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.cpp
index 0a39bf4725..51bf3e733a 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.cpp
@@ -77,6 +77,28 @@ void RenderSVGRoot::calcPrefWidths()
setPrefWidthsDirty(false);
}
+int RenderSVGRoot::calcReplacedWidth(bool includeMaxWidth) const
+{
+ int replacedWidth = RenderBox::calcReplacedWidth(includeMaxWidth);
+ if (!style()->width().isPercent())
+ return replacedWidth;
+
+ // FIXME: Investigate in size rounding issues
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ return static_cast<int>(roundf(replacedWidth * svg->currentScale()));
+}
+
+int RenderSVGRoot::calcReplacedHeight() const
+{
+ int replacedHeight = RenderBox::calcReplacedHeight();
+ if (!style()->height().isPercent())
+ return replacedHeight;
+
+ // FIXME: Investigate in size rounding issues
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ return static_cast<int>(roundf(replacedHeight * svg->currentScale()));
+}
+
void RenderSVGRoot::layout()
{
ASSERT(needsLayout());
@@ -84,25 +106,19 @@ void RenderSVGRoot::layout()
// Arbitrary affine transforms are incompatible with LayoutState.
view()->disableLayoutState();
- LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
+ bool needsLayout = selfNeedsLayout();
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && needsLayout);
+ IntSize oldSize(width(), height());
calcWidth();
calcHeight();
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
- setWidth(static_cast<int>(width() * svg->currentScale()));
- setHeight(static_cast<int>(height() * svg->currentScale()));
-
calcViewport();
-
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (selfNeedsLayout()) // either bounds or transform changed, force kids to relayout
- child->setNeedsLayout(true, false);
-
- child->layoutIfNeeded();
- ASSERT(!child->needsLayout());
- }
+ // RenderSVGRoot needs to take special care to propagate window size changes to the children,
+ // if the outermost <svg> is using relative x/y/width/height values. Hence the additonal parameters.
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ layoutChildren(this, needsLayout || (svg->hasRelativeValues() && oldSize != size()));
repainter.repaintAfterLayout();
view()->enableLayoutState();
@@ -113,7 +129,7 @@ bool RenderSVGRoot::selfWillPaint() const
{
#if ENABLE(FILTERS)
const SVGRenderStyle* svgStyle = style()->svgStyle();
- SVGResourceFilter* filter = getFilterById(document(), svgStyle->filter());
+ SVGResourceFilter* filter = getFilterById(document(), svgStyle->filter(), this);
if (filter)
return true;
#endif
@@ -126,13 +142,13 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
return;
IntPoint parentOriginInContainer(parentX, parentY);
- IntPoint borderBoxOriginInContainer = parentOriginInContainer + IntSize(x(), y());
+ IntPoint borderBoxOriginInContainer = parentOriginInContainer + parentOriginToBorderBox();
if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
paintBoxDecorations(paintInfo, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y());
// An empty viewport disables rendering. FIXME: Should we still render filters?
- if (viewportSize().isEmpty())
+ if (m_viewportSize.isEmpty())
return;
// Don't paint if we don't have kids, except if we have filters we should paint those.
@@ -143,9 +159,8 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
RenderObject::PaintInfo childPaintInfo(paintInfo);
childPaintInfo.context->save();
- // SVG does not support independent x/y clipping
- if (style()->overflowX() != OVISIBLE)
- childPaintInfo.context->clip(overflowClipRect(borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y()));
+ // Apply initial viewport clip - not affected by overflow handling
+ childPaintInfo.context->clip(overflowClipRect(borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y()));
// Convert from container offsets (html renderers) to a relative transform (svg renderers).
// Transform from our paint container's coordinate system to our local coords.
@@ -153,10 +168,13 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
SVGResourceFilter* filter = 0;
FloatRect boundingBox = repaintRectInLocalCoordinates();
+
+ bool continueRendering = true;
if (childPaintInfo.phase == PaintPhaseForeground)
- prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter);
+ continueRendering = prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter);
- RenderBox::paint(childPaintInfo, 0, 0);
+ if (continueRendering)
+ RenderBox::paint(childPaintInfo, 0, 0);
if (childPaintInfo.phase == PaintPhaseForeground)
finishRenderSVGContent(this, childPaintInfo, filter, paintInfo.context);
@@ -167,9 +185,10 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
paintOutline(paintInfo.context, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y(), width(), height(), style());
}
-const FloatSize& RenderSVGRoot::viewportSize() const
+void RenderSVGRoot::destroy()
{
- return m_viewportSize;
+ deregisterFromResources(this);
+ RenderBox::destroy();
}
void RenderSVGRoot::calcViewport()
@@ -183,28 +202,28 @@ void RenderSVGRoot::calcViewport()
// In the normal case of <svg> being stand-alone or in a CSSBoxModel object we use
// RenderBox::width()/height() (which pulls data from RenderStyle)
m_viewportSize = FloatSize(width(), height());
- } else {
- // In the SVGImage case grab the SVGLength values off of SVGSVGElement and use
- // the special relativeWidthValue accessors which respect the specified containerSize
- SVGLength width = svg->width();
- SVGLength height = svg->height();
- float viewportWidth = (width.unitType() == LengthTypePercentage) ? svg->relativeWidthValue() : width.value(svg);
- float viewportHeight = (height.unitType() == LengthTypePercentage) ? svg->relativeHeightValue() : height.value(svg);
- m_viewportSize = FloatSize(viewportWidth, viewportHeight);
+ return;
}
+
+ // In the SVGImage case grab the SVGLength values off of SVGSVGElement and use
+ // the special relativeWidthValue accessors which respect the specified containerSize
+ // FIXME: Check how SVGImage + zooming is supposed to be handled?
+ SVGLength width = svg->width();
+ SVGLength height = svg->height();
+ m_viewportSize = FloatSize(width.unitType() == LengthTypePercentage ? svg->relativeWidthValue() : width.value(svg),
+ height.unitType() == LengthTypePercentage ? svg->relativeHeightValue() : height.value(svg));
}
// RenderBox methods will expect coordinates w/o any transforms in coordinates
// relative to our borderBox origin. This method gives us exactly that.
-TransformationMatrix RenderSVGRoot::localToBorderBoxTransform() const
+AffineTransform RenderSVGRoot::localToBorderBoxTransform() const
{
- TransformationMatrix ctm;
IntSize borderAndPadding = borderOriginToContentBox();
- ctm.translate(borderAndPadding.width(), borderAndPadding.height());
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
- ctm.scale(svg->currentScale());
- ctm.translate(svg->currentTranslate().x(), svg->currentTranslate().y());
- return svg->viewBoxToViewTransform(width(), height()) * ctm;
+ float scale = svg->currentScale();
+ FloatPoint translate = svg->currentTranslate();
+ AffineTransform ctm(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y());
+ return svg->viewBoxToViewTransform(width() / scale, height() / scale) * ctm;
}
IntSize RenderSVGRoot::parentOriginToBorderBox() const
@@ -217,28 +236,21 @@ IntSize RenderSVGRoot::borderOriginToContentBox() const
return IntSize(borderLeft() + paddingLeft(), borderTop() + paddingTop());
}
-TransformationMatrix RenderSVGRoot::localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const
+AffineTransform RenderSVGRoot::localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const
{
- TransformationMatrix parentToContainer;
- parentToContainer.translate(parentOriginInContainer.x(), parentOriginInContainer.y());
- return localToParentTransform() * parentToContainer;
+ AffineTransform parentToContainer(localToParentTransform());
+ return parentToContainer.translateRight(parentOriginInContainer.x(), parentOriginInContainer.y());
}
-TransformationMatrix RenderSVGRoot::localToParentTransform() const
+const AffineTransform& RenderSVGRoot::localToParentTransform() const
{
IntSize parentToBorderBoxOffset = parentOriginToBorderBox();
- TransformationMatrix borderBoxOriginToParentOrigin;
- borderBoxOriginToParentOrigin.translate(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height());
-
- return localToBorderBoxTransform() * borderBoxOriginToParentOrigin;
-}
+ AffineTransform borderBoxOriginToParentOrigin(localToBorderBoxTransform());
+ borderBoxOriginToParentOrigin.translateRight(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height());
-// FIXME: This method should be removed as soon as callers to RenderBox::absoluteTransform() can be removed.
-TransformationMatrix RenderSVGRoot::absoluteTransform() const
-{
- // This would apply localTransform() twice if localTransform() were not the identity.
- return localToParentTransform() * RenderBox::absoluteTransform();
+ m_localToParentTransform = borderBoxOriginToParentOrigin;
+ return m_localToParentTransform;
}
FloatRect RenderSVGRoot::objectBoundingBox() const
@@ -249,18 +261,26 @@ FloatRect RenderSVGRoot::objectBoundingBox() const
FloatRect RenderSVGRoot::repaintRectInLocalCoordinates() const
{
// FIXME: This does not include the border but it should!
- return computeContainerBoundingBox(this, true);
+ FloatRect repaintRect = computeContainerBoundingBox(this, true);
+ style()->svgStyle()->inflateForShadow(repaintRect);
+ return repaintRect;
}
-TransformationMatrix RenderSVGRoot::localTransform() const
+AffineTransform RenderSVGRoot::localTransform() const
{
- return TransformationMatrix();
+ return AffineTransform();
}
void RenderSVGRoot::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
- // Apply our local transforms (except for x/y translation) and call RenderBox's method to handle all the normal CSS Box model bits
+ // Apply our local transforms (except for x/y translation), then our shadow,
+ // and then call RenderBox's method to handle all the normal CSS Box model bits
repaintRect = localToBorderBoxTransform().mapRect(repaintRect);
+
+ // Apply initial viewport clip - not affected by overflow settings
+ repaintRect.intersect(enclosingIntRect(FloatRect(FloatPoint(), m_viewportSize)));
+
+ style()->svgStyle()->inflateForShadow(repaintRect);
RenderBox::computeRectForRepaint(repaintContainer, repaintRect, fixed);
}
@@ -283,14 +303,9 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
IntPoint pointInBorderBox = pointInParent - parentOriginToBorderBox();
// Note: For now, we're ignoring hits to border and padding for <svg>
-
- if (style()->overflowX() == OHIDDEN) {
- // SVG doesn't support independent x/y overflow
- ASSERT(style()->overflowY() == OHIDDEN);
- IntPoint pointInContentBox = pointInBorderBox - borderOriginToContentBox();
- if (!contentBoxRect().contains(pointInContentBox))
- return false;
- }
+ IntPoint pointInContentBox = pointInBorderBox - borderOriginToContentBox();
+ if (!contentBoxRect().contains(pointInContentBox))
+ return false;
IntPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
@@ -310,5 +325,3 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
}
#endif // ENABLE(SVG)
-
-// vim:ts=4:noet
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.h
index 08c3058e70..53c1298c54 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGRoot.h
@@ -31,9 +31,9 @@
namespace WebCore {
class SVGStyledElement;
-class TransformationMatrix;
+class AffineTransform;
-class RenderSVGRoot : public RenderBox, SVGRenderBase {
+class RenderSVGRoot : public RenderBox, protected SVGRenderBase {
public:
RenderSVGRoot(SVGStyledElement*);
@@ -50,21 +50,24 @@ private:
virtual int lineHeight(bool b, bool isRootLineBox = false) const;
virtual int baselinePosition(bool b, bool isRootLineBox = false) const;
virtual void calcPrefWidths();
-
+ virtual int calcReplacedWidth(bool includeMaxWidth = true) const;
+ virtual int calcReplacedHeight() const;
virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual TransformationMatrix localToParentTransform() const;
+ virtual void destroy();
+
+ virtual const AffineTransform& localToParentTransform() const;
bool fillContains(const FloatPoint&) const;
bool strokeContains(const FloatPoint&) const;
virtual FloatRect objectBoundingBox() const;
+ virtual FloatRect strokeBoundingBox() const { return computeContainerBoundingBox(this, true); }
virtual FloatRect repaintRectInLocalCoordinates() const;
- // FIXME: Both of these overrides should be removed.
- virtual TransformationMatrix localTransform() const;
- virtual TransformationMatrix absoluteTransform() const;
+ // FIXME: This override should be removed.
+ virtual AffineTransform localTransform() const;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -73,17 +76,17 @@ private:
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
void calcViewport();
- const FloatSize& viewportSize() const;
bool selfWillPaint() const;
IntSize parentOriginToBorderBox() const;
IntSize borderOriginToContentBox() const;
- TransformationMatrix localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const;
- TransformationMatrix localToBorderBoxTransform() const;
+ AffineTransform localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const;
+ AffineTransform localToBorderBoxTransform() const;
RenderObjectChildList m_children;
FloatSize m_viewportSize;
+ mutable AffineTransform m_localToParentTransform;
};
inline RenderSVGRoot* toRenderSVGRoot(RenderObject* object)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
new file mode 100644
index 0000000000..9d3d26f232
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
@@ -0,0 +1,101 @@
+/*
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGShadowTreeRootContainer.h"
+
+#include "MouseEvent.h"
+#include "SVGShadowTreeElements.h"
+#include "SVGUseElement.h"
+
+namespace WebCore {
+
+RenderSVGShadowTreeRootContainer::RenderSVGShadowTreeRootContainer(SVGUseElement* node)
+ : RenderSVGTransformableContainer(node)
+ , m_recreateTree(false)
+{
+}
+
+RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer()
+{
+ if (m_shadowRoot && m_shadowRoot->attached())
+ m_shadowRoot->detach();
+}
+
+void RenderSVGShadowTreeRootContainer::updateStyle(Node::StyleChange change)
+{
+ if (m_shadowRoot && m_shadowRoot->attached())
+ m_shadowRoot->recalcStyle(change);
+}
+
+void RenderSVGShadowTreeRootContainer::updateFromElement()
+{
+ bool hadExistingTree = m_shadowRoot;
+
+ SVGUseElement* useElement = static_cast<SVGUseElement*>(node());
+ if (!m_shadowRoot) {
+ ASSERT(!m_recreateTree);
+ m_shadowRoot = new SVGShadowTreeRootElement(document(), useElement);
+ useElement->buildPendingResource();
+ }
+
+ ASSERT(m_shadowRoot->shadowParentNode() == useElement);
+
+ bool shouldRecreateTree = m_recreateTree;
+ if (m_recreateTree) {
+ ASSERT(hadExistingTree);
+
+ if (m_shadowRoot->attached())
+ m_shadowRoot->detach();
+
+ m_shadowRoot->removeAllChildren();
+ m_recreateTree = false;
+ }
+
+ // Only rebuild the shadow tree, if we a) never had a tree or b) we were specifically asked to do so
+ // If the use element is a pending resource, and a) or b) is true, do nothing, and wait for the use
+ // element to be asked to buildPendingResource(), this will call us again, with m_recreateTrue=true.
+ if ((shouldRecreateTree || !hadExistingTree) && !useElement->isPendingResource()) {
+ useElement->buildShadowAndInstanceTree(m_shadowRoot.get());
+
+ // Attach shadow root element
+ m_shadowRoot->attachElement(style(), renderArena());
+
+ // Attach subtree, as if it was a regular non-shadow tree
+ for (Node* child = m_shadowRoot->firstChild(); child; child = child->nextSibling())
+ child->attach();
+ }
+
+ ASSERT(!m_recreateTree);
+ RenderSVGTransformableContainer::updateFromElement();
+}
+
+void RenderSVGShadowTreeRootContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderSVGTransformableContainer::styleDidChange(diff, oldStyle);
+
+ if (RenderObject* shadowRootRenderer = m_shadowRoot ? m_shadowRoot->renderer() : 0)
+ shadowRootRenderer->setStyle(style());
+}
+
+}
+
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h
new file mode 100644
index 0000000000..01cd4270c8
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint 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 RenderSVGShadowTreeRootContainer_h
+#define RenderSVGShadowTreeRootContainer_h
+
+#if ENABLE(SVG)
+#include "RenderSVGTransformableContainer.h"
+
+namespace WebCore {
+
+class SVGUseElement;
+class SVGShadowTreeRootElement;
+
+class RenderSVGShadowTreeRootContainer : public RenderSVGTransformableContainer {
+public:
+ RenderSVGShadowTreeRootContainer(SVGUseElement*);
+ virtual ~RenderSVGShadowTreeRootContainer();
+
+ void markShadowTreeForRecreation() { m_recreateTree = true; }
+ void updateStyle(Node::StyleChange);
+ virtual void updateFromElement();
+
+private:
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+
+ bool m_recreateTree;
+ RefPtr<SVGShadowTreeRootElement> m_shadowRoot;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGTSpan.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGTSpan.h
index 652c5e39ea..931bd8c432 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGTSpan.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGTSpan.h
@@ -31,12 +31,6 @@ class RenderSVGTSpan : public RenderSVGInline {
public:
RenderSVGTSpan(Node*);
virtual const char* renderName() const { return "RenderSVGTSpan"; }
-
- // FIXME: These are incorrect, but have always behaved this way.
- // These empty implementations prevent us from hitting RenderObject ASSERTS.
- // tspan.getBBox() will be wrong, and repainting for tspans may not work correctly!
- virtual FloatRect objectBoundingBox() const { return FloatRect(); }
- virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
};
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.cpp
index 3919d7fef6..76b8b86a56 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.cpp
@@ -6,6 +6,7 @@
* 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
* 2007 Nikolas Zimmermann <zimmermann@kde.org>
* 2008 Rob Buis <buis@kde.org>
+ * 2009 Dirk Schulze <krit@webkit.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -69,10 +70,6 @@ void RenderSVGText::mapLocalToContainer(RenderBoxModelObject* repaintContainer,
void RenderSVGText::layout()
{
ASSERT(needsLayout());
-
- // FIXME: This is a hack to avoid the RenderBlock::layout() partial repainting code which is not (yet) SVG aware
- setNeedsLayout(true);
-
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
// Best guess for a relative starting point
@@ -111,6 +108,12 @@ bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResul
return false;
}
+void RenderSVGText::destroy()
+{
+ deregisterFromResources(this);
+ RenderSVGBlock::destroy();
+}
+
bool RenderSVGText::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
{
ASSERT_NOT_REACHED();
@@ -125,11 +128,8 @@ void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int)
// Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard
// to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
- for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
- ASSERT(runBox->isInlineFlowBox());
-
- InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
- for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
+ for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) {
+ for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine()) {
FloatRect boxRect(box->x(), box->y(), box->width(), box->height());
// FIXME: crawling up the parent chain to map each rect is very inefficient
// we should compute the absoluteTransform outside this loop first.
@@ -146,11 +146,8 @@ void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads)
// Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard
// to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
- for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
- ASSERT(runBox->isInlineFlowBox());
-
- InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
- for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
+ for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) {
+ for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine()) {
FloatRect boxRect(box->x(), box->y(), box->width(), box->height());
// FIXME: crawling up the parent chain to map each quad is very inefficient
// we should compute the absoluteTransform outside this loop first.
@@ -172,11 +169,8 @@ FloatRect RenderSVGText::objectBoundingBox() const
{
FloatRect boundingBox;
- for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
- ASSERT(runBox->isInlineFlowBox());
-
- InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
- for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine())
+ for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) {
+ for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine())
boundingBox.unite(FloatRect(box->x(), box->y(), box->width(), box->height()));
}
@@ -184,13 +178,13 @@ FloatRect RenderSVGText::objectBoundingBox() const
return boundingBox;
}
-FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
+FloatRect RenderSVGText::strokeBoundingBox() const
{
FloatRect repaintRect = objectBoundingBox();
// SVG needs to include the strokeWidth(), not the textStrokeWidth().
if (style()->svgStyle()->hasStroke()) {
- float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 0.0f);
+ float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 1.0f);
#if ENABLE(SVG_FONTS)
const Font& font = style()->font();
@@ -205,7 +199,28 @@ FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
repaintRect.inflate(strokeWidth);
}
- repaintRect.unite(filterBoundingBoxForRenderer(this));
+ return repaintRect;
+}
+
+FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
+{
+ FloatRect repaintRect = strokeBoundingBox();
+
+ // FIXME: We need to be careful here. We assume that there is no filter,
+ // clipper or masker if the rects are empty.
+ FloatRect rect = filterBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ repaintRect = rect;
+
+ rect = clipperBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ repaintRect.intersect(rect);
+
+ rect = maskerBoundingBoxForRenderer(this);
+ if (!rect.isEmpty())
+ repaintRect.intersect(rect);
+
+ style()->svgStyle()->inflateForShadow(repaintRect);
return repaintRect;
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h
index 9a2770ba3c..ab4b09b5c8 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h
@@ -26,7 +26,7 @@
#if ENABLE(SVG)
-#include "TransformationMatrix.h"
+#include "AffineTransform.h"
#include "RenderSVGBlock.h"
namespace WebCore {
@@ -40,9 +40,11 @@ public:
private:
virtual const char* renderName() const { return "RenderSVGText"; }
+ virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
+
virtual bool isSVGText() const { return true; }
- virtual TransformationMatrix localToParentTransform() const { return m_localTransform; }
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
virtual void paint(PaintInfo&, int tx, int ty);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -51,6 +53,8 @@ private:
virtual bool requiresLayer() const { return false; }
virtual void layout();
+ virtual void destroy();
+
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
@@ -60,14 +64,15 @@ private:
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
virtual FloatRect objectBoundingBox() const;
+ virtual FloatRect strokeBoundingBox() const;
virtual FloatRect repaintRectInLocalCoordinates() const;
// FIXME: This can be removed when localTransform() is removed from RenderObject
- virtual TransformationMatrix localTransform() const { return m_localTransform; }
+ virtual AffineTransform localTransform() const { return m_localTransform; }
virtual RootInlineBox* createRootInlineBox();
- TransformationMatrix m_localTransform;
+ AffineTransform m_localTransform;
};
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp
index 2324eee4f0..4bec7a7918 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
+ Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005, 2006 Rob Buis <buis@kde.org>
2009 Google, Inc.
@@ -20,12 +20,12 @@
*/
#include "config.h"
-#if ENABLE(SVG)
+#if ENABLE(SVG)
#include "RenderSVGTransformableContainer.h"
+#include "SVGShadowTreeElements.h"
#include "SVGStyledTransformableElement.h"
-#include "SVGTransformList.h"
namespace WebCore {
@@ -34,12 +34,12 @@ RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGStyledTransf
{
}
-TransformationMatrix RenderSVGTransformableContainer::localToParentTransform() const
+const AffineTransform& RenderSVGTransformableContainer::localToParentTransform() const
{
return m_localTransform;
}
-TransformationMatrix RenderSVGTransformableContainer::localTransform() const
+AffineTransform RenderSVGTransformableContainer::localTransform() const
{
return m_localTransform;
}
@@ -47,6 +47,14 @@ TransformationMatrix RenderSVGTransformableContainer::localTransform() const
void RenderSVGTransformableContainer::calculateLocalTransform()
{
m_localTransform = static_cast<SVGStyledTransformableElement*>(node())->animatedLocalTransform();
+ if (!node()->hasTagName(SVGNames::gTag) || !static_cast<SVGGElement*>(node())->isShadowTreeContainerElement())
+ return;
+
+ FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(node())->containerTranslation();
+ if (translation.width() == 0 && translation.height() == 0)
+ return;
+
+ m_localTransform.translate(translation.width(), translation.height());
}
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.h
index c929761f16..1de0b195c6 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.h
@@ -31,14 +31,14 @@ namespace WebCore {
public:
RenderSVGTransformableContainer(SVGStyledTransformableElement*);
- virtual TransformationMatrix localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
private:
virtual void calculateLocalTransform();
// FIXME: This can be made non-virtual once SVGRenderTreeAsText stops using localTransform()
- virtual TransformationMatrix localTransform() const;
+ virtual AffineTransform localTransform() const;
- TransformationMatrix m_localTransform;
+ AffineTransform m_localTransform;
};
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.cpp
index a432ef3b76..103d9d2f26 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.cpp
@@ -38,23 +38,33 @@ RenderSVGViewportContainer::RenderSVGViewportContainer(SVGStyledElement* node)
{
}
-void RenderSVGViewportContainer::paint(PaintInfo& paintInfo, int parentX, int parentY)
+FloatRect RenderSVGViewportContainer::markerBoundaries(const AffineTransform& markerTransformation) const
{
- // FIXME: The if statement here evaluates to false. isEmpty() is exactly the same
- // as what is on the right side, so it's basically !isEmpty && isEmpty. So this
- // function does nothing.
+ FloatRect coordinates = repaintRectInLocalCoordinates();
- // A value of zero disables rendering of the element.
- if (!m_viewport.isEmpty() && (m_viewport.width() <= 0. || m_viewport.height() <= 0.))
- return;
+ // Map repaint rect into parent coordinate space, in which the marker boundaries have to be evaluated
+ coordinates = localToParentTransform().mapRect(coordinates);
- RenderSVGContainer::paint(paintInfo, parentX, parentY);
+ return markerTransformation.mapRect(coordinates);
+}
+
+AffineTransform RenderSVGViewportContainer::markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth) const
+{
+ // The 'origin' coordinate maps to SVGs refX/refY, given in coordinates relative to the viewport established by the marker
+ FloatPoint mappedOrigin = viewportTransform().mapPoint(origin);
+
+ AffineTransform transformation = contentTransformation;
+ if (strokeWidth != -1)
+ transformation.scaleNonUniform(strokeWidth, strokeWidth);
+
+ transformation.translate(-mappedOrigin.x(), -mappedOrigin.y());
+ return transformation;
}
void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
{
- if (style()->overflowX() != OVISIBLE)
- paintInfo.context->clip(enclosingIntRect(m_viewport)); // FIXME: Eventually we'll want float-precision clipping
+ if (SVGRenderBase::isOverflowHidden(this))
+ paintInfo.context->clip(m_viewport);
}
void RenderSVGViewportContainer::calcViewport()
@@ -82,7 +92,7 @@ void RenderSVGViewportContainer::calcViewport()
}
}
-TransformationMatrix RenderSVGViewportContainer::viewportTransform() const
+AffineTransform RenderSVGViewportContainer::viewportTransform() const
{
if (node()->hasTagName(SVGNames::svgTag)) {
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
@@ -92,38 +102,27 @@ TransformationMatrix RenderSVGViewportContainer::viewportTransform() const
return marker->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
}
- return TransformationMatrix();
+ return AffineTransform();
}
-TransformationMatrix RenderSVGViewportContainer::localToParentTransform() const
+const AffineTransform& RenderSVGViewportContainer::localToParentTransform() const
{
- TransformationMatrix viewportTranslation;
- viewportTranslation.translate(m_viewport.x(), m_viewport.y());
- return viewportTransform() * viewportTranslation;
+ AffineTransform viewportTranslation(viewportTransform());
+ m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
+ return m_localToParentTransform;
// If this class were ever given a localTransform(), then the above would read:
// return viewportTransform() * localTransform() * viewportTranslation;
}
-// FIXME: This method should be removed as soon as callers to RenderBox::absoluteTransform() can be removed.
-TransformationMatrix RenderSVGViewportContainer::absoluteTransform() const
-{
- // This would apply localTransform() twice if localTransform() were not the identity.
- return localToParentTransform() * RenderSVGContainer::absoluteTransform();
-}
-
bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& pointInParent)
{
- // Respect the viewport clip (which is in parent coords). SVG does not support separate x/y overflow rules.
- if (style()->overflowX() == OHIDDEN) {
- ASSERT(style()->overflowY() == OHIDDEN);
- if (!m_viewport.contains(pointInParent))
- return false;
- }
- return true;
+ // Respect the viewport clip (which is in parent coords)
+ if (!SVGRenderBase::isOverflowHidden(this))
+ return true;
+
+ return m_viewport.contains(pointInParent);
}
}
#endif // ENABLE(SVG)
-
-// vim:ts=4:noet
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.h
index b8b30b5506..c4043ec946 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGViewportContainer.h
@@ -24,7 +24,6 @@
#define RenderSVGViewportContainer_h
#if ENABLE(SVG)
-
#include "RenderSVGContainer.h"
namespace WebCore {
@@ -35,19 +34,19 @@ class RenderSVGViewportContainer : public RenderSVGContainer {
public:
RenderSVGViewportContainer(SVGStyledElement*);
- // FIXME: This is only public for SVGResourceMarker::draw, likely the callsite should be changed.
- TransformationMatrix viewportTransform() const;
+ // Calculates marker boundaries, mapped to the target element's coordinate space
+ FloatRect markerBoundaries(const AffineTransform& markerTransformation) const;
- virtual void paint(PaintInfo&, int parentX, int parentY);
+ // Generates a transformation matrix usable to render marker content. Handles scaling the marker content
+ // acording to SVGs markerUnits="strokeWidth" concept, when a strokeWidth value != -1 is passed in.
+ AffineTransform markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth = -1) const;
private:
virtual bool isSVGContainer() const { return true; }
virtual const char* renderName() const { return "RenderSVGViewportContainer"; }
- virtual TransformationMatrix localToParentTransform() const;
-
- // FIXME: This override should be removed once callers of RenderBox::absoluteTransform() can be removed.
- virtual TransformationMatrix absoluteTransform() const;
+ AffineTransform viewportTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
virtual void calcViewport();
@@ -55,6 +54,7 @@ private:
virtual bool pointIsInsideViewportClip(const FloatPoint& pointInParent);
FloatRect m_viewport;
+ mutable AffineTransform m_localToParentTransform;
};
inline RenderSVGViewportContainer* toRenderSVGViewportContainer(RenderObject* object)
@@ -70,5 +70,3 @@ void toRenderSVGViewportContainer(const RenderSVGViewportContainer*);
#endif // ENABLE(SVG)
#endif // RenderSVGViewportContainer_h
-
-// vim:ts=4:noet
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarTheme.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarTheme.cpp
index 06ca32ad9c..19143ccc40 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarTheme.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderScrollbarTheme.cpp
@@ -109,7 +109,7 @@ IntRect RenderScrollbarTheme::constrainTrackRectToTrackPieces(Scrollbar* scrollb
void RenderScrollbarTheme::paintScrollCorner(ScrollView*, GraphicsContext* context, const IntRect& cornerRect)
{
// FIXME: Implement.
- context->fillRect(cornerRect, Color::white);
+ context->fillRect(cornerRect, Color::white, DeviceColorSpace);
}
void RenderScrollbarTheme::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSelectionInfo.h b/src/3rdparty/webkit/WebCore/rendering/RenderSelectionInfo.h
index e7b7b7893f..c06a9ae476 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSelectionInfo.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSelectionInfo.h
@@ -30,7 +30,7 @@
namespace WebCore {
-class RenderSelectionInfoBase {
+class RenderSelectionInfoBase : public Noncopyable {
public:
RenderSelectionInfoBase()
: m_object(0)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSlider.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSlider.cpp
index 442af39401..729fd1522b 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderSlider.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSlider.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -35,6 +35,7 @@
#include "RenderLayer.h"
#include "RenderTheme.h"
#include "RenderView.h"
+#include "StepRange.h"
#include <wtf/MathExtras.h>
using std::min;
@@ -45,70 +46,10 @@ using namespace HTMLNames;
static const int defaultTrackLength = 129;
-// FIXME: The SliderRange class and functions are entirely based on the DOM,
-// and could be put with HTMLInputElement (possibly with a new name) instead of here.
-struct SliderRange {
- bool isIntegral;
- double minimum;
- double maximum; // maximum must be >= minimum.
-
- explicit SliderRange(HTMLInputElement*);
- double clampValue(double value);
-
- // Map value into 0-1 range
- double proportionFromValue(double value)
- {
- if (minimum == maximum)
- return 0;
-
- return (value - minimum) / (maximum - minimum);
- }
-
- // Map from 0-1 range to value
- double valueFromProportion(double proportion)
- {
- return minimum + proportion * (maximum - minimum);
- }
-
- double valueFromElement(HTMLInputElement*, bool* wasClamped = 0);
-};
-
-SliderRange::SliderRange(HTMLInputElement* element)
-{
- // FIXME: What's the right way to handle an integral range with non-integral minimum and maximum?
- // Currently values are guaranteed to be integral but could be outside the range in that case.
-
- isIntegral = !equalIgnoringCase(element->getAttribute(precisionAttr), "float");
-
- maximum = element->rangeMaximum();
- minimum = element->rangeMinimum();
-}
-
-double SliderRange::clampValue(double value)
-{
- double clampedValue = max(minimum, min(value, maximum));
- return isIntegral ? round(clampedValue) : clampedValue;
-}
-
-double SliderRange::valueFromElement(HTMLInputElement* element, bool* wasClamped)
-{
- double oldValue;
- bool parseSuccess = HTMLInputElement::formStringToDouble(element->value(), &oldValue);
- if (!parseSuccess)
- oldValue = (minimum + maximum) / 2;
- double newValue = clampValue(oldValue);
-
- if (wasClamped)
- *wasClamped = !parseSuccess || newValue != oldValue;
-
- return newValue;
-}
-
// Returns a value between 0 and 1.
-// As with SliderRange, this could be on HTMLInputElement instead of here.
static double sliderPosition(HTMLInputElement* element)
{
- SliderRange range(element);
+ StepRange range(element);
return range.proportionFromValue(range.valueFromElement(element));
}
@@ -352,10 +293,9 @@ void RenderSlider::layout()
thumb->repaintDuringLayoutIfMoved(oldThumbRect);
statePusher.pop();
+ addOverflowFromChild(thumb);
}
- addOverflowFromChild(thumb);
-
repainter.repaintAfterLayout();
setNeedsLayout(false);
@@ -363,15 +303,6 @@ void RenderSlider::layout()
void RenderSlider::updateFromElement()
{
- HTMLInputElement* element = static_cast<HTMLInputElement*>(node());
-
- // Send the value back to the element if the range changes it.
- SliderRange range(element);
- bool clamped;
- double value = range.valueFromElement(element, &clamped);
- if (clamped)
- element->setValueFromRenderer(String::number(value));
-
// Layout will take care of the thumb's size and position.
if (!m_thumb) {
m_thumb = new SliderThumbElement(document(), node());
@@ -421,12 +352,12 @@ void RenderSlider::setValueForPosition(int position)
HTMLInputElement* element = static_cast<HTMLInputElement*>(node());
// Calculate the new value based on the position, and send it to the element.
- SliderRange range(element);
+ StepRange range(element);
double fraction = static_cast<double>(position) / trackSize();
if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart)
fraction = 1 - fraction;
double value = range.clampValue(range.valueFromProportion(fraction));
- element->setValueFromRenderer(String::number(value));
+ element->setValueFromRenderer(HTMLInputElement::serializeForNumberType(value));
// Also update the position if appropriate.
if (position != currentPosition()) {
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp
index 73f365410d..e0fbebef2f 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTable.cpp
@@ -485,6 +485,9 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
void RenderTable::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
{
+ if (!shouldPaintWithinRoot(paintInfo))
+ return;
+
int w = width();
int h = height();
@@ -578,6 +581,25 @@ void RenderTable::appendColumn(int span)
setNeedsLayoutAndPrefWidthsRecalc();
}
+RenderTableCol* RenderTable::nextColElement(RenderTableCol* current) const
+{
+ RenderObject* next = current->firstChild();
+ if (!next)
+ next = current->nextSibling();
+ if (!next && current->parent()->isTableCol())
+ next = current->parent()->nextSibling();
+
+ while (next) {
+ if (next->isTableCol())
+ return toRenderTableCol(next);
+ if (next != m_caption)
+ return 0;
+ next = next->nextSibling();
+ }
+
+ return 0;
+}
+
RenderTableCol* RenderTable::colElement(int col, bool* startEdge, bool* endEdge) const
{
if (!m_hasColElements)
@@ -586,32 +608,31 @@ RenderTableCol* RenderTable::colElement(int col, bool* startEdge, bool* endEdge)
int cCol = 0;
while (child) {
- if (child->isTableCol()) {
- RenderTableCol* colElem = toRenderTableCol(child);
- int span = colElem->span();
- if (!colElem->firstChild()) {
- int startCol = cCol;
- int endCol = cCol + span - 1;
- cCol += span;
- if (cCol > col) {
- if (startEdge)
- *startEdge = startCol == col;
- if (endEdge)
- *endEdge = endCol == col;
- return colElem;
- }
- }
-
- RenderObject* next = child->firstChild();
- if (!next)
- next = child->nextSibling();
- if (!next && child->parent()->isTableCol())
- next = child->parent()->nextSibling();
- child = next;
- } else if (child == m_caption)
- child = child->nextSibling();
- else
+ if (child->isTableCol())
break;
+ if (child != m_caption)
+ return 0;
+ child = child->nextSibling();
+ }
+ if (!child)
+ return 0;
+
+ RenderTableCol* colElem = toRenderTableCol(child);
+ while (colElem) {
+ int span = colElem->span();
+ if (!colElem->firstChild()) {
+ int startCol = cCol;
+ int endCol = cCol + span - 1;
+ cCol += span;
+ if (cCol > col) {
+ if (startEdge)
+ *startEdge = startCol == col;
+ if (endEdge)
+ *endEdge = endCol == col;
+ return colElem;
+ }
+ }
+ colElem = nextColElement(colElem);
}
return 0;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTable.h b/src/3rdparty/webkit/WebCore/rendering/RenderTable.h
index e75d644d3c..5978c0b066 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTable.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTable.h
@@ -113,6 +113,7 @@ public:
}
RenderTableCol* colElement(int col, bool* startEdge = 0, bool* endEdge = 0) const;
+ RenderTableCol* nextColElement(RenderTableCol* current) const;
bool needsSectionRecalc() const { return m_needsSectionRecalc; }
void setNeedsSectionRecalc()
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp
index 8dc9145b4d..7309ace5b7 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.cpp
@@ -83,18 +83,42 @@ void RenderTableCell::updateFromElement()
Length RenderTableCell::styleOrColWidth() const
{
Length w = style()->width();
- if (colSpan() > 1 || !w.isAuto())
+ if (!w.isAuto())
return w;
+
RenderTableCol* tableCol = table()->colElement(col());
+
if (tableCol) {
- w = tableCol->style()->width();
-
+ int colSpanCount = colSpan();
+
+ Length colWidthSum = Length(0, Fixed);
+ for (int i = 1; i <= colSpanCount; i++) {
+ Length colWidth = tableCol->style()->width();
+
+ // Percentage value should be returned only for colSpan == 1.
+ // Otherwise we return original width for the cell.
+ if (!colWidth.isFixed()) {
+ if (colSpanCount > 1)
+ return w;
+ return colWidth;
+ }
+
+ colWidthSum = Length(colWidthSum.value() + colWidth.value(), Fixed);
+
+ tableCol = table()->nextColElement(tableCol);
+ // If no next <col> tag found for the span we just return what we have for now.
+ if (!tableCol)
+ break;
+ }
+
// Column widths specified on <col> apply to the border box of the cell.
// Percentages don't need to be handled since they're always treated this way (even when specified on the cells).
// See Bugzilla bug 8126 for details.
- if (w.isFixed() && w.value() > 0)
- w = Length(max(0, w.value() - borderLeft() - borderRight() - paddingLeft() - paddingRight()), Fixed);
+ if (colWidthSum.isFixed() && colWidthSum.value() > 0)
+ colWidthSum = Length(max(0, colWidthSum.value() - borderLeft() - borderRight() - paddingLeft() - paddingRight()), Fixed);
+ return colWidthSum;
}
+
return w;
}
@@ -154,6 +178,17 @@ void RenderTableCell::setOverrideSize(int size)
RenderBlock::setOverrideSize(size);
}
+IntSize RenderTableCell::offsetFromContainer(RenderObject* o, const IntPoint& point) const
+{
+ ASSERT(o == container());
+
+ IntSize offset = RenderBlock::offsetFromContainer(o, point);
+ if (parent())
+ offset.expand(-parentBox()->x(), -parentBox()->y());
+
+ return offset;
+}
+
IntRect RenderTableCell::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
// If the table grid is dirty, we cannot get reliable information about adjoining cells,
@@ -212,35 +247,11 @@ void RenderTableCell::computeRectForRepaint(RenderBoxModelObject* repaintContain
return;
r.setY(r.y());
RenderView* v = view();
- if ((!v || !v->layoutStateEnabled()) && parent())
+ if ((!v || !v->layoutStateEnabled() || repaintContainer) && parent())
r.move(-parentBox()->x(), -parentBox()->y()); // Rows are in the same coordinate space, so don't add their offset in.
RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);
}
-void RenderTableCell::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
-{
- if (repaintContainer == this)
- return;
-
- RenderView* v = view();
- if ((!v || !v->layoutStateEnabled()) && parent()) {
- // Rows are in the same coordinate space, so don't add their offset in.
- // FIXME: this is wrong with transforms
- transformState.move(-parentBox()->x(), -parentBox()->y());
- }
- RenderBlock::mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
-}
-
-void RenderTableCell::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
-{
- RenderBlock::mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
- if (parent()) {
- // Rows are in the same coordinate space, so add their offset back in.
- // FIXME: this is wrong with transforms
- transformState.move(parentBox()->x(), parentBox()->y());
- }
-}
-
int RenderTableCell::baselinePosition(bool firstLine, bool isRootLineBox) const
{
if (isRootLineBox)
@@ -642,6 +653,9 @@ int RenderTableCell::borderHalfBottom(bool outer) const
void RenderTableCell::paint(PaintInfo& paintInfo, int tx, int ty)
{
if (paintInfo.phase == PaintPhaseCollapsedTableBorders && style()->visibility() == VISIBLE) {
+ if (!shouldPaintWithinRoot(paintInfo))
+ return;
+
tx += x();
ty += y();
int os = 2 * maximalOutlineSize(paintInfo.phase);
@@ -800,6 +814,9 @@ void RenderTableCell::paintCollapsedBorder(GraphicsContext* graphicsContext, int
void RenderTableCell::paintBackgroundsBehindCell(PaintInfo& paintInfo, int tx, int ty, RenderObject* backgroundObject)
{
+ if (!shouldPaintWithinRoot(paintInfo))
+ return;
+
if (!backgroundObject)
return;
@@ -831,7 +848,7 @@ void RenderTableCell::paintBackgroundsBehindCell(PaintInfo& paintInfo, int tx, i
paintInfo.context->save();
paintInfo.context->clip(clipRect);
}
- paintFillLayers(paintInfo, c, bgLayer, tx, ty, w, h);
+ paintFillLayers(paintInfo, c, bgLayer, tx, ty, w, h, CompositeSourceOver, backgroundObject);
if (shouldClip)
paintInfo.context->restore();
}
@@ -839,6 +856,9 @@ void RenderTableCell::paintBackgroundsBehindCell(PaintInfo& paintInfo, int tx, i
void RenderTableCell::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
{
+ if (!shouldPaintWithinRoot(paintInfo))
+ return;
+
RenderTable* tableElt = table();
if (!tableElt->collapseBorders() && style()->emptyCells() == HIDE && !firstChild())
return;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.h b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.h
index 8855dff9cb..b6622f4f74 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableCell.h
@@ -99,13 +99,12 @@ public:
virtual void setOverrideSize(int);
+ bool hasVisibleOverflow() const { return m_overflow; }
+
protected:
virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
- virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
-
private:
virtual const char* renderName() const { return isAnonymous() ? "RenderTableCell (anonymous)" : "RenderTableCell"; }
@@ -120,6 +119,7 @@ private:
virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
virtual void paintMask(PaintInfo&, int tx, int ty);
+ virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.cpp
index bafadfc460..a11a14ba85 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableRow.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1997 Martin Jones (mjones@kde.org)
* (C) 1997 Torben Weis (weis@kde.org)
* (C) 1998 Waldo Bastian (bastian@kde.org)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.cpp
index b8ac497b78..34c854bd5e 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTableSection.cpp
@@ -42,6 +42,14 @@ namespace WebCore {
using namespace HTMLNames;
+static inline void setRowHeightToRowStyleHeightIfNotRelative(RenderTableSection::RowStruct* row)
+{
+ ASSERT(row && row->rowRenderer);
+ row->height = row->rowRenderer->style()->height();
+ if (row->height.isRelative())
+ row->height = Length();
+}
+
RenderTableSection::RenderTableSection(Node* node)
: RenderBox(node)
, m_gridRows(0)
@@ -122,11 +130,8 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
m_grid[m_cRow].rowRenderer = toRenderTableRow(child);
- if (!beforeChild) {
- m_grid[m_cRow].height = child->style()->height();
- if (m_grid[m_cRow].height.isRelative())
- m_grid[m_cRow].height = Length();
- }
+ if (!beforeChild)
+ setRowHeightToRowStyleHeightIfNotRelative(&m_grid[m_cRow]);
// If the next renderer is actually wrapped in an anonymous table row, we need to go up and find that.
while (beforeChild && beforeChild->parent() != this)
@@ -641,12 +646,11 @@ int RenderTableSection::layoutRows(int toAdd)
if (r < totalRows - 1 && cell == cellAt(r + 1, c).cell)
continue;
addOverflowFromChild(cell);
+ m_hasOverflowingCell |= cell->hasVisibleOverflow();
}
}
- m_hasOverflowingCell = m_overflow;
-
- statePusher.pop();
+ statePusher.pop();
return height();
}
@@ -1083,6 +1087,7 @@ void RenderTableSection::recalcCells()
RenderTableRow* tableRow = toRenderTableRow(row);
m_grid[m_cRow].rowRenderer = tableRow;
+ setRowHeightToRowStyleHeightIfNotRelative(&m_grid[m_cRow]);
for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
if (cell->isTableCell())
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp
index 88a05e5f5f..aa919e0fb5 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp
@@ -25,7 +25,9 @@
#include "config.h"
#include "RenderText.h"
+#include "AXObjectCache.h"
#include "CharacterNames.h"
+#include "EllipsisBox.h"
#include "FloatQuad.h"
#include "FrameView.h"
#include "InlineTextBox.h"
@@ -46,12 +48,6 @@ using namespace Unicode;
namespace WebCore {
-// FIXME: Move to StringImpl.h eventually.
-static inline bool charactersAreAllASCII(StringImpl* text)
-{
- return charactersAreAllASCII(text->characters(), text->length());
-}
-
RenderText::RenderText(Node* node, PassRefPtr<StringImpl> str)
: RenderObject(node)
, m_minWidth(-1)
@@ -64,7 +60,7 @@ RenderText::RenderText(Node* node, PassRefPtr<StringImpl> str)
, m_hasTab(false)
, m_linesDirty(false)
, m_containsReversedText(false)
- , m_isAllASCII(charactersAreAllASCII(m_text.get()))
+ , m_isAllASCII(m_text.containsOnlyASCII())
, m_knownNotToUseFallbackFonts(false)
{
ASSERT(m_text);
@@ -148,9 +144,9 @@ void RenderText::extractTextBox(InlineTextBox* box)
if (box == m_firstTextBox)
m_firstTextBox = 0;
if (box->prevTextBox())
- box->prevTextBox()->setNextLineBox(0);
- box->setPreviousLineBox(0);
- for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())
+ box->prevTextBox()->setNextTextBox(0);
+ box->setPreviousTextBox(0);
+ for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox())
curr->setExtracted();
checkConsistency();
@@ -161,8 +157,8 @@ void RenderText::attachTextBox(InlineTextBox* box)
checkConsistency();
if (m_lastTextBox) {
- m_lastTextBox->setNextLineBox(box);
- box->setPreviousLineBox(m_lastTextBox);
+ m_lastTextBox->setNextTextBox(box);
+ box->setPreviousTextBox(m_lastTextBox);
} else
m_firstTextBox = box;
InlineTextBox* last = box;
@@ -184,9 +180,9 @@ void RenderText::removeTextBox(InlineTextBox* box)
if (box == m_lastTextBox)
m_lastTextBox = box->prevTextBox();
if (box->nextTextBox())
- box->nextTextBox()->setPreviousLineBox(box->prevTextBox());
+ box->nextTextBox()->setPreviousTextBox(box->prevTextBox());
if (box->prevTextBox())
- box->prevTextBox()->setNextLineBox(box->nextTextBox());
+ box->prevTextBox()->setNextTextBox(box->nextTextBox());
checkConsistency();
}
@@ -228,27 +224,32 @@ void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, u
start = min(start, static_cast<unsigned>(INT_MAX));
end = min(end, static_cast<unsigned>(INT_MAX));
- FloatPoint absPos = localToAbsolute(FloatPoint());
-
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
// Note: box->end() returns the index of the last character, not the index past it
if (start <= box->start() && box->end() < end) {
- IntRect r = IntRect(absPos.x() + box->x(), absPos.y() + box->y(), box->width(), box->height());
+ IntRect r = IntRect(box->x(), box->y(), box->width(), box->height());
if (useSelectionHeight) {
- IntRect selectionRect = box->selectionRect(absPos.x(), absPos.y(), start, end);
+ IntRect selectionRect = box->selectionRect(0, 0, start, end);
r.setHeight(selectionRect.height());
r.setY(selectionRect.y());
}
+ FloatPoint origin = localToAbsolute(r.location());
+ r.setX(origin.x());
+ r.setY(origin.y());
rects.append(r);
} else {
unsigned realEnd = min(box->end() + 1, end);
- IntRect r = box->selectionRect(absPos.x(), absPos.y(), start, realEnd);
+ IntRect r = box->selectionRect(0, 0, start, realEnd);
if (!r.isEmpty()) {
if (!useSelectionHeight) {
// change the height and y position because selectionRect uses selection-specific values
r.setHeight(box->height());
- r.setY(absPos.y() + box->y());
+ r.setY(box->y());
}
+ FloatPoint origin = localToAbsolute(r.location());
+ localToAbsolute(origin);
+ r.setX(origin.x());
+ r.setY(origin.y());
rects.append(r);
}
}
@@ -286,7 +287,7 @@ void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start,
} else {
unsigned realEnd = min(box->end() + 1, end);
IntRect r = box->selectionRect(0, 0, start, realEnd);
- if (!r.isEmpty()) {
+ if (r.height()) {
if (!useSelectionHeight) {
// change the height and y position because selectionRect uses selection-specific values
r.setHeight(box->height());
@@ -338,7 +339,7 @@ VisiblePosition RenderText::positionForPoint(const IntPoint& point)
// at the y coordinate of the last line or below
// and the x coordinate is to the right of the last text box right edge
offset = lastTextBox()->offsetForPosition(point.x());
- return createVisiblePosition(offset + lastTextBox()->start(), DOWNSTREAM);
+ return createVisiblePosition(offset + lastTextBox()->start(), VP_UPSTREAM_IF_POSSIBLE);
}
InlineTextBox* lastBoxAbove = 0;
@@ -435,8 +436,10 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len,
int w = 0;
bool isSpace;
bool previousCharWasSpace = true; // FIXME: Preserves historical behavior, but seems wrong for start > 0.
+ ASSERT(m_text);
+ StringImpl& text = *m_text.impl();
for (int i = start; i < start + len; i++) {
- char c = (*m_text)[i];
+ char c = text[i];
if (c <= ' ') {
if (c == ' ' || c == '\n') {
w += monospaceCharacterWidth;
@@ -479,7 +482,7 @@ void RenderText::trimmedPrefWidths(int leadWidth,
int len = textLength();
- if (!len || (stripFrontSpaces && m_text->containsOnlyWhitespace())) {
+ if (!len || (stripFrontSpaces && text()->containsOnlyWhitespace())) {
beginMinW = 0;
endMinW = 0;
beginMaxW = 0;
@@ -499,7 +502,9 @@ void RenderText::trimmedPrefWidths(int leadWidth,
hasBreakableChar = m_hasBreakableChar;
hasBreak = m_hasBreak;
- if ((*m_text)[0] == ' ' || ((*m_text)[0] == '\n' && !style()->preserveNewline()) || (*m_text)[0] == '\t') {
+ ASSERT(m_text);
+ StringImpl& text = *m_text.impl();
+ if (text[0] == ' ' || (text[0] == '\n' && !style()->preserveNewline()) || text[0] == '\t') {
const Font& f = style()->font(); // FIXME: This ignores first-line.
if (stripFrontSpaces) {
const UChar space = ' ';
@@ -522,7 +527,7 @@ void RenderText::trimmedPrefWidths(int leadWidth,
endMaxW = maxW;
for (int i = 0; i < len; i++) {
int linelen = 0;
- while (i + linelen < len && (*m_text)[i + linelen] != '\n')
+ while (i + linelen < len && text[i + linelen] != '\n')
linelen++;
if (linelen) {
@@ -757,11 +762,24 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f
setPrefWidthsDirty(false);
}
+bool RenderText::isAllCollapsibleWhitespace()
+{
+ int length = textLength();
+ const UChar* text = characters();
+ for (int i = 0; i < length; i++) {
+ if (!style()->isCollapsibleWhiteSpace(text[i]))
+ return false;
+ }
+ return true;
+}
+
bool RenderText::containsOnlyWhitespace(unsigned from, unsigned len) const
{
+ ASSERT(m_text);
+ StringImpl& text = *m_text.impl();
unsigned currPos;
for (currPos = from;
- currPos < from + len && ((*m_text)[currPos] == '\n' || (*m_text)[currPos] == ' ' || (*m_text)[currPos] == '\t');
+ currPos < from + len && (text[currPos] == '\n' || text[currPos] == ' ' || text[currPos] == '\t');
currPos++) { }
return currPos >= (from + len);
}
@@ -813,7 +831,9 @@ void RenderText::setSelectionState(SelectionState state)
}
}
- containingBlock()->setSelectionState(state);
+ // The returned value can be null in case of an orphaned tree.
+ if (RenderBlock* cb = containingBlock())
+ cb->setSelectionState(state);
}
void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, unsigned len, bool force)
@@ -932,7 +952,7 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
// characters into space characters. Then, it will draw all space characters, including
// leading, trailing and multiple contiguous space characters.
- m_text = m_text->replace('\n', ' ');
+ m_text.replace('\n', ' ');
// If xml:space="preserve" is set, white-space is set to "pre", which
// preserves leading, trailing & contiguous space character for us.
@@ -943,13 +963,13 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
// Then, it will strip off all leading and trailing space characters.
// Then, all contiguous space characters will be consolidated.
- m_text = m_text->replace('\n', StringImpl::empty());
+ m_text.replace('\n', StringImpl::empty());
// If xml:space="default" is set, white-space is set to "nowrap", which handles
// leading, trailing & contiguous space character removal for us.
}
- m_text = m_text->replace('\t', ' ');
+ m_text.replace('\t', ' ');
}
#endif
@@ -957,15 +977,14 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
switch (style()->textTransform()) {
case TTNONE:
break;
- case CAPITALIZE: {
- m_text = m_text->capitalize(previousCharacter());
+ case CAPITALIZE:
+ m_text.makeCapitalized(previousCharacter());
break;
- }
case UPPERCASE:
- m_text = m_text->upper();
+ m_text.makeUpper();
break;
case LOWERCASE:
- m_text = m_text->lower();
+ m_text.makeLower();
break;
}
@@ -975,32 +994,36 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
case TSNONE:
break;
case TSCIRCLE:
- m_text = m_text->secure(whiteBullet);
+ m_text.makeSecure(whiteBullet);
break;
case TSDISC:
- m_text = m_text->secure(bullet);
+ m_text.makeSecure(bullet);
break;
case TSSQUARE:
- m_text = m_text->secure(blackSquare);
+ m_text.makeSecure(blackSquare);
}
}
ASSERT(m_text);
- ASSERT(!isBR() || (textLength() == 1 && (*m_text)[0] == '\n'));
+ ASSERT(!isBR() || (textLength() == 1 && m_text[0] == '\n'));
- m_isAllASCII = charactersAreAllASCII(m_text.get());
+ m_isAllASCII = m_text.containsOnlyASCII();
}
void RenderText::setText(PassRefPtr<StringImpl> text, bool force)
{
ASSERT(text);
- if (!force && equal(m_text.get(), text.get()))
+ if (!force && equal(m_text.impl(), text.get()))
return;
setTextInternal(text);
setNeedsLayoutAndPrefWidthsRecalc();
m_knownNotToUseFallbackFonts = false;
+
+ AXObjectCache* axObjectCache = document()->axObjectCache();
+ if (axObjectCache->accessibilityEnabled())
+ axObjectCache->contentChanged(this);
}
int RenderText::lineHeight(bool firstLine, bool) const
@@ -1031,8 +1054,8 @@ InlineTextBox* RenderText::createInlineTextBox()
if (!m_firstTextBox)
m_firstTextBox = m_lastTextBox = textBox;
else {
- m_lastTextBox->setNextLineBox(textBox);
- textBox->setPreviousLineBox(m_lastTextBox);
+ m_lastTextBox->setNextTextBox(textBox);
+ textBox->setPreviousTextBox(m_lastTextBox);
m_lastTextBox = textBox;
}
textBox->setIsText(true);
@@ -1050,11 +1073,11 @@ void RenderText::positionLineBox(InlineBox* box)
if (m_firstTextBox == s)
m_firstTextBox = s->nextTextBox();
else
- s->prevTextBox()->setNextLineBox(s->nextTextBox());
+ s->prevTextBox()->setNextTextBox(s->nextTextBox());
if (m_lastTextBox == s)
m_lastTextBox = s->prevTextBox();
else
- s->nextTextBox()->setPreviousLineBox(s->prevTextBox());
+ s->nextTextBox()->setPreviousTextBox(s->prevTextBox());
s->destroy(renderArena());
return;
}
@@ -1158,9 +1181,25 @@ IntRect RenderText::selectionRectForRepaint(RenderBoxModelObject* repaintContain
return IntRect();
IntRect rect;
- for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
+ for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
rect.unite(box->selectionRect(0, 0, startPos, endPos));
+ // Check if there are ellipsis which fall within the selection.
+ unsigned short truncation = box->truncation();
+ if (truncation != cNoTruncation) {
+ if (EllipsisBox* ellipsis = box->root()->ellipsisBox()) {
+ int ePos = min<int>(endPos - box->start(), box->len());
+ int sPos = max<int>(startPos - box->start(), 0);
+ // The ellipsis should be considered to be selected if the end of
+ // the selection is past the beginning of the truncation and the
+ // beginning of the selection is before or at the beginning of the
+ // truncation.
+ if (ePos >= truncation && sPos <= truncation)
+ rect.unite(ellipsis->selectionRect(0, 0));
+ }
+ }
+ }
+
if (clipToVisibleContent)
computeRectForRepaint(repaintContainer, rect);
else {
@@ -1205,7 +1244,7 @@ unsigned RenderText::caretMaxRenderedOffset() const
int RenderText::previousOffset(int current) const
{
- StringImpl* si = m_text.get();
+ StringImpl* si = m_text.impl();
TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());
if (!iterator)
return current - 1;
@@ -1253,14 +1292,16 @@ inline bool isHangulLVT(UChar32 character)
int RenderText::previousOffsetForBackwardDeletion(int current) const
{
#if PLATFORM(MAC)
+ ASSERT(m_text);
+ StringImpl& text = *m_text.impl();
UChar32 character;
while (current > 0) {
- if (U16_IS_TRAIL((*m_text)[--current]))
+ if (U16_IS_TRAIL(text[--current]))
--current;
if (current < 0)
break;
- UChar32 character = m_text->characterStartingAt(current);
+ UChar32 character = text.characterStartingAt(current);
// We don't combine characters in Armenian ... Limbu range for backward deletion.
if ((character >= 0x0530) && (character < 0x1950))
@@ -1274,7 +1315,7 @@ int RenderText::previousOffsetForBackwardDeletion(int current) const
return current;
// Hangul
- character = m_text->characterStartingAt(current);
+ character = text.characterStartingAt(current);
if (((character >= HANGUL_CHOSEONG_START) && (character <= HANGUL_JONGSEONG_END)) || ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))) {
HangulState state;
HangulState initialState;
@@ -1290,7 +1331,7 @@ int RenderText::previousOffsetForBackwardDeletion(int current) const
initialState = state;
- while (current > 0 && ((character = m_text->characterStartingAt(current - 1)) >= HANGUL_CHOSEONG_START) && (character <= HANGUL_SYLLABLE_END) && ((character <= HANGUL_JONGSEONG_END) || (character >= HANGUL_SYLLABLE_START))) {
+ while (current > 0 && ((character = text.characterStartingAt(current - 1)) >= HANGUL_CHOSEONG_START) && (character <= HANGUL_SYLLABLE_END) && ((character <= HANGUL_JONGSEONG_END) || (character >= HANGUL_SYLLABLE_START))) {
switch (state) {
case HangulStateV:
if (character <= HANGUL_CHOSEONG_END)
@@ -1328,7 +1369,7 @@ int RenderText::previousOffsetForBackwardDeletion(int current) const
int RenderText::nextOffset(int current) const
{
- StringImpl* si = m_text.get();
+ StringImpl* si = m_text.impl();
TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());
if (!iterator)
return current + 1;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderText.h b/src/3rdparty/webkit/WebCore/rendering/RenderText.h
index 915ff40acb..e9ed147a4d 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderText.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderText.h
@@ -50,7 +50,7 @@ public:
virtual void destroy();
- StringImpl* text() const { return m_text.get(); }
+ StringImpl* text() const { return m_text.impl(); }
InlineTextBox* createInlineTextBox();
void dirtyLineBoxes(bool fullLayout);
@@ -63,8 +63,8 @@ public:
virtual VisiblePosition positionForPoint(const IntPoint&);
- const UChar* characters() const { return m_text->characters(); }
- unsigned textLength() const { return m_text->length(); } // non virtual implementation of length()
+ const UChar* characters() const { return m_text.characters(); }
+ unsigned textLength() const { return m_text.length(); } // non virtual implementation of length()
void positionLineBox(InlineBox*);
virtual unsigned width(unsigned from, unsigned len, const Font&, int xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0) const;
@@ -121,7 +121,8 @@ public:
void checkConsistency() const;
virtual void calcPrefWidths(int leadWidth);
-
+ bool isAllCollapsibleWhitespace();
+
protected:
virtual void styleWillChange(StyleDifference, const RenderStyle*) { }
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
@@ -150,7 +151,7 @@ private:
int m_minWidth; // here to minimize padding in 64-bit.
- RefPtr<StringImpl> m_text;
+ String m_text;
InlineTextBox* m_firstTextBox;
InlineTextBox* m_lastTextBox;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp
index f430399568..b98900a223 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp
@@ -70,8 +70,8 @@ static Color disabledTextColor(const Color& textColor, const Color& backgroundCo
RenderTextControl::RenderTextControl(Node* node, bool placeholderVisible)
: RenderBlock(node)
, m_placeholderVisible(placeholderVisible)
- , m_edited(false)
- , m_userEdited(false)
+ , m_wasChangedSinceLastChangeEvent(false)
+ , m_lastChangeWasUserEdit(false)
{
}
@@ -195,17 +195,17 @@ void RenderTextControl::setInnerTextValue(const String& innerTextValue)
ASSERT(!ec);
}
- m_edited = false;
- m_userEdited = false;
+ // We set m_lastChangeWasUserEdit to false since this change was not explicitly made by the user (say, via typing on the keyboard), see <rdar://problem/5359921>.
+ m_lastChangeWasUserEdit = false;
}
static_cast<Element*>(node())->setFormControlValueMatchesRenderer(true);
}
-void RenderTextControl::setUserEdited(bool isUserEdited)
+void RenderTextControl::setLastChangeWasUserEdit(bool lastChangeWasUserEdit)
{
- m_userEdited = isUserEdited;
- document()->setIgnoreAutofocus(isUserEdited);
+ m_lastChangeWasUserEdit = lastChangeWasUserEdit;
+ document()->setIgnoreAutofocus(lastChangeWasUserEdit);
}
int RenderTextControl::selectionStart()
@@ -266,11 +266,6 @@ void RenderTextControl::setSelectionRange(int start, int end)
if (Frame* frame = document()->frame())
frame->selection()->setSelection(newSelection);
-
- // FIXME: Granularity is stored separately on the frame, but also in the selection controller.
- // The granularity in the selection controller should be used, and then this line of code would not be needed.
- if (Frame* frame = document()->frame())
- frame->setSelectionGranularity(CharacterGranularity);
}
VisibleSelection RenderTextControl::selection(int start, int end) const
@@ -312,8 +307,8 @@ int RenderTextControl::indexForVisiblePosition(const VisiblePosition& pos)
void RenderTextControl::subtreeHasChanged()
{
- m_edited = true;
- m_userEdited = true;
+ m_wasChangedSinceLastChangeEvent = true;
+ m_lastChangeWasUserEdit = true;
}
String RenderTextControl::finishText(Vector<UChar>& result) const
@@ -459,6 +454,78 @@ IntRect RenderTextControl::controlClipRect(int tx, int ty) const
return clipRect;
}
+static const char* fontFamiliesWithInvalidCharWidth[] = {
+ "American Typewriter",
+ "Arial Hebrew",
+ "Chalkboard",
+ "Cochin",
+ "Corsiva Hebrew",
+ "Courier",
+ "Euphemia UCAS",
+ "Geneva",
+ "Gill Sans",
+ "Hei",
+ "Helvetica",
+ "Hoefler Text",
+ "InaiMathi",
+ "Kai",
+ "Lucida Grande",
+ "Marker Felt",
+ "Monaco",
+ "Mshtakan",
+ "New Peninim MT",
+ "Osaka",
+ "Raanana",
+ "STHeiti",
+ "Symbol",
+ "Times",
+ "Apple Braille",
+ "Apple LiGothic",
+ "Apple LiSung",
+ "Apple Symbols",
+ "AppleGothic",
+ "AppleMyungjo",
+ "#GungSeo",
+ "#HeadLineA",
+ "#PCMyungjo",
+ "#PilGi",
+};
+
+// For font families where any of the fonts don't have a valid entry in the OS/2 table
+// for avgCharWidth, fallback to the legacy webkit behavior of getting the avgCharWidth
+// from the width of a '0'. This only seems to apply to a fixed number of Mac fonts,
+// but, in order to get similar rendering across platforms, we do this check for
+// all platforms.
+bool RenderTextControl::hasValidAvgCharWidth(AtomicString family)
+{
+ static HashSet<AtomicString>* fontFamiliesWithInvalidCharWidthMap = 0;
+
+ if (!fontFamiliesWithInvalidCharWidthMap) {
+ fontFamiliesWithInvalidCharWidthMap = new HashSet<AtomicString>;
+
+ for (unsigned i = 0; i < sizeof(fontFamiliesWithInvalidCharWidth) / sizeof(fontFamiliesWithInvalidCharWidth[0]); i++)
+ fontFamiliesWithInvalidCharWidthMap->add(AtomicString(fontFamiliesWithInvalidCharWidth[i]));
+ }
+
+ return !fontFamiliesWithInvalidCharWidthMap->contains(family);
+}
+
+float RenderTextControl::getAvgCharWidth(AtomicString family)
+{
+ if (hasValidAvgCharWidth(family))
+ return roundf(style()->font().primaryFont()->avgCharWidth());
+
+ const UChar ch = '0';
+ return style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, false, false, false));
+}
+
+float RenderTextControl::scaleEmToUnits(int x) const
+{
+ // This matches the unitsPerEm value for MS Shell Dlg and Courier New from the "head" font table.
+ float unitsPerEm = 2048.0f;
+ return roundf(style()->font().size() * x / unitsPerEm);
+}
+
void RenderTextControl::calcPrefWidths()
{
ASSERT(prefWidthsDirty());
@@ -470,8 +537,8 @@ void RenderTextControl::calcPrefWidths()
m_minPrefWidth = m_maxPrefWidth = calcContentBoxWidth(style()->width().value());
else {
// Use average character width. Matches IE.
- float charWidth = style()->font().primaryFont()->avgCharWidth();
- m_maxPrefWidth = preferredContentWidth(charWidth) + m_innerText->renderBox()->paddingLeft() + m_innerText->renderBox()->paddingRight();
+ AtomicString family = style()->font().family().family();
+ m_maxPrefWidth = preferredContentWidth(getAvgCharWidth(family)) + m_innerText->renderBox()->paddingLeft() + m_innerText->renderBox()->paddingRight();
}
if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
@@ -505,9 +572,10 @@ void RenderTextControl::selectionChanged(bool userTriggered)
}
}
-void RenderTextControl::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
+void RenderTextControl::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
{
- graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
+ if (width() && height())
+ rects.append(IntRect(tx, ty, width(), height()));
}
HTMLElement* RenderTextControl::innerTextElement() const
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.h b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.h
index cdd8716d63..2fc8edca47 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.h
@@ -34,11 +34,11 @@ class RenderTextControl : public RenderBlock {
public:
virtual ~RenderTextControl();
- bool isEdited() const { return m_edited; }
- void setEdited(bool isEdited) { m_edited = isEdited; }
+ bool wasChangedSinceLastChangeEvent() const { return m_wasChangedSinceLastChangeEvent; }
+ void setChangedSinceLastChangeEvent(bool wasChangedSinceLastChangeEvent) { m_wasChangedSinceLastChangeEvent = wasChangedSinceLastChangeEvent; }
- bool isUserEdited() const { return m_userEdited; }
- void setUserEdited(bool isUserEdited);
+ bool lastChangeWasUserEdit() const { return m_lastChangeWasUserEdit; }
+ void setLastChangeWasUserEdit(bool lastChangeWasUserEdit);
int selectionStart();
int selectionEnd();
@@ -74,6 +74,10 @@ protected:
int textBlockWidth() const;
int textBlockHeight() const;
+ float scaleEmToUnits(int x) const;
+
+ static bool hasValidAvgCharWidth(AtomicString family);
+ virtual float getAvgCharWidth(AtomicString family);
virtual int preferredContentWidth(float charWidth) const = 0;
virtual void adjustControlHeightBasedOnLineHeight(int lineHeight) = 0;
virtual void cacheSelection(int start, int end) = 0;
@@ -99,14 +103,14 @@ private:
virtual bool avoidsFloats() const { return true; }
void setInnerTextStyle(PassRefPtr<RenderStyle>);
- virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
virtual bool canBeProgramaticallyScrolled(bool) const { return true; }
String finishText(Vector<UChar>&) const;
- bool m_edited;
- bool m_userEdited;
+ bool m_wasChangedSinceLastChangeEvent;
+ bool m_lastChangeWasUserEdit;
RefPtr<TextControlInnerTextElement> m_innerText;
};
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp
index a49e092b1b..af422538ac 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -47,7 +47,7 @@ void RenderTextControlMultiLine::subtreeHasChanged()
RenderTextControl::subtreeHasChanged();
HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node());
textArea->setFormControlValueMatchesRenderer(false);
- textArea->updateValidity();
+ textArea->setNeedsValidityCheck();
if (!node()->focused())
return;
@@ -64,8 +64,8 @@ bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitT
return false;
bool resultIsTextValueOrPlaceholder
- = !m_placeholderVisible && result.innerNode() == innerTextElement()
- || m_placeholderVisible && result.innerNode()->isDescendantOf(innerTextElement());
+ = (!m_placeholderVisible && result.innerNode() == innerTextElement())
+ || (m_placeholderVisible && result.innerNode()->isDescendantOf(innerTextElement()));
if (result.innerNode() == node() || resultIsTextValueOrPlaceholder)
hitInnerTextElement(result, x, y, tx, ty);
@@ -77,6 +77,17 @@ void RenderTextControlMultiLine::forwardEvent(Event* event)
RenderTextControl::forwardEvent(event);
}
+float RenderTextControlMultiLine::getAvgCharWidth(AtomicString family)
+{
+ // Since Lucida Grande is the default font, we want this to match the width
+ // of Courier New, the default font for textareas in IE, Firefox and Safari Win.
+ // 1229 is the avgCharWidth value in the OS/2 table for Courier New.
+ if (family == AtomicString("Lucida Grande"))
+ return scaleEmToUnits(1229);
+
+ return RenderTextControl::getAvgCharWidth(family);
+}
+
int RenderTextControlMultiLine::preferredContentWidth(float charWidth) const
{
int factor = static_cast<HTMLTextAreaElement*>(node())->cols();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.h b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.h
index 3371a8f1a0..fbca308145 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.h
@@ -40,6 +40,7 @@ private:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
+ virtual float getAvgCharWidth(AtomicString family);
virtual int preferredContentWidth(float charWidth) const;
virtual void adjustControlHeightBasedOnLineHeight(int lineHeight);
virtual int baselinePosition(bool firstLine, bool isRootLineBox) const;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp
index be800a7310..a762ac5499 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -150,7 +150,7 @@ void RenderTextControlSingleLine::hidePopup()
void RenderTextControlSingleLine::subtreeHasChanged()
{
- bool wasEdited = isEdited();
+ bool wasChanged = wasChangedSinceLastChangeEvent();
RenderTextControl::subtreeHasChanged();
InputElement* input = inputElement();
@@ -167,7 +167,7 @@ void RenderTextControlSingleLine::subtreeHasChanged()
if (input->searchEventsShouldBeDispatched())
startSearchEventTimer();
- if (!wasEdited && node()->focused()) {
+ if (!wasChanged && node()->focused()) {
if (Frame* frame = document()->frame())
frame->textFieldDidBeginEditing(static_cast<Element*>(node()));
}
@@ -374,7 +374,19 @@ int RenderTextControlSingleLine::textBlockWidth() const
return width;
}
+
+float RenderTextControlSingleLine::getAvgCharWidth(AtomicString family)
+{
+ // Since Lucida Grande is the default font, we want this to match the width
+ // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
+ // IE for some encodings (in IE, the default font is encoding specific).
+ // 901 is the avgCharWidth value in the OS/2 table for MS Shell Dlg.
+ if (family == AtomicString("Lucida Grande"))
+ return scaleEmToUnits(901);
+ return RenderTextControl::getAvgCharWidth(family);
+}
+
int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
{
int factor = inputElement()->size();
@@ -383,8 +395,20 @@ int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
int result = static_cast<int>(ceilf(charWidth * factor));
+ float maxCharWidth = 0.f;
+ AtomicString family = style()->font().family().family();
+ // Since Lucida Grande is the default font, we want this to match the width
+ // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
+ // IE for some encodings (in IE, the default font is encoding specific).
+ // 4027 is the (xMax - xMin) value in the "head" font table for MS Shell Dlg.
+ if (family == AtomicString("Lucida Grande"))
+ maxCharWidth = scaleEmToUnits(4027);
+ else if (hasValidAvgCharWidth(family))
+ maxCharWidth = roundf(style()->font().primaryFont()->maxCharWidth());
+
// For text inputs, IE adds some extra width.
- result += style()->font().primaryFont()->maxCharWidth() - charWidth;
+ if (maxCharWidth > 0.f)
+ result += maxCharWidth - charWidth;
if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0)
result += resultsRenderer->borderLeft() + resultsRenderer->borderRight() +
@@ -461,8 +485,12 @@ void RenderTextControlSingleLine::updateFromElement()
ExceptionCode ec = 0;
innerTextElement()->setInnerText(static_cast<Element*>(node())->getAttribute(placeholderAttr), ec);
ASSERT(!ec);
- } else
- setInnerTextValue(inputElement()->value());
+ } else {
+ if (!inputElement()->suggestedValue().isNull())
+ setInnerTextValue(inputElement()->suggestedValue());
+ else
+ setInnerTextValue(inputElement()->value());
+ }
if (m_searchPopupIsVisible)
m_searchPopup->updateFromElement();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.h b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.h
index e30ff0d3d1..e1bcc84568 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlSingleLine.h
@@ -75,6 +75,7 @@ private:
virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0);
int textBlockWidth() const;
+ virtual float getAvgCharWidth(AtomicString family);
virtual int preferredContentWidth(float charWidth) const;
virtual void adjustControlHeightBasedOnLineHeight(int lineHeight);
@@ -100,6 +101,7 @@ private:
virtual void valueChanged(unsigned listIndex, bool fireEvents = true);
virtual String itemText(unsigned listIndex) const;
virtual String itemToolTip(unsigned) const { return String(); }
+ virtual String itemAccessibilityText(unsigned) const { return String(); }
virtual bool itemIsEnabled(unsigned listIndex) const;
virtual PopupMenuStyle itemStyle(unsigned listIndex) const;
virtual PopupMenuStyle menuStyle() const;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextFragment.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextFragment.cpp
index 9ff110649e..f3398a3e35 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTextFragment.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextFragment.cpp
@@ -69,6 +69,10 @@ void RenderTextFragment::setTextInternal(PassRefPtr<StringImpl> text)
m_firstLetter = 0;
m_start = 0;
m_end = textLength();
+ if (Node* t = node()) {
+ ASSERT(!t->renderer());
+ t->setRenderer(this);
+ }
}
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp
index 5ee01e445a..7c284a6ced 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.cpp
@@ -1,7 +1,7 @@
/**
* This file is part of the theme implementation for form controls in WebCore.
*
- * Copyright (C) 2005, 2006, 2007, 2008 Apple Computer, Inc.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -87,6 +87,8 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El
switch (part) {
case ListButtonPart:
case CheckboxPart:
+ case InnerSpinButtonPart:
+ case OuterSpinButtonPart:
case RadioPart:
case PushButtonPart:
case SquareButtonPart:
@@ -176,6 +178,10 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El
case DefaultButtonPart:
case ButtonPart:
return adjustButtonStyle(selector, style, e);
+ case InnerSpinButtonPart:
+ return adjustInnerSpinButtonStyle(selector, style, e);
+ case OuterSpinButtonPart:
+ return adjustOuterSpinButtonStyle(selector, style, e);
#endif
case TextFieldPart:
return adjustTextFieldStyle(selector, style, e);
@@ -203,6 +209,10 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El
return adjustSearchFieldResultsDecorationStyle(selector, style, e);
case SearchFieldResultsButtonPart:
return adjustSearchFieldResultsButtonStyle(selector, style, e);
+#if ENABLE(PROGRESS_TAG)
+ case ProgressBarPart:
+ return adjustProgressBarStyle(selector, style, e);
+#endif
default:
break;
}
@@ -232,6 +242,8 @@ bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInf
case ListButtonPart:
case DefaultButtonPart:
case ButtonPart:
+ case InnerSpinButtonPart:
+ case OuterSpinButtonPart:
m_theme->paint(part, controlStatesForRenderer(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->style()->effectiveZoom(), o->view()->frameView());
return false;
default:
@@ -252,9 +264,17 @@ bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInf
case DefaultButtonPart:
case ButtonPart:
return paintButton(o, paintInfo, r);
+ case InnerSpinButtonPart:
+ return paintInnerSpinButton(o, paintInfo, r);
+ case OuterSpinButtonPart:
+ return paintOuterSpinButton(o, paintInfo, r);
#endif
case MenulistPart:
return paintMenuList(o, paintInfo, r);
+#if ENABLE(PROGRESS_TAG)
+ case ProgressBarPart:
+ return paintProgressBar(o, paintInfo, r);
+#endif
case SliderHorizontalPart:
case SliderVerticalPart:
return paintSliderTrack(o, paintInfo, r);
@@ -278,6 +298,8 @@ bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInf
return paintMediaRewindButton(o, paintInfo, r);
case MediaReturnToRealtimeButtonPart:
return paintMediaReturnToRealtimeButton(o, paintInfo, r);
+ case MediaToggleClosedCaptionsButtonPart:
+ return paintMediaToggleClosedCaptionsButton(o, paintInfo, r);
case MediaSliderPart:
return paintMediaSliderTrack(o, paintInfo, r);
case MediaSliderThumbPart:
@@ -343,6 +365,9 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const RenderObject::PaintInfo
case DefaultButtonPart:
case ButtonPart:
case MenulistPart:
+#if ENABLE(PROGRESS_TAG)
+ case ProgressBarPart:
+#endif
case SliderHorizontalPart:
case SliderVerticalPart:
case SliderThumbHorizontalPart:
@@ -378,6 +403,9 @@ bool RenderTheme::paintDecorations(RenderObject* o, const RenderObject::PaintInf
case DefaultButtonPart:
case ButtonPart:
case MenulistPart:
+#if ENABLE(PROGRESS_TAG)
+ case ProgressBarPart:
+#endif
case SliderHorizontalPart:
case SliderVerticalPart:
case SliderThumbHorizontalPart:
@@ -416,10 +444,41 @@ bool RenderTheme::shouldRenderMediaControlPart(ControlPart part, Element* e)
return mediaElement->movieLoadType() == MediaPlayer::LiveStream;
case MediaFullscreenButtonPart:
return mediaElement->supportsFullscreen();
+ case MediaToggleClosedCaptionsButtonPart:
+ return mediaElement->hasClosedCaptions();
default:
return true;
}
}
+
+String RenderTheme::formatMediaControlsTime(float time) const
+{
+ if (!isfinite(time))
+ time = 0;
+ int seconds = (int)fabsf(time);
+ int hours = seconds / (60 * 60);
+ int minutes = (seconds / 60) % 60;
+ seconds %= 60;
+ if (hours) {
+ if (hours > 9)
+ return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
+
+ return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
+ }
+
+ return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
+}
+
+String RenderTheme::formatMediaControlsCurrentTime(float currentTime, float /*duration*/) const
+{
+ return formatMediaControlsTime(currentTime);
+}
+
+String RenderTheme::formatMediaControlsRemainingTime(float currentTime, float duration) const
+{
+ return formatMediaControlsTime(currentTime - duration);
+}
+
#endif
Color RenderTheme::activeSelectionBackgroundColor() const
@@ -581,7 +640,7 @@ bool RenderTheme::supportsFocusRing(const RenderStyle* style) const
bool RenderTheme::stateChanged(RenderObject* o, ControlState state) const
{
- // Default implementation assumes the controls dont respond to changes in :hover state
+ // Default implementation assumes the controls don't respond to changes in :hover state
if (state == HoverState && !supportsHover(o->style()))
return false;
@@ -701,6 +760,10 @@ bool RenderTheme::isHovered(const RenderObject* o) const
bool RenderTheme::isDefault(const RenderObject* o) const
{
+ // A button should only have the default appearance if the page is active
+ if (!isActive(o))
+ return false;
+
if (!o->document())
return false;
@@ -754,6 +817,14 @@ void RenderTheme::adjustButtonStyle(CSSStyleSelector*, RenderStyle* style, Eleme
setButtonSize(style);
}
+void RenderTheme::adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const
+{
+}
+
+void RenderTheme::adjustOuterSpinButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const
+{
+}
+
#endif
void RenderTheme::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const
@@ -768,6 +839,18 @@ void RenderTheme::adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*)
{
}
+#if ENABLE(PROGRESS_TAG)
+bool RenderTheme::getNumberOfPixelsForProgressPosition(double , int& progressSize) const
+{
+ progressSize = 0;
+ return false;
+}
+
+void RenderTheme::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const
+{
+}
+#endif
+
void RenderTheme::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const
{
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h
index 1b6a7e44e5..fbdf91030d 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTheme.h
@@ -169,10 +169,22 @@ public:
// Method for painting the caps lock indicator
virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return 0; };
+#if ENABLE(PROGRESS_TAG)
+ // Helper method for optimizing the paint area of the progress bar.
+ // If supported, it returns number of pixels needed to draw the progress bar up to the progress position.
+ // progressSize is the value that is passed back to RenderTheme during drawing.
+ virtual bool getNumberOfPixelsForProgressPosition(double position, int& progressSize) const;
+#endif
+
#if ENABLE(VIDEO)
// Media controls
virtual bool hitTestMediaControlPart(RenderObject*, const IntPoint& absPoint);
virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
+ virtual double mediaControlsFadeInDuration() { return 0.1; }
+ virtual double mediaControlsFadeOutDuration() { return 0.3; }
+ virtual String formatMediaControlsTime(float time) const;
+ virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const;
+ virtual String formatMediaControlsRemainingTime(float currentTime, float duration) const;
#endif
protected:
@@ -203,6 +215,11 @@ protected:
virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual void setButtonSize(RenderStyle*) const { }
+
+ virtual void adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual bool paintInnerSpinButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
+ virtual void adjustOuterSpinButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual bool paintOuterSpinButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
#endif
virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
@@ -217,6 +234,11 @@ protected:
virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
+#if ENABLE(PROGRESS_TAG)
+ virtual void adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual bool paintProgressBar(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
+#endif
+
virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
@@ -250,6 +272,7 @@ protected:
virtual bool paintMediaVolumeSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaRewindButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaReturnToRealtimeButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
+ virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaControlsBackground(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaCurrentTime(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaTimeRemaining(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp
index 9048ce38e2..13c9cd62ad 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.cpp
@@ -25,13 +25,27 @@
#include "config.h"
#include "RenderThemeChromiumLinux.h"
-#include "Color.h"
#include "CSSValueKeywords.h"
+#include "Color.h"
#include "RenderObject.h"
#include "UserAgentStyleSheets.h"
namespace WebCore {
+unsigned RenderThemeChromiumLinux::m_thumbInactiveColor = 0xf0ebe5;
+unsigned RenderThemeChromiumLinux::m_thumbActiveColor = 0xfaf8f5;
+unsigned RenderThemeChromiumLinux::m_trackColor = 0xe3ddd8;
+unsigned RenderThemeChromiumLinux::m_activeSelectionBackgroundColor =
+ 0xff1e90ff;
+unsigned RenderThemeChromiumLinux::m_activeSelectionForegroundColor =
+ Color::black;
+unsigned RenderThemeChromiumLinux::m_inactiveSelectionBackgroundColor =
+ 0xffc8c8c8;
+unsigned RenderThemeChromiumLinux::m_inactiveSelectionForegroundColor =
+ 0xff323232;
+
+double RenderThemeChromiumLinux::m_caretBlinkInterval;
+
PassRefPtr<RenderTheme> RenderThemeChromiumLinux::create()
{
return adoptRef(new RenderThemeChromiumLinux());
@@ -92,6 +106,26 @@ Color RenderThemeChromiumLinux::inactiveListBoxSelectionForegroundColor() const
return Color(0x32, 0x32, 0x32);
}
+Color RenderThemeChromiumLinux::platformActiveSelectionBackgroundColor() const
+{
+ return m_activeSelectionBackgroundColor;
+}
+
+Color RenderThemeChromiumLinux::platformInactiveSelectionBackgroundColor() const
+{
+ return m_inactiveSelectionBackgroundColor;
+}
+
+Color RenderThemeChromiumLinux::platformActiveSelectionForegroundColor() const
+{
+ return m_activeSelectionForegroundColor;
+}
+
+Color RenderThemeChromiumLinux::platformInactiveSelectionForegroundColor() const
+{
+ return m_inactiveSelectionForegroundColor;
+}
+
void RenderThemeChromiumLinux::adjustSliderThumbSize(RenderObject* o) const
{
// These sizes match the sizes in Chromium Win.
@@ -122,4 +156,24 @@ double RenderThemeChromiumLinux::caretBlinkIntervalInternal() const
return m_caretBlinkInterval;
}
+void RenderThemeChromiumLinux::setSelectionColors(
+ unsigned activeBackgroundColor,
+ unsigned activeForegroundColor,
+ unsigned inactiveBackgroundColor,
+ unsigned inactiveForegroundColor)
+{
+ m_activeSelectionBackgroundColor = activeBackgroundColor;
+ m_activeSelectionForegroundColor = activeForegroundColor;
+ m_inactiveSelectionBackgroundColor = inactiveBackgroundColor;
+ m_inactiveSelectionForegroundColor = inactiveForegroundColor;
+}
+
+void RenderThemeChromiumLinux::setScrollbarColors(
+ SkColor inactiveColor, SkColor activeColor, SkColor trackColor)
+{
+ m_thumbInactiveColor = inactiveColor;
+ m_thumbActiveColor = activeColor;
+ m_trackColor = trackColor;
+}
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h
index e137ad598e..c60dec3266 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumLinux.h
@@ -49,11 +49,28 @@ namespace WebCore {
virtual Color inactiveListBoxSelectionBackgroundColor() const;
virtual Color inactiveListBoxSelectionForegroundColor() const;
+ virtual Color platformActiveSelectionBackgroundColor() const;
+ virtual Color platformInactiveSelectionBackgroundColor() const;
+ virtual Color platformActiveSelectionForegroundColor() const;
+ virtual Color platformInactiveSelectionForegroundColor() const;
+
virtual void adjustSliderThumbSize(RenderObject*) const;
- void setCaretBlinkInterval(double interval);
+ static void setCaretBlinkInterval(double interval);
virtual double caretBlinkIntervalInternal() const;
+ static void setSelectionColors(unsigned activeBackgroundColor,
+ unsigned activeForegroundColor,
+ unsigned inactiveBackgroundColor,
+ unsigned inactiveForegroundColor);
+
+ static void setScrollbarColors(unsigned inactive_color,
+ unsigned active_color,
+ unsigned track_color);
+ static unsigned thumbInactiveColor() { return m_thumbInactiveColor; }
+ static unsigned thumbActiveColor() { return m_thumbActiveColor; }
+ static unsigned trackColor() { return m_trackColor; }
+
private:
RenderThemeChromiumLinux();
virtual ~RenderThemeChromiumLinux();
@@ -61,7 +78,16 @@ namespace WebCore {
// A general method asking if any control tinting is supported at all.
virtual bool supportsControlTints() const;
- double m_caretBlinkInterval;
+ static double m_caretBlinkInterval;
+
+ static unsigned m_activeSelectionBackgroundColor;
+ static unsigned m_activeSelectionForegroundColor;
+ static unsigned m_inactiveSelectionBackgroundColor;
+ static unsigned m_inactiveSelectionForegroundColor;
+
+ static unsigned m_thumbInactiveColor;
+ static unsigned m_thumbActiveColor;
+ static unsigned m_trackColor;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h
index 61b5e8f39c..81010382fb 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h
@@ -191,7 +191,6 @@ private:
mutable HashMap<int, RGBA32> m_systemColorCache;
RetainPtr<WebCoreRenderThemeNotificationObserver> m_notificationObserver;
- bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*);
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm
index bcfcd577c6..03aab1cb5b 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm
@@ -41,7 +41,7 @@
#import "RenderSlider.h"
#import "RenderView.h"
#import "SharedBuffer.h"
-#import "UserAgentStyleSheets.h"
+#import "TimeRanges.h"
#import "WebCoreSystemInterface.h"
#import "UserAgentStyleSheets.h"
#import <Carbon/Carbon.h>
@@ -78,7 +78,7 @@ using std::min;
// The methods in this file are specific to the Mac OS X platform.
-// FIXME: The platform-independent code in this class should be factored out and merged with RenderThemeSafari.
+// FIXME: The platform-independent code in this class should be factored out and merged with RenderThemeSafari.
@interface WebCoreRenderThemeNotificationObserver : NSObject
{
@@ -96,7 +96,7 @@ using std::min;
{
[super init];
_theme = theme;
-
+
return self;
}
@@ -322,7 +322,7 @@ static RGBA32 convertNSColorToColor(NSColor *color)
static_cast<int>(scaleFactor * [colorInColorSpace blueComponent]));
}
- // This conversion above can fail if the NSColor in question is an NSPatternColor
+ // This conversion above can fail if the NSColor in question is an NSPatternColor
// (as many system colors are). These colors are actually a repeating pattern
// not just a solid color. To work around this we simply draw a 1x1 image of
// the color and use that pixel's color. It might be better to use an average of
@@ -390,7 +390,7 @@ Color RenderThemeChromiumMac::systemColor(int cssValueId) const
{
if (m_systemColorCache.contains(cssValueId))
return m_systemColorCache.get(cssValueId);
-
+
Color color;
switch (cssValueId) {
case CSSValueActiveborder:
@@ -504,7 +504,7 @@ bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const Bor
{
if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart || style->appearance() == ListboxPart)
return style->border() != border;
-
+
// FIXME: This is horrible, but there is not much else that can be done. Menu lists cannot draw properly when
// scaled. They can't really draw properly when transformed either. We can't detect the transform case at style
// adjustment time so that will just have to stay broken. We can however detect that we're zooming. If zooming
@@ -518,13 +518,14 @@ bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const Bor
void RenderThemeChromiumMac::adjustRepaintRect(const RenderObject* o, IntRect& r)
{
ControlPart part = o->style()->appearance();
-
+
#if USE(NEW_THEME)
switch (part) {
case CheckboxPart:
case RadioPart:
case PushButtonPart:
case SquareButtonPart:
+ case ListButtonPart:
case DefaultButtonPart:
case ButtonPart:
return RenderTheme::adjustRepaintRect(o, r);
@@ -565,13 +566,13 @@ IntRect RenderThemeChromiumMac::inflateRect(const IntRect& r, const IntSize& siz
FloatRect RenderThemeChromiumMac::convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const
{
FloatRect partRect(inputRect);
-
+
// Compute an offset between the part renderer and the input renderer
FloatSize offsetFromInputRenderer;
const RenderObject* renderer = partRenderer;
while (renderer && renderer != inputRenderer) {
RenderObject* containingRenderer = renderer->container();
- offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer);
+ offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer, IntPoint());
renderer = containingRenderer;
}
// If the input renderer was not a container, something went wrong
@@ -760,7 +761,7 @@ bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject*, const RenderO
LocalCurrentGraphicsContext localContext(paintInfo.context);
wkDrawCapsLockIndicator(paintInfo.context->platformContext(), r);
-
+
return false;
}
@@ -820,7 +821,7 @@ bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const RenderObject::
inflatedRect = inflateRect(inflatedRect, size, popupButtonMargins(), zoomLevel);
paintInfo.context->save();
-
+
#ifndef BUILDING_ON_TIGER
// On Leopard, the cell will draw outside of the given rect, so we have to clip to the rect
paintInfo.context->clip(inflatedRect);
@@ -980,10 +981,10 @@ bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const RenderOb
if (bounds.width() < arrowWidth + arrowPaddingLeft * o->style()->effectiveZoom())
return false;
-
+
paintInfo.context->save();
- paintInfo.context->setFillColor(o->style()->color());
+ paintInfo.context->setFillColor(o->style()->color(), o->style()->colorSpace());
paintInfo.context->setStrokeStyle(NoStroke);
FloatPoint arrow1[3];
@@ -1012,11 +1013,11 @@ bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const RenderOb
// Draw the separator to the left of the arrows
paintInfo.context->setStrokeThickness(1.0f); // Deliberately ignores zoom since it looks nicer if it stays thin.
paintInfo.context->setStrokeStyle(SolidStroke);
- paintInfo.context->setStrokeColor(leftSeparatorColor);
+ paintInfo.context->setStrokeColor(leftSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
IntPoint(leftEdgeOfSeparator, bounds.bottom()));
- paintInfo.context->setStrokeColor(rightSeparatorColor);
+ paintInfo.context->setStrokeColor(rightSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom()));
@@ -1036,7 +1037,7 @@ void RenderThemeChromiumMac::adjustMenuListStyle(CSSStyleSelector* selector, Ren
style->resetBorder();
style->resetPadding();
-
+
// Height is locked to auto.
style->setHeight(Length(Auto));
@@ -1106,7 +1107,7 @@ void RenderThemeChromiumMac::adjustMenuListButtonStyle(CSSStyleSelector*, Render
const int minHeight = 15;
style->setMinHeight(Length(minHeight, Fixed));
-
+
style->setLineHeight(RenderStyle::initialLineHeight());
}
@@ -1136,6 +1137,9 @@ int RenderThemeChromiumMac::minimumMenuListSize(RenderStyle* style) const
return sizeForSystemFont(style, menuListSizes()).width();
}
+const int trackWidth = 5;
+const int trackRadius = 2;
+
void RenderThemeChromiumMac::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
{
style->setBoxShadow(0);
@@ -1143,9 +1147,6 @@ void RenderThemeChromiumMac::adjustSliderTrackStyle(CSSStyleSelector*, RenderSty
bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- static const int trackWidth = 5;
- static const int trackRadius = 2;
-
IntRect bounds = r;
float zoomLevel = o->style()->effectiveZoom();
float zoomedTrackWidth = trackWidth * zoomLevel;
@@ -1179,7 +1180,7 @@ bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const RenderObjec
radius, radius);
CGContextDrawShading(context, mainShading.get());
paintInfo.context->restore();
-
+
return false;
}
@@ -1201,7 +1202,7 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObjec
LocalCurrentGraphicsContext localContext(paintInfo.context);
// Update the various states we respond to.
- updateActiveState(sliderThumbCell, o);
+ updateActiveState(sliderThumbCell, o->parent());
updateEnabledState(sliderThumbCell, o->parent());
updateFocusedState(sliderThumbCell, o->parent());
@@ -1233,7 +1234,7 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObjec
paintInfo.context->save();
float zoomLevel = o->style()->effectiveZoom();
-
+
FloatRect unzoomedRect = bounds;
if (zoomLevel != 1.0f) {
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
@@ -1251,22 +1252,6 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObjec
return false;
}
-void RenderThemeChromiumMac::adjustSliderThumbSize(RenderObject* o) const
-{
- static const int sliderThumbWidth = 15;
- static const int sliderThumbHeight = 15;
-
- float zoomLevel = o->style()->effectiveZoom();
- if (o->style()->appearance() == SliderThumbHorizontalPart || o->style()->appearance() == SliderThumbVerticalPart) {
- o->style()->setWidth(Length(static_cast<int>(sliderThumbWidth * zoomLevel), Fixed));
- o->style()->setHeight(Length(static_cast<int>(sliderThumbHeight * zoomLevel), Fixed));
- }
-
-#if ENABLE(VIDEO)
- RenderMediaControlsChromium::adjustMediaSliderThumbSize(o);
-#endif
-}
-
bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
NSSearchFieldCell* search = this->search();
@@ -1279,7 +1264,7 @@ bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const RenderObjec
float zoomLevel = o->style()->effectiveZoom();
IntRect unzoomedRect = r;
-
+
if (zoomLevel != 1.0f) {
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
@@ -1328,7 +1313,7 @@ void RenderThemeChromiumMac::setSearchFieldSize(RenderStyle* style) const
// If the width and height are both specified, then we have nothing to do.
if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
return;
-
+
// Use the font size to determine the intrinsic width of the control.
setSizeFromFont(style, searchFieldSizes());
}
@@ -1345,19 +1330,19 @@ void RenderThemeChromiumMac::adjustSearchFieldStyle(CSSStyleSelector* selector,
style->setBorderBottomWidth(borderWidth);
style->setBorderBottomStyle(INSET);
style->setBorderTopWidth(borderWidth);
- style->setBorderTopStyle(INSET);
-
+ style->setBorderTopStyle(INSET);
+
// Override height.
style->setHeight(Length(Auto));
setSearchFieldSize(style);
-
+
// Override padding size to match AppKit text positioning.
const int padding = 1 * style->effectiveZoom();
style->setPaddingLeft(Length(padding, Fixed));
style->setPaddingRight(Length(padding, Fixed));
style->setPaddingTop(Length(padding, Fixed));
style->setPaddingBottom(Length(padding, Fixed));
-
+
NSControlSize controlSize = controlSizeForFont(style);
setFontFromControlSize(selector, style, controlSize);
@@ -1495,7 +1480,7 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, cons
FloatRect localBounds = [search searchButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())];
localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r);
-
+
IntRect unzoomedRect(localBounds);
if (zoomLevel != 1.0f) {
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
@@ -1507,12 +1492,28 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, cons
[[search searchButtonCell] drawWithFrame:unzoomedRect inView:FlippedView()];
[[search searchButtonCell] setControlView:nil];
-
+
paintInfo.context->restore();
return false;
}
+const int sliderThumbWidth = 15;
+const int sliderThumbHeight = 15;
+
+void RenderThemeChromiumMac::adjustSliderThumbSize(RenderObject* o) const
+{
+ float zoomLevel = o->style()->effectiveZoom();
+ if (o->style()->appearance() == SliderThumbHorizontalPart || o->style()->appearance() == SliderThumbVerticalPart) {
+ o->style()->setWidth(Length(static_cast<int>(sliderThumbWidth * zoomLevel), Fixed));
+ o->style()->setHeight(Length(static_cast<int>(sliderThumbHeight * zoomLevel), Fixed));
+ }
+
+#if ENABLE(VIDEO)
+ RenderMediaControlsChromium::adjustMediaSliderThumbSize(o);
+#endif
+}
+
#if ENABLE(VIDEO)
bool RenderThemeChromiumMac::shouldRenderMediaControlPart(ControlPart part, Element* e)
{
@@ -1553,7 +1554,7 @@ bool RenderThemeChromiumMac::paintMediaControlsBackground(RenderObject* object,
{
return RenderMediaControlsChromium::paintMediaControlsPart(MediaTimelineContainer, object, paintInfo, rect);
}
-
+
String RenderThemeChromiumMac::extraMediaControlsStyleSheet()
{
return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet));
@@ -1568,7 +1569,7 @@ NSPopUpButtonCell* RenderThemeChromiumMac::popupButton() const
[m_popupButton.get() setUsesItemFromMenu:NO];
[m_popupButton.get() setFocusRingType:NSFocusRingTypeExterior];
}
-
+
return m_popupButton.get();
}
@@ -1602,7 +1603,7 @@ NSSliderCell* RenderThemeChromiumMac::sliderThumbHorizontal() const
[m_sliderThumbHorizontal.get() setControlSize:NSSmallControlSize];
[m_sliderThumbHorizontal.get() setFocusRingType:NSFocusRingTypeExterior];
}
-
+
return m_sliderThumbHorizontal.get();
}
@@ -1615,7 +1616,7 @@ NSSliderCell* RenderThemeChromiumMac::sliderThumbVertical() const
[m_sliderThumbVertical.get() setControlSize:NSSmallControlSize];
[m_sliderThumbVertical.get() setFocusRingType:NSFocusRingTypeExterior];
}
-
+
return m_sliderThumbVertical.get();
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp
index fb42bb7af5..8b3b388ca9 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp
@@ -217,6 +217,22 @@ int RenderThemeChromiumSkia::minimumMenuListSize(RenderStyle* style) const
return 0;
}
+// These are the default dimensions of radio buttons and checkboxes.
+static const int widgetStandardWidth = 13;
+static const int widgetStandardHeight = 13;
+
+// Return a rectangle that has the same center point as |original|, but with a
+// size capped at |width| by |height|.
+IntRect center(const IntRect& original, int width, int height)
+{
+ width = std::min(original.width(), width);
+ height = std::min(original.height(), height);
+ int x = original.x() + (original.width() - width) / 2;
+ int y = original.y() + (original.height() - height) / 2;
+
+ return IntRect(x, y, width, height);
+}
+
bool RenderThemeChromiumSkia::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
static Image* const checkedImage = Image::loadPlatformResource("linuxCheckboxOn").releaseRef();
@@ -231,7 +247,7 @@ bool RenderThemeChromiumSkia::paintCheckbox(RenderObject* o, const RenderObject:
else
image = this->isChecked(o) ? disabledCheckedImage : disabledUncheckedImage;
- i.context->drawImage(image, rect);
+ i.context->drawImage(image, o->style()->colorSpace(), center(rect, widgetStandardHeight, widgetStandardWidth));
return false;
}
@@ -246,7 +262,7 @@ void RenderThemeChromiumSkia::setCheckboxSize(RenderStyle* style) const
// 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);
+ const IntSize size(widgetStandardHeight, widgetStandardWidth);
setSizeIfAuto(style, size);
}
@@ -263,7 +279,7 @@ bool RenderThemeChromiumSkia::paintRadio(RenderObject* o, const RenderObject::Pa
else
image = this->isChecked(o) ? disabledCheckedImage : disabledUncheckedImage;
- i.context->drawImage(image, rect);
+ i.context->drawImage(image, o->style()->colorSpace(), center(rect, widgetStandardHeight, widgetStandardWidth));
return false;
}
@@ -348,6 +364,15 @@ bool RenderThemeChromiumSkia::paintButton(RenderObject* o, const RenderObject::P
return false;
}
+void RenderThemeChromiumSkia::adjustButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+{
+ if (style->appearance() == PushButtonPart) {
+ // Ignore line-height.
+ style->setLineHeight(RenderStyle::initialLineHeight());
+ }
+}
+
+
bool RenderThemeChromiumSkia::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
return true;
@@ -358,6 +383,12 @@ bool RenderThemeChromiumSkia::paintTextArea(RenderObject* o, const RenderObject:
return paintTextField(o, i, r);
}
+void RenderThemeChromiumSkia::adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+{
+ // Ignore line-height.
+ style->setLineHeight(RenderStyle::initialLineHeight());
+}
+
bool RenderThemeChromiumSkia::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
return paintTextField(o, i, r);
@@ -372,28 +403,41 @@ void RenderThemeChromiumSkia::adjustSearchFieldCancelButtonStyle(CSSStyleSelecto
style->setHeight(Length(cancelButtonSize, Fixed));
}
-bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+IntRect RenderThemeChromiumSkia::convertToPaintingRect(RenderObject* inputRenderer, const RenderObject* partRenderer, IntRect partRect, const IntRect& localOffset) const
{
- IntRect bounds = r;
- ASSERT(o->parent());
- if (!o->parent() || !o->parent()->isBox())
- return false;
-
- RenderBox* parentRenderBox = toRenderBox(o->parent());
+ // Compute an offset between the part renderer and the input renderer.
+ IntSize offsetFromInputRenderer = -(partRenderer->offsetFromAncestorContainer(inputRenderer));
+ // Move the rect into partRenderer's coords.
+ partRect.move(offsetFromInputRenderer);
+ // Account for the local drawing offset.
+ partRect.move(localOffset.x(), localOffset.y());
- IntRect parentBox = parentRenderBox->absoluteContentBox();
+ return partRect;
+}
- // Make sure the scaled button stays square and will fit in its parent's box
- bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height())));
- bounds.setWidth(bounds.height());
+bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* cancelButtonObject, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ // Get the renderer of <input> element.
+ Node* input = cancelButtonObject->node()->shadowAncestorNode();
+ if (!input->renderer()->isBox())
+ return false;
+ RenderBox* inputRenderBox = toRenderBox(input->renderer());
+ IntRect inputContentBox = inputRenderBox->contentBoxRect();
+ // Make sure the scaled button stays square and will fit in its parent's box.
+ int cancelButtonSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), r.height()));
+ // Calculate cancel button's coordinates relative to the input element.
// Center the button vertically. Round up though, so if it has to be one pixel off-center, it will
// be one pixel closer to the bottom of the field. This tends to look better with the text.
- bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
+ IntRect cancelButtonRect(cancelButtonObject->offsetFromAncestorContainer(inputRenderBox).width(),
+ inputContentBox.y() + (inputContentBox.height() - cancelButtonSize + 1) / 2,
+ cancelButtonSize, cancelButtonSize);
+ IntRect paintingRect = convertToPaintingRect(inputRenderBox, cancelButtonObject, cancelButtonRect, r);
static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef();
static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef();
- i.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, bounds);
+ paintInfo.context->drawImage(isPressed(cancelButtonObject) ? cancelPressedImage : cancelImage,
+ cancelButtonObject->style()->colorSpace(), paintingRect);
return false;
}
@@ -414,26 +458,27 @@ void RenderThemeChromiumSkia::adjustSearchFieldResultsDecorationStyle(CSSStyleSe
style->setHeight(Length(magnifierSize, Fixed));
}
-bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* magnifierObject, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- IntRect bounds = r;
- ASSERT(o->parent());
- if (!o->parent() || !o->parent()->isBox())
+ // Get the renderer of <input> element.
+ Node* input = magnifierObject->node()->shadowAncestorNode();
+ if (!input->renderer()->isBox())
return false;
+ RenderBox* inputRenderBox = toRenderBox(input->renderer());
+ IntRect inputContentBox = inputRenderBox->contentBoxRect();
- RenderBox* parentRenderBox = toRenderBox(o->parent());
- IntRect parentBox = parentRenderBox->absoluteContentBox();
-
- // Make sure the scaled decoration stays square and will fit in its parent's box
- bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height())));
- bounds.setWidth(bounds.height());
-
+ // Make sure the scaled decoration stays square and will fit in its parent's box.
+ int magnifierSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), r.height()));
+ // Calculate decoration's coordinates relative to the input element.
// Center the decoration vertically. Round up though, so if it has to be one pixel off-center, it will
// be one pixel closer to the bottom of the field. This tends to look better with the text.
- bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
+ IntRect magnifierRect(magnifierObject->offsetFromAncestorContainer(inputRenderBox).width(),
+ inputContentBox.y() + (inputContentBox.height() - magnifierSize + 1) / 2,
+ magnifierSize, magnifierSize);
+ IntRect paintingRect = convertToPaintingRect(inputRenderBox, magnifierObject, magnifierRect, r);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef();
- i.context->drawImage(magnifierImage, bounds);
+ paintInfo.context->drawImage(magnifierImage, magnifierObject->style()->colorSpace(), paintingRect);
return false;
}
@@ -448,28 +493,25 @@ void RenderThemeChromiumSkia::adjustSearchFieldResultsButtonStyle(CSSStyleSelect
style->setHeight(Length(magnifierHeight, Fixed));
}
-bool RenderThemeChromiumSkia::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+bool RenderThemeChromiumSkia::paintSearchFieldResultsButton(RenderObject* magnifierObject, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- IntRect bounds = r;
- ASSERT(o->parent());
- if (!o->parent())
- return false;
- if (!o->parent() || !o->parent()->isBox())
+ // Get the renderer of <input> element.
+ Node* input = magnifierObject->node()->shadowAncestorNode();
+ if (!input->renderer()->isBox())
return false;
+ RenderBox* inputRenderBox = toRenderBox(input->renderer());
+ IntRect inputContentBox = inputRenderBox->contentBoxRect();
- RenderBox* parentRenderBox = toRenderBox(o->parent());
- IntRect parentBox = parentRenderBox->absoluteContentBox();
-
- // Make sure the scaled decoration will fit in its parent's box
- bounds.setHeight(std::min(parentBox.height(), bounds.height()));
- bounds.setWidth(std::min(parentBox.width(), static_cast<int>(bounds.height() * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize)));
-
- // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will
- // be one pixel closer to the bottom of the field. This tends to look better with the text.
- bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
+ // Make sure the scaled decoration will fit in its parent's box.
+ int magnifierHeight = std::min(inputContentBox.height(), r.height());
+ int magnifierWidth = std::min(inputContentBox.width(), static_cast<int>(magnifierHeight * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize));
+ IntRect magnifierRect(magnifierObject->offsetFromAncestorContainer(inputRenderBox).width(),
+ inputContentBox.y() + (inputContentBox.height() - magnifierHeight + 1) / 2,
+ magnifierWidth, magnifierHeight);
+ IntRect paintingRect = convertToPaintingRect(inputRenderBox, magnifierObject, magnifierRect, r);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").releaseRef();
- i.context->drawImage(magnifierImage, bounds);
+ paintInfo.context->drawImage(magnifierImage, magnifierObject->style()->colorSpace(), paintingRect);
return false;
}
@@ -690,26 +732,6 @@ int RenderThemeChromiumSkia::popupInternalPaddingBottom(RenderStyle* style) cons
return menuListInternalPadding(style, BottomPadding);
}
-int RenderThemeChromiumSkia::buttonInternalPaddingLeft() const
-{
- return 3;
-}
-
-int RenderThemeChromiumSkia::buttonInternalPaddingRight() const
-{
- return 3;
-}
-
-int RenderThemeChromiumSkia::buttonInternalPaddingTop() const
-{
- return 1;
-}
-
-int RenderThemeChromiumSkia::buttonInternalPaddingBottom() const
-{
- return 1;
-}
-
#if ENABLE(VIDEO)
bool RenderThemeChromiumSkia::shouldRenderMediaControlPart(ControlPart part, Element* e)
{
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h
index 98e3a35571..dc920b1cf2 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.h
@@ -71,11 +71,13 @@ namespace WebCore {
virtual void setRadioSize(RenderStyle*) const;
virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
@@ -121,11 +123,6 @@ namespace WebCore {
virtual int popupInternalPaddingTop(RenderStyle*) const;
virtual int popupInternalPaddingBottom(RenderStyle*) const;
- virtual int buttonInternalPaddingLeft() const;
- virtual int buttonInternalPaddingRight() const;
- virtual int buttonInternalPaddingTop() const;
- virtual int buttonInternalPaddingBottom() const;
-
#if ENABLE(VIDEO)
// Media controls
virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
@@ -151,6 +148,7 @@ namespace WebCore {
private:
int menuListInternalPadding(RenderStyle*, int paddingType) const;
bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*);
+ IntRect convertToPaintingRect(RenderObject* inputRenderer, const RenderObject* partRenderer, IntRect partRect, const IntRect& localOffset) const;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp
index 4b38d53e74..db31825a0f 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp
@@ -86,7 +86,7 @@ private:
return transformMode == KeepTransform ? NoLayer : OpaqueCompositeLayer;
}
- static TransformMode getTransformMode(const TransformationMatrix& matrix)
+ static TransformMode getTransformMode(const AffineTransform& matrix)
{
if (matrix.b() != 0 || matrix.c() != 0) // Skew.
return Untransform;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h
index 1d68c630c9..48c6c42c20 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeMac.h
@@ -126,6 +126,7 @@ protected:
virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaRewindButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaReturnToRealtimeButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaControlsBackground(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaCurrentTime(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaTimeRemaining(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp
index 2ea3b8beaf..9e97079386 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeSafari.cpp
@@ -830,8 +830,8 @@ bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const RenderObject:
paintInfo.context->save();
- paintInfo.context->setFillColor(o->style()->color());
- paintInfo.context->setStrokeColor(NoStroke);
+ paintInfo.context->setFillColor(o->style()->color(), DeviceColorSpace);
+ paintInfo.context->setStrokeColor(NoStroke, DeviceColorSpace);
FloatPoint arrow[3];
arrow[0] = FloatPoint(leftEdge, centerY - arrowHeight / 2.0f);
@@ -851,11 +851,11 @@ bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const RenderObject:
// Draw the separator to the left of the arrows
paintInfo.context->setStrokeThickness(1.0f);
paintInfo.context->setStrokeStyle(SolidStroke);
- paintInfo.context->setStrokeColor(leftSeparatorColor);
+ paintInfo.context->setStrokeColor(leftSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
IntPoint(leftEdgeOfSeparator, bounds.bottom()));
- paintInfo.context->setStrokeColor(rightSeparatorColor);
+ paintInfo.context->setStrokeColor(rightSeparatorColor, DeviceColorSpace);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom()));
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp
index 92bfd03587..52afbd6c05 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.cpp
@@ -819,7 +819,7 @@ bool RenderThemeWin::paintSearchFieldCancelButton(RenderObject* o, const RenderO
static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef();
static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef();
- paintInfo.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, bounds);
+ paintInfo.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, o->style()->colorSpace(), bounds);
return false;
}
@@ -868,7 +868,7 @@ bool RenderThemeWin::paintSearchFieldResultsDecoration(RenderObject* o, const Re
bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef();
- paintInfo.context->drawImage(magnifierImage, bounds);
+ paintInfo.context->drawImage(magnifierImage, o->style()->colorSpace(), bounds);
return false;
}
@@ -904,7 +904,7 @@ bool RenderThemeWin::paintSearchFieldResultsButton(RenderObject* o, const Render
bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").releaseRef();
- paintInfo.context->drawImage(magnifierImage, bounds);
+ paintInfo.context->drawImage(magnifierImage, o->style()->colorSpace(), bounds);
return false;
}
@@ -955,6 +955,23 @@ Color RenderThemeWin::systemColor(int cssValueId) const
}
#if ENABLE(VIDEO)
+
+bool RenderThemeWin::shouldRenderMediaControlPart(ControlPart part, Element* element)
+{
+ if (part == MediaToggleClosedCaptionsButtonPart) {
+ // We rely on QuickTime to render captions so only enable the button for a video element.
+#if SAFARI_THEME_VERSION >= 4
+ if (!element->hasTagName(videoTag))
+ return false;
+#else
+ return false;
+#endif
+ }
+
+ return RenderTheme::shouldRenderMediaControlPart(part, element);
+}
+
+
bool RenderThemeWin::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
return RenderMediaControls::paintMediaControlsPart(MediaFullscreenButton, o, paintInfo, r);
@@ -989,6 +1006,12 @@ bool RenderThemeWin::paintMediaSliderThumb(RenderObject* o, const RenderObject::
{
return RenderMediaControls::paintMediaControlsPart(MediaSliderThumb, o, paintInfo, r);
}
+
+bool RenderThemeWin::paintMediaToggleClosedCaptionsButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ return RenderMediaControls::paintMediaControlsPart(MediaShowClosedCaptionsButton, o, paintInfo, r);
+}
+
#endif
}
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.h
index 99c200417c..a9fa5e66ac 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWin.h
@@ -125,6 +125,7 @@ public:
virtual bool supportsFocusRing(const RenderStyle*) const;
#if ENABLE(VIDEO)
+ virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
virtual bool paintMediaFullscreenButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
@@ -132,6 +133,7 @@ public:
virtual bool paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
#endif
private:
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWince.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWince.cpp
index fb89678b6c..c4aaaad878 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeWince.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeWince.cpp
@@ -28,6 +28,7 @@
#include "CSSValueKeywords.h"
#include "Document.h"
#include "GraphicsContext.h"
+#include "NotImplemented.h"
#if ENABLE(VIDEO)
#include "HTMLMediaElement.h"
#endif
@@ -377,12 +378,12 @@ bool RenderThemeWince::paintSearchFieldCancelButton(RenderObject* o, const Rende
IntRect cancelBounds(IntPoint(x, y), cancelSize);
paintInfo.context->save();
paintInfo.context->addRoundedRectClip(cancelBounds, cancelRadius, cancelRadius, cancelRadius, cancelRadius);
- paintInfo.context->fillRect(cancelBounds, buttonColor);
+ paintInfo.context->fillRect(cancelBounds, buttonColor, DeviceColorSpace);
// Draw the 'x'
IntSize xSize(3, 3);
IntRect xBounds(cancelBounds.location() + IntSize(3, 3), xSize);
- paintInfo.context->setStrokeColor(Color::white);
+ paintInfo.context->setStrokeColor(Color::white, DeviceColorSpace);
paintInfo.context->drawLine(xBounds.location(), xBounds.location() + xBounds.size());
paintInfo.context->drawLine(IntPoint(xBounds.right(), xBounds.y()), IntPoint(xBounds.x(), xBounds.bottom()));
@@ -489,11 +490,11 @@ bool RenderThemeWince::paintSliderTrack(RenderObject* o, const RenderObject::Pai
bool rc = RenderTheme::paintSliderTrack(o, i, r);
IntPoint left = IntPoint(r.x() + 2, (r.y() + r.bottom()) / 2);
i.context->save();
- i.context->setStrokeColor(Color::gray);
- i.context->setFillColor(Color::gray);
+ i.context->setStrokeColor(Color::gray, DeviceColorSpace);
+ i.context->setFillColor(Color::gray, DeviceColorSpace);
i.context->fillRect(r);
#if ENABLE(VIDEO)
- HTMLMediaElement *mediaElement = mediaElementParent(o->node());
+ HTMLMediaElement* mediaElement = mediaElementParent(o->node());
if (mediaElement) {
i.context->setStrokeColor(Color(0, 0xff, 0));
IntPoint right = IntPoint(left.x() + mediaElement->percentLoaded() * (r.right() - r.x() - 4), (r.y() + r.bottom()) / 2);
@@ -501,7 +502,7 @@ bool RenderThemeWince::paintSliderTrack(RenderObject* o, const RenderObject::Pai
left = right;
}
#endif
- i.context->setStrokeColor(Color::black);
+ i.context->setStrokeColor(Color::black, DeviceColorSpace);
i.context->drawLine(left, IntPoint(r.right() - 2, left.y()));
i.context->restore();
return rc;
@@ -511,10 +512,10 @@ bool RenderThemeWince::paintSliderThumb(RenderObject* o, const RenderObject::Pai
{
bool rc = RenderTheme::paintSliderThumb(o, i, r);
i.context->save();
- i.context->setStrokeColor(Color::black);
- i.context->setFillColor(Color::black);
+ i.context->setStrokeColor(Color::black, DeviceColorSpace);
+ i.context->setFillColor(Color::black, DeviceColorSpace);
#if ENABLE(VIDEO)
- HTMLMediaElement *mediaElement = mediaElementParent(o->node());
+ HTMLMediaElement* mediaElement = mediaElementParent(o->node());
if (mediaElement) {
float pt = (mediaElement->currentTime() - mediaElement->startTime()) / mediaElement->duration();
FloatRect intRect = r;
@@ -574,7 +575,7 @@ bool RenderThemeWince::paintMediaFullscreenButton(RenderObject* o, const RenderO
bool RenderThemeWince::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
bool rc = paintButton(o, paintInfo, r);
- HTMLMediaElement *mediaElement = mediaElementParent(o->node());
+ HTMLMediaElement* mediaElement = mediaElementParent(o->node());
bool muted = !mediaElement || mediaElement->muted();
FloatRect imRect = r;
imRect.inflate(-2);
@@ -604,7 +605,7 @@ bool RenderThemeWince::paintMediaPlayButton(RenderObject* o, const RenderObject:
paintInfo.context->save();
paintInfo.context->setStrokeColor(Color::black);
paintInfo.context->setFillColor(Color::black);
- HTMLMediaElement *mediaElement = mediaElementParent(o->node());
+ HTMLMediaElement* mediaElement = mediaElementParent(o->node());
bool paused = !mediaElement || mediaElement->paused();
if (paused) {
float width = imRect.width();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.cpp
index b7ab191d7d..164a6560ad 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.cpp
@@ -36,13 +36,16 @@
#include "HTMLNames.h"
#include "InlineTextBox.h"
#include "RenderBR.h"
+#include "RenderFileUploadControl.h"
#include "RenderInline.h"
#include "RenderListMarker.h"
+#include "RenderPart.h"
#include "RenderTableCell.h"
#include "RenderView.h"
#include "RenderWidget.h"
#include "SelectionController.h"
#include "TextStream.h"
+#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
#if ENABLE(SVG)
@@ -55,11 +58,19 @@
#include "SVGRenderTreeAsText.h"
#endif
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerBacking.h"
+#endif
+
+#if PLATFORM(QT)
+#include <QWidget>
+#endif
+
namespace WebCore {
using namespace HTMLNames;
-static void writeLayers(TextStream&, const RenderLayer* rootLayer, RenderLayer*, const IntRect& paintDirtyRect, int indent = 0);
+static void writeLayers(TextStream&, const RenderLayer* rootLayer, RenderLayer*, const IntRect& paintDirtyRect, int indent = 0, RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal);
#if !ENABLE(SVG)
static TextStream &operator<<(TextStream& ts, const IntRect& r)
@@ -217,6 +228,9 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o)
ts << " " << r;
if (!(o.isText() && !o.isBR())) {
+ if (o.isFileUploadControl()) {
+ ts << " " << quoteAndEscapeNonPrintables(toRenderFileUploadControl(&o)->fileTextValue());
+ }
if (o.parent() && (o.parent()->style()->color() != o.style()->color()))
ts << " [color=" << o.style()->color().name() << "]";
@@ -336,6 +350,24 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o)
}
}
+#if PLATFORM(QT)
+ // Print attributes of embedded QWidgets. E.g. when the WebCore::Widget
+ // is invisible the QWidget should be invisible too.
+ if (o.isRenderPart()) {
+ const RenderPart* part = toRenderPart(const_cast<RenderObject*>(&o));
+ if (part->widget() && part->widget()->platformWidget()) {
+ QWidget* wid = part->widget()->platformWidget();
+
+ ts << " [QT: ";
+ ts << "geometry: {" << wid->geometry() << "} ";
+ ts << "isHidden: " << wid->isHidden() << " ";
+ ts << "isSelfVisible: " << part->widget()->isSelfVisible() << " ";
+ ts << "isParentVisible: " << part->widget()->isParentVisible() << " ";
+ ts << "mask: {" << wid->mask().boundingRect() << "} ] ";
+ }
+ }
+#endif
+
return ts;
}
@@ -363,6 +395,10 @@ void write(TextStream& ts, const RenderObject& o, int indent)
write(ts, *toRenderPath(&o), indent);
return;
}
+ if (o.isSVGResource()) {
+ writeSVGResource(ts, o, indent);
+ return;
+ }
if (o.isSVGContainer()) {
writeSVGContainer(ts, o, indent);
return;
@@ -417,9 +453,15 @@ void write(TextStream& ts, const RenderObject& o, int indent)
}
}
+enum LayerPaintPhase {
+ LayerPaintPhaseAll = 0,
+ LayerPaintPhaseBackground = -1,
+ LayerPaintPhaseForeground = 1
+};
+
static void write(TextStream& ts, RenderLayer& l,
const IntRect& layerBounds, const IntRect& backgroundClipRect, const IntRect& clipRect, const IntRect& outlineClipRect,
- int layerType = 0, int indent = 0)
+ LayerPaintPhase paintPhase = LayerPaintPhaseAll, int indent = 0, RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal)
{
writeIndent(ts, indent);
@@ -445,19 +487,28 @@ static void write(TextStream& ts, RenderLayer& l,
ts << " scrollHeight " << l.scrollHeight();
}
- if (layerType == -1)
+ if (paintPhase == LayerPaintPhaseBackground)
ts << " layerType: background only";
- else if (layerType == 1)
+ else if (paintPhase == LayerPaintPhaseForeground)
ts << " layerType: foreground only";
-
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (behavior & RenderAsTextShowCompositedLayers) {
+ if (l.isComposited())
+ ts << " (composited, bounds " << l.backing()->compositedBounds() << ")";
+ }
+#else
+ UNUSED_PARAM(behavior);
+#endif
+
ts << "\n";
- if (layerType != -1)
+ if (paintPhase != LayerPaintPhaseBackground)
write(ts, *l.renderer(), indent + 1);
}
static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLayer* l,
- const IntRect& paintDirtyRect, int indent)
+ const IntRect& paintDirtyRect, int indent, RenderAsTextBehavior behavior)
{
// Calculate the clip rects we should use.
IntRect layerBounds, damageRect, clipRectToApply, outlineRect;
@@ -467,29 +518,46 @@ static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLaye
l->updateZOrderLists();
l->updateNormalFlowList();
- bool shouldPaint = l->intersectsDamageRect(layerBounds, damageRect, rootLayer);
+ bool shouldPaint = (behavior & RenderAsTextShowAllLayers) ? true : l->intersectsDamageRect(layerBounds, damageRect, rootLayer);
Vector<RenderLayer*>* negList = l->negZOrderList();
- if (shouldPaint && negList && negList->size() > 0)
- write(ts, *l, layerBounds, damageRect, clipRectToApply, outlineRect, -1, indent);
+ bool paintsBackgroundSeparately = negList && negList->size() > 0;
+ if (shouldPaint && paintsBackgroundSeparately)
+ write(ts, *l, layerBounds, damageRect, clipRectToApply, outlineRect, LayerPaintPhaseBackground, indent, behavior);
if (negList) {
+ int currIndent = indent;
+ if (behavior & RenderAsTextShowLayerNesting) {
+ writeIndent(ts, indent);
+ ts << " negative z-order list(" << negList->size() << ")\n";
+ ++currIndent;
+ }
for (unsigned i = 0; i != negList->size(); ++i)
- writeLayers(ts, rootLayer, negList->at(i), paintDirtyRect, indent);
+ writeLayers(ts, rootLayer, negList->at(i), paintDirtyRect, currIndent, behavior);
}
if (shouldPaint)
- write(ts, *l, layerBounds, damageRect, clipRectToApply, outlineRect, negList && negList->size() > 0, indent);
-
- Vector<RenderLayer*>* normalFlowList = l->normalFlowList();
- if (normalFlowList) {
+ write(ts, *l, layerBounds, damageRect, clipRectToApply, outlineRect, paintsBackgroundSeparately ? LayerPaintPhaseForeground : LayerPaintPhaseAll, indent, behavior);
+
+ if (Vector<RenderLayer*>* normalFlowList = l->normalFlowList()) {
+ int currIndent = indent;
+ if (behavior & RenderAsTextShowLayerNesting) {
+ writeIndent(ts, indent);
+ ts << " normal flow list(" << normalFlowList->size() << ")\n";
+ ++currIndent;
+ }
for (unsigned i = 0; i != normalFlowList->size(); ++i)
- writeLayers(ts, rootLayer, normalFlowList->at(i), paintDirtyRect, indent);
+ writeLayers(ts, rootLayer, normalFlowList->at(i), paintDirtyRect, currIndent, behavior);
}
- Vector<RenderLayer*>* posList = l->posZOrderList();
- if (posList) {
+ if (Vector<RenderLayer*>* posList = l->posZOrderList()) {
+ int currIndent = indent;
+ if (behavior & RenderAsTextShowLayerNesting) {
+ writeIndent(ts, indent);
+ ts << " positive z-order list(" << posList->size() << ")\n";
+ ++currIndent;
+ }
for (unsigned i = 0; i != posList->size(); ++i)
- writeLayers(ts, rootLayer, posList->at(i), paintDirtyRect, indent);
+ writeLayers(ts, rootLayer, posList->at(i), paintDirtyRect, currIndent, behavior);
}
}
@@ -535,8 +603,11 @@ static void writeSelection(TextStream& ts, const RenderObject* o)
<< "selection end: position " << selection.end().deprecatedEditingOffset() << " of " << nodePosition(selection.end().node()) << "\n";
}
-String externalRepresentation(RenderObject* o)
+String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior)
{
+ frame->document()->updateLayout();
+
+ RenderObject* o = frame->contentRenderer();
if (!o)
return String();
@@ -544,20 +615,21 @@ String externalRepresentation(RenderObject* o)
#if ENABLE(SVG)
writeRenderResources(ts, o->document());
#endif
- if (o->view()->frameView())
- o->view()->frameView()->layout();
if (o->hasLayer()) {
RenderLayer* l = toRenderBox(o)->layer();
- writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()));
+ writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), 0, behavior);
writeSelection(ts, o);
}
return ts.release();
}
-static void writeCounterValuesFromChildren(TextStream& stream, RenderObject* parent)
+static void writeCounterValuesFromChildren(TextStream& stream, RenderObject* parent, bool& isFirstCounter)
{
for (RenderObject* child = parent->firstChild(); child; child = child->nextSibling()) {
if (child->isCounter()) {
+ if (!isFirstCounter)
+ stream << " ";
+ isFirstCounter = false;
String str(toRenderText(child)->text());
stream << str;
}
@@ -570,12 +642,13 @@ String counterValueForElement(Element* element)
RefPtr<Element> elementRef(element);
element->document()->updateLayout();
TextStream stream;
+ bool isFirstCounter = true;
// The counter renderers should be children of anonymous children
// (i.e., :before or :after pseudo-elements).
if (RenderObject* renderer = element->renderer()) {
for (RenderObject* child = renderer->firstChild(); child; child = child->nextSibling()) {
if (child->isAnonymous())
- writeCounterValuesFromChildren(stream, child);
+ writeCounterValuesFromChildren(stream, child, isFirstCounter);
}
}
return stream.release();
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.h b/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.h
index 325f109478..13525e7d77 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderTreeAsText.h
@@ -29,11 +29,20 @@
namespace WebCore {
class Element;
+class Frame;
class RenderObject;
class String;
class TextStream;
-String externalRepresentation(RenderObject*);
+enum RenderAsTextBehaviorFlags {
+ RenderAsTextBehaviorNormal = 0,
+ RenderAsTextShowAllLayers = 1 << 0, // Dump all layers, not just those that would paint.
+ RenderAsTextShowLayerNesting = 1 << 1, // Annotate the layer lists.
+ RenderAsTextShowCompositedLayers = 1 << 2 // Show which layers are composited.
+};
+typedef unsigned RenderAsTextBehavior;
+
+String externalRepresentation(Frame*, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
void write(TextStream&, const RenderObject&, int indent = 0);
// Helper function shared with SVGRenderTreeAsText
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.cpp
index 246d0c0b7e..13d6f60d61 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
#include "HTMLNames.h"
#include "HTMLVideoElement.h"
#include "MediaPlayer.h"
+#include "RenderView.h"
#if USE(ACCELERATED_COMPOSITING)
#include "RenderLayer.h"
@@ -49,18 +50,25 @@ using namespace HTMLNames;
static const int cDefaultWidth = 300;
static const int cDefaultHeight = 150;
-RenderVideo::RenderVideo(HTMLMediaElement* video)
+RenderVideo::RenderVideo(HTMLVideoElement* video)
: RenderMedia(video)
{
if (video->player())
setIntrinsicSize(video->player()->naturalSize());
else {
- // Video in standalone media documents should not use the default 300x150
- // size since they also have audio thrown at them. By setting the intrinsic
- // size to 300x1 the video will resize itself in these cases, and audio will
- // have the correct height (it needs to be > 0 for controls to render properly).
- if (video->ownerDocument() && video->ownerDocument()->isMediaDocument())
+ // When the natural size of the video is unavailable, we use the provided
+ // width and height attributes of the video element as the intrinsic size until
+ // better values become available. If these attributes are not set, we fall back
+ // to a default video size (300x150).
+ if (video->hasAttribute(widthAttr) && video->hasAttribute(heightAttr))
+ setIntrinsicSize(IntSize(video->width(), video->height()));
+ else if (video->ownerDocument() && video->ownerDocument()->isMediaDocument()) {
+ // Video in standalone media documents should not use the default 300x150
+ // size since they also have audio thrown at them. By setting the intrinsic
+ // size to 300x1 the video will resize itself in these cases, and audio will
+ // have the correct height (it needs to be > 0 for controls to render properly).
setIntrinsicSize(IntSize(cDefaultWidth, 1));
+ }
else
setIntrinsicSize(IntSize(cDefaultWidth, cDefaultHeight));
}
@@ -73,7 +81,15 @@ RenderVideo::~RenderVideo()
p->setFrameView(0);
}
}
-
+
+void RenderVideo::intrinsicSizeChanged()
+{
+ if (videoElement()->shouldDisplayPosterImage())
+ RenderMedia::intrinsicSizeChanged();
+ videoSizeChanged();
+}
+
+
void RenderVideo::videoSizeChanged()
{
if (!player())
@@ -86,41 +102,72 @@ void RenderVideo::videoSizeChanged()
}
}
-IntRect RenderVideo::videoBox() const
+void RenderVideo::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
{
+ RenderMedia::imageChanged(newImage, rect);
+
+ // Cache the image intrinsic size so we can continue to use it to draw the image correctly
+ // even after we know the video intrisic size but aren't able to draw video frames yet
+ // (we don't want to scale the poster to the video size).
+ if (videoElement()->shouldDisplayPosterImage())
+ m_cachedImageSize = intrinsicSize();
+}
+
+IntRect RenderVideo::videoBox() const
+{
+ if (m_cachedImageSize.isEmpty() && videoElement()->shouldDisplayPosterImage())
+ return IntRect();
+
+ IntSize elementSize;
+ if (videoElement()->shouldDisplayPosterImage())
+ elementSize = m_cachedImageSize;
+ else
+ elementSize = intrinsicSize();
+
IntRect contentRect = contentBoxRect();
-
- if (intrinsicSize().isEmpty() || contentRect.isEmpty())
+ if (elementSize.isEmpty() || contentRect.isEmpty())
return IntRect();
- IntRect resultRect = contentRect;
- int ratio = contentRect.width() * intrinsicSize().height() - contentRect.height() * intrinsicSize().width();
+ IntRect renderBox = contentRect;
+ int ratio = renderBox.width() * elementSize.height() - renderBox.height() * elementSize.width();
if (ratio > 0) {
- int newWidth = contentRect.height() * intrinsicSize().width() / intrinsicSize().height();
+ int newWidth = renderBox.height() * elementSize.width() / elementSize.height();
// Just fill the whole area if the difference is one pixel or less (in both sides)
- if (resultRect.width() - newWidth > 2)
- resultRect.setWidth(newWidth);
- resultRect.move((contentRect.width() - resultRect.width()) / 2, 0);
+ if (renderBox.width() - newWidth > 2)
+ renderBox.setWidth(newWidth);
+ renderBox.move((contentRect.width() - renderBox.width()) / 2, 0);
} else if (ratio < 0) {
- int newHeight = contentRect.width() * intrinsicSize().height() / intrinsicSize().width();
- if (resultRect.height() - newHeight > 2)
- resultRect.setHeight(newHeight);
- resultRect.move(0, (contentRect.height() - resultRect.height()) / 2);
+ int newHeight = renderBox.width() * elementSize.height() / elementSize.width();
+ if (renderBox.height() - newHeight > 2)
+ renderBox.setHeight(newHeight);
+ renderBox.move(0, (contentRect.height() - renderBox.height()) / 2);
}
- return resultRect;
+
+ return renderBox;
}
void RenderVideo::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
{
MediaPlayer* mediaPlayer = player();
- if (!mediaPlayer)
+ bool displayingPoster = videoElement()->shouldDisplayPosterImage();
+
+ if (displayingPoster && document()->printing() && !view()->printImages())
return;
- updatePlayer();
+
+ if (!displayingPoster) {
+ if (!mediaPlayer)
+ return;
+ updatePlayer();
+ }
+
IntRect rect = videoBox();
if (rect.isEmpty())
return;
rect.move(tx, ty);
- mediaPlayer->paint(paintInfo.context, rect);
+ if (displayingPoster)
+ paintIntoRect(paintInfo.context, rect);
+ else
+ mediaPlayer->paint(paintInfo.context, rect);
}
void RenderVideo::layout()
@@ -129,6 +176,12 @@ void RenderVideo::layout()
updatePlayer();
}
+HTMLVideoElement* RenderVideo::videoElement() const
+{
+ ASSERT(node()->hasTagName(videoTag));
+ return static_cast<HTMLVideoElement*>(node());
+}
+
void RenderVideo::updateFromElement()
{
RenderMedia::updateFromElement();
@@ -140,7 +193,7 @@ void RenderVideo::updatePlayer()
MediaPlayer* mediaPlayer = player();
if (!mediaPlayer)
return;
- if (!mediaElement()->inActiveDocument()) {
+ if (!videoElement()->inActiveDocument()) {
mediaPlayer->setVisible(false);
return;
}
@@ -155,40 +208,6 @@ void RenderVideo::updatePlayer()
mediaPlayer->setVisible(true);
}
-bool RenderVideo::isWidthSpecified() const
-{
- switch (style()->width().type()) {
- case Fixed:
- case Percent:
- return true;
- case Auto:
- case Relative: // FIXME: Shouldn't this case return true? It doesn't for images.
- case Static:
- case Intrinsic:
- case MinIntrinsic:
- return false;
- }
- ASSERT(false);
- return false;
-}
-
-bool RenderVideo::isHeightSpecified() const
-{
- switch (style()->height().type()) {
- case Fixed:
- case Percent:
- return true;
- case Auto:
- case Relative: // FIXME: Shouldn't this case return true? It doesn't for images.
- case Static:
- case Intrinsic:
- case MinIntrinsic:
- return false;
- }
- ASSERT(false);
- return false;
-}
-
int RenderVideo::calcReplacedWidth(bool includeMaxWidth) const
{
int width;
@@ -235,24 +254,9 @@ int RenderVideo::calcAspectRatioHeight() const
return RenderBox::calcReplacedWidth() * intrinsicHeight / intrinsicWidth;
}
-void RenderVideo::calcPrefWidths()
+int RenderVideo::minimumReplacedHeight() const
{
- ASSERT(prefWidthsDirty());
-
- int paddingAndBorders = paddingLeft() + paddingRight() + borderLeft() + borderRight();
- m_maxPrefWidth = calcReplacedWidth(false) + paddingAndBorders;
-
- if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength)
- m_maxPrefWidth = min(m_maxPrefWidth, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? paddingAndBorders : 0));
-
- if (style()->width().isPercent() || style()->height().isPercent() ||
- style()->maxWidth().isPercent() || style()->maxHeight().isPercent() ||
- style()->minWidth().isPercent() || style()->minHeight().isPercent())
- m_minPrefWidth = 0;
- else
- m_minPrefWidth = m_maxPrefWidth;
-
- setPrefWidthsDirty(false);
+ return 0;
}
#if USE(ACCELERATED_COMPOSITING)
@@ -271,14 +275,6 @@ void RenderVideo::acceleratedRenderingStateChanged()
if (p)
p->acceleratedRenderingStateChanged();
}
-
-GraphicsLayer* RenderVideo::videoGraphicsLayer() const
-{
- if (hasLayer() && layer()->isComposited())
- return layer()->backing()->graphicsLayer();
-
- return 0;
-}
#endif // USE(ACCELERATED_COMPOSITING)
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h
index 79e5b4e3c4..16c846d290 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderVideo.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,13 +33,11 @@
namespace WebCore {
class HTMLMediaElement;
-#if USE(ACCELERATED_COMPOSITING)
-class GraphicsLayer;
-#endif
+class HTMLVideoElement;
class RenderVideo : public RenderMedia {
public:
- RenderVideo(HTMLMediaElement*);
+ RenderVideo(HTMLVideoElement*);
virtual ~RenderVideo();
void videoSizeChanged();
@@ -48,13 +46,14 @@ public:
#if USE(ACCELERATED_COMPOSITING)
bool supportsAcceleratedRendering() const;
void acceleratedRenderingStateChanged();
- GraphicsLayer* videoGraphicsLayer() const;
#endif
private:
virtual void updateFromElement();
+ inline HTMLVideoElement* videoElement() const;
- virtual void intrinsicSizeChanged() { videoSizeChanged(); }
+ virtual void intrinsicSizeChanged();
+ virtual void imageChanged(WrappedImagePtr, const IntRect*);
virtual const char* renderName() const { return "RenderVideo"; }
@@ -67,16 +66,14 @@ private:
virtual int calcReplacedWidth(bool includeMaxWidth = true) const;
virtual int calcReplacedHeight() const;
-
- virtual void calcPrefWidths();
+ virtual int minimumReplacedHeight() const;
int calcAspectRatioWidth() const;
int calcAspectRatioHeight() const;
- bool isWidthSpecified() const;
- bool isHeightSpecified() const;
-
void updatePlayer();
+
+ IntSize m_cachedImageSize;
};
inline RenderVideo* toRenderVideo(RenderObject* object)
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderView.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderView.cpp
index e2b4b045f1..4f76e8010b 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderView.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderView.cpp
@@ -198,7 +198,7 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, int, int)
if (baseColor.alpha() > 0) {
paintInfo.context->save();
paintInfo.context->setCompositeOperation(CompositeCopy);
- paintInfo.context->fillRect(paintInfo.rect, baseColor);
+ paintInfo.context->fillRect(paintInfo.rect, baseColor, style()->colorSpace());
paintInfo.context->restore();
} else
paintInfo.context->clearRect(paintInfo.rect);
@@ -326,7 +326,13 @@ IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
SelectionMap::iterator end = selectedObjects.end();
for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
RenderSelectionInfo* info = i->second;
- selRect.unite(info->rect());
+ // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
+ IntRect currRect = info->rect();
+ if (RenderBoxModelObject* repaintContainer = info->repaintContainer()) {
+ FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
+ currRect = absQuad.enclosingBoundingBox();
+ }
+ selRect.unite(currRect);
delete info;
}
return selRect;
@@ -425,7 +431,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
o = o->nextInPreOrder();
}
- m_cachedSelectionBounds = IntRect();
+ m_layer->clearBlockSelectionGapsBounds();
// Now that the selection state has been updated for the new objects, walk them again and
// put them in the new objects list.
@@ -438,9 +444,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
RenderBlockSelectionInfo* blockInfo = newSelectedBlocks.get(cb);
if (blockInfo)
break;
- blockInfo = new RenderBlockSelectionInfo(cb);
- newSelectedBlocks.set(cb, blockInfo);
- m_cachedSelectionBounds.unite(blockInfo->rects());
+ newSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
cb = cb->containingBlock();
}
}
@@ -517,7 +521,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
void RenderView::clearSelection()
{
- repaintViewRectangle(m_cachedSelectionBounds);
+ m_layer->repaintBlockSelectionGaps();
setSelection(0, -1, 0, -1, RepaintNewMinusOld);
}
@@ -537,6 +541,8 @@ void RenderView::updateWidgetPositions()
RenderWidgetSet::iterator end = m_widgets.end();
for (RenderWidgetSet::iterator it = m_widgets.begin(); it != end; ++it)
(*it)->updateWidgetPosition();
+ for (RenderWidgetSet::iterator it = m_widgets.begin(); it != end; ++it)
+ (*it)->widgetPositionsUpdated();
}
void RenderView::addWidget(RenderWidget* o)
@@ -648,6 +654,17 @@ void RenderView::pushLayoutState(RenderObject* root)
m_layoutState = new (renderArena()) LayoutState(root);
}
+bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) const
+{
+ RenderObject* o = renderer;
+ while (o) {
+ if (o->hasColumns() || o->hasTransform() || o->hasReflection())
+ return true;
+ o = o->container();
+ }
+ return false;
+}
+
void RenderView::updateHitTestResult(HitTestResult& result, const IntPoint& point)
{
if (result.innerNode())
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderView.h b/src/3rdparty/webkit/WebCore/rendering/RenderView.h
index bc5db9e643..1e007e8af9 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderView.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderView.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML widget for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2006 Apple Computer, Inc.
*
@@ -77,9 +75,11 @@ public:
bool printing() const;
void setPrintImages(bool enable) { m_printImages = enable; }
bool printImages() const { return m_printImages; }
- void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_forcedPageBreak = false; }
+ void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_minimumColumnHeight = 0; m_forcedPageBreak = false; }
void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
+ void setMinimumColumnHeight(int height) { m_minimumColumnHeight = height; }
int bestTruncatedAt() const { return m_bestTruncatedAt; }
+ int minimumColumnHeight() const { return m_minimumColumnHeight; }
int truncatedAt() const { return m_truncatedAt; }
@@ -140,6 +140,8 @@ public:
state->destroy(renderArena());
}
+ bool shouldDisableLayoutStateForSubtree(RenderObject*) const;
+
// Returns true if layoutState should be used for its cached offset and clip.
bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m_layoutState; }
LayoutState* layoutState() const { return m_layoutState; }
@@ -193,10 +195,9 @@ protected:
RenderWidgetSet m_widgets;
private:
- IntRect m_cachedSelectionBounds;
-
int m_bestTruncatedAt;
int m_truncatorWidth;
+ int m_minimumColumnHeight;
bool m_forcedPageBreak;
LayoutState* m_layoutState;
unsigned m_layoutStateDisableCount;
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp
index 9af7137faf..561bead868 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp
@@ -23,8 +23,8 @@
#include "config.h"
#include "RenderWidget.h"
-#include "AnimationController.h"
#include "AXObjectCache.h"
+#include "AnimationController.h"
#include "GraphicsContext.h"
#include "HitTestResult.h"
#include "RenderView.h"
@@ -40,18 +40,65 @@ static HashMap<const Widget*, RenderWidget*>& widgetRendererMap()
return *staticWidgetRendererMap;
}
+static size_t widgetHierarchyUpdateSuspendCount;
+
+typedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap;
+
+static WidgetToParentMap& widgetNewParentMap()
+{
+ DEFINE_STATIC_LOCAL(WidgetToParentMap, map, ());
+ return map;
+}
+
+void RenderWidget::suspendWidgetHierarchyUpdates()
+{
+ widgetHierarchyUpdateSuspendCount++;
+}
+
+void RenderWidget::resumeWidgetHierarchyUpdates()
+{
+ ASSERT(widgetHierarchyUpdateSuspendCount);
+ if (widgetHierarchyUpdateSuspendCount == 1) {
+ WidgetToParentMap map = widgetNewParentMap();
+ widgetNewParentMap().clear();
+ WidgetToParentMap::iterator end = map.end();
+ for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) {
+ Widget* child = it->first.get();
+ ScrollView* currentParent = child->parent();
+ FrameView* newParent = it->second;
+ if (newParent != currentParent) {
+ if (currentParent)
+ currentParent->removeChild(child);
+ if (newParent)
+ newParent->addChild(child);
+ }
+ }
+ }
+ widgetHierarchyUpdateSuspendCount--;
+}
+
+static void moveWidgetToParentSoon(Widget* child, FrameView* parent)
+{
+ if (!widgetHierarchyUpdateSuspendCount) {
+ if (parent)
+ parent->addChild(child);
+ else
+ child->removeFromParent();
+ return;
+ }
+ widgetNewParentMap().set(child, parent);
+}
+
RenderWidget::RenderWidget(Node* node)
: RenderReplaced(node)
, m_widget(0)
, m_frameView(node->document()->view())
- , m_refCount(0)
-{
- view()->addWidget(this);
-
// Reference counting is used to prevent the widget from being
// destroyed while inside the Widget code, which might not be
// able to handle that.
- ref();
+ , m_refCount(1)
+{
+ view()->addWidget(this);
}
void RenderWidget::destroy()
@@ -62,14 +109,6 @@ void RenderWidget::destroy()
// both RenderBox::destroy() and RenderObject::destroy().
// Fix originally made for <rdar://problem/4228818>.
- // <rdar://problem/6937089> suggests that node() can be null by the time we call renderArena()
- // in the end of this function. One way this might happen is if this function was invoked twice
- // in a row, so bail out and turn a crash into an assertion failure in debug builds and a leak
- // in release builds.
- ASSERT(node());
- if (!node())
- return;
-
animation()->cancelAnimations(this);
if (RenderView* v = view())
@@ -81,12 +120,8 @@ void RenderWidget::destroy()
}
remove();
- if (m_widget) {
- if (m_frameView)
- m_frameView->removeChild(m_widget.get());
- widgetRendererMap().remove(m_widget.get());
- }
-
+ setWidget(0);
+
// removes from override size map
if (hasOverrideSize())
setOverrideSize(-1);
@@ -100,14 +135,6 @@ void RenderWidget::destroy()
destroyLayer();
}
- // <rdar://problem/6937089> suggests that node() can be null here. One way this might happen is
- // if this function was re-entered (and therefore the null check at the beginning did not fail),
- // so bail out and turn a crash into an assertion failure in debug builds and a leak in release
- // builds.
- ASSERT(node());
- if (!node())
- return;
-
// Grab the arena from node()->document()->renderArena() before clearing the node pointer.
// Clear the node before deref-ing, as this may be deleted when deref is called.
RenderArena* arena = renderArena();
@@ -121,39 +148,52 @@ RenderWidget::~RenderWidget()
clearWidget();
}
-void RenderWidget::setWidgetGeometry(const IntRect& frame)
+bool RenderWidget::setWidgetGeometry(const IntRect& frame)
{
- if (node() && m_widget->frameRect() != frame) {
- RenderWidgetProtector protector(this);
- RefPtr<Node> protectedNode(node());
- m_widget->setFrameRect(frame);
- }
+ ASSERT(!widgetHierarchyUpdateSuspendCount);
+ if (!node())
+ return false;
+
+ IntRect windowClipRect = m_frameView ? m_frameView->windowClipRectForLayer(enclosingLayer(), true) : IntRect();
+ bool clipChanged = m_windowClipRect != windowClipRect;
+ bool boundsChanged = m_widget->frameRect() != frame;
+
+ if (!boundsChanged && !clipChanged)
+ return false;
+
+ m_windowClipRect = windowClipRect;
+
+ RenderWidgetProtector protector(this);
+ RefPtr<Node> protectedNode(node());
+ m_widget->setFrameRect(frame);
+ return boundsChanged;
}
void RenderWidget::setWidget(PassRefPtr<Widget> widget)
{
- if (widget != m_widget) {
- if (m_widget) {
- m_widget->removeFromParent();
- widgetRendererMap().remove(m_widget.get());
- clearWidget();
- }
- m_widget = widget;
- if (m_widget) {
- widgetRendererMap().add(m_widget.get(), this);
- // if we've already received a layout, apply the calculated space to the
- // widget immediately, but we have to have really been full constructed (with a non-null
- // style pointer).
- if (style()) {
- if (!needsLayout())
- setWidgetGeometry(absoluteContentBox());
- if (style()->visibility() != VISIBLE)
- m_widget->hide();
- else
- m_widget->show();
- }
- m_frameView->addChild(m_widget.get());
+ if (widget == m_widget)
+ return;
+
+ if (m_widget) {
+ moveWidgetToParentSoon(m_widget.get(), 0);
+ widgetRendererMap().remove(m_widget.get());
+ clearWidget();
+ }
+ m_widget = widget;
+ if (m_widget) {
+ widgetRendererMap().add(m_widget.get(), this);
+ // If we've already received a layout, apply the calculated space to the
+ // widget immediately, but we have to have really been fully constructed (with a non-null
+ // style pointer).
+ if (style()) {
+ if (!needsLayout())
+ setWidgetGeometry(absoluteContentBox());
+ if (style()->visibility() != VISIBLE)
+ m_widget->hide();
+ else
+ m_widget->show();
}
+ moveWidgetToParentSoon(m_widget.get(), m_frameView);
}
}
@@ -221,19 +261,28 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty)
}
if (m_widget) {
- // Move the widget if necessary. We normally move and resize widgets during layout, but sometimes
- // widgets can move without layout occurring (most notably when you scroll a document that
- // contains fixed positioned elements).
- m_widget->move(tx + borderLeft() + paddingLeft(), ty + borderTop() + paddingTop());
-
// Tell the widget to paint now. This is the only time the widget is allowed
// to paint itself. That way it will composite properly with z-indexed layers.
if (m_substituteImage)
- paintInfo.context->drawImage(m_substituteImage.get(), m_widget->frameRect());
- else
- m_widget->paint(paintInfo.context, paintInfo.rect);
+ paintInfo.context->drawImage(m_substituteImage.get(), style()->colorSpace(), m_widget->frameRect());
+ else {
+ IntPoint widgetLocation = m_widget->frameRect().location();
+ IntPoint paintLocation(tx + borderLeft() + paddingLeft(), ty + borderTop() + paddingTop());
+ IntRect paintRect = paintInfo.rect;
+
+ IntSize paintOffset = paintLocation - widgetLocation;
+ // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
+ // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
+ if (!paintOffset.isZero()) {
+ paintInfo.context->translate(paintOffset);
+ paintRect.move(-paintOffset);
+ }
+ m_widget->paint(paintInfo.context, paintRect);
- if (m_widget->isFrameView() && paintInfo.overlapTestRequests && !static_cast<FrameView*>(m_widget.get())->useSlowRepaints()) {
+ if (!paintOffset.isZero())
+ paintInfo.context->translate(-paintOffset);
+ }
+ if (m_widget->isFrameView() && paintInfo.overlapTestRequests && !static_cast<FrameView*>(m_widget.get())->useSlowRepaintsIfNotOverlapped()) {
ASSERT(!paintInfo.overlapTestRequests->contains(this));
paintInfo.overlapTestRequests->set(this, m_widget->frameRect());
}
@@ -245,7 +294,7 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty)
// Paint a partially transparent wash over selected widgets.
if (isSelected() && !document()->printing()) {
// FIXME: selectionRect() is in absolute, not painting coordinates.
- paintInfo.context->fillRect(selectionRect(), selectionBackgroundColor());
+ paintInfo.context->fillRect(selectionRect(), selectionBackgroundColor(), style()->colorSpace());
}
}
@@ -274,15 +323,8 @@ void RenderWidget::updateWidgetPosition()
int w = width() - borderLeft() - borderRight() - paddingLeft() - paddingRight();
int h = height() - borderTop() - borderBottom() - paddingTop() - paddingBottom();
- IntRect newBounds(absPos.x(), absPos.y(), w, h);
- IntRect oldBounds(m_widget->frameRect());
- bool boundsChanged = newBounds != oldBounds;
- if (boundsChanged) {
- RenderWidgetProtector protector(this);
- RefPtr<Node> protectedNode(node());
- m_widget->setFrameRect(newBounds);
- }
-
+ bool boundsChanged = setWidgetGeometry(IntRect(absPos.x(), absPos.y(), w, h));
+
// if the frame bounds got changed, or if view needs layout (possibly indicating
// content size is wrong) we have to do a layout to set the right widget size
if (m_widget->isFrameView()) {
@@ -292,6 +334,13 @@ void RenderWidget::updateWidgetPosition()
}
}
+void RenderWidget::widgetPositionsUpdated()
+{
+ if (!m_widget)
+ return;
+ m_widget->widgetPositionsUpdated();
+}
+
void RenderWidget::setSelectionState(SelectionState state)
{
if (selectionState() != state) {
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.h b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.h
index 78537fdfa5..e57955600b 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.h
@@ -39,9 +39,14 @@ public:
static RenderWidget* find(const Widget*);
void updateWidgetPosition();
+ void widgetPositionsUpdated();
+ IntRect windowClipRect() const { return m_windowClipRect; }
void showSubstituteImage(PassRefPtr<Image>);
+ static void suspendWidgetHierarchyUpdates();
+ static void resumeWidgetHierarchyUpdates();
+
protected:
RenderWidget(Node*);
@@ -51,17 +56,17 @@ protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void layout();
+ virtual void paint(PaintInfo&, int x, int y);
private:
virtual bool isWidget() const { return true; }
- virtual void paint(PaintInfo&, int x, int y);
virtual void destroy();
virtual void setSelectionState(SelectionState);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual void setOverlapTestResult(bool);
- void setWidgetGeometry(const IntRect&);
+ bool setWidgetGeometry(const IntRect&);
friend class RenderWidgetProtector;
RenderArena* ref() { ++m_refCount; return renderArena(); }
@@ -70,6 +75,7 @@ private:
RefPtr<Widget> m_widget;
RefPtr<Image> m_substituteImage;
FrameView* m_frameView;
+ IntRect m_windowClipRect;
int m_refCount;
};
diff --git a/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.cpp
index c8e072ea79..23316f7104 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.cpp
@@ -21,6 +21,7 @@
#include "RootInlineBox.h"
#include "BidiResolver.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
#include "EllipsisBox.h"
diff --git a/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.h b/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.h
index b0b0e15daa..fae0cba0e0 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.h
+++ b/src/3rdparty/webkit/WebCore/rendering/RootInlineBox.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the line box implementation for KDE.
- *
* Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -51,8 +49,8 @@ public:
void detachEllipsisBox(RenderArena*);
- RootInlineBox* nextRootBox() const { return static_cast<RootInlineBox*>(m_nextLine); }
- RootInlineBox* prevRootBox() const { return static_cast<RootInlineBox*>(m_prevLine); }
+ RootInlineBox* nextRootBox() const { return static_cast<RootInlineBox*>(m_nextLineBox); }
+ RootInlineBox* prevRootBox() const { return static_cast<RootInlineBox*>(m_prevLineBox); }
virtual void adjustPosition(int dx, int dy);
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.cpp
index 900e0baed0..7e856725a5 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.cpp
@@ -512,9 +512,9 @@ bool SVGChar::isHidden() const
return pathData && pathData->hidden;
}
-TransformationMatrix SVGChar::characterTransform() const
+AffineTransform SVGChar::characterTransform() const
{
- TransformationMatrix ctm;
+ AffineTransform ctm;
// Rotate character around angle, and possibly scale.
ctm.translate(x, y);
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.h b/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.h
index b5b4f3e00d..f0d1fa4b26 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.h
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGCharacterLayoutInfo.h
@@ -24,15 +24,15 @@
#define SVGCharacterLayoutInfo_h
#if ENABLE(SVG)
+#include "AffineTransform.h"
+#include "SVGRenderStyle.h"
+#include "SVGTextContentElement.h"
+
#include <wtf/Assertions.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
-#include <wtf/Vector.h>
-
-#include "TransformationMatrix.h"
#include <wtf/RefCounted.h>
-#include "SVGRenderStyle.h"
-#include "SVGTextContentElement.h"
+#include <wtf/Vector.h>
namespace WebCore {
@@ -234,7 +234,7 @@ struct SVGChar {
// Helper methods
bool isHidden() const;
- TransformationMatrix characterTransform() const;
+ AffineTransform characterTransform() const;
};
struct SVGInlineBoxCharacterRange {
@@ -275,7 +275,7 @@ struct SVGTextChunk {
// textLength & lengthAdjust support
float textLength;
ELengthAdjust lengthAdjust;
- TransformationMatrix ctm;
+ AffineTransform ctm;
// status flags
bool isVerticalText : 1;
@@ -291,15 +291,12 @@ struct SVGTextChunk {
struct SVGTextChunkWalkerBase {
virtual ~SVGTextChunkWalkerBase() { }
- virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end) = 0;
// Followings methods are only used for painting text chunks
virtual void start(InlineBox*) = 0;
virtual void end(InlineBox*) = 0;
-
- virtual bool setupFill(InlineBox*) = 0;
- virtual bool setupStroke(InlineBox*) = 0;
};
template<typename CallbackClass>
@@ -307,7 +304,7 @@ struct SVGTextChunkWalker : public SVGTextChunkWalkerBase {
public:
typedef void (CallbackClass::*SVGTextChunkWalkerCallback)(SVGInlineTextBox* textBox,
int startOffset,
- const TransformationMatrix& chunkCtm,
+ const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start,
const Vector<SVGChar>::iterator& end);
@@ -315,27 +312,20 @@ public:
typedef void (CallbackClass::*SVGTextChunkStartCallback)(InlineBox* box);
typedef void (CallbackClass::*SVGTextChunkEndCallback)(InlineBox* box);
- typedef bool (CallbackClass::*SVGTextChunkSetupFillCallback)(InlineBox* box);
- typedef bool (CallbackClass::*SVGTextChunkSetupStrokeCallback)(InlineBox* box);
-
- SVGTextChunkWalker(CallbackClass* object,
+ SVGTextChunkWalker(CallbackClass* object,
SVGTextChunkWalkerCallback walker,
SVGTextChunkStartCallback start = 0,
- SVGTextChunkEndCallback end = 0,
- SVGTextChunkSetupFillCallback fill = 0,
- SVGTextChunkSetupStrokeCallback stroke = 0)
+ SVGTextChunkEndCallback end = 0)
: m_object(object)
, m_walkerCallback(walker)
, m_startCallback(start)
, m_endCallback(end)
- , m_setupFillCallback(fill)
- , m_setupStrokeCallback(stroke)
{
ASSERT(object);
ASSERT(walker);
}
- virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
(*m_object.*m_walkerCallback)(textBox, startOffset, chunkCtm, start, end);
@@ -358,31 +348,11 @@ public:
ASSERT_NOT_REACHED();
}
- virtual bool setupFill(InlineBox* box)
- {
- if (m_setupFillCallback)
- return (*m_object.*m_setupFillCallback)(box);
-
- ASSERT_NOT_REACHED();
- return false;
- }
-
- virtual bool setupStroke(InlineBox* box)
- {
- if (m_setupStrokeCallback)
- return (*m_object.*m_setupStrokeCallback)(box);
-
- ASSERT_NOT_REACHED();
- return false;
- }
-
private:
CallbackClass* m_object;
SVGTextChunkWalkerCallback m_walkerCallback;
SVGTextChunkStartCallback m_startCallback;
SVGTextChunkEndCallback m_endCallback;
- SVGTextChunkSetupFillCallback m_setupFillCallback;
- SVGTextChunkSetupStrokeCallback m_setupStrokeCallback;
};
struct SVGTextChunkLayoutInfo {
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.cpp
index d0fa9ae0ca..65aa5a14e1 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2007 Rob Buis <buis@kde.org>
* (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
*
@@ -110,9 +108,7 @@ FloatRect SVGInlineTextBox::calculateGlyphBoundaries(RenderStyle* style, int off
FloatRect glyphRect(x1, y1, x2 - x1, y2 - y1);
// Take per-character transformations into account
- TransformationMatrix ctm = svgChar.characterTransform();
- if (!ctm.isIdentity())
- glyphRect = ctm.mapRect(glyphRect);
+ glyphRect = svgChar.characterTransform().mapRect(glyphRect);
return glyphRect;
}
@@ -128,7 +124,7 @@ struct SVGInlineTextBoxClosestCharacterToPositionWalker {
{
}
- void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
RenderStyle* style = textBox->textRenderer()->style();
@@ -195,7 +191,7 @@ struct SVGInlineTextBoxSelectionRectWalker {
{
}
- void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
RenderStyle* style = textBox->textRenderer()->style();
@@ -326,7 +322,33 @@ IntRect SVGInlineTextBox::selectionRect(int, int, int startPos, int endPos)
return enclosingIntRect(walkerCallback.selectionRect());
}
-void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int tx, int ty, const SVGChar& svgChar, const UChar* chars, int length, SVGPaintServer* activePaintServer)
+bool SVGInlineTextBox::chunkSelectionStartEnd(const UChar* chunk, int chunkLength, int& selectionStart, int& selectionEnd)
+{
+ // NOTE: We ignore SVGInlineTextBox::m_start here because it is always 0.
+ // Curently SVG doesn't use HTML block-level layout, in which m_start would be set.
+
+ int chunkStart = chunk - textRenderer()->characters();
+ ASSERT(0 <= chunkStart);
+
+ selectionStartEnd(selectionStart, selectionEnd);
+ if (selectionEnd <= chunkStart)
+ return false;
+ if (chunkStart + chunkLength <= selectionStart)
+ return false;
+
+ // Map indices from view-global to chunk-local.
+ selectionStart -= chunkStart;
+ selectionEnd -= chunkStart;
+ // Then clamp with chunk range
+ if (selectionStart < 0)
+ selectionStart = 0;
+ if (chunkLength < selectionEnd)
+ selectionEnd = chunkLength;
+
+ return selectionStart < selectionEnd;
+}
+
+void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int tx, int ty, const SVGChar& svgChar, const UChar* chars, int length, SVGTextPaintInfo& textPaintInfo)
{
if (renderer()->style()->visibility() != VISIBLE || paintInfo.phase == PaintPhaseOutline)
return;
@@ -352,13 +374,13 @@ void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int t
RenderStyle* styleToUse = text->style(isFirstLineStyle());
const Font& font = styleToUse->font();
- TransformationMatrix ctm = svgChar.characterTransform();
+ AffineTransform ctm = svgChar.characterTransform();
if (!ctm.isIdentity())
paintInfo.context->concatCTM(ctm);
// 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection
// and marked text.
- if (paintInfo.phase != PaintPhaseSelection && !isPrinting) {
+ if (paintInfo.phase != PaintPhaseSelection && !isPrinting && textPaintInfo.subphase == SVGTextPaintSubphaseBackground) {
#if PLATFORM(MAC)
// Custom highlighters go behind everything else.
if (styleToUse->highlight() != nullAtom && !paintInfo.context->paintingDisabled())
@@ -378,28 +400,52 @@ void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int t
}
}
- // Set a text shadow if we have one.
- // FIXME: Support multiple shadow effects. Need more from the CG API before
- // we can do this.
- bool setShadow = false;
- if (styleToUse->textShadow()) {
- paintInfo.context->setShadow(IntSize(styleToUse->textShadow()->x, styleToUse->textShadow()->y),
- styleToUse->textShadow()->blur, styleToUse->textShadow()->color);
- setShadow = true;
- }
+ bool isGlyphPhase = textPaintInfo.subphase == SVGTextPaintSubphaseGlyphFill || textPaintInfo.subphase == SVGTextPaintSubphaseGlyphStroke;
+ bool isSelectionGlyphPhase = textPaintInfo.subphase == SVGTextPaintSubphaseGlyphFillSelection || textPaintInfo.subphase == SVGTextPaintSubphaseGlyphStrokeSelection;
+
+ if (isGlyphPhase || isSelectionGlyphPhase) {
+ // Set a text shadow if we have one.
+ // FIXME: Support multiple shadow effects. Need more from the CG API before
+ // we can do this.
+ bool setShadow = false;
+ if (styleToUse->textShadow()) {
+ paintInfo.context->setShadow(IntSize(styleToUse->textShadow()->x, styleToUse->textShadow()->y),
+ styleToUse->textShadow()->blur, styleToUse->textShadow()->color,
+ styleToUse->colorSpace());
+ setShadow = true;
+ }
- IntPoint origin((int) svgChar.x, (int) svgChar.y);
- TextRun run = svgTextRunForInlineTextBox(chars, length, styleToUse, this, svgChar.x);
+ IntPoint origin((int) svgChar.x, (int) svgChar.y);
+ TextRun run = svgTextRunForInlineTextBox(chars, length, styleToUse, this, svgChar.x);
#if ENABLE(SVG_FONTS)
- // SVG Fonts need access to the paint server used to draw the current text chunk.
- // They need to be able to call renderPath() on a SVGPaintServer object.
- run.setActivePaintServer(activePaintServer);
+ // SVG Fonts need access to the paint server used to draw the current text chunk.
+ // They need to be able to call renderPath() on a SVGPaintServer object.
+ ASSERT(textPaintInfo.activePaintServer);
+ run.setActivePaintServer(textPaintInfo.activePaintServer);
#endif
- paintInfo.context->drawText(font, run, origin);
+ int selectionStart = 0;
+ int selectionEnd = 0;
+ bool haveSelectedRange = haveSelection && chunkSelectionStartEnd(chars, length, selectionStart, selectionEnd);
+
+ if (isGlyphPhase) {
+ if (haveSelectedRange) {
+ paintInfo.context->drawText(font, run, origin, 0, selectionStart);
+ paintInfo.context->drawText(font, run, origin, selectionEnd, run.length());
+ } else
+ paintInfo.context->drawText(font, run, origin);
+ } else {
+ ASSERT(isSelectionGlyphPhase);
+ if (haveSelectedRange)
+ paintInfo.context->drawText(font, run, origin, selectionStart, selectionEnd);
+ }
+
+ if (setShadow)
+ paintInfo.context->clearShadow();
+ }
- if (paintInfo.phase != PaintPhaseSelection) {
+ if (paintInfo.phase != PaintPhaseSelection && textPaintInfo.subphase == SVGTextPaintSubphaseForeground) {
paintDocumentMarkers(paintInfo.context, tx, ty, styleToUse, font, false);
if (useCustomUnderlines) {
@@ -429,9 +475,6 @@ void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int t
}
- if (setShadow)
- paintInfo.context->clearShadow();
-
if (!ctm.isIdentity())
paintInfo.context->concatCTM(ctm.inverse());
}
@@ -477,7 +520,7 @@ void SVGInlineTextBox::paintSelection(int boxStartOffset, const SVGChar& svgChar
int adjust = startPos >= boxStartOffset ? boxStartOffset : 0;
p->drawHighlightForText(font, svgTextRunForInlineTextBox(textRenderer()->text()->characters() + start() + boxStartOffset, length, style, this, svgChar.x),
IntPoint((int) svgChar.x, (int) svgChar.y - font.ascent()),
- font.ascent() + font.descent(), color, startPos - adjust, endPos - adjust);
+ font.ascent() + font.descent(), color, style->colorSpace(), startPos - adjust, endPos - adjust);
p->restore();
}
@@ -521,7 +564,7 @@ void SVGInlineTextBox::paintDecoration(ETextDecoration decoration, GraphicsConte
context->save();
context->beginPath();
- TransformationMatrix ctm = svgChar.characterTransform();
+ AffineTransform ctm = svgChar.characterTransform();
if (!ctm.isIdentity())
context->concatCTM(ctm);
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.h b/src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.h
index 76837ccdfa..596fdf325b 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.h
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGInlineTextBox.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2007 Rob Buis <buis@kde.org>
* (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
*
@@ -34,6 +32,22 @@ namespace WebCore {
struct SVGChar;
struct SVGTextDecorationInfo;
+ enum SVGTextPaintSubphase {
+ SVGTextPaintSubphaseBackground,
+ SVGTextPaintSubphaseGlyphFill,
+ SVGTextPaintSubphaseGlyphFillSelection,
+ SVGTextPaintSubphaseGlyphStroke,
+ SVGTextPaintSubphaseGlyphStrokeSelection,
+ SVGTextPaintSubphaseForeground
+ };
+
+ struct SVGTextPaintInfo {
+ SVGTextPaintInfo() : activePaintServer(0), subphase(SVGTextPaintSubphaseBackground) {}
+
+ SVGPaintServer* activePaintServer;
+ SVGTextPaintSubphase subphase;
+ };
+
class SVGInlineTextBox : public InlineTextBox {
public:
SVGInlineTextBox(RenderObject* obj);
@@ -51,7 +65,7 @@ namespace WebCore {
virtual IntRect selectionRect(int absx, int absy, int startPos, int endPos);
// SVGs custom paint text method
- void paintCharacters(RenderObject::PaintInfo&, int tx, int ty, const SVGChar&, const UChar* chars, int length, SVGPaintServer*);
+ void paintCharacters(RenderObject::PaintInfo&, int tx, int ty, const SVGChar&, const UChar* chars, int length, SVGTextPaintInfo&);
// SVGs custom paint selection method
void paintSelection(int boxStartOffset, const SVGChar&, const UChar*, int length, GraphicsContext*, RenderStyle*, const Font&);
@@ -71,6 +85,7 @@ namespace WebCore {
private:
friend class RenderSVGInlineText;
bool svgCharacterHitsPosition(int x, int y, int& offset) const;
+ bool chunkSelectionStartEnd(const UChar* chunk, int chunkLength, int& selectionStart, int& selectionEnd);
int m_height;
};
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGMarkerData.h b/src/3rdparty/webkit/WebCore/rendering/SVGMarkerData.h
new file mode 100644
index 0000000000..5ff29939cc
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGMarkerData.h
@@ -0,0 +1,134 @@
+/*
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint 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 SVGMarkerData_h
+#define SVGMarkerData_h
+
+#if ENABLE(SVG)
+#include "FloatConversion.h"
+#include "Path.h"
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+class SVGResourceMarker;
+
+class SVGMarkerData {
+public:
+ enum Type {
+ Unknown = 0,
+ Start,
+ Mid,
+ End
+ };
+
+ SVGMarkerData(const Type& type = Unknown, SVGResourceMarker* marker = 0)
+ : m_type(type)
+ , m_marker(marker)
+ {
+ }
+
+ FloatPoint origin() const { return m_origin; }
+ SVGResourceMarker* marker() const { return m_marker; }
+
+ float currentAngle() const
+ {
+ FloatSize inslopeChange = m_inslopePoints[1] - m_inslopePoints[0];
+ FloatSize outslopeChange = m_outslopePoints[1] - m_outslopePoints[0];
+
+ double inslope = rad2deg(atan2(inslopeChange.height(), inslopeChange.width()));
+ double outslope = rad2deg(atan2(outslopeChange.height(), outslopeChange.width()));
+
+ double angle = 0;
+ switch (m_type) {
+ case Start:
+ angle = outslope;
+ break;
+ case Mid:
+ angle = (inslope + outslope) / 2;
+ break;
+ case End:
+ angle = inslope;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+
+ return narrowPrecisionToFloat(angle);
+ }
+
+ void updateTypeAndMarker(const Type& type, SVGResourceMarker* marker)
+ {
+ m_type = type;
+ m_marker = marker;
+ }
+
+ void updateOutslope(const FloatPoint& point)
+ {
+ m_outslopePoints[0] = m_origin;
+ m_outslopePoints[1] = point;
+ }
+
+ void updateMarkerDataForPathElement(const PathElement* element)
+ {
+ FloatPoint* points = element->points;
+
+ switch (element->type) {
+ case PathElementAddQuadCurveToPoint:
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=33115 (PathElementAddQuadCurveToPoint not handled for <marker>)
+ m_origin = points[1];
+ break;
+ case PathElementAddCurveToPoint:
+ m_inslopePoints[0] = points[1];
+ m_inslopePoints[1] = points[2];
+ m_origin = points[2];
+ break;
+ case PathElementMoveToPoint:
+ m_subpathStart = points[0];
+ case PathElementAddLineToPoint:
+ updateInslope(points[0]);
+ m_origin = points[0];
+ break;
+ case PathElementCloseSubpath:
+ updateInslope(points[0]);
+ m_origin = m_subpathStart;
+ m_subpathStart = FloatPoint();
+ }
+ }
+
+private:
+ void updateInslope(const FloatPoint& point)
+ {
+ m_inslopePoints[0] = m_origin;
+ m_inslopePoints[1] = point;
+ }
+
+ Type m_type;
+ SVGResourceMarker* m_marker;
+ FloatPoint m_origin;
+ FloatPoint m_subpathStart;
+ FloatPoint m_inslopePoints[2];
+ FloatPoint m_outslopePoints[2];
+};
+
+}
+
+#endif // ENABLE(SVG)
+#endif // SVGMarkerData_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGMarkerLayoutInfo.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGMarkerLayoutInfo.cpp
new file mode 100644
index 0000000000..3fe513f527
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGMarkerLayoutInfo.cpp
@@ -0,0 +1,124 @@
+/*
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ 2004, 2005, 2008 Rob Buis <buis@kde.org>
+ 2005, 2007 Eric Seidel <eric@webkit.org>
+ 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
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "SVGMarkerLayoutInfo.h"
+
+#include "RenderSVGViewportContainer.h"
+#include "SVGResourceMarker.h"
+
+namespace WebCore {
+
+SVGMarkerLayoutInfo::SVGMarkerLayoutInfo()
+ : m_midMarker(0)
+ , m_elementIndex(0)
+ , m_strokeWidth(0)
+{
+}
+
+SVGMarkerLayoutInfo::~SVGMarkerLayoutInfo()
+{
+}
+
+static inline void processStartAndMidMarkers(void* infoPtr, const PathElement* element)
+{
+ SVGMarkerLayoutInfo& info = *reinterpret_cast<SVGMarkerLayoutInfo*>(infoPtr);
+ SVGMarkerData& markerData = info.markerData();
+ int& elementIndex = info.elementIndex();
+
+ // First update the outslope for the previous element
+ markerData.updateOutslope(element->points[0]);
+
+ // Draw the marker for the previous element
+ SVGResourceMarker* marker = markerData.marker();
+ if (elementIndex > 0 && marker)
+ info.addLayoutedMarker(marker, markerData.origin(), markerData.currentAngle());
+
+ // Update our marker data for this element
+ markerData.updateMarkerDataForPathElement(element);
+
+ // After drawing the start marker, switch to drawing mid markers
+ if (elementIndex == 1)
+ markerData.updateTypeAndMarker(SVGMarkerData::Mid, info.midMarker());
+
+ ++elementIndex;
+}
+
+FloatRect SVGMarkerLayoutInfo::calculateBoundaries(SVGResourceMarker* startMarker, SVGResourceMarker* midMarker, SVGResourceMarker* endMarker, float strokeWidth, const Path& path)
+{
+ m_layout.clear();
+ m_midMarker = midMarker;
+ m_strokeWidth = strokeWidth;
+ m_elementIndex = 0;
+ m_markerData = SVGMarkerData(SVGMarkerData::Start, startMarker);
+ path.apply(this, processStartAndMidMarkers);
+
+ if (endMarker) {
+ m_markerData.updateTypeAndMarker(SVGMarkerData::End, endMarker);
+ addLayoutedMarker(endMarker, m_markerData.origin(), m_markerData.currentAngle());
+ }
+
+ if (m_layout.isEmpty())
+ return FloatRect();
+
+ Vector<MarkerLayout>::iterator it = m_layout.begin();
+ Vector<MarkerLayout>::iterator end = m_layout.end();
+
+ FloatRect bounds;
+ for (; it != end; ++it) {
+ MarkerLayout& layout = *it;
+
+ RenderSVGViewportContainer* markerContent = layout.marker->renderer();
+ ASSERT(markerContent);
+
+ bounds.unite(markerContent->markerBoundaries(layout.matrix));
+ }
+
+ return bounds;
+}
+
+void SVGMarkerLayoutInfo::drawMarkers(RenderObject::PaintInfo& paintInfo)
+{
+ if (m_layout.isEmpty())
+ return;
+
+ Vector<MarkerLayout>::iterator it = m_layout.begin();
+ Vector<MarkerLayout>::iterator end = m_layout.end();
+
+ for (; it != end; ++it) {
+ MarkerLayout& layout = *it;
+ layout.marker->draw(paintInfo, layout.matrix);
+ }
+}
+
+void SVGMarkerLayoutInfo::addLayoutedMarker(SVGResourceMarker* marker, const FloatPoint& origin, float angle)
+{
+ ASSERT(marker);
+ m_layout.append(MarkerLayout(marker, marker->markerTransformation(origin, angle, m_strokeWidth)));
+}
+
+}
+
+#endif // ENABLE(SVG)
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGMarkerLayoutInfo.h b/src/3rdparty/webkit/WebCore/rendering/SVGMarkerLayoutInfo.h
new file mode 100644
index 0000000000..517c993eb6
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGMarkerLayoutInfo.h
@@ -0,0 +1,74 @@
+/*
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint 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 SVGMarkerLayoutInfo_h
+#define SVGMarkerLayoutInfo_h
+
+#if ENABLE(SVG)
+#include "RenderObject.h"
+#include "SVGMarkerData.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class Path;
+class SVGResourceMarker;
+
+struct MarkerLayout {
+ MarkerLayout(SVGResourceMarker* markerObj = 0, AffineTransform matrixObj = AffineTransform())
+ : marker(markerObj)
+ , matrix(matrixObj)
+ {
+ ASSERT(marker);
+ }
+
+ SVGResourceMarker* marker;
+ AffineTransform matrix;
+};
+
+class SVGMarkerLayoutInfo : public Noncopyable {
+public:
+ SVGMarkerLayoutInfo();
+ ~SVGMarkerLayoutInfo();
+
+ FloatRect calculateBoundaries(SVGResourceMarker* startMarker, SVGResourceMarker* midMarker, SVGResourceMarker* endMarker, float strokeWidth, const Path&);
+ void drawMarkers(RenderObject::PaintInfo&);
+
+ // Used by static inline helper functions in SVGMarkerLayoutInfo.cpp
+ SVGMarkerData& markerData() { return m_markerData; }
+ SVGResourceMarker* midMarker() const { return m_midMarker; }
+ int& elementIndex() { return m_elementIndex; }
+ void addLayoutedMarker(SVGResourceMarker*, const FloatPoint& origin, float angle);
+
+private:
+ SVGResourceMarker* m_midMarker;
+
+ // Used while layouting markers
+ int m_elementIndex;
+ SVGMarkerData m_markerData;
+ float m_strokeWidth;
+
+ // Holds the final computed result
+ Vector<MarkerLayout> m_layout;
+};
+
+}
+
+#endif // ENABLE(SVG)
+#endif // SVGMarkerLayoutInfo_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp
index ea087f9031..284a9da7d0 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.cpp
@@ -2,7 +2,9 @@
* Copyright (C) 2007, 2008 Rob Buis <buis@kde.org>
* (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
* (C) 2007 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2009 Google, Inc. All rights reserved.
+ * (C) 2009 Google, Inc. All rights reserved.
+ * (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,21 +28,27 @@
#if ENABLE(SVG)
#include "SVGRenderSupport.h"
+#include "AffineTransform.h"
+#include "Document.h"
#include "ImageBuffer.h"
#include "RenderObject.h"
#include "RenderSVGContainer.h"
+#include "RenderSVGResource.h"
+#include "RenderSVGResourceClipper.h"
+#include "RenderSVGResourceMasker.h"
#include "RenderView.h"
-#include "SVGResourceClipper.h"
#include "SVGResourceFilter.h"
-#include "SVGResourceMasker.h"
#include "SVGStyledElement.h"
#include "SVGURIReference.h"
#include "TransformState.h"
-#include "TransformationMatrix.h"
#include <wtf/UnusedParam.h>
namespace WebCore {
+SVGRenderBase::~SVGRenderBase()
+{
+}
+
IntRect SVGRenderBase::clippedOverflowRectForRepaint(RenderObject* object, RenderBoxModelObject* repaintContainer)
{
// Return early for any cases where we don't actually paint
@@ -56,6 +64,8 @@ IntRect SVGRenderBase::clippedOverflowRectForRepaint(RenderObject* object, Rende
void SVGRenderBase::computeRectForRepaint(RenderObject* object, RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
+ object->style()->svgStyle()->inflateForShadow(repaintRect);
+
// Translate to coords in our parent renderer, and then call computeRectForRepaint on our parent
repaintRect = object->localToParentTransform().mapRect(repaintRect);
object->parent()->computeRectForRepaint(repaintContainer, repaintRect, fixed);
@@ -64,12 +74,12 @@ void SVGRenderBase::computeRectForRepaint(RenderObject* object, RenderBoxModelOb
void SVGRenderBase::mapLocalToContainer(const RenderObject* object, RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState)
{
ASSERT(!fixed); // We should have no fixed content in the SVG rendering tree.
- ASSERT(useTransforms); // mapping a point through SVG w/o respecting trasnforms is useless.
+ ASSERT(useTransforms); // Mapping a point through SVG w/o respecting transforms is useless.
transformState.applyTransform(object->localToParentTransform());
object->parent()->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
}
-void SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& boundingBox, SVGResourceFilter*& filter, SVGResourceFilter* rootFilter)
+bool SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& repaintRect, SVGResourceFilter*& filter, SVGResourceFilter* rootFilter)
{
#if !ENABLE(FILTERS)
UNUSED_PARAM(filter);
@@ -90,12 +100,15 @@ void SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
// Setup transparency layers before setting up filters!
float opacity = style->opacity();
if (opacity < 1.0f) {
- paintInfo.context->clip(enclosingIntRect(boundingBox));
+ paintInfo.context->clip(repaintRect);
paintInfo.context->beginTransparencyLayer(opacity);
}
- if (ShadowData* shadow = svgStyle->shadow())
- paintInfo.context->setShadow(IntSize(shadow->x, shadow->y), shadow->blur, shadow->color);
+ if (ShadowData* shadow = svgStyle->shadow()) {
+ paintInfo.context->clip(repaintRect);
+ paintInfo.context->setShadow(IntSize(shadow->x, shadow->y), shadow->blur, shadow->color, style->colorSpace());
+ paintInfo.context->beginTransparencyLayer(1.0f);
+ }
#if ENABLE(FILTERS)
AtomicString filterId(svgStyle->filter());
@@ -107,7 +120,7 @@ void SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
Document* document = object->document();
#if ENABLE(FILTERS)
- SVGResourceFilter* newFilter = getFilterById(document, filterId);
+ SVGResourceFilter* newFilter = getFilterById(document, filterId, object);
if (newFilter == rootFilter) {
// Catch <text filter="url(#foo)">Test<tspan filter="url(#foo)">123</tspan></text>.
// The filter is NOT meant to be applied twice in that case!
@@ -117,28 +130,27 @@ void SVGRenderBase::prepareToRenderSVGContent(RenderObject* object, RenderObject
filter = newFilter;
#endif
- SVGResourceClipper* clipper = getClipperById(document, clipperId);
- SVGResourceMasker* masker = getMaskerById(document, maskerId);
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, maskerId)) {
+ if (!masker->applyResource(object, paintInfo.context))
+ return false;
+ } else if (!maskerId.isEmpty())
+ svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
+
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, clipperId))
+ clipper->applyResource(object, paintInfo.context);
+ else if (!clipperId.isEmpty())
+ svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);
#if ENABLE(FILTERS)
if (filter) {
filter->addClient(styledElement);
- filter->prepareFilter(paintInfo.context, object);
+ if (!filter->prepareFilter(paintInfo.context, object))
+ return false;
} else if (!filterId.isEmpty())
svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
#endif
- if (clipper) {
- clipper->addClient(styledElement);
- clipper->applyClip(paintInfo.context, boundingBox);
- } else if (!clipperId.isEmpty())
- svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);
-
- if (masker) {
- masker->addClient(styledElement);
- masker->applyMask(paintInfo.context, boundingBox);
- } else if (!maskerId.isEmpty())
- svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
+ return true;
}
void SVGRenderBase::finishRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, SVGResourceFilter*& filter, GraphicsContext* savedContext)
@@ -163,6 +175,11 @@ void SVGRenderBase::finishRenderSVGContent(RenderObject* object, RenderObject::P
float opacity = style->opacity();
if (opacity < 1.0f)
paintInfo.context->endTransparencyLayer();
+
+ // This needs to be done separately from opacity, because if both properties are set,
+ // then the transparency layers are nested.
+ if (style->svgStyle()->shadow())
+ paintInfo.context->endTransparencyLayer();
}
void renderSubtreeToImage(ImageBuffer* image, RenderObject* item)
@@ -218,19 +235,81 @@ FloatRect SVGRenderBase::computeContainerBoundingBox(const RenderObject* contain
return boundingBox;
}
-FloatRect SVGRenderBase::filterBoundingBoxForRenderer(const RenderObject* object)
+void SVGRenderBase::layoutChildren(RenderObject* start, bool selfNeedsLayout)
+{
+ for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
+ // Only force our kids to layout if we're being asked to relayout as a result of a parent changing
+ // FIXME: We should be able to skip relayout of non-relative kids when only bounds size has changed
+ // that's a possible future optimization using LayoutState
+ // http://bugs.webkit.org/show_bug.cgi?id=15391
+ bool needsLayout = selfNeedsLayout;
+ if (!needsLayout) {
+ if (SVGElement* element = child->node()->isSVGElement() ? static_cast<SVGElement*>(child->node()) : 0) {
+ if (element->isStyled())
+ needsLayout = static_cast<SVGStyledElement*>(element)->hasRelativeValues();
+ }
+ }
+
+ if (needsLayout)
+ child->setNeedsLayout(true, false);
+
+ child->layoutIfNeeded();
+ ASSERT(!child->needsLayout());
+ }
+}
+
+bool SVGRenderBase::isOverflowHidden(const RenderObject* object)
+{
+ // SVG doesn't support independent x/y overflow
+ ASSERT(object->style()->overflowX() == object->style()->overflowY());
+
+ // OSCROLL is never set for SVG - see CSSStyleSelector::adjustRenderStyle
+ ASSERT(object->style()->overflowX() != OSCROLL);
+
+ // RenderSVGRoot should never query for overflow state - it should always clip itself to the initial viewport size.
+ ASSERT(!object->isRoot());
+
+ return object->style()->overflowX() == OHIDDEN;
+}
+
+FloatRect SVGRenderBase::filterBoundingBoxForRenderer(const RenderObject* object) const
{
#if ENABLE(FILTERS)
- SVGResourceFilter* filter = getFilterById(object->document(), object->style()->svgStyle()->filter());
+ SVGResourceFilter* filter = getFilterById(object->document(), object->style()->svgStyle()->filter(), object);
if (filter)
- return filter->filterBoundingBox();
+ return filter->filterBoundingBox(object->objectBoundingBox());
#else
UNUSED_PARAM(object);
#endif
return FloatRect();
}
-void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const TransformationMatrix& localToAncestorTransform)
+FloatRect SVGRenderBase::clipperBoundingBoxForRenderer(const RenderObject* object) const
+{
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object->document(), object->style()->svgStyle()->clipPath()))
+ return clipper->resourceBoundingBox(object->objectBoundingBox());
+
+ return FloatRect();
+}
+
+FloatRect SVGRenderBase::maskerBoundingBoxForRenderer(const RenderObject* object) const
+{
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskElement()))
+ return masker->resourceBoundingBox(object->objectBoundingBox());
+
+ return FloatRect();
+}
+
+void SVGRenderBase::deregisterFromResources(RenderObject* object)
+{
+ // We only have the renderer for masker and clipper at the moment.
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), object->style()->svgStyle()->maskElement()))
+ masker->invalidateClient(object);
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object->document(), object->style()->svgStyle()->clipPath()))
+ clipper->invalidateClient(object);
+}
+
+void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const AffineTransform& localToAncestorTransform)
{
if (localToAncestorTransform.isIdentity())
return;
@@ -239,6 +318,16 @@ void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const Transfo
paintInfo.rect = localToAncestorTransform.inverse().mapRect(paintInfo.rect);
}
-} // namespace WebCore
+const RenderObject* findTextRootObject(const RenderObject* start)
+{
+ while (start && !start->isSVGText())
+ start = start->parent();
+ ASSERT(start);
+ ASSERT(start->isSVGText());
-#endif // ENABLE(SVG)
+ return start;
+}
+
+}
+
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.h b/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.h
index da2bf5910c..7170855e37 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.h
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGRenderSupport.h
@@ -26,46 +26,67 @@
#if ENABLE(SVG)
#include "RenderObject.h"
+#include "SVGElement.h"
+#include "SVGStyledElement.h"
namespace WebCore {
- class SVGResourceFilter;
- class ImageBuffer;
+class SVGResourceFilter;
+class ImageBuffer;
- // SVGRendererBase is an abstract base class which all SVG renderers inherit
- // from in order to share SVG renderer code.
- // FIXME: This code can all move into RenderSVGModelObject once
- // all SVG renderers inherit from RenderSVGModelObject.
- class SVGRenderBase {
- public:
- // FIXME: These are only public for SVGRootInlineBox.
- // It's unclear if these should be exposed or not. SVGRootInlineBox may
- // pass the wrong RenderObject* and boundingBox to these functions.
- static void prepareToRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, const FloatRect& boundingBox, SVGResourceFilter*&, SVGResourceFilter* rootFilter = 0);
- static void finishRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, SVGResourceFilter*&, GraphicsContext* savedContext);
+// SVGRendererBase is an abstract base class which all SVG renderers inherit
+// from in order to share SVG renderer code.
+// FIXME: This code can all move into RenderSVGModelObject once
+// all SVG renderers inherit from RenderSVGModelObject.
+class SVGRenderBase {
+public:
+ virtual ~SVGRenderBase();
- protected:
- static IntRect clippedOverflowRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer);
- static void computeRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer, IntRect&, bool fixed);
+ virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
- static void mapLocalToContainer(const RenderObject*, RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&);
+ // FIXME: These are only public for SVGRootInlineBox.
+ // It's unclear if these should be exposed or not. SVGRootInlineBox may
+ // pass the wrong RenderObject* and boundingBox to these functions.
+ static bool prepareToRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, const FloatRect& boundingBox, SVGResourceFilter*&, SVGResourceFilter* rootFilter = 0);
+ static void finishRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, SVGResourceFilter*&, GraphicsContext* savedContext);
- // Used to share the "walk all the children" logic between objectBoundingBox
- // and repaintRectInLocalCoordinates in RenderSVGRoot and RenderSVGContainer
- static FloatRect computeContainerBoundingBox(const RenderObject* container, bool includeAllPaintedContent);
+ // Layout all children of the passed render object
+ static void layoutChildren(RenderObject*, bool selfNeedsLayout);
- // returns the filter bounding box (or the empty rect if no filter) in local coordinates
- static FloatRect filterBoundingBoxForRenderer(const RenderObject*);
- };
+ // Helper function determining wheter overflow is hidden
+ static bool isOverflowHidden(const RenderObject*);
- // FIXME: This should move to RenderObject or PaintInfo
- // Used for transforming the GraphicsContext and damage rect before passing PaintInfo to child renderers.
- void applyTransformToPaintInfo(RenderObject::PaintInfo&, const TransformationMatrix& localToChildTransform);
+ virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
+ virtual FloatRect markerBoundingBox() const { return FloatRect(); }
- // This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.
- void renderSubtreeToImage(ImageBuffer*, RenderObject*);
+ // returns the bounding box of filter, clipper, marker and masker (or the empty rect if no filter) in local coordinates
+ FloatRect filterBoundingBoxForRenderer(const RenderObject*) const;
+ FloatRect clipperBoundingBoxForRenderer(const RenderObject*) const;
+ FloatRect maskerBoundingBoxForRenderer(const RenderObject*) const;
- void clampImageBufferSizeToViewport(FrameView*, IntSize& imageBufferSize);
+protected:
+ static IntRect clippedOverflowRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer);
+ static void computeRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer, IntRect&, bool fixed);
+
+ static void mapLocalToContainer(const RenderObject*, RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&);
+
+ // Used to share the "walk all the children" logic between objectBoundingBox
+ // and repaintRectInLocalCoordinates in RenderSVGRoot and RenderSVGContainer
+ static FloatRect computeContainerBoundingBox(const RenderObject* container, bool includeAllPaintedContent);
+
+ static void deregisterFromResources(RenderObject*);
+};
+
+// FIXME: This should move to RenderObject or PaintInfo
+// Used for transforming the GraphicsContext and damage rect before passing PaintInfo to child renderers.
+void applyTransformToPaintInfo(RenderObject::PaintInfo&, const AffineTransform& localToChildTransform);
+
+// This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.
+void renderSubtreeToImage(ImageBuffer*, RenderObject*);
+
+void clampImageBufferSizeToViewport(FrameView*, IntSize& imageBufferSize);
+
+const RenderObject* findTextRootObject(const RenderObject* start);
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.cpp
index 28e506ad90..5d70505f57 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -34,10 +34,13 @@
#include "HTMLNames.h"
#include "InlineTextBox.h"
#include "NodeRenderStyle.h"
+#include "Path.h"
#include "RenderImage.h"
#include "RenderPath.h"
#include "RenderSVGContainer.h"
#include "RenderSVGInlineText.h"
+#include "RenderSVGResourceClipper.h"
+#include "RenderSVGResourceMasker.h"
#include "RenderSVGRoot.h"
#include "RenderSVGText.h"
#include "RenderTreeAsText.h"
@@ -46,7 +49,6 @@
#include "SVGPaintServerGradient.h"
#include "SVGPaintServerPattern.h"
#include "SVGPaintServerSolid.h"
-#include "SVGResourceClipper.h"
#include "SVGRootInlineBox.h"
#include "SVGStyledElement.h"
#include <math.h>
@@ -179,7 +181,7 @@ TextStream& operator<<(TextStream& ts, const FloatSize& s)
return ts;
}
-TextStream& operator<<(TextStream& ts, const TransformationMatrix& transform)
+TextStream& operator<<(TextStream& ts, const AffineTransform& transform)
{
if (transform.isIdentity())
ts << "identity";
@@ -195,6 +197,37 @@ TextStream& operator<<(TextStream& ts, const TransformationMatrix& transform)
return ts;
}
+static TextStream& operator<<(TextStream& ts, const WindRule rule)
+{
+ switch (rule) {
+ case RULE_NONZERO:
+ ts << "NON-ZERO";
+ break;
+ case RULE_EVENODD:
+ ts << "EVEN-ODD";
+ break;
+ }
+
+ return ts;
+}
+
+static TextStream& operator<<(TextStream& ts, const SVGUnitTypes::SVGUnitType& unitType)
+{
+ switch (unitType) {
+ case SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN:
+ ts << "unknown";
+ break;
+ case SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE:
+ ts << "userSpaceOnUse";
+ break;
+ case SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX:
+ ts << "objectBoundingBox";
+ break;
+ }
+
+ return ts;
+}
+
TextStream& operator<<(TextStream& ts, const Color& c)
{
return ts << c.name();
@@ -298,10 +331,9 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
writeIfNotDefault(ts, "fill rule", svgStyle->fillRule(), RULE_NONZERO);
ts << "}]";
}
+ writeIfNotDefault(ts, "clip rule", svgStyle->clipRule(), RULE_NONZERO);
}
- if (!svgStyle->clipPath().isEmpty())
- writeNameAndQuotedValue(ts, "clip path", svgStyle->clipPath());
writeIfNotEmpty(ts, "start marker", svgStyle->startMarker());
writeIfNotEmpty(ts, "middle marker", svgStyle->midMarker());
writeIfNotEmpty(ts, "end marker", svgStyle->endMarker());
@@ -310,7 +342,7 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
static TextStream& writePositionAndStyle(TextStream& ts, const RenderObject& object)
{
- ts << " " << object.absoluteTransform().mapRect(object.repaintRectInLocalCoordinates());
+ ts << " " << const_cast<RenderObject&>(object).absoluteClippedOverflowRect();
writeStyle(ts, object);
return ts;
}
@@ -464,11 +496,37 @@ static void writeChildren(TextStream& ts, const RenderObject& object, int indent
write(ts, *child, indent + 1);
}
+void writeSVGResource(TextStream& ts, const RenderObject& object, int indent)
+{
+ writeStandardPrefix(ts, object, indent);
+
+ Element* element = static_cast<Element*>(object.node());
+ const AtomicString& id = element->getIDAttribute();
+ writeNameAndQuotedValue(ts, "id", id);
+
+ RenderSVGResource* resource = const_cast<RenderObject&>(object).toRenderSVGResource();
+ if (resource->resourceType() == MaskerResourceType) {
+ RenderSVGResourceMasker* masker = static_cast<RenderSVGResourceMasker*>(resource);
+ ASSERT(masker);
+ writeNameValuePair(ts, "maskUnits", masker->maskUnits());
+ writeNameValuePair(ts, "maskContentUnits", masker->maskContentUnits());
+ } else if (resource->resourceType() == ClipperResourceType) {
+ RenderSVGResourceClipper* clipper = static_cast<RenderSVGResourceClipper*>(resource);
+ ASSERT(clipper);
+ writeNameValuePair(ts, "clipPathUnits", clipper->clipPathUnits());
+ }
+
+ // FIXME: Handle other RenderSVGResource* classes here, after converting them from SVGResource*.
+ ts << "\n";
+ writeChildren(ts, object, indent);
+}
+
void writeSVGContainer(TextStream& ts, const RenderObject& container, int indent)
{
writeStandardPrefix(ts, container, indent);
writePositionAndStyle(ts, container);
ts << "\n";
+ writeResources(ts, container, indent);
writeChildren(ts, container, indent);
}
@@ -484,6 +542,7 @@ void writeSVGText(TextStream& ts, const RenderBlock& text, int indent)
writeStandardPrefix(ts, text, indent);
writeRenderSVGTextBox(ts, text);
ts << "\n";
+ writeResources(ts, text, indent);
writeChildren(ts, text, indent);
}
@@ -493,20 +552,51 @@ void writeSVGInlineText(TextStream& ts, const RenderText& text, int indent)
// Why not just linesBoundingBox()?
ts << " " << FloatRect(text.firstRunOrigin(), text.linesBoundingBox().size()) << "\n";
+ writeResources(ts, text, indent);
writeSVGInlineTextBoxes(ts, text, indent);
}
+void writeSVGImage(TextStream& ts, const RenderImage& image, int indent)
+{
+ writeStandardPrefix(ts, image, indent);
+ writePositionAndStyle(ts, image);
+ ts << "\n";
+ writeResources(ts, image, indent);
+}
+
void write(TextStream& ts, const RenderPath& path, int indent)
{
writeStandardPrefix(ts, path, indent);
ts << path << "\n";
+ writeResources(ts, path, indent);
}
-void writeSVGImage(TextStream& ts, const RenderImage& image, int indent)
+void writeResources(TextStream& ts, const RenderObject& object, int indent)
{
- writeStandardPrefix(ts, image, indent);
- writePositionAndStyle(ts, image);
- ts << "\n";
+ const RenderStyle* style = object.style();
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+
+ if (!svgStyle->maskElement().isEmpty()) {
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskElement())) {
+ writeIndent(ts, indent);
+ ts << " ";
+ writeNameAndQuotedValue(ts, "masker", svgStyle->maskElement());
+ ts << " ";
+ writeStandardPrefix(ts, *masker, 0);
+ ts << " " << masker->resourceBoundingBox(object.objectBoundingBox()) << "\n";
+ }
+ }
+ if (!svgStyle->clipPath().isEmpty()) {
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object.document(), svgStyle->clipPath())) {
+ writeIndent(ts, indent);
+ ts << " ";
+ writeNameAndQuotedValue(ts, "clipPath", svgStyle->clipPath());
+ ts << " ";
+ writeStandardPrefix(ts, *clipper, 0);
+ ts << " " << clipper->resourceBoundingBox(object.objectBoundingBox()) << "\n";
+ }
+ }
+ // FIXME: Handle other RenderSVGResource* classes here, after converting them from SVGResource*.
}
void writeRenderResources(TextStream& ts, Node* parent)
@@ -521,11 +611,11 @@ void writeRenderResources(TextStream& ts, Node* parent)
continue;
SVGStyledElement* styled = static_cast<SVGStyledElement*>(svgElement);
- RefPtr<SVGResource> resource(styled->canvasResource());
+ RefPtr<SVGResource> resource(styled->canvasResource(node->renderer()));
if (!resource)
continue;
- String elementId = svgElement->getAttribute(HTMLNames::idAttr);
+ String elementId = svgElement->getAttribute(svgElement->idAttributeName());
// FIXME: These names are lies!
if (resource->isPaintServer()) {
RefPtr<SVGPaintServer> paintServer = WTF::static_pointer_cast<SVGPaintServer>(resource);
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.h b/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.h
index bee4f36fbe..905652b279 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.h
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGRenderTreeAsText.h
@@ -45,20 +45,23 @@ namespace WebCore {
class RenderPath;
class RenderSVGRoot;
class RenderText;
- class TransformationMatrix;
+ class AffineTransform;
+ class SVGUnitTypes;
// functions used by the main RenderTreeAsText code
void write(TextStream&, const RenderPath&, int indent);
void write(TextStream&, const RenderSVGRoot&, int indent);
+void writeSVGResource(TextStream&, const RenderObject&, int indent);
void writeSVGContainer(TextStream&, const RenderObject&, int indent);
void writeSVGImage(TextStream&, const RenderImage&, int indent);
void writeSVGInlineText(TextStream&, const RenderText&, int indent);
void writeSVGText(TextStream&, const RenderBlock&, int indent);
+void writeResources(TextStream&, const RenderObject&, int indent);
void writeRenderResources(TextStream&, Node* parent);
// helper operators defined used in various classes to dump the render tree.
-TextStream& operator<<(TextStream&, const TransformationMatrix&);
+TextStream& operator<<(TextStream&, const AffineTransform&);
TextStream& operator<<(TextStream&, const IntRect&);
TextStream& operator<<(TextStream&, const Color&);
TextStream& operator<<(TextStream&, const IntPoint&);
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.cpp
index 58297428da..03b9db4a7a 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.cpp
@@ -363,6 +363,13 @@ struct SVGRootInlineBoxPaintWalker {
ASSERT(!m_chunkStarted);
}
+ bool mayHaveSelection(SVGInlineTextBox* box) const
+ {
+ int selectionStart = 0, selectionEnd = 0;
+ box->selectionStartEnd(selectionStart, selectionEnd);
+ return selectionStart < selectionEnd;
+ }
+
void teardownFillPaintServer()
{
if (!m_fillPaintServer)
@@ -429,7 +436,13 @@ struct SVGRootInlineBoxPaintWalker {
m_paintInfo.rect = m_savedInfo.rect;
}
- bool chunkSetupFillCallback(InlineBox* box)
+ bool setupBackground(SVGInlineTextBox* /*box*/)
+ {
+ m_textPaintInfo.subphase = SVGTextPaintSubphaseBackground;
+ return true;
+ }
+
+ bool setupFill(SVGInlineTextBox* box)
{
InlineFlowBox* flowBox = box->parent();
@@ -440,6 +453,7 @@ struct SVGRootInlineBoxPaintWalker {
ASSERT(!m_strokePaintServer);
teardownFillPaintServer();
+ m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphFill;
m_fillPaintServer = SVGPaintServer::fillPaintServer(object->style(), object);
if (m_fillPaintServer) {
m_fillPaintServer->setup(m_paintInfo.context, object, ApplyToFillTargetType, true);
@@ -450,7 +464,35 @@ struct SVGRootInlineBoxPaintWalker {
return false;
}
- bool chunkSetupStrokeCallback(InlineBox* box)
+ bool setupFillSelection(SVGInlineTextBox* box)
+ {
+ InlineFlowBox* flowBox = box->parent();
+
+ // Setup fill paint server
+ RenderObject* object = flowBox->renderer();
+ ASSERT(object);
+ RenderStyle* style = object->getCachedPseudoStyle(SELECTION);
+ if (!style)
+ style = object->style();
+
+ ASSERT(!m_strokePaintServer);
+ teardownFillPaintServer();
+
+ if (!mayHaveSelection(box))
+ return false;
+
+ m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphFillSelection;
+ m_fillPaintServer = SVGPaintServer::fillPaintServer(style, object);
+ if (m_fillPaintServer) {
+ m_fillPaintServer->setup(m_paintInfo.context, object, style, ApplyToFillTargetType, true);
+ m_fillPaintServerObject = object;
+ return true;
+ }
+
+ return false;
+ }
+
+ bool setupStroke(SVGInlineTextBox* box)
{
InlineFlowBox* flowBox = box->parent();
@@ -462,6 +504,7 @@ struct SVGRootInlineBoxPaintWalker {
teardownFillPaintServer();
teardownStrokePaintServer();
+ m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphStroke;
m_strokePaintServer = SVGPaintServer::strokePaintServer(object->style(), object);
if (m_strokePaintServer) {
@@ -473,9 +516,88 @@ struct SVGRootInlineBoxPaintWalker {
return false;
}
- void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ bool setupStrokeSelection(SVGInlineTextBox* box)
+ {
+ InlineFlowBox* flowBox = box->parent();
+
+ // Setup stroke paint server
+ RenderObject* object = flowBox->renderer();
+ ASSERT(object);
+ RenderStyle* style = object->getCachedPseudoStyle(SELECTION);
+ if (!style)
+ style = object->style();
+
+ // If we're both stroked & filled, teardown fill paint server before stroking.
+ teardownFillPaintServer();
+ teardownStrokePaintServer();
+
+ if (!mayHaveSelection(box))
+ return false;
+
+ m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphStrokeSelection;
+ m_strokePaintServer = SVGPaintServer::strokePaintServer(style, object);
+ if (m_strokePaintServer) {
+ m_strokePaintServer->setup(m_paintInfo.context, object, style, ApplyToStrokeTargetType, true);
+ m_strokePaintServerObject = object;
+ return true;
+ }
+
+ return false;
+ }
+
+ bool setupForeground(SVGInlineTextBox* /*box*/)
+ {
+ teardownFillPaintServer();
+ teardownStrokePaintServer();
+
+ m_textPaintInfo.subphase = SVGTextPaintSubphaseForeground;
+
+ return true;
+ }
+
+ SVGPaintServer* activePaintServer() const
+ {
+ switch (m_textPaintInfo.subphase) {
+ case SVGTextPaintSubphaseGlyphFill:
+ case SVGTextPaintSubphaseGlyphFillSelection:
+ ASSERT(m_fillPaintServer);
+ return m_fillPaintServer;
+ case SVGTextPaintSubphaseGlyphStroke:
+ case SVGTextPaintSubphaseGlyphStrokeSelection:
+ ASSERT(m_strokePaintServer);
+ return m_strokePaintServer;
+ case SVGTextPaintSubphaseBackground:
+ case SVGTextPaintSubphaseForeground:
+ default:
+ return 0;
+ }
+ }
+
+ void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
+ if (setupBackground(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupFill(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupFillSelection(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupStroke(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupStrokeSelection(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+
+ if (setupForeground(textBox))
+ paintChunk(textBox, startOffset, chunkCtm, start, end);
+ }
+
+ void paintChunk(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
+ const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
+ {
RenderText* text = textBox->textRenderer();
ASSERT(text);
@@ -523,12 +645,8 @@ struct SVGRootInlineBoxPaintWalker {
textBox->paintDecoration(OVERLINE, m_paintInfo.context, decorationOrigin.x(), decorationOrigin.y(), textWidth, *it, info);
// Paint text
- SVGPaintServer* activePaintServer = m_fillPaintServer;
- if (!activePaintServer)
- activePaintServer = m_strokePaintServer;
-
- ASSERT(activePaintServer);
- textBox->paintCharacters(m_paintInfo, m_tx, m_ty, *it, stringStart, stringLength, activePaintServer);
+ m_textPaintInfo.activePaintServer = activePaintServer();
+ textBox->paintCharacters(m_paintInfo, m_tx, m_ty, *it, stringStart, stringLength, m_textPaintInfo);
// Paint decorations, that have to be drawn afterwards
if (textDecorations & LINE_THROUGH && textWidth != 0.0f)
@@ -561,6 +679,8 @@ private:
int m_tx;
int m_ty;
+
+ SVGTextPaintInfo m_textPaintInfo;
};
void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
@@ -575,18 +695,16 @@ void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
FloatRect boundingBox(tx + x(), ty + y(), width(), height());
// Initialize text rendering
- SVGRenderBase::prepareToRenderSVGContent(renderer(), paintInfo, boundingBox, filter);
-
- // Render text, chunk-by-chunk
- SVGRootInlineBoxPaintWalker walkerCallback(this, filter, paintInfo, tx, ty);
- SVGTextChunkWalker<SVGRootInlineBoxPaintWalker> walker(&walkerCallback,
- &SVGRootInlineBoxPaintWalker::chunkPortionCallback,
- &SVGRootInlineBoxPaintWalker::chunkStartCallback,
- &SVGRootInlineBoxPaintWalker::chunkEndCallback,
- &SVGRootInlineBoxPaintWalker::chunkSetupFillCallback,
- &SVGRootInlineBoxPaintWalker::chunkSetupStrokeCallback);
-
- walkTextChunks(&walker);
+ if (SVGRenderBase::prepareToRenderSVGContent(renderer(), paintInfo, boundingBox, filter)) {
+ // Render text, chunk-by-chunk
+ SVGRootInlineBoxPaintWalker walkerCallback(this, filter, paintInfo, tx, ty);
+ SVGTextChunkWalker<SVGRootInlineBoxPaintWalker> walker(&walkerCallback,
+ &SVGRootInlineBoxPaintWalker::chunkPortionCallback,
+ &SVGRootInlineBoxPaintWalker::chunkStartCallback,
+ &SVGRootInlineBoxPaintWalker::chunkEndCallback);
+
+ walkTextChunks(&walker);
+ }
// Finalize text rendering
SVGRenderBase::finishRenderSVGContent(renderer(), paintInfo, filter, savedInfo.context);
@@ -831,9 +949,8 @@ static void applyTextLengthCorrectionToTextChunk(SVGTextChunk& chunk)
SVGChar& firstChar = *(chunk.start);
// Assure we apply the chunk scaling in the right origin
- TransformationMatrix newChunkCtm;
- newChunkCtm.translate(firstChar.x, firstChar.y);
- newChunkCtm = chunk.ctm * newChunkCtm;
+ AffineTransform newChunkCtm(chunk.ctm);
+ newChunkCtm.translateRight(firstChar.x, firstChar.y);
newChunkCtm.translate(-firstChar.x, -firstChar.y);
chunk.ctm = newChunkCtm;
@@ -944,7 +1061,6 @@ void SVGRootInlineBox::buildLayoutInformation(InlineFlowBox* start, SVGCharacter
Vector<SVGTextChunk>::iterator it = tempChunks.begin();
Vector<SVGTextChunk>::iterator end = tempChunks.end();
- TransformationMatrix ctm;
float computedLength = 0.0f;
for (; it != end; ++it) {
@@ -1388,7 +1504,7 @@ void SVGRootInlineBox::buildTextChunks(Vector<SVGChar>& svgChars, InlineFlowBox*
} else
ASSERT(!info.chunk.boxes.isEmpty());
- // Walk string to find out new chunk positions, if existant
+ // Walk string to find out new chunk positions, if existent
for (unsigned i = 0; i < length; ++i) {
ASSERT(info.it != svgChars.end());
@@ -1677,15 +1793,7 @@ void SVGRootInlineBox::walkTextChunks(SVGTextChunkWalkerBase* walker, const SVGI
ASSERT(itCharEnd <= curChunk.end);
// Process this chunk portion
- if (textBox)
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
- else {
- if (walker->setupFill(range.box))
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
-
- if (walker->setupStroke(range.box))
- (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
- }
+ (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
chunkOffset += length;
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.h b/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.h
index 65bade04fb..7b1dcc44d0 100644
--- a/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.h
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGRootInlineBox.h
@@ -28,6 +28,7 @@
#if ENABLE(SVG)
#include "RootInlineBox.h"
#include "SVGCharacterLayoutInfo.h"
+#include "SVGRenderSupport.h"
namespace WebCore {
@@ -43,13 +44,14 @@ struct LastGlyphInfo {
bool isValid;
};
-class SVGRootInlineBox : public RootInlineBox {
+class SVGRootInlineBox : public RootInlineBox, protected SVGRenderBase {
public:
SVGRootInlineBox(RenderObject* obj)
: RootInlineBox(obj)
, m_height(0)
{
}
+ virtual const SVGRenderBase* toSVGRenderBase() const { return this; }
virtual bool isSVGRootInlineBox() { return true; }
@@ -63,6 +65,9 @@ public:
virtual void computePerCharacterLayoutInformation();
+ virtual FloatRect objectBoundingBox() const { return FloatRect(); }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
+
// Used by SVGInlineTextBox
const Vector<SVGTextChunk>& svgTextChunks() const;
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp b/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp
new file mode 100644
index 0000000000..d9ce640028
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "SVGShadowTreeElements.h"
+
+#include "Document.h"
+#include "FloatSize.h"
+#include "RenderObject.h"
+#include "SVGNames.h"
+
+namespace WebCore {
+
+// SVGShadowTreeContainerElement
+SVGShadowTreeContainerElement::SVGShadowTreeContainerElement(Document* document)
+ : SVGGElement(SVGNames::gTag, document)
+{
+}
+
+SVGShadowTreeContainerElement::~SVGShadowTreeContainerElement()
+{
+}
+
+FloatSize SVGShadowTreeContainerElement::containerTranslation() const
+{
+ return FloatSize(m_xOffset.value(this), m_yOffset.value(this));
+}
+
+// SVGShadowTreeRootElement
+SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, Node* shadowParent)
+ : SVGShadowTreeContainerElement(document)
+ , m_shadowParent(shadowParent)
+{
+ setInDocument(true);
+}
+
+SVGShadowTreeRootElement::~SVGShadowTreeRootElement()
+{
+}
+
+void SVGShadowTreeRootElement::attachElement(PassRefPtr<RenderStyle> style, RenderArena* arena)
+{
+ ASSERT(m_shadowParent);
+
+ // Create the renderer with the specified style
+ RenderObject* renderer = createRenderer(arena, style.get());
+ if (renderer) {
+ setRenderer(renderer);
+ renderer->setStyle(style);
+ }
+
+ // Set these explicitly since this normally happens during an attach()
+ setAttached();
+
+ // Add the renderer to the render tree
+ if (renderer)
+ m_shadowParent->renderer()->addChild(renderer);
+}
+
+}
+
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h b/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h
new file mode 100644
index 0000000000..ed42e89740
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h
@@ -0,0 +1,67 @@
+/*
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint 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 SVGShadowTreeElements_h
+#define SVGShadowTreeElements_h
+
+#if ENABLE(SVG)
+#include "SVGGElement.h"
+#include "SVGLength.h"
+
+namespace WebCore {
+
+class FloatSize;
+
+class SVGShadowTreeContainerElement : public SVGGElement {
+public:
+ SVGShadowTreeContainerElement(Document*);
+ virtual ~SVGShadowTreeContainerElement();
+
+ virtual bool isShadowTreeContainerElement() const { return true; }
+
+ FloatSize containerTranslation() const;
+ void setContainerOffset(const SVGLength& x, const SVGLength& y)
+ {
+ m_xOffset = x;
+ m_yOffset = y;
+ }
+
+private:
+ SVGLength m_xOffset;
+ SVGLength m_yOffset;
+};
+
+class SVGShadowTreeRootElement : public SVGShadowTreeContainerElement {
+public:
+ SVGShadowTreeRootElement(Document*, Node* shadowParent);
+ virtual ~SVGShadowTreeRootElement();
+
+ virtual bool isShadowNode() const { return m_shadowParent; }
+ virtual Node* shadowParentNode() { return m_shadowParent; }
+
+ void attachElement(PassRefPtr<RenderStyle>, RenderArena*);
+
+private:
+ Node* m_shadowParent;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/3rdparty/webkit/WebCore/rendering/TableLayout.h b/src/3rdparty/webkit/WebCore/rendering/TableLayout.h
index 8ae0ce781e..10d6e260d2 100644
--- a/src/3rdparty/webkit/WebCore/rendering/TableLayout.h
+++ b/src/3rdparty/webkit/WebCore/rendering/TableLayout.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the HTML rendering engine for KDE.
- *
* Copyright (C) 2002 Lars Knoll (knoll@kde.org)
* (C) 2002 Dirk Mueller (mueller@kde.org)
*
@@ -23,11 +21,13 @@
#ifndef TableLayout_h
#define TableLayout_h
+#include <wtf/Noncopyable.h>
+
namespace WebCore {
class RenderTable;
-class TableLayout {
+class TableLayout : public Noncopyable {
public:
TableLayout(RenderTable* table)
: m_table(table)
diff --git a/src/3rdparty/webkit/WebCore/rendering/TextControlInnerElements.cpp b/src/3rdparty/webkit/WebCore/rendering/TextControlInnerElements.cpp
index fc7f7f0e0c..4cd55c5fc9 100644
--- a/src/3rdparty/webkit/WebCore/rendering/TextControlInnerElements.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/TextControlInnerElements.cpp
@@ -63,18 +63,17 @@ bool RenderTextControlInnerBlock::nodeAtPoint(const HitTestRequest& request, Hit
VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& point)
{
- int contentsX = point.x();
- int contentsY = point.y();
+ IntPoint contentsPoint(point);
// Multiline text controls have the scroll on shadowAncestorNode, so we need to take that
// into account here.
if (m_multiLine) {
RenderTextControl* renderer = toRenderTextControl(node()->shadowAncestorNode()->renderer());
if (renderer->hasOverflowClip())
- renderer->layer()->addScrolledContentOffset(contentsX, contentsY);
+ contentsPoint += renderer->layer()->scrolledContentOffset();
}
- return RenderBlock::positionForPoint(IntPoint(contentsX, contentsY));
+ return RenderBlock::positionForPoint(contentsPoint);
}
TextControlInnerElement::TextControlInnerElement(Document* doc, Node* shadowParent)
diff --git a/src/3rdparty/webkit/WebCore/rendering/TrailingFloatsRootInlineBox.h b/src/3rdparty/webkit/WebCore/rendering/TrailingFloatsRootInlineBox.h
new file mode 100644
index 0000000000..68bf637bab
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/TrailingFloatsRootInlineBox.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TrailingFloatsRootInlineBox_h
+#define TrailingFloatsRootInlineBox_h
+
+#include "RootInlineBox.h"
+
+namespace WebCore {
+
+class TrailingFloatsRootInlineBox : public RootInlineBox {
+public:
+ TrailingFloatsRootInlineBox(RenderObject* object) : RootInlineBox(object)
+ {
+#if ENABLE(SVG)
+ setHasVirtualHeight();
+#endif
+ }
+
+private:
+ virtual int virtualHeight() const { return 0; }
+};
+
+} // namespace WebCore
+
+#endif // TrailingFloatsRootInlineBox_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/TransformState.cpp b/src/3rdparty/webkit/WebCore/rendering/TransformState.cpp
index a9e68f4b1a..ecc614e0e4 100644
--- a/src/3rdparty/webkit/WebCore/rendering/TransformState.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/TransformState.cpp
@@ -49,6 +49,12 @@ void TransformState::move(int x, int y, TransformAccumulation accumulate)
m_accumulatingTransform = accumulate == AccumulateTransform;
}
+// FIXME: We transform AffineTransform to TransformationMatrix. This is rather inefficient.
+void TransformState::applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation accumulate)
+{
+ applyTransform(transformFromContainer.toTransformationMatrix(), accumulate);
+}
+
void TransformState::applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation accumulate)
{
// If we have an accumulated transform from last time, multiply in this transform
@@ -115,7 +121,7 @@ void TransformState::flattenWithTransform(const TransformationMatrix& t)
}
// We could throw away m_accumulatedTransform if we wanted to here, but that
- // would cause thrash when traversing hierarachies with alternating
+ // would cause thrash when traversing hierarchies with alternating
// preserve-3d and flat elements.
if (m_accumulatedTransform)
m_accumulatedTransform->makeIdentity();
diff --git a/src/3rdparty/webkit/WebCore/rendering/TransformState.h b/src/3rdparty/webkit/WebCore/rendering/TransformState.h
index d2c962a90c..0b4ca46b23 100644
--- a/src/3rdparty/webkit/WebCore/rendering/TransformState.h
+++ b/src/3rdparty/webkit/WebCore/rendering/TransformState.h
@@ -26,6 +26,7 @@
#ifndef TransformState_h
#define TransformState_h
+#include "AffineTransform.h"
#include "FloatPoint.h"
#include "FloatQuad.h"
#include "IntSize.h"
@@ -59,6 +60,7 @@ public:
}
void move(int x, int y, TransformAccumulation = FlattenTransform);
+ void applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation = FlattenTransform);
void applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation = FlattenTransform);
void flatten();
diff --git a/src/3rdparty/webkit/WebCore/rendering/break_lines.cpp b/src/3rdparty/webkit/WebCore/rendering/break_lines.cpp
index 9b46cd2e34..1cc6fd1efe 100644
--- a/src/3rdparty/webkit/WebCore/rendering/break_lines.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/break_lines.cpp
@@ -1,21 +1,26 @@
/*
- * Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2007, 2010 Apple Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * 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.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -44,13 +49,30 @@ static inline bool isBreakableSpace(UChar ch, bool treatNoBreakSpaceAsBreak)
}
}
-static inline bool shouldBreakAfter(UChar ch)
+// This differs from the Unicode algorithm only in that Unicode does not break
+// between a question mark and a vertical line (U+007C).
+static const unsigned char internetExplorerLineBreaksAfterQuestionMarkTable[0x80] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, // \t
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, // ! " ' ) , . /
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, // : ; ?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, // ]
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 // }
+};
+
+static const size_t internetExplorerLineBreaksAfterQuestionMarkTableSize = sizeof(internetExplorerLineBreaksAfterQuestionMarkTable) / sizeof(*internetExplorerLineBreaksAfterQuestionMarkTable);
+
+static inline bool shouldBreakAfter(UChar ch, UChar nextCh)
{
- // Match WinIE's breaking strategy, which is to always allow breaks after hyphens and question marks.
- // FIXME: it appears that IE behavior is more complex, see <http://bugs.webkit.org/show_bug.cgi?id=17475>.
switch (ch) {
- case '-':
+ // For a question mark preceding a non-ASCII characters, defer to the Unicode algorithm by returning false.
+ // For ASCII characters, use a lookup table for enhanced speed and for compatibility with Internet Explorer.
case '?':
+ return nextCh < internetExplorerLineBreaksAfterQuestionMarkTableSize && internetExplorerLineBreaksAfterQuestionMarkTable[nextCh];
+ // Internet Explorer always allows breaking after a hyphen.
+ case '-':
case softHyphen:
// FIXME: cases for ideographicComma and ideographicFullStop are a workaround for an issue in Unicode 5.0
// which is likely to be resolved in Unicode 5.1 <http://bugs.webkit.org/show_bug.cgi?id=17411>.
@@ -88,7 +110,7 @@ int nextBreakablePosition(const UChar* str, int pos, int len, bool treatNoBreakS
for (int i = pos; i < len; i++) {
UChar ch = str[i];
- if (isBreakableSpace(ch, treatNoBreakSpaceAsBreak) || shouldBreakAfter(lastCh))
+ if (isBreakableSpace(ch, treatNoBreakSpaceAsBreak) || shouldBreakAfter(lastCh, ch))
return i;
if (needsLineBreakIterator(ch) || needsLineBreakIterator(lastCh)) {
diff --git a/src/3rdparty/webkit/WebCore/rendering/break_lines.h b/src/3rdparty/webkit/WebCore/rendering/break_lines.h
index 14f740fe87..4d6b8dcd7d 100644
--- a/src/3rdparty/webkit/WebCore/rendering/break_lines.h
+++ b/src/3rdparty/webkit/WebCore/rendering/break_lines.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2005 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/ContentData.h b/src/3rdparty/webkit/WebCore/rendering/style/ContentData.h
index 24d5f86f95..2c261f84be 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/ContentData.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/ContentData.h
@@ -25,15 +25,15 @@
#ifndef ContentData_h
#define ContentData_h
-#include "PlatformString.h"
#include "RenderStyleConstants.h"
-#include "StringImpl.h"
-#include "StyleImage.h"
#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
namespace WebCore {
class CounterContent;
+class StringImpl;
+class StyleImage;
struct ContentData : Noncopyable {
public:
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/CounterContent.h b/src/3rdparty/webkit/WebCore/rendering/style/CounterContent.h
index cf118132ee..702d9c2395 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/CounterContent.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/CounterContent.h
@@ -30,7 +30,7 @@
namespace WebCore {
-class CounterContent {
+class CounterContent : public FastAllocBase {
public:
CounterContent(const AtomicString& identifier, EListStyleType style, const AtomicString& separator)
: m_identifier(identifier)
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.cpp b/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.cpp
index ec910c9cfa..597e919656 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.cpp
@@ -270,4 +270,15 @@ bool FillLayer::containsImage(StyleImage* s) const
return false;
}
+bool FillLayer::imagesAreLoaded() const
+{
+ const FillLayer* curr;
+ for (curr = this; curr; curr = curr->next()) {
+ if (curr->m_image && !curr->m_image->isLoaded())
+ return false;
+ }
+
+ return true;
+}
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.h b/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.h
index fb928b6596..cef6b19beb 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/FillLayer.h
@@ -59,7 +59,7 @@ struct FillSize {
LengthSize size;
};
-struct FillLayer {
+struct FillLayer : FastAllocBase {
public:
FillLayer(EFillLayerType);
~FillLayer();
@@ -126,6 +126,7 @@ public:
}
bool containsImage(StyleImage*) const;
+ bool imagesAreLoaded() const;
bool hasImage() const
{
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/LineClampValue.h b/src/3rdparty/webkit/WebCore/rendering/style/LineClampValue.h
new file mode 100644
index 0000000000..2119ca2916
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/style/LineClampValue.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LineClampValue_h
+#define LineClampValue_h
+
+#include "RenderStyleConstants.h"
+
+namespace WebCore {
+
+class LineClampValue {
+public:
+ LineClampValue()
+ : m_type(LineClampLineCount)
+ , m_value(-1)
+ {
+ }
+
+ LineClampValue(int value, ELineClampType type)
+ : m_type(type)
+ , m_value(value)
+ {
+ }
+
+ int value() const { return m_value; }
+
+ bool isPercentage() const { return m_type == LineClampPercentage; }
+
+ bool isNone() const { return m_value == -1; }
+
+ bool operator==(const LineClampValue& o) const
+ {
+ return value() == o.value() && isPercentage() == o.isPercentage();
+ }
+
+ bool operator!=(const LineClampValue& o) const
+ {
+ return !(*this == o);
+ }
+
+private:
+ ELineClampType m_type;
+ int m_value;
+};
+
+} // namespace WebCore
+
+#endif // LineClampValue_h
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp
index a861fea314..712344fdd2 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.cpp
@@ -192,6 +192,11 @@ static inline int pseudoBit(PseudoId pseudo)
return 1 << (pseudo - 1);
}
+bool RenderStyle::hasAnyPublicPseudoStyles() const
+{
+ return PUBLIC_PSEUDOID_MASK & noninherited_flags._pseudoBits;
+}
+
bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const
{
ASSERT(pseudo > NOPSEUDO);
@@ -454,8 +459,8 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
if (inherited->m_effectiveZoom != other->inherited->m_effectiveZoom)
return StyleDifferenceLayout;
- if (rareNonInheritedData->opacity == 1 && other->rareNonInheritedData->opacity < 1 ||
- rareNonInheritedData->opacity < 1 && other->rareNonInheritedData->opacity == 1) {
+ if ((rareNonInheritedData->opacity == 1 && other->rareNonInheritedData->opacity < 1) ||
+ (rareNonInheritedData->opacity < 1 && other->rareNonInheritedData->opacity == 1)) {
// FIXME: We should add an optimized form of layout that just recomputes visual overflow.
return StyleDifferenceLayout;
}
@@ -702,7 +707,7 @@ void RenderStyle::addBindingURI(StringImpl* uri)
void RenderStyle::setTextShadow(ShadowData* val, bool add)
{
- ASSERT(!val || !val->spread && val->style == Normal);
+ ASSERT(!val || (!val->spread && val->style == Normal));
StyleRareInheritedData* rareData = rareInheritedData.access();
if (!add) {
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h
index 2e8fb0acda..6ec05343c5 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h
@@ -37,6 +37,7 @@
#include "CachedImage.h"
#include "CollapsedBorderValue.h"
#include "Color.h"
+#include "ColorSpace.h"
#include "ContentData.h"
#include "CounterDirectives.h"
#include "CursorList.h"
@@ -49,6 +50,7 @@
#include "Length.h"
#include "LengthBox.h"
#include "LengthSize.h"
+#include "LineClampValue.h"
#include "NinePieceImage.h"
#include "OutlineValue.h"
#include "Pair.h"
@@ -87,8 +89,8 @@
#include "BindingURI.h"
#endif
-#ifdef __WINS__
-#define compareEqual(t, u) ((t) == (u))
+#if COMPILER(WINSCW)
+#define compareEqual(t, u) ((t) == (u))
#else
template<typename T, typename U> inline bool compareEqual(const T& t, const U& u) { return t == static_cast<T>(u); }
#endif
@@ -181,7 +183,7 @@ protected:
unsigned _empty_cells : 1; // EEmptyCell
unsigned _caption_side : 2; // ECaptionSide
- unsigned _list_style_type : 5 ; // EListStyleType
+ unsigned _list_style_type : 7; // EListStyleType
unsigned _list_style_position : 1; // EListStylePosition
unsigned _visibility : 2; // EVisibility
unsigned _text_align : 3; // ETextAlign
@@ -192,37 +194,38 @@ protected:
bool _border_collapse : 1 ;
unsigned _white_space : 3; // EWhiteSpace
unsigned _box_direction : 1; // EBoxDirection (CSS3 box_direction property, flexible box layout module)
- // 32 bits
+ // 34 bits
// non CSS2 inherited
bool _visuallyOrdered : 1;
bool _htmlHacks : 1;
bool _force_backgrounds_to_white : 1;
unsigned _pointerEvents : 4; // EPointerEvents
- // 39 bits
+ // 41 bits
} inherited_flags;
// don't inherit
struct NonInheritedFlags {
bool operator==(const NonInheritedFlags& other) const
{
- return (_effectiveDisplay == other._effectiveDisplay) &&
- (_originalDisplay == other._originalDisplay) &&
- (_overflowX == other._overflowX) &&
- (_overflowY == other._overflowY) &&
- (_vertical_align == other._vertical_align) &&
- (_clear == other._clear) &&
- (_position == other._position) &&
- (_floating == other._floating) &&
- (_table_layout == other._table_layout) &&
- (_page_break_before == other._page_break_before) &&
- (_page_break_after == other._page_break_after) &&
- (_styleType == other._styleType) &&
- (_affectedByHover == other._affectedByHover) &&
- (_affectedByActive == other._affectedByActive) &&
- (_affectedByDrag == other._affectedByDrag) &&
- (_pseudoBits == other._pseudoBits) &&
- (_unicodeBidi == other._unicodeBidi);
+ return _effectiveDisplay == other._effectiveDisplay
+ && _originalDisplay == other._originalDisplay
+ && _overflowX == other._overflowX
+ && _overflowY == other._overflowY
+ && _vertical_align == other._vertical_align
+ && _clear == other._clear
+ && _position == other._position
+ && _floating == other._floating
+ && _table_layout == other._table_layout
+ && _page_break_before == other._page_break_before
+ && _page_break_after == other._page_break_after
+ && _page_break_inside == other._page_break_inside
+ && _styleType == other._styleType
+ && _affectedByHover == other._affectedByHover
+ && _affectedByActive == other._affectedByActive
+ && _affectedByDrag == other._affectedByDrag
+ && _pseudoBits == other._pseudoBits
+ && _unicodeBidi == other._unicodeBidi;
}
bool operator!=(const NonInheritedFlags& other) const { return !(*this == other); }
@@ -239,6 +242,7 @@ protected:
unsigned _page_break_before : 2; // EPageBreak
unsigned _page_break_after : 2; // EPageBreak
+ unsigned _page_break_inside : 2; // EPageBreak
unsigned _styleType : 5; // PseudoId
bool _affectedByHover : 1;
@@ -246,7 +250,7 @@ protected:
bool _affectedByDrag : 1;
unsigned _pseudoBits : 7;
unsigned _unicodeBidi : 2; // EUnicodeBidi
- // 48 bits
+ // 50 bits
} noninherited_flags;
// !END SYNC!
@@ -282,6 +286,7 @@ protected:
noninherited_flags._table_layout = initialTableLayout();
noninherited_flags._page_break_before = initialPageBreak();
noninherited_flags._page_break_after = initialPageBreak();
+ noninherited_flags._page_break_inside = initialPageBreak();
noninherited_flags._styleType = NOPSEUDO;
noninherited_flags._affectedByHover = false;
noninherited_flags._affectedByActive = false;
@@ -345,6 +350,7 @@ public:
bool isStyleAvailable() const;
+ bool hasAnyPublicPseudoStyles() const;
bool hasPseudoStyle(PseudoId pseudo) const;
void setHasPseudoStyle(PseudoId pseudo);
@@ -462,7 +468,7 @@ public:
return font().lineSpacing();
if (lh.isPercent())
- return lh.calcMinValue(fontSize(), true);
+ return lh.calcMinValue(fontSize());
return lh.value();
}
@@ -583,7 +589,7 @@ public:
short widows() const { return inherited->widows; }
short orphans() const { return inherited->orphans; }
- EPageBreak pageBreakInside() const { return static_cast<EPageBreak>(inherited->page_break_inside); }
+ EPageBreak pageBreakInside() const { return static_cast<EPageBreak>(noninherited_flags._page_break_inside); }
EPageBreak pageBreakBefore() const { return static_cast<EPageBreak>(noninherited_flags._page_break_before); }
EPageBreak pageBreakAfter() const { return static_cast<EPageBreak>(noninherited_flags._page_break_after); }
@@ -603,6 +609,7 @@ public:
const Color& textStrokeColor() const { return rareInheritedData->textStrokeColor; }
float textStrokeWidth() const { return rareInheritedData->textStrokeWidth; }
const Color& textFillColor() const { return rareInheritedData->textFillColor; }
+ ColorSpace colorSpace() const { return static_cast<ColorSpace>(rareInheritedData->colorSpace); }
float opacity() const { return rareNonInheritedData->opacity; }
ControlPart appearance() const { return static_cast<ControlPart>(rareNonInheritedData->m_appearance); }
EBoxAlignment boxAlign() const { return static_cast<EBoxAlignment>(rareNonInheritedData->flexibleBox->align); }
@@ -697,7 +704,7 @@ public:
bool isRunningAcceleratedAnimation() const { return rareNonInheritedData->m_runningAcceleratedAnimation; }
#endif
- int lineClamp() const { return rareNonInheritedData->lineClamp; }
+ const LineClampValue& lineClamp() const { return rareNonInheritedData->lineClamp; }
bool textSizeAdjust() const { return rareInheritedData->textSizeAdjust; }
ETextSecurity textSecurity() const { return static_cast<ETextSecurity>(rareInheritedData->textSecurity); }
@@ -918,7 +925,7 @@ public:
void setWidows(short w) { SET_VAR(inherited, widows, w); }
void setOrphans(short o) { SET_VAR(inherited, orphans, o); }
- void setPageBreakInside(EPageBreak b) { SET_VAR(inherited, page_break_inside, b); }
+ void setPageBreakInside(EPageBreak b) { noninherited_flags._page_break_inside = b; }
void setPageBreakBefore(EPageBreak b) { noninherited_flags._page_break_before = b; }
void setPageBreakAfter(EPageBreak b) { noninherited_flags._page_break_after = b; }
@@ -934,6 +941,7 @@ public:
void setTextStrokeColor(const Color& c) { SET_VAR(rareInheritedData, textStrokeColor, c) }
void setTextStrokeWidth(float w) { SET_VAR(rareInheritedData, textStrokeWidth, w) }
void setTextFillColor(const Color& c) { SET_VAR(rareInheritedData, textFillColor, c) }
+ void setColorSpace(ColorSpace space) { SET_VAR(rareInheritedData, colorSpace, space) }
void setOpacity(float f) { SET_VAR(rareNonInheritedData, opacity, f); }
void setAppearance(ControlPart a) { SET_VAR(rareNonInheritedData, m_appearance, a); }
void setBoxAlign(EBoxAlignment a) { SET_VAR(rareNonInheritedData.access()->flexibleBox, align, a); }
@@ -1013,7 +1021,7 @@ public:
void setIsRunningAcceleratedAnimation(bool b = true) { SET_VAR(rareNonInheritedData, m_runningAcceleratedAnimation, b); }
#endif
- void setLineClamp(int c) { SET_VAR(rareNonInheritedData, lineClamp, c); }
+ void setLineClamp(LineClampValue c) { SET_VAR(rareNonInheritedData, lineClamp, c); }
void setTextSizeAdjust(bool b) { SET_VAR(rareInheritedData, textSizeAdjust, b); }
void setTextSecurity(ETextSecurity aTextSecurity) { SET_VAR(rareInheritedData, textSecurity, aTextSecurity); }
@@ -1106,7 +1114,7 @@ public:
static EEmptyCell initialEmptyCells() { return SHOW; }
static EFloat initialFloating() { return FNONE; }
static EListStylePosition initialListStylePosition() { return OUTSIDE; }
- static EListStyleType initialListStyleType() { return DISC; }
+ static EListStyleType initialListStyleType() { return Disc; }
static EOverflow initialOverflowX() { return OVISIBLE; }
static EOverflow initialOverflowY() { return OVISIBLE; }
static EPageBreak initialPageBreak() { return PBAUTO; }
@@ -1185,7 +1193,7 @@ public:
static Color initialBackgroundColor() { return Color::transparent; }
// Keep these at the end.
- static int initialLineClamp() { return -1; }
+ static LineClampValue initialLineClamp() { return LineClampValue(); }
static bool initialTextSizeAdjust() { return true; }
static ETextSecurity initialTextSecurity() { return TSNONE; }
#if ENABLE(DASHBOARD_SUPPORT)
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h
index 3010947ad7..29412c67b5 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* (C) 2000 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
* Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
@@ -66,15 +66,19 @@ enum StyleDifferenceContextSensitiveProperty {
// Static pseudo styles. Dynamic ones are produced on the fly.
enum PseudoId {
+ // The order must be NOP ID, public IDs, and then internal IDs.
NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR, FILE_UPLOAD_BUTTON, INPUT_PLACEHOLDER,
SLIDER_THUMB, SEARCH_CANCEL_BUTTON, SEARCH_DECORATION, SEARCH_RESULTS_DECORATION, SEARCH_RESULTS_BUTTON, MEDIA_CONTROLS_PANEL,
MEDIA_CONTROLS_PLAY_BUTTON, MEDIA_CONTROLS_MUTE_BUTTON, MEDIA_CONTROLS_TIMELINE, MEDIA_CONTROLS_TIMELINE_CONTAINER,
- MEDIA_CONTROLS_VOLUME_SLIDER, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER, MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, MEDIA_CONTROLS_SEEK_BACK_BUTTON,
- MEDIA_CONTROLS_SEEK_FORWARD_BUTTON, MEDIA_CONTROLS_FULLSCREEN_BUTTON, MEDIA_CONTROLS_REWIND_BUTTON, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON,
+ MEDIA_CONTROLS_VOLUME_SLIDER, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER, MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, MEDIA_CONTROLS_TIME_REMAINING_DISPLAY,
+ MEDIA_CONTROLS_SEEK_BACK_BUTTON, MEDIA_CONTROLS_SEEK_FORWARD_BUTTON, MEDIA_CONTROLS_FULLSCREEN_BUTTON, MEDIA_CONTROLS_REWIND_BUTTON,
+ MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON,
MEDIA_CONTROLS_STATUS_DISPLAY, SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
- INPUT_LIST_BUTTON,
+ INPUT_LIST_BUTTON, INNER_SPIN_BUTTON, OUTER_SPIN_BUTTON,
- FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON
+ FIRST_PUBLIC_PSEUDOID = FIRST_LINE,
+ FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON,
+ PUBLIC_PSEUDOID_MASK = ((1 << FIRST_INTERNAL_PSEUDOID) - 1) & ~((1 << FIRST_PUBLIC_PSEUDOID) - 1)
};
// These have been defined in the order of their precedence for border-collapsing. Do
@@ -202,12 +206,85 @@ enum EResize {
RESIZE_NONE, RESIZE_BOTH, RESIZE_HORIZONTAL, RESIZE_VERTICAL
};
+// The order of this enum must match the order of the list style types in CSSValueKeywords.in.
enum EListStyleType {
- DISC, CIRCLE, SQUARE, LDECIMAL, DECIMAL_LEADING_ZERO,
- LOWER_ROMAN, UPPER_ROMAN, LOWER_GREEK,
- LOWER_ALPHA, LOWER_LATIN, UPPER_ALPHA, UPPER_LATIN,
- HEBREW, ARMENIAN, GEORGIAN, CJK_IDEOGRAPHIC,
- HIRAGANA, KATAKANA, HIRAGANA_IROHA, KATAKANA_IROHA, LNONE
+ Disc,
+ Circle,
+ Square,
+ DecimalListStyle,
+ DecimalLeadingZero,
+ ArabicIndic,
+ BinaryListStyle,
+ Bengali,
+ Cambodian,
+ Khmer,
+ Devanagari,
+ Gujarati,
+ Gurmukhi,
+ Kannada,
+ LowerHexadecimal,
+ Lao,
+ Malayalam,
+ Mongolian,
+ Myanmar,
+ Octal,
+ Oriya,
+ Persian,
+ Urdu,
+ Telugu,
+ Tibetan,
+ Thai,
+ UpperHexadecimal,
+ LowerRoman,
+ UpperRoman,
+ LowerGreek,
+ LowerAlpha,
+ LowerLatin,
+ UpperAlpha,
+ UpperLatin,
+ Afar,
+ EthiopicHalehameAaEt,
+ EthiopicHalehameAaEr,
+ Amharic,
+ EthiopicHalehameAmEt,
+ AmharicAbegede,
+ EthiopicAbegedeAmEt,
+ CjkEarthlyBranch,
+ CjkHeavenlyStem,
+ Ethiopic,
+ EthiopicHalehameGez,
+ EthiopicAbegede,
+ EthiopicAbegedeGez,
+ HangulConsonant,
+ Hangul,
+ LowerNorwegian,
+ Oromo,
+ EthiopicHalehameOmEt,
+ Sidama,
+ EthiopicHalehameSidEt,
+ Somali,
+ EthiopicHalehameSoEt,
+ Tigre,
+ EthiopicHalehameTig,
+ TigrinyaEr,
+ EthiopicHalehameTiEr,
+ TigrinyaErAbegede,
+ EthiopicAbegedeTiEr,
+ TigrinyaEt,
+ EthiopicHalehameTiEt,
+ TigrinyaEtAbegede,
+ EthiopicAbegedeTiEt,
+ UpperGreek,
+ UpperNorwegian,
+ Hebrew,
+ Armenian,
+ Georgian,
+ CJKIdeographic,
+ Hiragana,
+ Katakana,
+ HiraganaIroha,
+ KatakanaIroha,
+ NoneListStyle
};
enum StyleContentType {
@@ -216,6 +293,8 @@ enum StyleContentType {
enum EBorderFit { BorderFitBorder, BorderFitLines };
+enum EAnimationFillMode { AnimationFillModeNone, AnimationFillModeForwards, AnimationFillModeBackwards, AnimationFillModeBoth };
+
enum EAnimPlayState {
AnimPlayStatePlaying = 0x0,
AnimPlayStatePaused = 0x1
@@ -321,6 +400,8 @@ enum ETransformStyle3D {
enum EBackfaceVisibility {
BackfaceVisibilityVisible, BackfaceVisibilityHidden
};
+
+enum ELineClampType { LineClampLineCount, LineClampPercentage };
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.cpp b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.cpp
index e8827c4733..79580885bd 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -8,8 +8,6 @@
Copyright (C) 2002-2003 Dirk Mueller (mueller@kde.org)
Copyright (C) 2002 Apple Computer, Inc.
- This file is part of the KDE project
-
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
@@ -32,11 +30,14 @@
#include "CSSPrimitiveValue.h"
#include "CSSValueList.h"
+#include "IntRect.h"
#include "NodeRenderStyle.h"
#include "RenderObject.h"
#include "RenderStyle.h"
#include "SVGStyledElement.h"
+using namespace std;
+
namespace WebCore {
SVGRenderStyle::SVGRenderStyle()
@@ -143,6 +144,56 @@ float SVGRenderStyle::cssPrimitiveToLength(const RenderObject* item, CSSValue* v
return primitive->computeLengthFloat(const_cast<RenderStyle*>(item->style()), item->document()->documentElement()->renderStyle());
}
+
+static void getSVGShadowExtent(ShadowData* shadow, int& top, int& right, int& bottom, int& left)
+{
+ top = 0;
+ right = 0;
+ bottom = 0;
+ left = 0;
+
+ int blurAndSpread = shadow->blur + shadow->spread;
+
+ top = min(top, shadow->y - blurAndSpread);
+ right = max(right, shadow->x + blurAndSpread);
+ bottom = max(bottom, shadow->y + blurAndSpread);
+ left = min(left, shadow->x - blurAndSpread);
+}
+
+void SVGRenderStyle::inflateForShadow(IntRect& repaintRect) const
+{
+ ShadowData* svgShadow = shadow();
+ if (!svgShadow)
+ return;
+
+ FloatRect repaintFloatRect = FloatRect(repaintRect);
+ inflateForShadow(repaintFloatRect);
+ repaintRect = enclosingIntRect(repaintFloatRect);
+}
+
+void SVGRenderStyle::inflateForShadow(FloatRect& repaintRect) const
+{
+ ShadowData* svgShadow = shadow();
+ if (!svgShadow)
+ return;
+
+ int shadowTop;
+ int shadowRight;
+ int shadowBottom;
+ int shadowLeft;
+ getSVGShadowExtent(svgShadow, shadowTop, shadowRight, shadowBottom, shadowLeft);
+
+ int overflowLeft = repaintRect.x() + shadowLeft;
+ int overflowRight = repaintRect.right() + shadowRight;
+ int overflowTop = repaintRect.y() + shadowTop;
+ int overflowBottom = repaintRect.bottom() + shadowBottom;
+
+ repaintRect.setX(overflowLeft);
+ repaintRect.setY(overflowTop);
+ repaintRect.setWidth(overflowRight - overflowLeft);
+ repaintRect.setHeight(overflowBottom - overflowTop);
+}
+
}
#endif // ENABLE(SVG)
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.h b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.h
index 12477d771e..3f35a636b6 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyle.h
@@ -3,8 +3,6 @@
2004, 2005 Rob Buis <buis@kde.org>
Copyright (C) 2005, 2006 Apple Computer, Inc.
- This file is part of the KDE project
-
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
@@ -32,180 +30,184 @@
#include "SVGRenderStyleDefs.h"
#include "ShadowData.h"
-#include <wtf/Platform.h>
-
namespace WebCore {
- class RenderObject;
- class RenderStyle;
-
- class SVGRenderStyle : public RefCounted<SVGRenderStyle> {
- public:
- static PassRefPtr<SVGRenderStyle> create() { return adoptRef(new SVGRenderStyle); }
- PassRefPtr<SVGRenderStyle> copy() const { return adoptRef(new SVGRenderStyle(*this));}
- ~SVGRenderStyle();
+class FloatRect;
+class IntRect;
+class RenderObject;
+class RenderStyle;
+
+class SVGRenderStyle : public RefCounted<SVGRenderStyle> {
+public:
+ static PassRefPtr<SVGRenderStyle> create() { return adoptRef(new SVGRenderStyle); }
+ PassRefPtr<SVGRenderStyle> copy() const { return adoptRef(new SVGRenderStyle(*this));}
+ ~SVGRenderStyle();
+
+ bool inheritedNotEqual(const SVGRenderStyle*) const;
+ void inheritFrom(const SVGRenderStyle*);
+
+ // FIXME: These functions should move to ShadowData.
+ void inflateForShadow(IntRect&) const;
+ void inflateForShadow(FloatRect&) const;
+
+ bool operator==(const SVGRenderStyle&) const;
+ bool operator!=(const SVGRenderStyle& o) const { return !(*this == o); }
+
+ // SVG CSS Properties
+ SVG_RS_DEFINE_ATTRIBUTE(EAlignmentBaseline, AlignmentBaseline, alignmentBaseline, AB_AUTO)
+ SVG_RS_DEFINE_ATTRIBUTE(EDominantBaseline, DominantBaseline, dominantBaseline, DB_AUTO)
+ SVG_RS_DEFINE_ATTRIBUTE(EBaselineShift, BaselineShift, baselineShift, BS_BASELINE)
+
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(LineCap, CapStyle, capStyle, ButtCap)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(WindRule, ClipRule, clipRule, RULE_NONZERO)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EColorInterpolation, ColorInterpolation, colorInterpolation, CI_SRGB)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EColorInterpolation, ColorInterpolationFilters, colorInterpolationFilters, CI_LINEARRGB)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EColorRendering, ColorRendering, colorRendering, CR_AUTO)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(WindRule, FillRule, fillRule, RULE_NONZERO)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EImageRendering, ImageRendering, imageRendering, IR_AUTO)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(LineJoin, JoinStyle, joinStyle, MiterJoin)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EShapeRendering, ShapeRendering, shapeRendering, SR_AUTO)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(ETextAnchor, TextAnchor, textAnchor, TA_START)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EWritingMode, WritingMode, writingMode, WM_LRTB)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EGlyphOrientation, GlyphOrientationHorizontal, glyphOrientationHorizontal, GO_0DEG)
+ SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EGlyphOrientation, GlyphOrientationVertical, glyphOrientationVertical, GO_AUTO)
+
+ // SVG CSS Properties (using DataRef's)
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, fill, opacity, FillOpacity, fillOpacity, 1.0f)
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(SVGPaint, fill, paint, FillPaint, fillPaint, SVGPaint::defaultFill())
+
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stroke, opacity, StrokeOpacity, strokeOpacity, 1.0f)
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(SVGPaint, stroke, paint, StrokePaint, strokePaint, SVGPaint::defaultStroke())
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValueList, stroke, dashArray, StrokeDashArray, strokeDashArray, 0)
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stroke, miterLimit, StrokeMiterLimit, strokeMiterLimit, 4.0f)
+
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, stroke, width, StrokeWidth, strokeWidth, 0)
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, stroke, dashOffset, StrokeDashOffset, strokeDashOffset, 0);
+
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, text, kerning, Kerning, kerning, 0)
+
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stops, opacity, StopOpacity, stopOpacity, 1.0f)
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, stops, color, StopColor, stopColor, Color(0, 0, 0))
+
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, clip, clipPath, ClipPath, clipPath, String())
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, mask, maskElement, MaskElement, maskElement, String())
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, markers, startMarker, StartMarker, startMarker, String())
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, markers, midMarker, MidMarker, midMarker, String())
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, markers, endMarker, EndMarker, endMarker, String())
+
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, misc, filter, Filter, filter, String())
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, misc, floodOpacity, FloodOpacity, floodOpacity, 1.0f)
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, misc, floodColor, FloodColor, floodColor, Color(0, 0, 0))
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, misc, lightingColor, LightingColor, lightingColor, Color(255, 255, 255))
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, misc, baselineShiftValue, BaselineShiftValue, baselineShiftValue, 0)
+
+ SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_OWNPTR(ShadowData, shadowSVG, shadow, Shadow, shadow, 0)
+
+ // convenience
+ bool hasStroke() const { return (strokePaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE); }
+ bool hasFill() const { return (fillPaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE); }
+
+ static float cssPrimitiveToLength(const RenderObject*, CSSValue*, float defaultValue = 0.0f);
+
+protected:
+ // inherit
+ struct InheritedFlags {
+ bool operator==(const InheritedFlags& other) const
+ {
+ return (_colorRendering == other._colorRendering)
+ && (_imageRendering == other._imageRendering)
+ && (_shapeRendering == other._shapeRendering)
+ && (_clipRule == other._clipRule)
+ && (_fillRule == other._fillRule)
+ && (_capStyle == other._capStyle)
+ && (_joinStyle == other._joinStyle)
+ && (_textAnchor == other._textAnchor)
+ && (_colorInterpolation == other._colorInterpolation)
+ && (_colorInterpolationFilters == other._colorInterpolationFilters)
+ && (_writingMode == other._writingMode)
+ && (_glyphOrientationHorizontal == other._glyphOrientationHorizontal)
+ && (_glyphOrientationVertical == other._glyphOrientationVertical);
+ }
- bool inheritedNotEqual(const SVGRenderStyle*) const;
- void inheritFrom(const SVGRenderStyle*);
-
- bool operator==(const SVGRenderStyle&) const;
- bool operator!=(const SVGRenderStyle& o) const { return !(*this == o); }
-
- // SVG CSS Properties
- SVG_RS_DEFINE_ATTRIBUTE(EAlignmentBaseline, AlignmentBaseline, alignmentBaseline, AB_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE(EDominantBaseline, DominantBaseline, dominantBaseline, DB_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE(EBaselineShift, BaselineShift, baselineShift, BS_BASELINE)
-
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(LineCap, CapStyle, capStyle, ButtCap)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(WindRule, ClipRule, clipRule, RULE_NONZERO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EColorInterpolation, ColorInterpolation, colorInterpolation, CI_SRGB)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EColorInterpolation, ColorInterpolationFilters, colorInterpolationFilters, CI_LINEARRGB)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EColorRendering, ColorRendering, colorRendering, CR_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(WindRule, FillRule, fillRule, RULE_NONZERO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EImageRendering, ImageRendering, imageRendering, IR_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(LineJoin, JoinStyle, joinStyle, MiterJoin)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EShapeRendering, ShapeRendering, shapeRendering, SR_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(ETextAnchor, TextAnchor, textAnchor, TA_START)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EWritingMode, WritingMode, writingMode, WM_LRTB)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EGlyphOrientation, GlyphOrientationHorizontal, glyphOrientationHorizontal, GO_0DEG)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EGlyphOrientation, GlyphOrientationVertical, glyphOrientationVertical, GO_AUTO)
-
- // SVG CSS Properties (using DataRef's)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, fill, opacity, FillOpacity, fillOpacity, 1.0f)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(SVGPaint, fill, paint, FillPaint, fillPaint, SVGPaint::defaultFill())
-
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stroke, opacity, StrokeOpacity, strokeOpacity, 1.0f)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(SVGPaint, stroke, paint, StrokePaint, strokePaint, SVGPaint::defaultStroke())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValueList, stroke, dashArray, StrokeDashArray, strokeDashArray, 0)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stroke, miterLimit, StrokeMiterLimit, strokeMiterLimit, 4.0f)
-
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, stroke, width, StrokeWidth, strokeWidth, 0)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, stroke, dashOffset, StrokeDashOffset, strokeDashOffset, 0);
-
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, text, kerning, Kerning, kerning, 0)
-
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stops, opacity, StopOpacity, stopOpacity, 1.0f)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, stops, color, StopColor, stopColor, Color(0, 0, 0))
-
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, clip, clipPath, ClipPath, clipPath, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, mask, maskElement, MaskElement, maskElement, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, markers, startMarker, StartMarker, startMarker, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, markers, midMarker, MidMarker, midMarker, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, markers, endMarker, EndMarker, endMarker, String())
-
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, misc, filter, Filter, filter, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, misc, floodOpacity, FloodOpacity, floodOpacity, 1.0f)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, misc, floodColor, FloodColor, floodColor, Color(0, 0, 0))
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, misc, lightingColor, LightingColor, lightingColor, Color(255, 255, 255))
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, misc, baselineShiftValue, BaselineShiftValue, baselineShiftValue, 0)
-
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_OWNPTR(ShadowData, shadowSVG, shadow, Shadow, shadow, 0)
-
- // convenience
- bool hasStroke() const { return (strokePaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE); }
- bool hasFill() const { return (fillPaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE); }
-
- static float cssPrimitiveToLength(const RenderObject*, CSSValue*, float defaultValue = 0.0f);
-
- protected:
- // inherit
- struct InheritedFlags {
- bool operator==(const InheritedFlags& other) const
- {
- return (_colorRendering == other._colorRendering) &&
- (_imageRendering == other._imageRendering) &&
- (_shapeRendering == other._shapeRendering) &&
- (_clipRule == other._clipRule) &&
- (_fillRule == other._fillRule) &&
- (_capStyle == other._capStyle) &&
- (_joinStyle == other._joinStyle) &&
- (_textAnchor == other._textAnchor) &&
- (_colorInterpolation == other._colorInterpolation) &&
- (_colorInterpolationFilters == other._colorInterpolationFilters) &&
- (_writingMode == other._writingMode) &&
- (_glyphOrientationHorizontal == other._glyphOrientationHorizontal) &&
- (_glyphOrientationVertical == other._glyphOrientationVertical);
- }
-
- bool operator!=(const InheritedFlags& other) const
- {
- return !(*this == other);
- }
-
- unsigned _colorRendering : 2; // EColorRendering
- unsigned _imageRendering : 2; // EImageRendering
- unsigned _shapeRendering : 2; // EShapeRendering
- unsigned _clipRule : 1; // WindRule
- unsigned _fillRule : 1; // WindRule
- unsigned _capStyle : 2; // LineCap
- unsigned _joinStyle : 2; // LineJoin
- unsigned _textAnchor : 2; // ETextAnchor
- unsigned _colorInterpolation : 2; // EColorInterpolation
- unsigned _colorInterpolationFilters : 2; // EColorInterpolation
- unsigned _writingMode : 3; // EWritingMode
- unsigned _glyphOrientationHorizontal : 3; // EGlyphOrientation
- unsigned _glyphOrientationVertical : 3; // EGlyphOrientation
- } svg_inherited_flags;
-
- // don't inherit
- struct NonInheritedFlags {
- // 32 bit non-inherited, don't add to the struct, or the operator will break.
- bool operator==(const NonInheritedFlags &other) const { return _niflags == other._niflags; }
- bool operator!=(const NonInheritedFlags &other) const { return _niflags != other._niflags; }
-
- union {
- struct {
- unsigned _alignmentBaseline : 4; // EAlignmentBaseline
- unsigned _dominantBaseline : 4; // EDominantBaseline
- unsigned _baselineShift : 2; // EBaselineShift
- // 22 bits unused
- } f;
- uint32_t _niflags;
- };
- } svg_noninherited_flags;
-
- // inherited attributes
- DataRef<StyleFillData> fill;
- DataRef<StyleStrokeData> stroke;
- DataRef<StyleMarkerData> markers;
- DataRef<StyleTextData> text;
-
- // non-inherited attributes
- DataRef<StyleStopData> stops;
- DataRef<StyleClipData> clip;
- DataRef<StyleMaskData> mask;
- DataRef<StyleMiscData> misc;
- DataRef<StyleShadowSVGData> shadowSVG;
-
- private:
- enum CreateDefaultType { CreateDefault };
-
- SVGRenderStyle();
- SVGRenderStyle(const SVGRenderStyle&);
- SVGRenderStyle(CreateDefaultType); // Used to create the default style.
-
- void setBitDefaults()
+ bool operator!=(const InheritedFlags& other) const
{
- svg_inherited_flags._clipRule = initialClipRule();
- svg_inherited_flags._colorRendering = initialColorRendering();
- svg_inherited_flags._fillRule = initialFillRule();
- svg_inherited_flags._imageRendering = initialImageRendering();
- svg_inherited_flags._shapeRendering = initialShapeRendering();
- svg_inherited_flags._textAnchor = initialTextAnchor();
- svg_inherited_flags._capStyle = initialCapStyle();
- svg_inherited_flags._joinStyle = initialJoinStyle();
- svg_inherited_flags._colorInterpolation = initialColorInterpolation();
- svg_inherited_flags._colorInterpolationFilters = initialColorInterpolationFilters();
- svg_inherited_flags._writingMode = initialWritingMode();
- svg_inherited_flags._glyphOrientationHorizontal = initialGlyphOrientationHorizontal();
- svg_inherited_flags._glyphOrientationVertical = initialGlyphOrientationVertical();
-
- svg_noninherited_flags._niflags = 0;
- svg_noninherited_flags.f._alignmentBaseline = initialAlignmentBaseline();
- svg_noninherited_flags.f._dominantBaseline = initialDominantBaseline();
- svg_noninherited_flags.f._baselineShift = initialBaselineShift();
+ return !(*this == other);
}
- };
+
+ unsigned _colorRendering : 2; // EColorRendering
+ unsigned _imageRendering : 2; // EImageRendering
+ unsigned _shapeRendering : 2; // EShapeRendering
+ unsigned _clipRule : 1; // WindRule
+ unsigned _fillRule : 1; // WindRule
+ unsigned _capStyle : 2; // LineCap
+ unsigned _joinStyle : 2; // LineJoin
+ unsigned _textAnchor : 2; // ETextAnchor
+ unsigned _colorInterpolation : 2; // EColorInterpolation
+ unsigned _colorInterpolationFilters : 2; // EColorInterpolation
+ unsigned _writingMode : 3; // EWritingMode
+ unsigned _glyphOrientationHorizontal : 3; // EGlyphOrientation
+ unsigned _glyphOrientationVertical : 3; // EGlyphOrientation
+ } svg_inherited_flags;
+
+ // don't inherit
+ struct NonInheritedFlags {
+ // 32 bit non-inherited, don't add to the struct, or the operator will break.
+ bool operator==(const NonInheritedFlags &other) const { return _niflags == other._niflags; }
+ bool operator!=(const NonInheritedFlags &other) const { return _niflags != other._niflags; }
+
+ union {
+ struct {
+ unsigned _alignmentBaseline : 4; // EAlignmentBaseline
+ unsigned _dominantBaseline : 4; // EDominantBaseline
+ unsigned _baselineShift : 2; // EBaselineShift
+ // 22 bits unused
+ } f;
+ uint32_t _niflags;
+ };
+ } svg_noninherited_flags;
+
+ // inherited attributes
+ DataRef<StyleFillData> fill;
+ DataRef<StyleStrokeData> stroke;
+ DataRef<StyleMarkerData> markers;
+ DataRef<StyleTextData> text;
+
+ // non-inherited attributes
+ DataRef<StyleStopData> stops;
+ DataRef<StyleClipData> clip;
+ DataRef<StyleMaskData> mask;
+ DataRef<StyleMiscData> misc;
+ DataRef<StyleShadowSVGData> shadowSVG;
+
+private:
+ enum CreateDefaultType { CreateDefault };
+
+ SVGRenderStyle();
+ SVGRenderStyle(const SVGRenderStyle&);
+ SVGRenderStyle(CreateDefaultType); // Used to create the default style.
+
+ void setBitDefaults()
+ {
+ svg_inherited_flags._clipRule = initialClipRule();
+ svg_inherited_flags._colorRendering = initialColorRendering();
+ svg_inherited_flags._fillRule = initialFillRule();
+ svg_inherited_flags._imageRendering = initialImageRendering();
+ svg_inherited_flags._shapeRendering = initialShapeRendering();
+ svg_inherited_flags._textAnchor = initialTextAnchor();
+ svg_inherited_flags._capStyle = initialCapStyle();
+ svg_inherited_flags._joinStyle = initialJoinStyle();
+ svg_inherited_flags._colorInterpolation = initialColorInterpolation();
+ svg_inherited_flags._colorInterpolationFilters = initialColorInterpolationFilters();
+ svg_inherited_flags._writingMode = initialWritingMode();
+ svg_inherited_flags._glyphOrientationHorizontal = initialGlyphOrientationHorizontal();
+ svg_inherited_flags._glyphOrientationVertical = initialGlyphOrientationVertical();
+
+ svg_noninherited_flags._niflags = 0;
+ svg_noninherited_flags.f._alignmentBaseline = initialAlignmentBaseline();
+ svg_noninherited_flags.f._dominantBaseline = initialDominantBaseline();
+ svg_noninherited_flags.f._baselineShift = initialBaselineShift();
+ }
+};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.cpp b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.cpp
index 2ed1d8fcc1..093f1f1fb6 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.cpp
@@ -8,8 +8,6 @@
Copyright (C) 2002-2003 Dirk Mueller (mueller@kde.org)
Copyright (C) 2002 Apple Computer, Inc.
- This file is part of the KDE project
-
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.h b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.h
index f4cf9327a3..8f01d9f12d 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/SVGRenderStyleDefs.h
@@ -8,8 +8,6 @@
(C) 2000-2003 Dirk Mueller (mueller@kde.org)
(C) 2002-2003 Apple Computer, Inc.
- This file is part of the KDE project
-
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/ShadowData.h b/src/3rdparty/webkit/WebCore/rendering/style/ShadowData.h
index f4061f2e5e..089cf77599 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/ShadowData.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/ShadowData.h
@@ -26,6 +26,7 @@
#define ShadowData_h
#include "Color.h"
+#include <wtf/FastAllocBase.h>
namespace WebCore {
@@ -33,7 +34,7 @@ enum ShadowStyle { Normal, Inset };
// This struct holds information about shadows for the text-shadow and box-shadow properties.
-struct ShadowData {
+struct ShadowData : FastAllocBase {
ShadowData()
: x(0)
, y(0)
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.cpp b/src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.cpp
index f59c0c2420..c73497f397 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.cpp
@@ -37,7 +37,6 @@ StyleInheritedData::StyleInheritedData()
, vertical_border_spacing(RenderStyle::initialVerticalBorderSpacing())
, widows(RenderStyle::initialWidows())
, orphans(RenderStyle::initialOrphans())
- , page_break_inside(RenderStyle::initialPageBreak())
{
}
@@ -58,7 +57,6 @@ StyleInheritedData::StyleInheritedData(const StyleInheritedData& o)
, vertical_border_spacing(o.vertical_border_spacing)
, widows(o.widows)
, orphans(o.orphans)
- , page_break_inside(o.page_break_inside)
{
}
@@ -84,8 +82,7 @@ bool StyleInheritedData::operator==(const StyleInheritedData& o) const
horizontal_border_spacing == o.horizontal_border_spacing &&
vertical_border_spacing == o.vertical_border_spacing &&
widows == o.widows &&
- orphans == o.orphans &&
- page_break_inside == o.page_break_inside;
+ orphans == o.orphans;
}
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.h b/src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.h
index 548ca72364..3b30b8f64a 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/StyleInheritedData.h
@@ -68,7 +68,6 @@ public:
// Paged media properties.
short widows;
short orphans;
- unsigned page_break_inside : 2; // EPageBreak
private:
StyleInheritedData();
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.cpp b/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.cpp
index ce21720c5b..f731098f80 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.cpp
@@ -39,6 +39,7 @@ StyleRareInheritedData::StyleRareInheritedData()
, textSizeAdjust(RenderStyle::initialTextSizeAdjust())
, resize(RenderStyle::initialResize())
, userSelect(RenderStyle::initialUserSelect())
+ , colorSpace(DeviceColorSpace)
{
}
@@ -58,6 +59,7 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
, textSizeAdjust(o.textSizeAdjust)
, resize(o.resize)
, userSelect(o.userSelect)
+ , colorSpace(o.colorSpace)
{
}
@@ -81,7 +83,8 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
&& khtmlLineBreak == o.khtmlLineBreak
&& textSizeAdjust == o.textSizeAdjust
&& resize == o.resize
- && userSelect == o.userSelect;
+ && userSelect == o.userSelect
+ && colorSpace == o.colorSpace;
}
bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.h b/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.h
index 06ad400480..2e87e6b97f 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/StyleRareInheritedData.h
@@ -65,6 +65,7 @@ public:
bool textSizeAdjust : 1; // An Apple extension.
unsigned resize : 2; // EResize
unsigned userSelect : 1; // EUserSelect
+ unsigned colorSpace : 1; // ColorSpace
private:
StyleRareInheritedData();
diff --git a/src/3rdparty/webkit/WebCore/rendering/style/StyleRareNonInheritedData.h b/src/3rdparty/webkit/WebCore/rendering/style/StyleRareNonInheritedData.h
index 8dd22b39b1..452b273de2 100644
--- a/src/3rdparty/webkit/WebCore/rendering/style/StyleRareNonInheritedData.h
+++ b/src/3rdparty/webkit/WebCore/rendering/style/StyleRareNonInheritedData.h
@@ -29,6 +29,7 @@
#include "CursorData.h"
#include "DataRef.h"
#include "FillLayer.h"
+#include "LineClampValue.h"
#include "NinePieceImage.h"
#include "StyleTransformData.h"
#include <wtf/OwnPtr.h>
@@ -77,7 +78,7 @@ public:
bool animationDataEquivalent(const StyleRareNonInheritedData&) const;
bool transitionDataEquivalent(const StyleRareNonInheritedData&) const;
- int lineClamp; // An Apple extension.
+ LineClampValue lineClamp; // An Apple extension.
#if ENABLE(DASHBOARD_SUPPORT)
Vector<StyleDashboardRegion> m_dashboardRegions;
#endif