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.
26 #include "wtf/Platform.h"
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"
39 using namespace khtml
;
41 static inline bool isChildOfHiddenContainer(RenderObject
* start
)
44 if (start
->isSVGHiddenContainer())
47 start
= start
->parent();
53 RenderSVGInlineText::RenderSVGInlineText(Node
* n
, DOMStringImpl
* 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());
68 if (selectionState() == SelectionNone
)
71 // Early exit if we're ie. a <text> within a <defs> section.
72 if (isChildOfHiddenContainer(this))
75 // Now calculate startPos and endPos for painting selection.
76 // We include a selection while endPos > 0
78 if (selectionState() == SelectionInside
) {
79 // We are fully selected.
81 endPos
= stringLength();
83 selectionStartEnd(startPos
, endPos
);
84 if (selectionState() == SelectionStart
)
85 endPos
= stringLength();
86 else if (selectionState() == SelectionEnd
)
90 if (startPos
== endPos
)
93 return computeAbsoluteRectForRange(startPos
, endPos
);
96 IntRect
RenderSVGInlineText::computeAbsoluteRectForRange(int startPos
, int endPos
)
100 RenderBlock
* cb
= containingBlock();
101 if (!cb
|| !cb
->container())
104 RenderSVGRoot
* root
= findSVGRootObject(parent());
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.
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
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;
146 return VisiblePosition(element(), 0, DOWNSTREAM);
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)
157 if (offset > (int) box->start())
163 return VisiblePosition(element(), offset, DOWNSTREAM);
168 #endif // ENABLE(SVG)