summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.cpp180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.cpp
new file mode 100644
index 0000000..2212d78
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGInlineText.cpp
@@ -0,0 +1,180 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
+ * (C) 2006 Apple Computer Inc.
+ * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * (C) 2008 Rob Buis <buis@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGInlineText.h"
+
+#include "FloatConversion.h"
+#include "RenderBlock.h"
+#include "RenderSVGRoot.h"
+#include "SVGInlineTextBox.h"
+#include "SVGRootInlineBox.h"
+
+namespace WebCore {
+
+static inline bool isChildOfHiddenContainer(RenderObject* start)
+{
+ while (start) {
+ if (start->isSVGHiddenContainer())
+ return true;
+
+ start = start->parent();
+ }
+
+ return false;
+}
+
+RenderSVGInlineText::RenderSVGInlineText(Node* n, PassRefPtr<StringImpl> str)
+ : RenderText(n, str)
+{
+}
+
+void RenderSVGInlineText::absoluteRects(Vector<IntRect>& rects, int, int, bool)
+{
+ rects.append(computeAbsoluteRectForRange(0, textLength()));
+}
+
+void RenderSVGInlineText::absoluteQuads(Vector<FloatQuad>& quads, bool)
+{
+ quads.append(FloatRect(computeAbsoluteRectForRange(0, textLength())));
+}
+
+IntRect RenderSVGInlineText::selectionRect(bool)
+{
+ ASSERT(!needsLayout());
+
+ IntRect rect;
+ if (selectionState() == SelectionNone)
+ return rect;
+
+ // Early exit if we're ie. a <text> within a <defs> section.
+ if (isChildOfHiddenContainer(this))
+ return rect;
+
+ // Now calculate startPos and endPos for painting selection.
+ // We include a selection while endPos > 0
+ int startPos, endPos;
+ if (selectionState() == SelectionInside) {
+ // We are fully selected.
+ startPos = 0;
+ endPos = textLength();
+ } else {
+ selectionStartEnd(startPos, endPos);
+ if (selectionState() == SelectionStart)
+ endPos = textLength();
+ else if (selectionState() == SelectionEnd)
+ startPos = 0;
+ }
+
+ if (startPos == endPos)
+ return rect;
+
+ return computeAbsoluteRectForRange(startPos, endPos);
+}
+
+IntRect RenderSVGInlineText::computeAbsoluteRectForRange(int startPos, int endPos)
+{
+ IntRect rect;
+
+ RenderBlock* cb = containingBlock();
+ if (!cb || !cb->container())
+ return rect;
+
+ RenderSVGRoot* root = findSVGRootObject(parent());
+ if (!root)
+ return rect;
+
+ for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
+ rect.unite(box->selectionRect(0, 0, startPos, endPos));
+
+ // Mimic RenderBox::computeAbsoluteRepaintRect() functionality. But only the subset needed for SVG and respecting SVG transformations.
+ FloatPoint absPos = cb->container()->localToAbsolute();
+
+ // Remove HTML parent translation offsets here! These need to be retrieved from the RenderSVGRoot object.
+ // But do take the containingBlocks's container position into account, ie. SVG text in scrollable <div>.
+ TransformationMatrix htmlParentCtm = root->RenderContainer::absoluteTransform();
+
+ FloatRect fixedRect(narrowPrecisionToFloat(rect.x() + absPos.x() - xPos() - htmlParentCtm.e()),
+ narrowPrecisionToFloat(rect.y() + absPos.y() - yPos() - htmlParentCtm.f()), rect.width(), rect.height());
+ // FIXME: broken with CSS transforms
+ return enclosingIntRect(absoluteTransform().mapRect(fixedRect));
+}
+
+InlineTextBox* RenderSVGInlineText::createInlineTextBox()
+{
+ return new (renderArena()) SVGInlineTextBox(this);
+}
+
+IntRect RenderSVGInlineText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
+{
+ // SVG doesn't have any editable content where a caret rect would be needed
+ return IntRect();
+}
+
+VisiblePosition RenderSVGInlineText::positionForCoordinates(int x, int y)
+{
+ SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(firstTextBox());
+
+ if (!textBox || textLength() == 0)
+ return VisiblePosition(element(), 0, DOWNSTREAM);
+
+ SVGRootInlineBox* rootBox = textBox->svgRootInlineBox();
+ RenderObject* object = rootBox ? rootBox->object() : 0;
+
+ if (!object)
+ return VisiblePosition(element(), 0, DOWNSTREAM);
+
+ int offset = 0;
+
+ for (SVGInlineTextBox* box = textBox; box; box = static_cast<SVGInlineTextBox*>(box->nextTextBox())) {
+ if (box->svgCharacterHitsPosition(x + object->xPos(), y + object->yPos(), offset)) {
+ // If we're not at the end/start of the box, stop looking for other selected boxes.
+ if (box->direction() == LTR) {
+ if (offset <= (int) box->end() + 1)
+ break;
+ } else {
+ if (offset > (int) box->start())
+ break;
+ }
+ }
+ }
+
+ return VisiblePosition(element(), offset, DOWNSTREAM);
+}
+
+void RenderSVGInlineText::destroy()
+{
+ if (!documentBeingDestroyed()) {
+ setNeedsLayoutAndPrefWidthsRecalc();
+ repaint();
+ }
+ RenderText::destroy();
+}
+
+}
+
+#endif // ENABLE(SVG)