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