2 * This file is part of the DOM implementation for KDE.
4 * (C) 1999 Lars Knoll (knoll@kde.org)
5 * (C) 2000 Dirk Mueller (mueller@kde.org)
6 * Copyright (C) 2004 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., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, 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_flow.h"
33 #include <qptrvector.h>
35 #include "KWQKHTMLPart.h"
45 // Define a constant for soft hyphen's unicode value.
46 #define SOFT_HYPHEN 173
48 const int cNoTruncation = -1;
49 const int cFullTruncation = -2;
56 class InlineTextBox : public InlineRunBox
59 InlineTextBox(RenderObject* obj)
67 m_truncation = cNoTruncation;
70 InlineTextBox* nextTextBox() const { return static_cast<InlineTextBox*>(nextLineBox()); }
71 InlineTextBox* prevTextBox() const { return static_cast<InlineTextBox*>(prevLineBox()); }
73 uint start() const { return m_start; }
74 uint end() const { return m_len ? m_start+m_len-1 : m_start; }
75 uint len() const { return m_len; }
77 void offsetRun(int d) { m_start += d; }
79 void detach(RenderArena* arena);
81 QRect selectionRect(int absx, int absy, int startPos, int endPos);
82 bool isSelected(int startPos, int endPos) const;
83 void selectionStartEnd(int& sPos, int& ePos);
85 virtual void paint(RenderObject::PaintInfo& i, int tx, int ty);
86 virtual bool nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty);
88 RenderText* textObject();
90 virtual void deleteLine(RenderArena* arena);
91 virtual void extractLine();
92 virtual void attachLine();
94 virtual RenderObject::SelectionState selectionState();
96 virtual void clearTruncation() { m_truncation = cNoTruncation; }
97 virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool& foundBox);
99 // Overloaded new operator. Derived classes must override operator new
100 // in order to allocate out of the RenderArena.
101 void* operator new(size_t sz, RenderArena* renderArena) throw();
103 // Overridden to prevent the normal delete from being called.
104 void operator delete(void* ptr, size_t sz);
107 // The normal operator new is disallowed.
108 void* operator new(size_t sz) throw();
111 void setSpaceAdd(int add) { m_width -= m_toAdd; m_toAdd = add; m_width += m_toAdd; }
112 int spaceAdd() { return m_toAdd; }
114 virtual bool isInlineTextBox() { return true; }
115 virtual bool isText() const { return m_treatAsText; }
116 void setIsText(bool b) { m_treatAsText = b; }
118 void paintDecoration(QPainter* p, int _tx, int _ty, int decoration);
119 void paintSelection(QPainter* p, int tx, int ty, RenderStyle* style, const Font* font);
120 void paintMarkedTextBackground(QPainter* p, int tx, int ty, RenderStyle* style, const Font* font, int startPos, int endPos);
121 void paintMarker(QPainter* p, int _tx, int _ty, DOM::DocumentMarker marker);
122 void paintMarkedTextUnderline(QPainter *pt, int _tx, int _ty, KWQKHTMLPart::MarkedTextUnderline underline);
123 virtual long caretMinOffset() const;
124 virtual long caretMaxOffset() const;
125 virtual unsigned long caretMaxRenderedOffset() const;
127 int offsetForPosition(int _x, bool includePartialGlyphs = true);
130 * if this text run was rendered @ref _ty pixels below the upper edge
131 * of a view, would the @ref _y -coordinate be inside the vertical range
132 * of this object's representation?
134 bool checkVerticalPoint(int _y, int _ty, int _h);
137 unsigned short m_len;
139 int m_truncation; // Where to truncate when text overflow is applied. We use special constants to
140 // denote no truncation (the whole run paints) and full truncation (nothing paints at all).
143 bool m_treatAsText : 1; // Whether or not to treat a <br> as text for the purposes of line height.
144 int m_toAdd : 14; // for justified text
147 friend class RenderText;
150 class RenderText : public RenderObject
152 friend class InlineTextBox;
155 RenderText(DOM::NodeImpl* node, DOM::DOMStringImpl *_str);
156 virtual ~RenderText();
158 virtual bool isTextFragment() const;
159 virtual DOM::DOMStringImpl* originalString() const;
161 virtual const char *renderName() const { return "RenderText"; }
163 virtual void setStyle(RenderStyle *style);
165 void extractTextBox(InlineTextBox* textBox);
166 void attachTextBox(InlineTextBox* textBox);
167 void removeTextBox(InlineTextBox* textBox);
168 void deleteTextBoxes();
169 virtual void detach();
171 DOM::DOMString data() const { return str; }
172 DOM::DOMStringImpl *string() const { return str; }
174 virtual InlineBox* createInlineBox(bool,bool, bool isOnlyRun = false);
175 virtual void dirtyLineBoxes(bool fullLayout, bool isRootInlineBox = false);
177 virtual void paint(PaintInfo& i, int tx, int ty) { assert(false); }
178 virtual void layout() { assert(false); }
180 virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
181 HitTestAction hitTestAction) { assert(false); return false; }
183 virtual void absoluteRects(QValueList<QRect>& rects, int _tx, int _ty);
185 virtual VisiblePosition positionForCoordinates(int x, int y);
187 unsigned int length() const { return str->l; }
188 QChar *text() const { return str->s; }
189 unsigned int stringLength() const { return str->l; } // non virtual implementation of length()
190 virtual void position(InlineBox* box, int from, int len, bool reverse);
192 virtual unsigned int width(unsigned int from, unsigned int len, const Font *f) const;
193 virtual unsigned int width(unsigned int from, unsigned int len, bool firstLine = false) const;
194 virtual int width() const;
195 virtual int height() const;
197 // height of the contents (without paddings, margins and borders)
198 virtual short lineHeight( bool firstLine, bool isRootLineBox=false ) const;
199 virtual short baselinePosition( bool firstLine, bool isRootLineBox=false ) const;
202 virtual void calcMinMaxWidth();
203 virtual int minWidth() const { return m_minWidth; }
204 virtual int maxWidth() const { return m_maxWidth; }
205 virtual void trimmedMinMaxWidth(int& beginMinW, bool& beginWS,
206 int& endMinW, bool& endWS,
207 bool& hasBreakableChar, bool& hasBreak,
208 int& beginMaxW, int& endMaxW,
209 int& minW, int& maxW, bool& stripFrontSpaces);
211 bool containsOnlyWhitespace(unsigned int from, unsigned int len) const;
213 // returns the minimum x position of all runs relative to the parent.
217 virtual int xPos() const;
218 virtual int yPos() const;
220 virtual const QFont &font();
221 virtual short verticalPositionHint( bool firstLine ) const;
223 void setText(DOM::DOMStringImpl *text, bool force=false);
224 void setTextWithOffset(DOM::DOMStringImpl *text, uint offset, uint len, bool force=false);
226 virtual bool canBeSelectionLeaf() const { return true; }
227 virtual SelectionState selectionState() const {return m_selectionState;}
228 virtual void setSelectionState(SelectionState s);
229 virtual QRect selectionRect();
230 virtual QRect caretRect(int offset, EAffinity affinity, int *extraWidthToEndOfLine = 0);
231 void posOfChar(int ch, int &x, int &y);
233 virtual int marginLeft() const { return style()->marginLeft().minWidth(0); }
234 virtual int marginRight() const { return style()->marginRight().minWidth(0); }
236 virtual QRect getAbsoluteRepaintRect();
238 const QFontMetrics &metrics(bool firstLine) const;
239 const Font *htmlFont(bool firstLine) const;
241 DOM::TextImpl *element() const
242 { return static_cast<DOM::TextImpl*>(RenderObject::element()); }
244 InlineTextBox* firstTextBox() const { return m_firstTextBox; }
245 InlineTextBox* lastTextBox() const { return m_lastTextBox; }
247 virtual InlineBox *inlineBox(long offset, EAffinity affinity = UPSTREAM);
250 int widthFromCache(const Font *, int start, int len) const;
251 bool shouldUseMonospaceCache(const Font *) const;
253 bool allAscii() const;
256 virtual long caretMinOffset() const;
257 virtual long caretMaxOffset() const;
258 virtual unsigned long caretMaxRenderedOffset() const;
260 virtual long previousOffset (long current) const;
261 virtual long nextOffset (long current) const;
266 InlineTextBox * findNextInlineTextBox( int offset, int &pos ) const;
268 protected: // members
269 DOM::DOMStringImpl *str;
271 InlineTextBox* m_firstTextBox;
272 InlineTextBox* m_lastTextBox;
279 SelectionState m_selectionState : 3 ;
280 bool m_hasBreakableChar : 1; // Whether or not we can be broken into multiple lines.
281 bool m_hasBreak : 1; // Whether or not we have a hard break (e.g., <pre> with '\n').
282 bool m_hasBeginWS : 1; // Whether or not we begin with WS (only true if we aren't pre)
283 bool m_hasEndWS : 1; // Whether or not we end with WS (only true if we aren't pre)
285 bool m_linesDirty : 1; // This bit indicates that the text run has already dirtied specific
286 // line boxes, and this hint will enable layoutInlineChildren to avoid
287 // just dirtying everything when character data is modified (e.g., appended/inserted
292 mutable bool m_allAsciiChecked:1;
293 mutable bool m_allAscii:1;
294 int m_monospaceCharacterWidth;
298 // Used to represent a text substring of an element, e.g., for text runs that are split because of
299 // first letter and that must therefore have different styles (and positions in the render tree).
300 // We cache offsets so that text transformations can be applied in such a way that we can recover
301 // the original unaltered string from our corresponding DOM node.
302 class RenderTextFragment : public RenderText
305 RenderTextFragment(DOM::NodeImpl* _node, DOM::DOMStringImpl* _str,
306 int startOffset, int endOffset);
307 RenderTextFragment(DOM::NodeImpl* _node, DOM::DOMStringImpl* _str);
308 ~RenderTextFragment();
310 virtual bool isTextFragment() const;
312 uint start() const { return m_start; }
313 uint end() const { return m_end; }
315 DOM::DOMStringImpl* contentString() const { return m_generatedContentStr; }
316 virtual DOM::DOMStringImpl* originalString() const;
321 DOM::DOMStringImpl* m_generatedContentStr;