2 * This file is part of the DOM implementation for KDE.
4 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
5 * (C) 2000-2003 Dirk Mueller (mueller@kde.org)
6 * (C) 2003 Apple Computer, Inc.
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.
27 #include "dom/dom_string.h"
28 #include "xml/dom_stringimpl.h"
29 #include "xml/dom_textimpl.h"
30 #include "rendering/render_object.h"
31 #include "rendering/render_line.h"
33 #include <QtCore/QMutableVectorIterator>
39 // Define a constant for soft hyphen's unicode value.
40 #define SOFT_HYPHEN 173
42 const int cNoTruncation
= -1;
43 const int cFullTruncation
= -2;
54 class InlineTextBox
: public InlineRunBox
57 InlineTextBox(RenderObject
*obj
)
59 // ### necessary as some codepaths (<br>) do *not* initialize these (LS)
60 m_start(0), m_len(0), m_truncation(cNoTruncation
), m_reversed(false), m_toAdd(0)
64 uint
start() const { return m_start
; }
65 uint
end() const { return m_len
? m_start
+m_len
-1 : m_start
; }
66 uint
len() const { return m_len
; }
68 void detach(RenderArena
* renderArena
, bool noRemove
=false);
70 InlineTextBox
* nextTextBox() const { return static_cast<InlineTextBox
*>(nextLineBox()); }
71 InlineTextBox
* prevTextBox() const { return static_cast<InlineTextBox
*>(prevLineBox()); }
73 virtual void clearTruncation() { m_truncation
= cNoTruncation
; }
74 virtual int placeEllipsisBox(bool ltr
, int blockEdge
, int ellipsisWidth
, bool& foundBox
);
76 // Overloaded new operator. Derived classes must override operator new
77 // in order to allocate out of the RenderArena.
78 void* operator new(size_t sz
, RenderArena
* renderArena
) throw();
80 // Overridden to prevent the normal delete from being called.
81 void operator delete(void* ptr
, size_t sz
);
84 // The normal operator new is disallowed.
85 void* operator new(size_t sz
) throw();
88 void setSpaceAdd(int add
) { m_width
-= m_toAdd
; m_toAdd
= add
; m_width
+= m_toAdd
; }
89 int spaceAdd() { return m_toAdd
; }
91 virtual bool isInlineTextBox() const { return true; }
93 void paint(RenderObject::PaintInfo
& i
, int tx
, int ty
);
94 void paintDecoration(QPainter
*pt
, const Font
*f
, int _tx
, int _ty
, int decoration
);
95 void paintShadow(QPainter
*pt
, const Font
* f
, int _tx
, int _ty
, const ShadowData
*shadow
);
96 void paintSelection(const Font
*f
, RenderText
*text
, QPainter
*p
, RenderStyle
* style
, int tx
, int ty
, int startPos
, int endPos
, int deco
);
98 void selectionStartEnd(int& sPos
, int& ePos
);
99 RenderObject::SelectionState
selectionState();
101 // Return before, after (offset set to max), or inside the text, at @p offset
102 FindSelectionResult
checkSelectionPoint(int _x
, int _y
, int _tx
, int _ty
, int & offset
);
104 bool checkVerticalPoint(int _y
, int _ty
, int _h
, int height
)
105 { if((_ty
+ m_y
> _y
+ _h
) || (_ty
+ m_y
+ m_baseline
+ height
< _y
)) return false; return true; }
108 * determines the offset into the DOMString of the character the given
109 * coordinate points to.
110 * The returned offset is never out of range.
111 * @param _x given coordinate (relative to containing block)
112 * @param ax returns exact coordinate the offset corresponds to
113 * (relative to containing block)
114 * @return the offset (relative to the RenderText object, not to this run)
116 int offsetForPoint(int _x
, int &ax
) const;
119 * calculates the with of the specified chunk in this text box.
120 * @param pos zero-based position within the text box up to which
121 * the width is to be determined
122 * @return the width in pixels
124 int widthFromStart(int pos
) const;
126 virtual long caretMinOffset() const;
127 virtual long caretMaxOffset() const;
128 virtual unsigned long caretMaxRenderedOffset() const;
130 /** returns the associated render text
132 const RenderText
*renderText() const;
133 RenderText
*renderText();
135 virtual void extractLine();
136 virtual void deleteLine(RenderArena
* arena
);
137 virtual void attachLine();
141 unsigned short m_len
;
143 int m_truncation
; // Where to truncate when text overflow is applied.
144 // We use special constants to denote no truncation (the whole run paints)
145 // and full truncation (nothing paints at all).
148 unsigned m_toAdd
: 14; // for justified text
150 friend class RenderText
;
153 class RenderText
: public RenderObject
155 friend class InlineTextBox
;
158 RenderText(DOM::NodeImpl
* node
, DOM::DOMStringImpl
*_str
);
159 virtual ~RenderText();
161 virtual bool isTextFragment() const;
162 virtual DOM::DOMStringImpl
* originalString() const;
164 virtual const char *renderName() const { return "RenderText"; }
166 virtual void setStyle(RenderStyle
*style
);
168 virtual void detach( );
170 virtual void deleteInlineBoxes(RenderArena
* arena
=0);
171 virtual void dirtyInlineBoxes(bool fullLayout
, bool);
172 virtual void removeInlineBox(InlineBox
* _box
);
174 DOM::DOMString
data() const { return str
; }
175 DOM::DOMStringImpl
*string() const { return str
; }
177 virtual InlineBox
* createInlineBox(bool, bool);
179 virtual void layout() {assert(false);}
181 virtual bool nodeAtPoint(NodeInfo
& info
, int x
, int y
, int tx
, int ty
, HitTestAction hitTestAction
, bool inBox
);
183 virtual DOM::Position
positionForCoordinates(int _x
, int _y
);
185 // Return before, after (offset set to max), or inside the text, at @p offset
186 virtual FindSelectionResult
checkSelectionPoint( int _x
, int _y
, int _tx
, int _ty
,
187 DOM::NodeImpl
*& node
, int & offset
,
190 unsigned int length() const { if (str
) return str
->l
; else return 0; }
191 QChar
*text() const { if (str
) return str
->s
; else return 0; }
192 unsigned int stringLength() const { return str
->l
; } // non virtual implementation of length()
193 virtual void position(InlineBox
* box
, int from
, int len
, bool reverse
);
195 virtual unsigned int width(unsigned int from
, unsigned int len
, const Font
*f
) const;
196 virtual unsigned int width(unsigned int from
, unsigned int len
, bool firstLine
= false) const;
197 virtual short width() const;
198 virtual int height() const;
200 // height of the contents (without paddings, margins and borders)
201 virtual short lineHeight( bool firstLine
) const;
202 virtual short baselinePosition( bool firstLine
) const;
205 virtual void calcMinMaxWidth();
206 virtual short minWidth() const { return m_minWidth
; }
207 virtual int maxWidth() const { return m_maxWidth
; }
209 void trimmedMinMaxWidth(short& beginMinW
, bool& beginWS
,
210 short& endMinW
, bool& endWS
,
211 bool& hasBreakableChar
, bool& hasBreak
,
212 short& beginMaxW
, short& endMaxW
,
213 short& minW
, short& maxW
, bool& stripFrontSpaces
);
215 bool containsOnlyWhitespace(unsigned int from
, unsigned int len
) const;
217 ushort
startMin() const { return m_startMin
; }
218 ushort
endMin() const { return m_endMin
; }
220 // returns the minimum x position of all runs relative to the parent.
224 virtual int inlineXPos() const;
225 virtual int inlineYPos() const;
227 bool hasReturn() const { return m_hasReturn
; }
229 virtual const QFont
&font();
230 virtual short verticalPositionHint( bool firstLine
) const;
232 bool isFixedWidthFont() const;
234 void setText(DOM::DOMStringImpl
*text
, bool force
=false);
236 virtual SelectionState
selectionState() const {return KDE_CAST_BF_ENUM(SelectionState
, m_selectionState
);}
237 virtual void setSelectionState(SelectionState s
) {m_selectionState
= s
; }
238 virtual void caretPos(int offset
, int flags
, int &_x
, int &_y
, int &width
, int &height
) const;
239 virtual bool absolutePosition(int &/*xPos*/, int &/*yPos*/, bool f
= false) const;
240 bool posOfChar(int ch
, int &x
, int &y
) const;
241 virtual bool isPointInsideSelection(int x
, int y
, const DOM::Selection
&) const;
243 virtual short marginLeft() const { return style()->marginLeft().minWidth(0); }
244 virtual short marginRight() const { return style()->marginRight().minWidth(0); }
246 virtual void repaint(Priority p
=NormalPriority
);
248 InlineTextBox
* firstTextBox() const { return m_firstTextBox
; }
249 InlineTextBox
* lastTextBox() const { return m_lastTextBox
; }
251 bool hasBreakableChar() const { return m_hasBreakableChar
; }
252 bool isSimpleText() const { return m_isSimpleText
; }
253 const QFontMetrics
&metrics(bool firstLine
) const;
254 const Font
*htmlFont(bool firstLine
) const;
256 DOM::TextImpl
*element() const
257 { return static_cast<DOM::TextImpl
*>(RenderObject::element()); }
259 virtual InlineBox
*inlineBox(long offset
);
261 void removeTextBox(InlineTextBox
* box
);
262 void attachTextBox(InlineTextBox
* box
);
263 void extractTextBox(InlineTextBox
* box
);
266 virtual void dump(QTextStream
&stream
, const QString
&ind
) const;
269 virtual long caretMinOffset() const;
270 virtual long caretMaxOffset() const;
271 virtual unsigned long caretMaxRenderedOffset() const;
273 /** Find the text box that includes the character at @p offset
274 * and return pos, which is the position of the char in the run.
275 * @param offset zero-based offset into DOM string
276 * @param pos returns relative position within text box
277 * @param checkFirstLetter passing @p true will also regard :first-letter
278 * boxes, if available.
279 * @return the text box, or 0 if no match has been found
281 const InlineTextBox
* findInlineTextBox( int offset
, int &pos
,
282 bool checkFirstLetter
= false ) const;
284 protected: // members
285 InlineTextBox
* m_firstTextBox
;
286 InlineTextBox
* m_lastTextBox
;
288 DOM::DOMStringImpl
*str
; //
293 short m_beginMinWidth
;
296 KDE_BF_ENUM(SelectionState
) m_selectionState
: 3 ;
297 bool m_hasReturn
: 1;
298 bool m_hasBreakableChar
: 1;
300 bool m_hasBeginWS
: 1;
302 bool m_isSimpleText
: 1;
304 ushort m_startMin
: 8;
308 inline const RenderText
* InlineTextBox::renderText() const
309 { return static_cast<RenderText
*>( object() ); }
311 inline RenderText
* InlineTextBox::renderText()
312 { return static_cast<RenderText
*>( object() ); }
314 // Used to represent a text substring of an element, e.g., for text runs that are split because of
315 // first letter and that must therefore have different styles (and positions in the render tree).
316 // We cache offsets so that text transformations can be applied in such a way that we can recover
317 // the original unaltered string from our corresponding DOM node.
318 class RenderTextFragment
: public RenderText
321 RenderTextFragment(DOM::NodeImpl
* _node
, DOM::DOMStringImpl
* _str
,
322 int startOffset
, int endOffset
);
323 RenderTextFragment(DOM::NodeImpl
* _node
, DOM::DOMStringImpl
* _str
);
324 ~RenderTextFragment();
326 virtual bool isTextFragment() const;
327 virtual const char *renderName() const { return "RenderTextFragment"; }
329 uint
start() const { return m_start
; }
330 uint
end() const { return m_end
; }
332 DOM::DOMStringImpl
* contentString() const { return m_generatedContentStr
; }
333 virtual DOM::DOMStringImpl
* originalString() const;
338 DOM::DOMStringImpl
* m_generatedContentStr
;