Get started with patching up the Qt GUI docs
[profile/ivi/qtbase.git] / src / gui / text / qtextobject.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qtextobject.h"
43 #include "qtextobject_p.h"
44 #include "qtextdocument.h"
45 #include "qtextformat_p.h"
46 #include "qtextdocument_p.h"
47 #include "qtextcursor.h"
48 #include "qtextlist.h"
49 #include "qabstracttextdocumentlayout.h"
50 #include "qtextengine_p.h"
51 #include "qdebug.h"
52
53 QT_BEGIN_NAMESPACE
54
55 // ### DOC: We ought to explain the CONCEPT of objectIndexes if
56 // relevant to the public API
57 /*!
58     \class QTextObject
59     \reentrant
60
61     \brief The QTextObject class is a base class for different kinds
62     of objects that can group parts of a QTextDocument together.
63     \inmodule QtGui
64
65     \ingroup richtext-processing
66
67     The common grouping text objects are lists (QTextList), frames
68     (QTextFrame), and tables (QTextTable). A text object has an
69     associated format() and document().
70
71     There are essentially two kinds of text objects: those that are used
72     with blocks (block formats), and those that are used with characters
73     (character formats). The first kind are derived from QTextBlockGroup,
74     and the second kind from QTextFrame.
75
76     You rarely need to use this class directly. When creating custom text
77     objects, you will also need to reimplement QTextDocument::createObject()
78     which acts as a factory method for creating text objects.
79
80     \sa QTextDocument, {Text Object Example}
81 */
82
83 /*!
84     \fn QTextObject::QTextObject(QTextDocument *document)
85
86     Creates a new QTextObject for the given \a document.
87
88     \warning This function should never be called directly, but only
89     from QTextDocument::createObject().
90 */
91 QTextObject::QTextObject(QTextDocument *doc)
92     : QObject(*new QTextObjectPrivate(doc), doc)
93 {
94 }
95
96 /*!
97   \fn QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *document)
98
99   \internal
100 */
101 QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *doc)
102     : QObject(p, doc)
103 {
104 }
105
106 /*!
107     Destroys the text object.
108
109     \warning Text objects are owned by the document, so you should
110     never destroy them yourself.
111 */
112 QTextObject::~QTextObject()
113 {
114 }
115
116 /*!
117     Returns the text object's format.
118
119     \sa setFormat(), document()
120 */
121 QTextFormat QTextObject::format() const
122 {
123     Q_D(const QTextObject);
124     return d->pieceTable->formatCollection()->objectFormat(d->objectIndex);
125 }
126
127 /*!
128     Returns the index of the object's format in the document's internal
129     list of formats.
130
131     \sa QTextDocument::allFormats()
132 */
133 int QTextObject::formatIndex() const
134 {
135     Q_D(const QTextObject);
136     return d->pieceTable->formatCollection()->objectFormatIndex(d->objectIndex);
137 }
138
139
140 /*!
141     Sets the text object's \a format.
142
143     \sa format()
144 */
145 void QTextObject::setFormat(const QTextFormat &format)
146 {
147     Q_D(QTextObject);
148     int idx = d->pieceTable->formatCollection()->indexForFormat(format);
149     d->pieceTable->changeObjectFormat(this, idx);
150 }
151
152 /*!
153     Returns the object index of this object. This can be used together with
154     QTextFormat::setObjectIndex().
155 */
156 int QTextObject::objectIndex() const
157 {
158     Q_D(const QTextObject);
159     return d->objectIndex;
160 }
161
162 /*!
163     Returns the document this object belongs to.
164
165     \sa format()
166 */
167 QTextDocument *QTextObject::document() const
168 {
169     return static_cast<QTextDocument *>(parent());
170 }
171
172 /*!
173   \internal
174 */
175 QTextDocumentPrivate *QTextObject::docHandle() const
176 {
177     return static_cast<const QTextDocument *>(parent())->docHandle();
178 }
179
180 /*!
181     \class QTextBlockGroup
182     \reentrant
183
184     \brief The QTextBlockGroup class provides a container for text blocks within
185     a QTextDocument.
186     \inmodule QtGui
187
188     \ingroup richtext-processing
189
190     Block groups can be used to organize blocks of text within a document.
191     They maintain an up-to-date list of the text blocks that belong to
192     them, even when text blocks are being edited.
193
194     Each group has a parent document which is specified when the group is
195     constructed.
196
197     Text blocks can be inserted into a group with blockInserted(), and removed
198     with blockRemoved(). If a block's format is changed, blockFormatChanged()
199     is called.
200
201     The list of blocks in the group is returned by blockList(). Note that the
202     blocks in the list are not necessarily adjacent elements in the document;
203     for example, the top-level items in a multi-level list will be separated
204     by the items in lower levels of the list.
205
206     \sa QTextBlock, QTextDocument
207 */
208
209 void QTextBlockGroupPrivate::markBlocksDirty()
210 {
211     for (int i = 0; i < blocks.count(); ++i) {
212         const QTextBlock &block = blocks.at(i);
213         pieceTable->documentChange(block.position(), block.length());
214     }
215 }
216
217 /*!
218     \fn QTextBlockGroup::QTextBlockGroup(QTextDocument *document)
219
220     Creates a new new block group for the given \a document.
221
222     \warning This function should only be called from
223     QTextDocument::createObject().
224 */
225 QTextBlockGroup::QTextBlockGroup(QTextDocument *doc)
226     : QTextObject(*new QTextBlockGroupPrivate(doc), doc)
227 {
228 }
229
230 /*!
231   \internal
232 */
233 QTextBlockGroup::QTextBlockGroup(QTextBlockGroupPrivate &p, QTextDocument *doc)
234     : QTextObject(p, doc)
235 {
236 }
237
238 /*!
239     Destroys this block group; the blocks are not deleted, they simply
240     don't belong to this block anymore.
241 */
242 QTextBlockGroup::~QTextBlockGroup()
243 {
244 }
245
246 // ### DOC: Shouldn't this be insertBlock()?
247 /*!
248     Appends the given \a block to the end of the group.
249
250     \warning If you reimplement this function you must call the base
251     class implementation.
252 */
253 void QTextBlockGroup::blockInserted(const QTextBlock &block)
254 {
255     Q_D(QTextBlockGroup);
256     QTextBlockGroupPrivate::BlockList::Iterator it = qLowerBound(d->blocks.begin(), d->blocks.end(), block);
257     d->blocks.insert(it, block);
258     d->markBlocksDirty();
259 }
260
261 // ### DOC: Shouldn't this be removeBlock()?
262 /*!
263     Removes the given \a block from the group; the block itself is not
264     deleted, it simply isn't a member of this group anymore.
265 */
266 void QTextBlockGroup::blockRemoved(const QTextBlock &block)
267 {
268     Q_D(QTextBlockGroup);
269     d->blocks.removeAll(block);
270     d->markBlocksDirty();
271     if (d->blocks.isEmpty()) {
272         document()->docHandle()->deleteObject(this);
273         return;
274     }
275 }
276
277 /*!
278     This function is called whenever the specified \a block of text is changed.
279     The text block is a member of this group.
280
281     The base class implementation does nothing.
282 */
283 void QTextBlockGroup::blockFormatChanged(const QTextBlock &)
284 {
285 }
286
287 /*!
288     Returns a (possibly empty) list of all the blocks that are part of
289     the block group.
290 */
291 QList<QTextBlock> QTextBlockGroup::blockList() const
292 {
293     Q_D(const QTextBlockGroup);
294     return d->blocks;
295 }
296
297
298
299 QTextFrameLayoutData::~QTextFrameLayoutData()
300 {
301 }
302
303
304 /*!
305     \class QTextFrame
306     \reentrant
307
308     \brief The QTextFrame class represents a frame in a QTextDocument.
309     \inmodule QtGui
310
311     \ingroup richtext-processing
312
313     Text frames provide structure for the text in a document. They are used
314     as generic containers for other document elements.
315     Frames are usually created by using QTextCursor::insertFrame().
316
317     \omit
318     Each frame in a document consists of a frame start character,
319     QChar(0xFDD0), followed by the frame's contents, followed by a
320     frame end character, QChar(0xFDD1). The character formats of the
321     start and end character contain a reference to the frame object's
322     objectIndex.
323     \endomit
324
325     Frames can be used to create hierarchical structures in rich text documents.
326     Each document has a root frame (QTextDocument::rootFrame()), and each frame
327     beneath the root frame has a parent frame and a (possibly empty) list of
328     child frames. The parent frame can be found with parentFrame(), and the
329     childFrames() function provides a list of child frames.
330
331     Each frame contains at least one text block to enable text cursors to
332     insert new document elements within. As a result, the QTextFrame::iterator
333     class is used to traverse both the blocks and child frames within a given
334     frame. The first and last child elements in the frame can be found with
335     begin() and end().
336
337     A frame also has a format (specified using QTextFrameFormat) which can be set
338     with setFormat() and read with format().
339
340     Text cursors can be obtained that point to the first and last valid cursor
341     positions within a frame; use the firstCursorPosition() and
342     lastCursorPosition() functions for this. The frame's extent in the
343     document can be found with firstPosition() and lastPosition().
344
345     You can iterate over a frame's contents using the
346     QTextFrame::iterator class: this provides read-only access to its
347     internal list of text blocks and child frames.
348
349     \sa QTextCursor, QTextDocument
350 */
351
352 /*!
353     \typedef QTextFrame::Iterator
354
355     Qt-style synonym for QTextFrame::iterator.
356 */
357
358 /*!
359     \fn QTextFrame *QTextFrame::iterator::parentFrame() const
360
361     Returns the parent frame of the current frame.
362
363     \sa currentFrame(), QTextFrame::parentFrame()
364 */
365
366 /*!
367     \fn bool QTextFrame::iterator::operator==(const iterator &other) const
368
369     Retuns true if the iterator is the same as the \a other iterator;
370     otherwise returns false.
371 */
372
373 /*!
374     \fn bool QTextFrame::iterator::operator!=(const iterator &other) const
375
376     Retuns true if the iterator is different from the \a other iterator;
377     otherwise returns false.
378 */
379
380 /*!
381     \fn QTextFrame::iterator QTextFrame::iterator::operator++(int)
382
383     The postfix ++ operator (\c{i++}) advances the iterator to the
384     next item in the text frame, and returns an iterator to the old item.
385 */
386
387 /*!
388     \fn QTextFrame::iterator QTextFrame::iterator::operator--(int)
389
390     The postfix -- operator (\c{i--}) makes the preceding item in the
391     current frame, and returns an iterator to the old item.
392 */
393
394 /*!
395     \fn void QTextFrame::setFrameFormat(const QTextFrameFormat &format)
396
397     Sets the frame's \a format.
398
399     \sa frameFormat()
400 */
401
402 /*!
403     \fn QTextFrameFormat QTextFrame::frameFormat() const
404
405     Returns the frame's format.
406
407     \sa setFrameFormat()
408 */
409
410 /*!
411     \fn QTextFrame::QTextFrame(QTextDocument *document)
412
413     Creates a new empty frame for the text \a document.
414 */
415 QTextFrame::QTextFrame(QTextDocument *doc)
416     : QTextObject(*new QTextFramePrivate(doc), doc)
417 {
418 }
419
420 // ### DOC: What does this do to child frames?
421 /*!
422     Destroys the frame, and removes it from the document's layout.
423 */
424 QTextFrame::~QTextFrame()
425 {
426     Q_D(QTextFrame);
427     delete d->layoutData;
428 }
429
430 /*!
431     \internal
432 */
433 QTextFrame::QTextFrame(QTextFramePrivate &p, QTextDocument *doc)
434     : QTextObject(p, doc)
435 {
436 }
437
438 /*!
439     Returns a (possibly empty) list of the frame's child frames.
440
441     \sa parentFrame()
442 */
443 QList<QTextFrame *> QTextFrame::childFrames() const
444 {
445     Q_D(const QTextFrame);
446     return d->childFrames;
447 }
448
449 /*!
450     Returns the frame's parent frame. If the frame is the root frame of a
451     document, this will return 0.
452
453     \sa childFrames(), QTextDocument::rootFrame()
454 */
455 QTextFrame *QTextFrame::parentFrame() const
456 {
457     Q_D(const QTextFrame);
458     return d->parentFrame;
459 }
460
461
462 /*!
463     Returns the first cursor position inside the frame.
464
465     \sa lastCursorPosition(), firstPosition(), lastPosition()
466 */
467 QTextCursor QTextFrame::firstCursorPosition() const
468 {
469     Q_D(const QTextFrame);
470     return QTextCursor(d->pieceTable, firstPosition());
471 }
472
473 /*!
474     Returns the last cursor position inside the frame.
475
476     \sa firstCursorPosition(), firstPosition(), lastPosition()
477 */
478 QTextCursor QTextFrame::lastCursorPosition() const
479 {
480     Q_D(const QTextFrame);
481     return QTextCursor(d->pieceTable, lastPosition());
482 }
483
484 /*!
485     Returns the first document position inside the frame.
486
487     \sa lastPosition(), firstCursorPosition(), lastCursorPosition()
488 */
489 int QTextFrame::firstPosition() const
490 {
491     Q_D(const QTextFrame);
492     if (!d->fragment_start)
493         return 0;
494     return d->pieceTable->fragmentMap().position(d->fragment_start) + 1;
495 }
496
497 /*!
498     Returns the last document position inside the frame.
499
500     \sa firstPosition(), firstCursorPosition(), lastCursorPosition()
501 */
502 int QTextFrame::lastPosition() const
503 {
504     Q_D(const QTextFrame);
505     if (!d->fragment_end)
506         return d->pieceTable->length() - 1;
507     return d->pieceTable->fragmentMap().position(d->fragment_end);
508 }
509
510 /*!
511   \internal
512 */
513 QTextFrameLayoutData *QTextFrame::layoutData() const
514 {
515     Q_D(const QTextFrame);
516     return d->layoutData;
517 }
518
519 /*!
520   \internal
521 */
522 void QTextFrame::setLayoutData(QTextFrameLayoutData *data)
523 {
524     Q_D(QTextFrame);
525     delete d->layoutData;
526     d->layoutData = data;
527 }
528
529
530
531 void QTextFramePrivate::fragmentAdded(QChar type, uint fragment)
532 {
533     if (type == QTextBeginningOfFrame) {
534         Q_ASSERT(!fragment_start);
535         fragment_start = fragment;
536     } else if (type == QTextEndOfFrame) {
537         Q_ASSERT(!fragment_end);
538         fragment_end = fragment;
539     } else if (type == QChar::ObjectReplacementCharacter) {
540         Q_ASSERT(!fragment_start);
541         Q_ASSERT(!fragment_end);
542         fragment_start = fragment;
543         fragment_end = fragment;
544     } else {
545         Q_ASSERT(false);
546     }
547 }
548
549 void QTextFramePrivate::fragmentRemoved(QChar type, uint fragment)
550 {
551     Q_UNUSED(fragment); // --release warning
552     if (type == QTextBeginningOfFrame) {
553         Q_ASSERT(fragment_start == fragment);
554         fragment_start = 0;
555     } else if (type == QTextEndOfFrame) {
556         Q_ASSERT(fragment_end == fragment);
557         fragment_end = 0;
558     } else if (type == QChar::ObjectReplacementCharacter) {
559         Q_ASSERT(fragment_start == fragment);
560         Q_ASSERT(fragment_end == fragment);
561         fragment_start = 0;
562         fragment_end = 0;
563     } else {
564         Q_ASSERT(false);
565     }
566     remove_me();
567 }
568
569
570 void QTextFramePrivate::remove_me()
571 {
572     Q_Q(QTextFrame);
573     if (fragment_start == 0 && fragment_end == 0
574         && !parentFrame) {
575         q->document()->docHandle()->deleteObject(q);
576         return;
577     }
578
579     if (!parentFrame)
580         return;
581
582     int index = parentFrame->d_func()->childFrames.indexOf(q);
583
584     // iterator over all children and move them to the parent
585     for (int i = 0; i < childFrames.size(); ++i) {
586         QTextFrame *c = childFrames.at(i);
587         parentFrame->d_func()->childFrames.insert(index, c);
588         c->d_func()->parentFrame = parentFrame;
589         ++index;
590     }
591     Q_ASSERT(parentFrame->d_func()->childFrames.at(index) == q);
592     parentFrame->d_func()->childFrames.removeAt(index);
593
594     childFrames.clear();
595     parentFrame = 0;
596 }
597
598 /*!
599     \class QTextFrame::iterator
600     \reentrant
601
602     \brief The iterator class provides an iterator for reading
603     the contents of a QTextFrame.
604
605     \inmodule QtGui
606     \ingroup richtext-processing
607
608     A frame consists of an arbitrary sequence of \l{QTextBlock}s and
609     child \l{QTextFrame}s. This class provides a way to iterate over the
610     child objects of a frame, and read their contents. It does not provide
611     a way to modify the contents of the frame.
612
613 */
614
615 /*!
616     \fn bool QTextFrame::iterator::atEnd() const
617
618     Returns true if the current item is the last item in the text frame.
619 */
620
621 /*!
622     Returns an iterator pointing to the first document element inside the frame.
623     Please see the document \l{STL-style-Iterators} for more information.
624
625     \sa end()
626 */
627 QTextFrame::iterator QTextFrame::begin() const
628 {
629     const QTextDocumentPrivate *priv = docHandle();
630     int b = priv->blockMap().findNode(firstPosition());
631     int e = priv->blockMap().findNode(lastPosition()+1);
632     return iterator(const_cast<QTextFrame *>(this), b, b, e);
633 }
634
635 /*!
636     Returns an iterator pointing to the position past the last document element inside the frame.
637     Please see the document \l{STL-Style Iterators} for more information.    
638     \sa begin()
639 */
640 QTextFrame::iterator QTextFrame::end() const
641 {
642     const QTextDocumentPrivate *priv = docHandle();
643     int b = priv->blockMap().findNode(firstPosition());
644     int e = priv->blockMap().findNode(lastPosition()+1);
645     return iterator(const_cast<QTextFrame *>(this), e, b, e);
646 }
647
648 /*!
649     Constructs an invalid iterator.
650 */
651 QTextFrame::iterator::iterator()
652 {
653     f = 0;
654     b = 0;
655     e = 0;
656     cf = 0;
657     cb = 0;
658 }
659
660 /*!
661   \internal
662 */
663 QTextFrame::iterator::iterator(QTextFrame *frame, int block, int begin, int end)
664 {
665     f = frame;
666     b = begin;
667     e = end;
668     cf = 0;
669     cb = block;
670 }
671
672 /*!
673     Copy constructor. Constructs a copy of the \a other iterator.
674 */
675 QTextFrame::iterator::iterator(const iterator &other)
676 {
677     f = other.f;
678     b = other.b;
679     e = other.e;
680     cf = other.cf;
681     cb = other.cb;
682 }
683
684 /*!
685     Assigns \a other to this iterator and returns a reference to
686     this iterator.
687 */
688 QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other)
689 {
690     f = other.f;
691     b = other.b;
692     e = other.e;
693     cf = other.cf;
694     cb = other.cb;
695     return *this;
696 }
697
698 /*!
699     Returns the current frame pointed to by the iterator, or 0 if the
700     iterator currently points to a block.
701
702     \sa currentBlock()
703 */
704 QTextFrame *QTextFrame::iterator::currentFrame() const
705 {
706     return cf;
707 }
708
709 /*!
710     Returns the current block the iterator points to. If the iterator
711     points to a child frame, the returned block is invalid.
712
713     \sa currentFrame()
714 */
715 QTextBlock QTextFrame::iterator::currentBlock() const
716 {
717     if (!f)
718         return QTextBlock();
719     return QTextBlock(f->docHandle(), cb);
720 }
721
722 /*!
723     Moves the iterator to the next frame or block.
724
725     \sa currentBlock(), currentFrame()
726 */
727 QTextFrame::iterator &QTextFrame::iterator::operator++()
728 {
729     const QTextDocumentPrivate *priv = f->docHandle();
730     const QTextDocumentPrivate::BlockMap &map = priv->blockMap();
731     if (cf) {
732         int end = cf->lastPosition() + 1;
733         cb = map.findNode(end);
734         cf = 0;
735     } else if (cb) {
736         cb = map.next(cb);
737         if (cb == e)
738             return *this;
739
740         if (!f->d_func()->childFrames.isEmpty()) {
741             int pos = map.position(cb);
742             // check if we entered a frame
743             QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1);
744             if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
745                 QTextFrame *nf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format));
746                 if (nf) {
747                     if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame && nf != f) {
748                         cf = nf;
749                         cb = 0;
750                     } else {
751                         Q_ASSERT(priv->buffer().at(frag->stringPosition) != QTextEndOfFrame);
752                     }
753                 }
754             }
755         }
756     }
757     return *this;
758 }
759
760 /*!
761     Moves the iterator to the previous frame or block.
762
763     \sa currentBlock(), currentFrame()
764 */
765 QTextFrame::iterator &QTextFrame::iterator::operator--()
766 {
767     const QTextDocumentPrivate *priv = f->docHandle();
768     const QTextDocumentPrivate::BlockMap &map = priv->blockMap();
769     if (cf) {
770         int start = cf->firstPosition() - 1;
771         cb = map.findNode(start);
772         cf = 0;
773     } else {
774         if (cb == b)
775             goto end;
776         if (cb != e) {
777             int pos = map.position(cb);
778             // check if we have to enter a frame
779             QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1);
780             if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
781                 QTextFrame *pf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format));
782                 if (pf) {
783                     if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame) {
784                         Q_ASSERT(pf == f);
785                     } else if (priv->buffer().at(frag->stringPosition) == QTextEndOfFrame) {
786                         Q_ASSERT(pf != f);
787                         cf = pf;
788                         cb = 0;
789                         goto end;
790                     }
791                 }
792             }
793         }
794         cb = map.previous(cb);
795     }
796  end:
797     return *this;
798 }
799
800 /*!
801     \class QTextBlockUserData
802     \reentrant
803
804     \brief The QTextBlockUserData class is used to associate custom data with blocks of text.
805     \inmodule QtGui
806     \since 4.1
807
808     \ingroup richtext-processing
809
810     QTextBlockUserData provides an abstract interface for container classes that are used
811     to associate application-specific user data with text blocks in a QTextDocument.
812
813     Generally, subclasses of this class provide functions to allow data to be stored
814     and retrieved, and instances are attached to blocks of text using
815     QTextBlock::setUserData(). This makes it possible to store additional data per text
816     block in a way that can be retrieved safely by the application.
817
818     Each subclass should provide a reimplementation of the destructor to ensure that any
819     private data is automatically cleaned up when user data objects are deleted.
820
821     \sa QTextBlock
822 */
823
824 /*!
825     Destroys the user data.
826 */
827 QTextBlockUserData::~QTextBlockUserData()
828 {
829 }
830
831 /*!
832     \class QTextBlock
833     \reentrant
834
835     \brief The QTextBlock class provides a container for text fragments in a
836     QTextDocument.
837     \inmodule QtGui
838
839     \ingroup richtext-processing
840
841     A text block encapsulates a block or paragraph of text in a QTextDocument.
842     QTextBlock provides read-only access to the block/paragraph structure of
843     QTextDocuments. It is mainly of use if you want to implement your own
844     layouts for the visual representation of a QTextDocument, or if you want to
845     iterate over a document and write out the contents in your own custom
846     format.
847
848     Text blocks are created by their parent documents. If you need to create
849     a new text block, or modify the contents of a document while examining its
850     contents, use the cursor-based interface provided by QTextCursor instead.
851
852     Each text block is located at a specific position() in a document().
853     The contents of the block can be obtained by using the text() function.
854     The length() function determines the block's size within the document
855     (including formatting characters).
856     The visual properties of the block are determined by its text layout(),
857     its charFormat(), and its blockFormat().
858
859     The next() and previous() functions enable iteration over consecutive
860     valid blocks in a document under the condition that the document is not
861     modified by other means during the iteration process. Note that, although
862     blocks are returned in sequence, adjacent blocks may come from different
863     places in the document structure. The validity of a block can be determined
864     by calling isValid().
865
866     QTextBlock provides comparison operators to make it easier to work with
867     blocks: \l operator==() compares two block for equality, \l operator!=()
868     compares two blocks for inequality, and \l operator<() determines whether
869     a block precedes another in the same document.
870
871     \img qtextblock-sequence.png
872
873     \sa QTextBlockFormat, QTextCharFormat, QTextFragment
874  */
875
876 /*!
877     \fn QTextBlock::QTextBlock(QTextDocumentPrivate *priv, int b)
878
879     \internal
880 */
881
882 /*!
883     \fn QTextBlock::QTextBlock()
884
885     \internal
886 */
887
888 /*!
889     \fn QTextBlock::QTextBlock(const QTextBlock &other)
890
891     Copies the \a other text block's attributes to this text block.
892 */
893
894 /*!
895     \fn bool QTextBlock::isValid() const
896
897     Returns true if this text block is valid; otherwise returns false.
898 */
899
900 bool QTextBlock::isValid() const
901 {
902     return p != 0 && p->blockMap().isValid(n);
903 }
904
905 /*!
906     \fn QTextBlock &QTextBlock::operator=(const QTextBlock &other)
907
908     Assigns the \a other text block to this text block.
909 */
910
911 /*!
912     \fn bool QTextBlock::operator==(const QTextBlock &other) const
913
914     Returns true if this text block is the same as the \a other text
915     block.
916 */
917
918 /*!
919     \fn bool QTextBlock::operator!=(const QTextBlock &other) const
920
921     Returns true if this text block is different from the \a other
922     text block.
923 */
924
925 /*!
926     \fn bool QTextBlock::operator<(const QTextBlock &other) const
927
928     Returns true if this text block occurs before the \a other text
929     block in the document.
930 */
931
932 /*!
933     \class QTextBlock::iterator
934     \reentrant
935
936     \brief The QTextBlock::iterator class provides an iterator for reading
937     the contents of a QTextBlock.
938     \inmodule QtGui
939
940     \ingroup richtext-processing
941
942     A block consists of a sequence of text fragments. This class provides
943     a way to iterate over these, and read their contents. It does not provide
944     a way to modify the internal structure or contents of the block.
945
946     An iterator can be constructed and used to access the fragments within
947     a text block in the following way:
948
949     \snippet textblock-fragments/xmlwriter.cpp 4
950     \snippet textblock-fragments/xmlwriter.cpp 7
951
952     \sa QTextFragment
953 */
954
955 /*!
956     \typedef QTextBlock::Iterator
957
958     Qt-style synonym for QTextBlock::iterator.
959 */
960
961 /*!
962     \fn QTextBlock::iterator::iterator()
963
964     Constructs an iterator for this text block.
965 */
966
967 /*!
968     \fn QTextBlock::iterator::iterator(const iterator &other)
969
970     Copy constructor. Constructs a copy of the \a other iterator.
971 */
972
973 /*!
974     \fn bool QTextBlock::iterator::atEnd() const
975
976     Returns true if the current item is the last item in the text block.
977 */
978
979 /*!
980     \fn bool QTextBlock::iterator::operator==(const iterator &other) const
981
982     Retuns true if this iterator is the same as the \a other iterator;
983     otherwise returns false.
984 */
985
986 /*!
987     \fn bool QTextBlock::iterator::operator!=(const iterator &other) const
988
989     Retuns true if this iterator is different from the \a other iterator;
990     otherwise returns false.
991 */
992
993 /*!
994     \fn QTextBlock::iterator QTextBlock::iterator::operator++(int)
995
996     The postfix ++ operator (\c{i++}) advances the iterator to the
997     next item in the text block and returns an iterator to the old current
998     item.
999 */
1000
1001 /*!
1002     \fn QTextBlock::iterator QTextBlock::iterator::operator--(int)
1003
1004     The postfix -- operator (\c{i--}) makes the preceding item current and
1005     returns an iterator to the old current item.
1006 */
1007
1008 /*!
1009     \fn QTextDocumentPrivate *QTextBlock::docHandle() const
1010
1011     \internal
1012 */
1013
1014 /*!
1015     \fn int QTextBlock::fragmentIndex() const
1016
1017     \internal
1018 */
1019
1020 /*!
1021     Returns the index of the block's first character within the document.
1022  */
1023 int QTextBlock::position() const
1024 {
1025     if (!p || !n)
1026         return 0;
1027
1028     return p->blockMap().position(n);
1029 }
1030
1031 /*!
1032     Returns the length of the block in characters.
1033
1034     \note The length returned includes all formatting characters,
1035     for example, newline.
1036
1037     \sa text(), charFormat(), blockFormat()
1038  */
1039 int QTextBlock::length() const
1040 {
1041     if (!p || !n)
1042         return 0;
1043
1044     return p->blockMap().size(n);
1045 }
1046
1047 /*!
1048     Returns true if the given \a position is located within the text
1049     block; otherwise returns false.
1050  */
1051 bool QTextBlock::contains(int position) const
1052 {
1053     if (!p || !n)
1054         return false;
1055
1056     int pos = p->blockMap().position(n);
1057     int len = p->blockMap().size(n);
1058     return position >= pos && position < pos + len;
1059 }
1060
1061 /*!
1062     Returns the QTextLayout that is used to lay out and display the
1063     block's contents.
1064
1065     Note that the returned QTextLayout object can only be modified from the
1066     documentChanged implementation of a QAbstractTextDocumentLayout subclass.
1067     Any changes applied from the outside cause undefined behavior.
1068
1069     \sa clearLayout()
1070  */
1071 QTextLayout *QTextBlock::layout() const
1072 {
1073     if (!p || !n)
1074         return 0;
1075
1076     const QTextBlockData *b = p->blockMap().fragment(n);
1077     if (!b->layout)
1078         b->layout = new QTextLayout(*this);
1079     return b->layout;
1080 }
1081
1082 /*!
1083     \since 4.4
1084     Clears the QTextLayout that is used to lay out and display the
1085     block's contents.
1086
1087     \sa layout()
1088  */
1089 void QTextBlock::clearLayout()
1090 {
1091     if (!p || !n)
1092         return;
1093
1094     const QTextBlockData *b = p->blockMap().fragment(n);
1095     if (b->layout)
1096         b->layout->clearLayout();
1097 }
1098
1099 /*!
1100     Returns the QTextBlockFormat that describes block-specific properties.
1101
1102     \sa charFormat()
1103  */
1104 QTextBlockFormat QTextBlock::blockFormat() const
1105 {
1106     if (!p || !n)
1107         return QTextFormat().toBlockFormat();
1108
1109     return p->formatCollection()->blockFormat(p->blockMap().fragment(n)->format);
1110 }
1111
1112 /*!
1113     Returns an index into the document's internal list of block formats
1114     for the text block's format.
1115
1116     \sa QTextDocument::allFormats()
1117 */
1118 int QTextBlock::blockFormatIndex() const
1119 {
1120     if (!p || !n)
1121         return -1;
1122
1123     return p->blockMap().fragment(n)->format;
1124 }
1125
1126 /*!
1127     Returns the QTextCharFormat that describes the block's character
1128     format. The block's character format is used when inserting text into
1129     an empty block.
1130
1131     \sa blockFormat()
1132  */
1133 QTextCharFormat QTextBlock::charFormat() const
1134 {
1135     if (!p || !n)
1136         return QTextFormat().toCharFormat();
1137
1138     return p->formatCollection()->charFormat(charFormatIndex());
1139 }
1140
1141 /*!
1142     Returns an index into the document's internal list of character formats
1143     for the text block's character format.
1144
1145     \sa QTextDocument::allFormats()
1146 */
1147 int QTextBlock::charFormatIndex() const
1148 {
1149     if (!p || !n)
1150         return -1;
1151
1152     return p->blockCharFormatIndex(n);
1153 }
1154
1155 /*!
1156   \since 4.7
1157
1158   Returns the resolved text direction.
1159
1160   If the block has no explicit direction set, it will resolve the
1161   direction from the blocks content. Returns either Qt::LeftToRight
1162   or Qt::RightToLeft.
1163
1164   \sa QTextFormat::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection
1165 */
1166 Qt::LayoutDirection QTextBlock::textDirection() const
1167 {
1168     Qt::LayoutDirection dir = blockFormat().layoutDirection();
1169     if (dir != Qt::LayoutDirectionAuto)
1170         return dir;
1171
1172     dir = p->defaultTextOption.textDirection();
1173     if (dir != Qt::LayoutDirectionAuto)
1174         return dir;
1175
1176     const QString buffer = p->buffer();
1177
1178     const int pos = position();
1179     QTextDocumentPrivate::FragmentIterator it = p->find(pos);
1180     QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
1181     for (; it != end; ++it) {
1182         const QTextFragmentData * const frag = it.value();
1183         const QChar *p = buffer.constData() + frag->stringPosition;
1184         const QChar * const end = p + frag->size_array[0];
1185         while (p < end) {
1186             switch(QChar::direction(p->unicode()))
1187             {
1188             case QChar::DirL:
1189                 return Qt::LeftToRight;
1190             case QChar::DirR:
1191             case QChar::DirAL:
1192                 return Qt::RightToLeft;
1193             default:
1194                 break;
1195             }
1196             ++p;
1197         }
1198     }
1199     return Qt::LeftToRight;
1200 }
1201
1202 /*!
1203     Returns the block's contents as plain text.
1204
1205     \sa length(), charFormat(), blockFormat()
1206  */
1207 QString QTextBlock::text() const
1208 {
1209     if (!p || !n)
1210         return QString();
1211
1212     const QString buffer = p->buffer();
1213     QString text;
1214     text.reserve(length());
1215
1216     const int pos = position();
1217     QTextDocumentPrivate::FragmentIterator it = p->find(pos);
1218     QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
1219     for (; it != end; ++it) {
1220         const QTextFragmentData * const frag = it.value();
1221         text += QString::fromRawData(buffer.constData() + frag->stringPosition, frag->size_array[0]);
1222     }
1223
1224     return text;
1225 }
1226
1227
1228 /*!
1229     Returns the text document this text block belongs to, or 0 if the
1230     text block does not belong to any document.
1231 */
1232 const QTextDocument *QTextBlock::document() const
1233 {
1234     return p ? p->document() : 0;
1235 }
1236
1237 /*!
1238     If the block represents a list item, returns the list that the item belongs
1239     to; otherwise returns 0.
1240 */
1241 QTextList *QTextBlock::textList() const
1242 {
1243     if (!isValid())
1244         return 0;
1245
1246     const QTextBlockFormat fmt = blockFormat();
1247     QTextObject *obj = p->document()->objectForFormat(fmt);
1248     return qobject_cast<QTextList *>(obj);
1249 }
1250
1251 /*!
1252     \since 4.1
1253
1254     Returns a pointer to a QTextBlockUserData object if previously set with
1255     setUserData() or a null pointer.
1256 */
1257 QTextBlockUserData *QTextBlock::userData() const
1258 {
1259     if (!p || !n)
1260         return 0;
1261
1262     const QTextBlockData *b = p->blockMap().fragment(n);
1263     return b->userData;
1264 }
1265
1266 /*!
1267     \since 4.1
1268
1269     Attaches the given \a data object to the text block.
1270
1271     QTextBlockUserData can be used to store custom settings.  The
1272     ownership is passed to the underlying text document, i.e. the
1273     provided QTextBlockUserData object will be deleted if the
1274     corresponding text block gets deleted. The user data object is
1275     not stored in the undo history, so it will not be available after
1276     undoing the deletion of a text block.
1277
1278     For example, if you write a programming editor in an IDE, you may
1279     want to let your user set breakpoints visually in your code for an
1280     integrated debugger. In a programming editor a line of text
1281     usually corresponds to one QTextBlock. The QTextBlockUserData
1282     interface allows the developer to store data for each QTextBlock,
1283     like for example in which lines of the source code the user has a
1284     breakpoint set. Of course this could also be stored externally,
1285     but by storing it inside the QTextDocument, it will for example be
1286     automatically deleted when the user deletes the associated
1287     line. It's really just a way to store custom information in the
1288     QTextDocument without using custom properties in QTextFormat which
1289     would affect the undo/redo stack.
1290 */
1291 void QTextBlock::setUserData(QTextBlockUserData *data)
1292 {
1293     if (!p || !n)
1294         return;
1295
1296     const QTextBlockData *b = p->blockMap().fragment(n);
1297     if (data != b->userData)
1298         delete b->userData;
1299     b->userData = data;
1300 }
1301
1302 /*!
1303     \since 4.1
1304
1305     Returns the integer value previously set with setUserState() or -1.
1306 */
1307 int QTextBlock::userState() const
1308 {
1309     if (!p || !n)
1310         return -1;
1311
1312     const QTextBlockData *b = p->blockMap().fragment(n);
1313     return b->userState;
1314 }
1315
1316 /*!
1317     \since 4.1
1318
1319     Stores the specified \a state integer value in the text block. This may be
1320     useful for example in a syntax highlighter to store a text parsing state.
1321 */
1322 void QTextBlock::setUserState(int state)
1323 {
1324     if (!p || !n)
1325         return;
1326
1327     const QTextBlockData *b = p->blockMap().fragment(n);
1328     b->userState = state;
1329 }
1330
1331 /*!
1332     \since 4.4
1333
1334     Returns the blocks revision.
1335
1336     \sa setRevision(), QTextDocument::revision()
1337 */
1338 int QTextBlock::revision() const
1339 {
1340     if (!p || !n)
1341         return -1;
1342
1343     const QTextBlockData *b = p->blockMap().fragment(n);
1344     return b->revision;
1345 }
1346
1347 /*!
1348     \since 4.4
1349
1350     Sets a blocks revision to \a rev.
1351
1352     \sa revision(), QTextDocument::revision()
1353 */
1354 void QTextBlock::setRevision(int rev)
1355 {
1356     if (!p || !n)
1357         return;
1358
1359     const QTextBlockData *b = p->blockMap().fragment(n);
1360     b->revision = rev;
1361 }
1362
1363 /*!
1364     \since 4.4
1365
1366     Returns true if the block is visible; otherwise returns false.
1367
1368     \sa setVisible()
1369 */
1370 bool QTextBlock::isVisible() const
1371 {
1372     if (!p || !n)
1373         return true;
1374
1375     const QTextBlockData *b = p->blockMap().fragment(n);
1376     return !b->hidden;
1377 }
1378
1379 /*!
1380     \since 4.4
1381
1382     Sets the block's visibility to \a visible.
1383
1384     \sa isVisible()
1385 */
1386 void QTextBlock::setVisible(bool visible)
1387 {
1388     if (!p || !n)
1389         return;
1390
1391     const QTextBlockData *b = p->blockMap().fragment(n);
1392     b->hidden = !visible;
1393 }
1394
1395
1396 /*!
1397 \since 4.4
1398
1399     Returns the number of this block, or -1 if the block is invalid.
1400
1401     \sa QTextCursor::blockNumber()
1402
1403 */
1404 int QTextBlock::blockNumber() const
1405 {
1406     if (!p || !n)
1407         return -1;
1408     return p->blockMap().position(n, 1);
1409 }
1410
1411 /*!
1412 \since 4.5
1413
1414     Returns the first line number of this block, or -1 if the block is invalid.
1415     Unless the layout supports it, the line number is identical to the block number.
1416
1417     \sa QTextBlock::blockNumber()
1418
1419 */
1420 int QTextBlock::firstLineNumber() const
1421 {
1422     if (!p || !n)
1423         return -1;
1424     return p->blockMap().position(n, 2);
1425 }
1426
1427
1428 /*!
1429 \since 4.5
1430
1431 Sets the line count to \a count.
1432
1433 \sa lineCount()
1434 */
1435 void QTextBlock::setLineCount(int count)
1436 {
1437     if (!p || !n)
1438         return;
1439     p->blockMap().setSize(n, count, 2);
1440 }
1441 /*!
1442 \since 4.5
1443
1444 Returns the line count. Not all document layouts support this feature.
1445
1446 \sa setLineCount()
1447  */
1448 int QTextBlock::lineCount() const
1449 {
1450     if (!p || !n)
1451         return -1;
1452     return p->blockMap().size(n, 2);
1453 }
1454
1455
1456 /*!
1457     Returns a text block iterator pointing to the beginning of the
1458     text block.
1459
1460     \sa end()
1461 */
1462 QTextBlock::iterator QTextBlock::begin() const
1463 {
1464     if (!p || !n)
1465         return iterator();
1466
1467     int pos = position();
1468     int len = length() - 1; // exclude the fragment that holds the paragraph separator
1469     int b = p->fragmentMap().findNode(pos);
1470     int e = p->fragmentMap().findNode(pos+len);
1471     return iterator(p, b, e, b);
1472 }
1473
1474 /*!
1475     Returns a text block iterator pointing to the end of the text
1476     block.
1477
1478     \sa begin(), next(), previous()
1479 */
1480 QTextBlock::iterator QTextBlock::end() const
1481 {
1482     if (!p || !n)
1483         return iterator();
1484
1485     int pos = position();
1486     int len = length() - 1; // exclude the fragment that holds the paragraph separator
1487     int b = p->fragmentMap().findNode(pos);
1488     int e = p->fragmentMap().findNode(pos+len);
1489     return iterator(p, b, e, e);
1490 }
1491
1492
1493 /*!
1494     Returns the text block in the document after this block, or an empty
1495     text block if this is the last one.
1496
1497     Note that the next block may be in a different frame or table to this block.
1498
1499     \sa previous(), begin(), end()
1500 */
1501 QTextBlock QTextBlock::next() const
1502 {
1503     if (!isValid())
1504         return QTextBlock();
1505
1506     return QTextBlock(p, p->blockMap().next(n));
1507 }
1508
1509 /*!
1510     Returns the text block in the document before this block, or an empty text
1511     block if this is the first one.
1512
1513     Note that the next block may be in a different frame or table to this block.
1514
1515     \sa next(), begin(), end()
1516 */
1517 QTextBlock QTextBlock::previous() const
1518 {
1519     if (!p)
1520         return QTextBlock();
1521
1522     return QTextBlock(p, p->blockMap().previous(n));
1523 }
1524
1525
1526 /*!
1527     Returns the text fragment the iterator currently points to.
1528 */
1529 QTextFragment QTextBlock::iterator::fragment() const
1530 {
1531     int ne = n;
1532     int formatIndex = p->fragmentMap().fragment(n)->format;
1533     do {
1534         ne = p->fragmentMap().next(ne);
1535     } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex);
1536     return QTextFragment(p, n, ne);
1537 }
1538
1539 /*!
1540     The prefix ++ operator (\c{++i}) advances the iterator to the
1541     next item in the hash and returns an iterator to the new current
1542     item.
1543 */
1544
1545 QTextBlock::iterator &QTextBlock::iterator::operator++()
1546 {
1547     int ne = n;
1548     int formatIndex = p->fragmentMap().fragment(n)->format;
1549     do {
1550         ne = p->fragmentMap().next(ne);
1551     } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex);
1552     n = ne;
1553     return *this;
1554 }
1555
1556 /*!
1557     The prefix -- operator (\c{--i}) makes the preceding item
1558     current and returns an iterator pointing to the new current item.
1559 */
1560
1561 QTextBlock::iterator &QTextBlock::iterator::operator--()
1562 {
1563     n = p->fragmentMap().previous(n);
1564
1565     if (n == b)
1566         return *this;
1567
1568     int formatIndex = p->fragmentMap().fragment(n)->format;
1569     int last = n;
1570
1571     while (n != b && p->fragmentMap().fragment(n)->format != formatIndex) {
1572         last = n;
1573         n = p->fragmentMap().previous(n);
1574     }
1575
1576     n = last;
1577     return *this;
1578 }
1579
1580
1581 /*!
1582     \class QTextFragment
1583     \reentrant
1584
1585     \brief The QTextFragment class holds a piece of text in a
1586     QTextDocument with a single QTextCharFormat.
1587     \inmodule QtGui
1588
1589     \ingroup richtext-processing
1590
1591     A text fragment describes a piece of text that is stored with a single
1592     character format. Text in which the character format changes can be
1593     represented by sequences of text fragments with different formats.
1594
1595     If the user edits the text in a fragment and introduces a different
1596     character format, the fragment's text will be split at each point where
1597     the format changes, and new fragments will be created.
1598     For example, changing the style of some text in the middle of a
1599     sentence will cause the fragment to be broken into three separate fragments:
1600     the first and third with the same format as before, and the second with
1601     the new style. The first fragment will contain the text from the beginning
1602     of the sentence, the second will contain the text from the middle, and the
1603     third takes the text from the end of the sentence.
1604
1605     \img qtextfragment-split.png
1606
1607     A fragment's text and character format can be obtained with the text()
1608     and charFormat() functions. The length() function gives the length of
1609     the text in the fragment. position() gives the position in the document
1610     of the start of the fragment. To determine whether the fragment contains
1611     a particular position within the document, use the contains() function.
1612
1613     \sa QTextDocument, {Rich Text Document Structure}
1614 */
1615
1616 /*!
1617     \fn QTextFragment::QTextFragment(const QTextDocumentPrivate *priv, int f, int fe)
1618     \internal
1619 */
1620
1621 /*!
1622     \fn QTextFragment::QTextFragment()
1623
1624     Creates a new empty text fragment.
1625 */
1626
1627 /*!
1628     \fn QTextFragment::QTextFragment(const QTextFragment &other)
1629
1630     Copies the content (text and format) of the \a other text fragment
1631     to this text fragment.
1632 */
1633
1634 /*!
1635     \fn QTextFragment &QTextFragment::operator=(const QTextFragment
1636     &other)
1637
1638     Assigns the content (text and format) of the \a other text fragment
1639     to this text fragment.
1640 */
1641
1642 /*!
1643     \fn bool QTextFragment::isValid() const
1644
1645     Returns true if this is a valid text fragment (i.e. has a valid
1646     position in a document); otherwise returns false.
1647 */
1648
1649 /*!
1650     \fn bool QTextFragment::operator==(const QTextFragment &other) const
1651
1652     Returns true if this text fragment is the same (at the same
1653     position) as the \a other text fragment; otherwise returns false.
1654 */
1655
1656 /*!
1657     \fn bool QTextFragment::operator!=(const QTextFragment &other) const
1658
1659     Returns true if this text fragment is different (at a different
1660     position) from the \a other text fragment; otherwise returns
1661     false.
1662 */
1663
1664 /*!
1665     \fn bool QTextFragment::operator<(const QTextFragment &other) const
1666
1667     Returns true if this text fragment appears earlier in the document
1668     than the \a other text fragment; otherwise returns false.
1669 */
1670
1671 /*!
1672     Returns the glyphs of this text fragment. The positions of the glyphs are
1673     relative to the position of the QTextBlock's layout.
1674
1675     \sa QGlyphRun, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphRun()
1676 */
1677 #if !defined(QT_NO_RAWFONT)
1678 QList<QGlyphRun> QTextFragment::glyphRuns(int pos, int len) const
1679 {
1680     if (!p || !n)
1681         return QList<QGlyphRun>();
1682
1683     int blockNode = p->blockMap().findNode(position());
1684
1685     const QTextBlockData *blockData = p->blockMap().fragment(blockNode);
1686     QTextLayout *layout = blockData->layout;
1687
1688     int blockPosition = p->blockMap().position(blockNode);
1689     if (pos < 0)
1690         pos = position() - blockPosition;
1691     if (len < 0)
1692         len = length();
1693     if (len == 0)
1694         return QList<QGlyphRun>();
1695
1696     QList<QGlyphRun> ret;
1697     for (int i=0; i<layout->lineCount(); ++i) {
1698         QTextLine textLine = layout->lineAt(i);
1699         ret += textLine.glyphRuns(pos, len);
1700     }
1701
1702     return ret;
1703 }
1704 #endif // QT_NO_RAWFONT
1705
1706 /*!
1707     Returns the position of this text fragment in the document.
1708 */
1709 int QTextFragment::position() const
1710 {
1711     if (!p || !n)
1712         return 0; // ### -1 instead?
1713
1714     return p->fragmentMap().position(n);
1715 }
1716
1717 /*!
1718     Returns the number of characters in the text fragment.
1719
1720     \sa text()
1721 */
1722 int QTextFragment::length() const
1723 {
1724     if (!p || !n)
1725         return 0;
1726
1727     int len = 0;
1728     int f = n;
1729     while (f != ne) {
1730         len += p->fragmentMap().size(f);
1731         f = p->fragmentMap().next(f);
1732     }
1733     return len;
1734 }
1735
1736 /*!
1737     Returns true if the text fragment contains the text at the given
1738     \a position in the document; otherwise returns false.
1739 */
1740 bool QTextFragment::contains(int position) const
1741 {
1742     if (!p || !n)
1743         return false;
1744     int pos = this->position();
1745     return position >= pos && position < pos + length();
1746 }
1747
1748 /*!
1749     Returns the text fragment's character format.
1750
1751     \sa text()
1752 */
1753 QTextCharFormat QTextFragment::charFormat() const
1754 {
1755     if (!p || !n)
1756         return QTextCharFormat();
1757     const QTextFragmentData *data = p->fragmentMap().fragment(n);
1758     return p->formatCollection()->charFormat(data->format);
1759 }
1760
1761 /*!
1762     Returns an index into the document's internal list of character formats
1763     for the text fragment's character format.
1764
1765     \sa QTextDocument::allFormats()
1766 */
1767 int QTextFragment::charFormatIndex() const
1768 {
1769     if (!p || !n)
1770         return -1;
1771     const QTextFragmentData *data = p->fragmentMap().fragment(n);
1772     return data->format;
1773 }
1774
1775 /*!
1776     Returns the text fragment's as plain text.
1777
1778     \sa length(), charFormat()
1779 */
1780 QString QTextFragment::text() const
1781 {
1782     if (!p || !n)
1783         return QString();
1784
1785     QString result;
1786     QString buffer = p->buffer();
1787     int f = n;
1788     while (f != ne) {
1789         const QTextFragmentData * const frag = p->fragmentMap().fragment(f);
1790         result += QString(buffer.constData() + frag->stringPosition, frag->size_array[0]);
1791         f = p->fragmentMap().next(f);
1792     }
1793     return result;
1794 }
1795
1796 QT_END_NAMESPACE