📄 qtextlayout.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qtextlayout.h"#include "qtextengine_p.h"#include <qfont.h>#include <qapplication.h>#include <qpainter.h>#include <qvarlengtharray.h>#include <qtextformat.h>#include <qabstracttextdocumentlayout.h>#include "qtextdocument_p.h"#include "qtextformat_p.h"#include "qstyleoption.h"#include "qpainterpath.h"#include <limits.h>#include <qdebug.h>#include "qfontengine_p.h"#define ObjectSelectionBrush (QTextFormat::ForegroundBrush + 1)static inline QFixed leadingSpaceWidth(QTextEngine *eng, const QScriptLine &line){ if (!line.hasTrailingSpaces || (eng->option.flags() & QTextOption::IncludeTrailingSpaces) || !(eng->option.alignment() & Qt::AlignRight) || (eng->option.textDirection() != Qt::RightToLeft)) return QFixed(); int pos = line.length; const QCharAttributes *attributes = eng->attributes(); while (pos > 0 && attributes[line.from + pos - 1].whiteSpace) --pos; return eng->width(line.from + pos, line.length - pos);}static QFixed alignLine(QTextEngine *eng, const QScriptLine &line){ QFixed x = 0; eng->justify(line); if (!line.justified) { int align = eng->option.alignment(); if (align & Qt::AlignJustify && eng->option.textDirection() == Qt::RightToLeft) align = Qt::AlignRight; if (align & Qt::AlignRight) x = line.width - (line.textWidth + leadingSpaceWidth(eng, line)); else if (align & Qt::AlignHCenter) x = (line.width - line.textWidth)/2; } return x;}/*! \class QTextLayout::FormatRange \brief The QTextLayout::FormatRange structure is used to apply extra formatting information for a specified area in the text layout's content. \sa QTextLayout::setAdditionalFormats(), QTextLayout::draw()*//*! \variable QTextLayout::FormatRange::start Specifies the beginning of the format range within the text layout's text.*//*! \variable QTextLayout::FormatRange::length Specifies the numer of characters the format range spans.*//*! \variable QTextLayout::FormatRange::format Specifies the format to apply.*//*! \class QTextInlineObject \brief The QTextInlineObject class represents an inline object in a QTextLayout. \ingroup text This class is only used if the text layout is used to lay out parts of a QTextDocument. The inline object has various attributes that can be set, for example using, setWidth(), setAscent(), and setDescent(). The rectangle it occupies is given by rect(), and its direction by isRightToLeft(). Its position in the text layout is given by at(), and its format is given by format().*//*! \fn QTextInlineObject::QTextInlineObject(int i, QTextEngine *e) Creates a new inline object for the item at position \a i in the text engine \a e.*//*! \fn QTextInlineObject::QTextInlineObject() \internal*//*! \fn bool QTextInlineObject::isValid() const Returns true if this inline object is valid; otherwise returns false.*//*! Returns the inline object's rectangle. \sa ascent() descent() width()*/QRectF QTextInlineObject::rect() const{ QScriptItem& si = eng->layoutData->items[itm]; return QRectF(0, -si.ascent.toReal(), si.width.toReal(), si.height().toReal());}/*! Returns the inline object's width. \sa ascent() descent() rect()*/qreal QTextInlineObject::width() const{ return eng->layoutData->items[itm].width.toReal();}/*! Returns the inline object's ascent. \sa descent() width() rect()*/qreal QTextInlineObject::ascent() const{ return eng->layoutData->items[itm].ascent.toReal();}/*! Returns the inline object's descent. \sa ascent() width() rect()*/qreal QTextInlineObject::descent() const{ return eng->layoutData->items[itm].descent.toReal();}/*! Returns the inline object's total height. This is equal to ascent() + descent() + 1. \sa ascent() descent() width() rect()*/qreal QTextInlineObject::height() const{ return eng->layoutData->items[itm].height().toReal();}/*! Sets the inline object's width to \a w. \sa width() ascent() descent() rect()*/void QTextInlineObject::setWidth(qreal w){ eng->layoutData->items[itm].width = QFixed::fromReal(w);}/*! Sets the inline object's ascent to \a a. \sa ascent() setDescent() width() rect()*/void QTextInlineObject::setAscent(qreal a){ eng->layoutData->items[itm].ascent = QFixed::fromReal(a);}/*! Sets the inline object's decent to \a d. \sa descent() setAscent() width() rect()*/void QTextInlineObject::setDescent(qreal d){ eng->layoutData->items[itm].descent = QFixed::fromReal(d);}/*! The position of the inline object within the text layout.*/int QTextInlineObject::textPosition() const{ return eng->layoutData->items[itm].position;}/*! Returns an integer describing the format of the inline object within the text layout.*/int QTextInlineObject::formatIndex() const{ return eng->formatIndex(&eng->layoutData->items[itm]);}/*! Returns format of the inline object within the text layout.*/QTextFormat QTextInlineObject::format() const{ if (!eng->block.docHandle()) return QTextFormat(); return eng->formats()->format(eng->formatIndex(&eng->layoutData->items[itm]));}/*! Returns if the object should be laid out right-to-left or left-to-right.*/Qt::LayoutDirection QTextInlineObject::textDirection() const{ return (eng->layoutData->items[itm].analysis.bidiLevel % 2 ? Qt::RightToLeft : Qt::LeftToRight);}/*! \class QTextLayout \brief The QTextLayout class is used to lay out and paint a single paragraph of text. \ingroup text It offers most features expected from a modern text layout engine, including Unicode compliant rendering, line breaking and handling of cursor positioning. It can also produce and render device independent layout, something that is important for WYSIWYG applications. The class has a rather low level API and unless you intend to implement your own text rendering for some specialized widget, you probably won't need to use it directly. QTextLayout can currently deal with plain text and rich text paragraphs that are part of a QTextDocument. QTextLayout can be used to create a sequence of QTextLine's with given widths and can position them independently on the screen. Once the layout is done, these lines can be drawn on a paint device. Here's some pseudo code that presents the layout phase: \code int leading = fontMetrics.leading(); int height = 0; qreal widthUsed = 0; textLayout.beginLayout(); while (1) { QTextLine line = textLayout.createLine(); if (!line.isValid()) break; line.setLineWidth(lineWidth); height += leading; line.setPosition(QPoint(0, height)); height += line.height(); widthUsed = qMax(widthUsed, line.naturalTextWidth()); } textLayout.endLayout(); \endcode The text can be drawn by calling the layout's draw() function: \code QPainter painter(this); textLayout.draw(&painter, QPoint(0, 0)); \endcode The text layout's text is set in the constructor or with setText(). The layout can be seen as a sequence of QTextLine objects; use lineAt() or lineForTextPosition() to get a QTextLine, createLine() to create one. For a given position in the text you can find a valid cursor position with isValidCursorPosition(), nextCursorPosition(), and previousCursorPosition(). The layout itself can be positioned with setPosition(); it has a boundingRect(), and a minimumWidth() and a maximumWidth(). A text layout can be drawn on a painter device using draw().*//*! \enum QTextLayout::CursorMode \value SkipCharacters \value SkipWords*//*! \fn QTextEngine *QTextLayout::engine() const \internal Returns the text engine used to render the text layout.*//*! Constructs an empty text layout. \sa setText()*/QTextLayout::QTextLayout(){ d = new QTextEngine(); }/*! Constructs a text layout to lay out the given \a text.*/QTextLayout::QTextLayout(const QString& text){ d = new QTextEngine(); d->text = text;}/*! Constructs a text layout to lay out the given \a text with the specified \a font. All the metric and layout calculations will be done in terms of the paint device, \a paintdevice. If \a paintdevice is 0 the calculations will be done in screen metrics.*/QTextLayout::QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice){ QFontPrivate *f = paintdevice ? QFont(font, paintdevice).d : font.d; d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f);}/*! \internal Constructs a text layout to lay out the given \a block.*/QTextLayout::QTextLayout(const QTextBlock &block){ d = new QTextEngine(); d->block = block;}/*! Destructs the layout.*/QTextLayout::~QTextLayout(){ if (!d->stackEngine) delete d;}/*! Sets the layout's font to the given \a font. The layout is invalidated and must be laid out again. \sa text()*/void QTextLayout::setFont(const QFont &font){ d->fnt = font;}/*! Returns the current font that is used for the layout, or a default font if none is set.*/QFont QTextLayout::font() const{ return d->font();}/*! Sets the layout's text to the given \a string. The layout is invalidated and must be laid out again. \sa text()*/void QTextLayout::setText(const QString& string){ d->invalidate(); d->text = string;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -