fix logic
[personal-kdelibs.git] / khtml / rendering / RenderSVGInlineText.cpp
blobeb9de3cda1546dbb7e0a41a328ed9cc8cdf6f842
1 /*
2 * This file is part of the WebKit project.
4 * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
5 * (C) 2006 Apple Computer Inc.
6 * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
25 #include "config.h"
26 #include "wtf/Platform.h"
28 #if ENABLE(SVG)
29 #include "RenderSVGInlineText.h"
31 #include "FloatConversion.h"
32 //#include "RenderBlock.h"
33 #include "render_block.h" // khtml
34 #include "RenderSVGRoot.h"
35 #include "SVGInlineTextBox.h"
36 #include "SVGRootInlineBox.h"
38 namespace WebCore {
39 using namespace khtml;
41 static inline bool isChildOfHiddenContainer(RenderObject* start)
43 while (start) {
44 if (start->isSVGHiddenContainer())
45 return true;
47 start = start->parent();
50 return false;
53 RenderSVGInlineText::RenderSVGInlineText(Node* n, DOMStringImpl* str)
54 : RenderText(n, str)
58 void RenderSVGInlineText::absoluteRects(Vector<IntRect>& rects, int, int, bool)
60 rects.append(computeAbsoluteRectForRange(0, stringLength()));
63 IntRect RenderSVGInlineText::selectionRect(bool)
65 ASSERT(!needsLayout());
67 IntRect rect;
68 if (selectionState() == SelectionNone)
69 return rect;
71 // Early exit if we're ie. a <text> within a <defs> section.
72 if (isChildOfHiddenContainer(this))
73 return rect;
75 // Now calculate startPos and endPos for painting selection.
76 // We include a selection while endPos > 0
77 int startPos, endPos;
78 if (selectionState() == SelectionInside) {
79 // We are fully selected.
80 startPos = 0;
81 endPos = stringLength();
82 } else {
83 selectionStartEnd(startPos, endPos);
84 if (selectionState() == SelectionStart)
85 endPos = stringLength();
86 else if (selectionState() == SelectionEnd)
87 startPos = 0;
90 if (startPos == endPos)
91 return rect;
93 return computeAbsoluteRectForRange(startPos, endPos);
96 IntRect RenderSVGInlineText::computeAbsoluteRectForRange(int startPos, int endPos)
98 IntRect rect;
100 RenderBlock* cb = containingBlock();
101 if (!cb || !cb->container())
102 return rect;
104 RenderSVGRoot* root = findSVGRootObject(parent());
105 if (!root)
106 return rect;
108 /*FIXME khtml for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
109 rect.unite(box->selectionRect(0, 0, startPos, endPos));*/
111 // Mimic RenderBox::computeAbsoluteRepaintRect() functionality. But only the subset needed for SVG and respecting SVG transformations.
112 int x, y;
113 cb->container()->absolutePosition(x, y);
115 // Remove HTML parent translation offsets here! These need to be retrieved from the RenderSVGRoot object.
116 // But do take the containingBlocks's container position into account, ie. SVG text in scrollable <div>.
117 AffineTransform htmlParentCtm = root->RenderContainer::absoluteTransform();
119 FloatRect fixedRect(narrowPrecisionToFloat(rect.x() + x - xPos() - htmlParentCtm.e()), narrowPrecisionToFloat(rect.y() + y - yPos() - htmlParentCtm.f()), rect.width(), rect.height());
120 return enclosingIntRect(absoluteTransform().mapRect(fixedRect));
123 InlineTextBox* RenderSVGInlineText::createInlineTextBox()
125 kDebug() << "allocate" << endl;
126 return new (renderArena()) SVGInlineTextBox(this);
129 /*IntRect RenderSVGInlineText::caretRect(int offset, EAffinity affinity, int* extraWidthToEndOfLine)
131 // SVG doesn't have any editable content where a caret rect would be needed
132 return IntRect();
135 /*VisiblePosition RenderSVGInlineText::positionForCoordinates(int x, int y)
137 SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(firstTextBox());
139 if (!textBox || textLength() == 0)
140 return VisiblePosition(element(), 0, DOWNSTREAM);
142 SVGRootInlineBox* rootBox = textBox->svgRootInlineBox();
143 RenderObject* object = rootBox ? rootBox->object() : 0;
145 if (!object)
146 return VisiblePosition(element(), 0, DOWNSTREAM);
148 int offset = 0;
150 for (SVGInlineTextBox* box = textBox; box; box = static_cast<SVGInlineTextBox*>(box->nextTextBox())) {
151 if (box->svgCharacterHitsPosition(x + object->xPos(), y + object->yPos(), offset)) {
152 // If we're not at the end/start of the box, stop looking for other selected boxes.
153 if (!box->m_reversed) {
154 if (offset <= (int) box->end() + 1)
155 break;
156 } else {
157 if (offset > (int) box->start())
158 break;
163 return VisiblePosition(element(), offset, DOWNSTREAM);
168 #endif // ENABLE(SVG)