aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/qquicktext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/items/qquicktext.cpp')
-rw-r--r--src/declarative/items/qquicktext.cpp1950
1 files changed, 0 insertions, 1950 deletions
diff --git a/src/declarative/items/qquicktext.cpp b/src/declarative/items/qquicktext.cpp
deleted file mode 100644
index 630b466d80..0000000000
--- a/src/declarative/items/qquicktext.cpp
+++ /dev/null
@@ -1,1950 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.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 the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquicktext_p.h"
-#include "qquicktext_p_p.h"
-
-#include <private/qsgcontext_p.h>
-#include <private/qsgadaptationlayer_p.h>
-#include "qquicktextnode_p.h"
-#include "qquickimage_p_p.h"
-#include <private/qsgtexture_p.h>
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qabstracttextdocumentlayout.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qtextdocument.h>
-#include <QtGui/qtextobject.h>
-#include <QtGui/qtextcursor.h>
-#include <QtGui/qguiapplication.h>
-
-#include <private/qdeclarativestyledtext_p.h>
-#include <private/qdeclarativepixmapcache_p.h>
-
-#include <qmath.h>
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
-
-class QQuickTextDocumentWithImageResources : public QTextDocument {
- Q_OBJECT
-
-public:
- QQuickTextDocumentWithImageResources(QQuickText *parent);
- virtual ~QQuickTextDocumentWithImageResources();
-
- void setText(const QString &);
- int resourcesLoading() const { return outstanding; }
-
-protected:
- QVariant loadResource(int type, const QUrl &name);
-
-private slots:
- void requestFinished();
-
-private:
- QHash<QUrl, QDeclarativePixmap *> m_resources;
-
- int outstanding;
- static QSet<QUrl> errors;
-};
-
-DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
-DEFINE_BOOL_CONFIG_OPTION(enableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE);
-
-QString QQuickTextPrivate::elideChar = QString(0x2026);
-
-QQuickTextPrivate::QQuickTextPrivate()
-: color((QRgb)0), style(QQuickText::Normal), hAlign(QQuickText::AlignLeft),
- vAlign(QQuickText::AlignTop), elideMode(QQuickText::ElideNone),
- format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap), lineHeight(1),
- lineHeightMode(QQuickText::ProportionalHeight), lineCount(1), maximumLineCount(INT_MAX),
- maximumLineCountValid(false),
- texture(0),
- imageCacheDirty(false), updateOnComponentComplete(true),
- richText(false), styledText(false), singleline(false), cacheAllTextAsImage(true), internalWidthUpdate(false),
- requireImplicitWidth(false), truncated(false), hAlignImplicit(true), rightToLeftText(false),
- layoutTextElided(false), richTextAsImage(false), textureImageCacheDirty(false), textHasChanged(true),
- naturalWidth(0), doc(0), elipsisLayout(0), textLine(0), nodeType(NodeIsNull)
-
-#if defined(Q_OS_MAC)
-, layoutThread(0), paintingThread(0)
-#endif
-
-{
- cacheAllTextAsImage = enableImageCache();
-}
-
-void QQuickTextPrivate::init()
-{
- Q_Q(QQuickText);
- q->setAcceptedMouseButtons(Qt::LeftButton);
- q->setFlag(QQuickItem::ItemHasContents);
-}
-
-QQuickTextDocumentWithImageResources::QQuickTextDocumentWithImageResources(QQuickText *parent)
-: QTextDocument(parent), outstanding(0)
-{
- setUndoRedoEnabled(false);
-}
-
-QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
-{
- if (!m_resources.isEmpty())
- qDeleteAll(m_resources);
-}
-
-QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
-{
- QDeclarativeContext *context = qmlContext(parent());
- QUrl url = context->resolvedUrl(name);
-
- if (type == QTextDocument::ImageResource) {
- QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
-
- if (iter == m_resources.end()) {
- QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
- iter = m_resources.insert(url, p);
-
- if (p->isLoading()) {
- p->connectFinished(this, SLOT(requestFinished()));
- outstanding++;
- }
- }
-
- QDeclarativePixmap *p = *iter;
- if (p->isReady()) {
- return p->image();
- } else if (p->isError()) {
- if (!errors.contains(url)) {
- errors.insert(url);
- qmlInfo(parent()) << p->error();
- }
- }
- }
-
- return QTextDocument::loadResource(type,url); // The *resolved* URL
-}
-
-void QQuickTextDocumentWithImageResources::requestFinished()
-{
- outstanding--;
- if (outstanding == 0) {
- QQuickText *textItem = static_cast<QQuickText*>(parent());
- QString text = textItem->text();
-#ifndef QT_NO_TEXTHTMLPARSER
- setHtml(text);
-#else
- setPlainText(text);
-#endif
- QQuickTextPrivate *d = QQuickTextPrivate::get(textItem);
- d->updateLayout();
- }
-}
-
-void QQuickTextDocumentWithImageResources::setText(const QString &text)
-{
- if (!m_resources.isEmpty()) {
- qDeleteAll(m_resources);
- m_resources.clear();
- outstanding = 0;
- }
-
-#ifndef QT_NO_TEXTHTMLPARSER
- setHtml(text);
-#else
- setPlainText(text);
-#endif
-}
-
-QSet<QUrl> QQuickTextDocumentWithImageResources::errors;
-
-QQuickTextPrivate::~QQuickTextPrivate()
-{
- delete elipsisLayout;
- delete textLine; textLine = 0;
-}
-
-qreal QQuickTextPrivate::getImplicitWidth() const
-{
- if (!requireImplicitWidth) {
- // We don't calculate implicitWidth unless it is required.
- // We need to force a size update now to ensure implicitWidth is calculated
- QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
- me->requireImplicitWidth = true;
- me->updateSize();
- }
- return implicitWidth;
-}
-
-void QQuickTextPrivate::updateLayout()
-{
- Q_Q(QQuickText);
- if (!q->isComponentComplete()) {
- updateOnComponentComplete = true;
- return;
- }
- updateOnComponentComplete = false;
- layoutTextElided = false;
- // Setup instance of QTextLayout for all cases other than richtext
- if (!richText) {
- if (elipsisLayout) {
- delete elipsisLayout;
- elipsisLayout = 0;
- }
- layout.clearLayout();
- layout.setFont(font);
- if (!styledText) {
- QString tmp = text;
- tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
- singleline = !tmp.contains(QChar::LineSeparator);
- if (singleline && !maximumLineCountValid && elideMode != QQuickText::ElideNone && q->widthValid() && wrapMode == QQuickText::NoWrap) {
- QFontMetrics fm(font);
- tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width());
- if (tmp != text) {
- layoutTextElided = true;
- if (!truncated) {
- truncated = true;
- emit q->truncatedChanged();
- }
- }
- }
- layout.setText(tmp);
- } else {
- singleline = false;
- if (textHasChanged) {
- QDeclarativeStyledText::parse(text, layout);
- textHasChanged = false;
- }
- }
- } else {
- ensureDoc();
- QTextBlockFormat::LineHeightTypes type;
- type = lineHeightMode == QQuickText::FixedHeight ? QTextBlockFormat::FixedHeight : QTextBlockFormat::ProportionalHeight;
- QTextBlockFormat blockFormat;
- blockFormat.setLineHeight((lineHeightMode == QQuickText::FixedHeight ? lineHeight : lineHeight * 100), type);
- for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next()) {
- QTextCursor cursor(it);
- cursor.mergeBlockFormat(blockFormat);
- }
- }
-
- updateSize();
-}
-
-void QQuickTextPrivate::updateSize()
-{
- Q_Q(QQuickText);
-
- if (!q->isComponentComplete()) {
- updateOnComponentComplete = true;
- return;
- }
-
- if (!requireImplicitWidth) {
- emit q->implicitWidthChanged();
- // if the implicitWidth is used, then updateSize() has already been called (recursively)
- if (requireImplicitWidth)
- return;
- }
-
- invalidateImageCache();
-
- QFontMetrics fm(font);
- if (text.isEmpty()) {
- q->setImplicitSize(0, fm.height());
- paintedSize = QSize(0, fm.height());
- emit q->paintedSizeChanged();
- q->update();
- return;
- }
-
- int dy = q->height();
- QSize size(0, 0);
-
-#if defined(Q_OS_MAC)
- layoutThread = QThread::currentThread();
-#endif
-
- //setup instance of QTextLayout for all cases other than richtext
- if (!richText) {
- QRect textRect = setupTextLayout();
- layedOutTextRect = textRect;
- size = textRect.size();
- dy -= size.height();
- } else {
- singleline = false; // richtext can't elide or be optimized for single-line case
- ensureDoc();
- doc->setDefaultFont(font);
- QQuickText::HAlignment horizontalAlignment = q->effectiveHAlign();
- if (rightToLeftText) {
- if (horizontalAlignment == QQuickText::AlignLeft)
- horizontalAlignment = QQuickText::AlignRight;
- else if (horizontalAlignment == QQuickText::AlignRight)
- horizontalAlignment = QQuickText::AlignLeft;
- }
- QTextOption option;
- option.setAlignment((Qt::Alignment)int(horizontalAlignment | vAlign));
- option.setWrapMode(QTextOption::WrapMode(wrapMode));
- if (!cacheAllTextAsImage && !richTextAsImage && !qmlDisableDistanceField())
- option.setUseDesignMetrics(true);
- doc->setDefaultTextOption(option);
- if (requireImplicitWidth && q->widthValid()) {
- doc->setTextWidth(-1);
- naturalWidth = doc->idealWidth();
- }
- if (wrapMode != QQuickText::NoWrap && q->widthValid())
- doc->setTextWidth(q->width());
- else
- doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
- dy -= (int)doc->size().height();
- QSize dsize = doc->size().toSize();
- layedOutTextRect = QRect(QPoint(0,0), dsize);
- size = QSize(int(doc->idealWidth()),dsize.height());
- }
- int yoff = 0;
-
- if (q->heightValid()) {
- if (vAlign == QQuickText::AlignBottom)
- yoff = dy;
- else if (vAlign == QQuickText::AlignVCenter)
- yoff = dy/2;
- }
- q->setBaselineOffset(fm.ascent() + yoff);
-
- //### need to comfirm cost of always setting these for richText
- internalWidthUpdate = true;
- qreal iWidth = -1;
- if (!q->widthValid())
- iWidth = size.width();
- else if (requireImplicitWidth)
- iWidth = naturalWidth;
- if (iWidth > -1)
- q->setImplicitSize(iWidth, size.height());
- internalWidthUpdate = false;
-
- if (iWidth == -1)
- q->setImplicitHeight(size.height());
- if (paintedSize != size) {
- paintedSize = size;
- emit q->paintedSizeChanged();
- }
- q->update();
-}
-
-QQuickTextLine::QQuickTextLine()
- : QObject(), m_line(0), m_height(0)
-{
-}
-
-void QQuickTextLine::setLine(QTextLine *line)
-{
- m_line = line;
-}
-
-int QQuickTextLine::number() const
-{
- if (m_line)
- return m_line->lineNumber();
- return 0;
-}
-
-qreal QQuickTextLine::width() const
-{
- if (m_line)
- return m_line->width();
- return 0;
-}
-
-void QQuickTextLine::setWidth(qreal width)
-{
- if (m_line)
- m_line->setLineWidth(width);
-}
-
-qreal QQuickTextLine::height() const
-{
- if (m_height)
- return m_height;
- if (m_line)
- return m_line->height();
- return 0;
-}
-
-void QQuickTextLine::setHeight(qreal height)
-{
- if (m_line)
- m_line->setPosition(QPointF(m_line->x(), m_line->y() - m_line->height() + height));
- m_height = height;
-}
-
-qreal QQuickTextLine::x() const
-{
- if (m_line)
- return m_line->x();
- return 0;
-}
-
-void QQuickTextLine::setX(qreal x)
-{
- if (m_line)
- m_line->setPosition(QPointF(x, m_line->y()));
-}
-
-qreal QQuickTextLine::y() const
-{
- if (m_line)
- return m_line->y();
- return 0;
-}
-
-void QQuickTextLine::setY(qreal y)
-{
- if (m_line)
- m_line->setPosition(QPointF(m_line->x(), y));
-}
-
-void QQuickText::doLayout()
-{
- Q_D(QQuickText);
- d->updateSize();
-}
-
-bool QQuickTextPrivate::isLineLaidOutConnected()
-{
- static int idx = this->signalIndex("lineLaidOut(QQuickTextLine*)");
- return this->isSignalConnected(idx);
-}
-
-void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, qreal elideWidth = 0)
-{
- Q_Q(QQuickText);
-
-#if defined(Q_OS_MAC)
- if (QThread::currentThread() != paintingThread) {
-#endif
- if (!line.lineNumber())
- linesRects.clear();
-
- if (!textLine)
- textLine = new QQuickTextLine;
- textLine->setLine(&line);
- textLine->setY(height);
- textLine->setHeight(0);
-
- // use the text item's width by default if it has one and wrap is on
- if (q->widthValid() && q->wrapMode() != QQuickText::NoWrap)
- textLine->setWidth(q->width() - elideWidth);
- else
- textLine->setWidth(INT_MAX);
- if (lineHeight != 1.0)
- textLine->setHeight((lineHeightMode == QQuickText::FixedHeight) ? lineHeight : line.height() * lineHeight);
-
- emit q->lineLaidOut(textLine);
-
- linesRects << QRectF(textLine->x(), textLine->y(), textLine->width(), textLine->height());
- height += textLine->height();
-
-#if defined(Q_OS_MAC)
- } else {
- if (line.lineNumber() < linesRects.count()) {
- QRectF r = linesRects.at(line.lineNumber());
- line.setLineWidth(r.width());
- line.setPosition(r.topLeft());
- }
- }
-#endif
-}
-
-/*!
- Lays out the QQuickTextPrivate::layout QTextLayout in the constraints of the QQuickText.
-
- Returns the size of the final text. This can be used to position the text vertically (the text is
- already absolutely positioned horizontally).
-*/
-QRect QQuickTextPrivate::setupTextLayout()
-{
- // ### text layout handling should be profiled and optimized as needed
- // what about QStackTextEngine engine(tmp, d->font.font()); QTextLayout textLayout(&engine);
- Q_Q(QQuickText);
- layout.setCacheEnabled(true);
-
- qreal lineWidth = 0;
- int visibleCount = 0;
-
- //set manual width
- if (q->widthValid())
- lineWidth = q->width();
-
- QTextOption textOption = layout.textOption();
- textOption.setAlignment(Qt::Alignment(q->effectiveHAlign()));
- textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
- if (!cacheAllTextAsImage && !richTextAsImage && !qmlDisableDistanceField())
- textOption.setUseDesignMetrics(true);
- layout.setTextOption(textOption);
-
- QFontMetrics fm(layout.font());
- elidePos = QPointF();
-
- if (requireImplicitWidth && q->widthValid()) {
- // requires an extra layout
- QString elidedText;
- if (layoutTextElided) {
- // We have provided elided text to the layout, but we must calculate unelided width.
- elidedText = layout.text();
- layout.setText(text);
- }
- layout.beginLayout();
- forever {
- QTextLine line = layout.createLine();
- if (!line.isValid())
- break;
- }
- layout.endLayout();
- QRectF br;
- for (int i = 0; i < layout.lineCount(); ++i) {
- QTextLine line = layout.lineAt(i);
- br = br.united(line.naturalTextRect());
- }
- naturalWidth = br.width();
- if (layoutTextElided)
- layout.setText(elidedText);
- }
-
- qreal height = 0;
- QRectF br;
-
- bool truncate = false;
- bool customLayout = isLineLaidOutConnected();
- bool elideEnabled = elideMode == QQuickText::ElideRight && q->widthValid();
-
- layout.beginLayout();
- if (!lineWidth)
- lineWidth = INT_MAX;
- int linesLeft = maximumLineCount;
- int visibleTextLength = 0;
- forever {
- QTextLine line = layout.createLine();
- if (!line.isValid())
- break;
-
- visibleCount++;
-
- qreal preLayoutHeight = height;
- if (customLayout) {
- setupCustomLineGeometry(line, height);
- } else if (lineWidth) {
- line.setLineWidth(lineWidth);
- line.setPosition(QPointF(line.position().x(), height));
- height += (lineHeightMode == QQuickText::FixedHeight) ? lineHeight : line.height() * lineHeight;
- }
-
- bool elide = false;
- if (elideEnabled && q->heightValid() && height > q->height()) {
- // This line does not fit in the remaining area.
- elide = true;
- if (visibleCount > 1) {
- --visibleCount;
- height = preLayoutHeight;
- line.setLineWidth(0.0);
- line.setPosition(QPointF(FLT_MAX,FLT_MAX));
- line = layout.lineAt(visibleCount-1);
- }
- } else {
- visibleTextLength += line.textLength();
- }
-
- if (elide || (maximumLineCountValid && --linesLeft == 0)) {
- if (visibleTextLength < text.length()) {
- truncate = true;
- if (elideEnabled) {
- qreal elideWidth = fm.width(elideChar);
- // Need to correct for alignment
- if (customLayout)
- setupCustomLineGeometry(line, height, elideWidth);
- else
- line.setLineWidth(lineWidth - elideWidth);
- if (layout.text().mid(line.textStart(), line.textLength()).isRightToLeft()) {
- line.setPosition(QPointF(line.position().x() + elideWidth, line.position().y()));
- elidePos.setX(line.naturalTextRect().left() - elideWidth);
- } else {
- elidePos.setX(line.naturalTextRect().right());
- }
- elidePos.setY(line.position().y());
- if (!elipsisLayout)
- elipsisLayout = new QTextLayout(elideChar, layout.font());
- elipsisLayout->beginLayout();
- QTextLine el = elipsisLayout->createLine();
- el.setPosition(elidePos);
- elipsisLayout->endLayout();
- br = br.united(el.naturalTextRect());
- }
- br = br.united(line.naturalTextRect());
- break;
- }
- }
- br = br.united(line.naturalTextRect());
- }
- layout.endLayout();
-
- //Update truncated
- if (truncated != truncate) {
- truncated = truncate;
- emit q->truncatedChanged();
- }
-
- if (!customLayout)
- br.setHeight(height);
-
- if (!q->widthValid())
- naturalWidth = br.width();
-
- //Update the number of visible lines
- if (lineCount != visibleCount) {
- lineCount = visibleCount;
- emit q->lineCountChanged();
- }
-
- return QRect(qRound(br.x()), qRound(br.y()), qCeil(br.width()), qCeil(br.height()));
-}
-
-/*!
- Returns a painted version of the QQuickTextPrivate::layout QTextLayout.
- If \a drawStyle is true, the style color overrides all colors in the document.
-*/
-QPixmap QQuickTextPrivate::textLayoutImage(bool drawStyle)
-{
- QSize size = layedOutTextRect.size();
-
- //paint text
- QPixmap img(size);
- if (!size.isEmpty()) {
- img.fill(Qt::transparent);
-/*#ifdef Q_OS_MAC // Fails on CocoaX64
- bool oldSmooth = qt_applefontsmoothing_enabled;
- qt_applefontsmoothing_enabled = false;
-#endif*/
- QPainter p(&img);
-/*#ifdef Q_OS_MAC // Fails on CocoaX64
- qt_applefontsmoothing_enabled = oldSmooth;
-#endif*/
- drawTextLayout(&p, QPointF(-layedOutTextRect.x(),0), drawStyle);
- }
- return img;
-}
-
-/*!
- Paints the QQuickTextPrivate::layout QTextLayout into \a painter at \a pos. If
- \a drawStyle is true, the style color overrides all colors in the document.
-*/
-void QQuickTextPrivate::drawTextLayout(QPainter *painter, const QPointF &pos, bool drawStyle)
-{
- if (drawStyle)
- painter->setPen(styleColor);
- else
- painter->setPen(color);
- painter->setFont(font);
- layout.draw(painter, pos);
- if (!elidePos.isNull())
- painter->drawText(pos + elidePos, elideChar);
-}
-
-/*!
- Returns a painted version of the QQuickTextPrivate::doc QTextDocument.
- If \a drawStyle is true, the style color overrides all colors in the document.
-*/
-QPixmap QQuickTextPrivate::textDocumentImage(bool drawStyle)
-{
- QSize size = doc->size().toSize();
-
- //paint text
- QPixmap img(size);
- img.fill(Qt::transparent);
-/*#ifdef Q_OS_MAC // Fails on CocoaX64
- bool oldSmooth = qt_applefontsmoothing_enabled;
- qt_applefontsmoothing_enabled = false;
-#endif*/
- QPainter p(&img);
-/*#ifdef Q_OS_MAC // Fails on CocoaX64
- qt_applefontsmoothing_enabled = oldSmooth;
-#endif*/
-
- QAbstractTextDocumentLayout::PaintContext context;
-
- QTextOption oldOption(doc->defaultTextOption());
- if (drawStyle) {
- context.palette.setColor(QPalette::Text, styleColor);
- QTextOption colorOption(doc->defaultTextOption());
- colorOption.setFlags(QTextOption::SuppressColors);
- doc->setDefaultTextOption(colorOption);
- } else {
- context.palette.setColor(QPalette::Text, color);
- }
- doc->documentLayout()->draw(&p, context);
- if (drawStyle)
- doc->setDefaultTextOption(oldOption);
- return img;
-}
-
-/*!
- Mark the image cache as dirty.
-*/
-void QQuickTextPrivate::invalidateImageCache()
-{
- Q_Q(QQuickText);
-
- if (richTextAsImage || cacheAllTextAsImage || (qmlDisableDistanceField() && style != QQuickText::Normal)) { // If actually using the image cache
- if (imageCacheDirty)
- return;
-
- imageCacheDirty = true;
-
- if (q->isComponentComplete())
- QCoreApplication::postEvent(q, new QEvent(QEvent::User));
- } else if (q->isComponentComplete())
- q->update();
-}
-
-/*!
- Tests if the image cache is dirty, and repaints it if it is.
-*/
-void QQuickTextPrivate::checkImageCache()
-{
- Q_Q(QQuickText);
-
- if (!imageCacheDirty)
- return;
-
- if (text.isEmpty()) {
-
- imageCache = QPixmap();
-
- } else {
-
- QPixmap textImage;
- QPixmap styledImage;
-
- if (richText) {
- textImage = textDocumentImage(false);
- if (style != QQuickText::Normal)
- styledImage = textDocumentImage(true); //### should use styleColor
- } else {
- textImage = textLayoutImage(false);
- if (style != QQuickText::Normal)
- styledImage = textLayoutImage(true); //### should use styleColor
- }
-
- switch (style) {
- case QQuickText::Outline:
- imageCache = drawOutline(textImage, styledImage);
- break;
- case QQuickText::Sunken:
- imageCache = drawOutline(textImage, styledImage, -1);
- break;
- case QQuickText::Raised:
- imageCache = drawOutline(textImage, styledImage, 1);
- break;
- default:
- imageCache = textImage;
- break;
- }
-
- }
-
- imageCacheDirty = false;
- textureImageCacheDirty = true;
- q->update();
-}
-
-/*!
- Ensures the QQuickTextPrivate::doc variable is set to a valid text document
-*/
-void QQuickTextPrivate::ensureDoc()
-{
- if (!doc) {
- Q_Q(QQuickText);
- doc = new QQuickTextDocumentWithImageResources(q);
- doc->setDocumentMargin(0);
- }
-}
-
-/*!
- Draw \a styleSource as an outline around \a source and return the new image.
-*/
-QPixmap QQuickTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource)
-{
- QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
- img.fill(Qt::transparent);
-
- QPainter ppm(&img);
-
- QPoint pos(0, 0);
- pos += QPoint(-1, 0);
- ppm.drawPixmap(pos, styleSource);
- pos += QPoint(2, 0);
- ppm.drawPixmap(pos, styleSource);
- pos += QPoint(-1, -1);
- ppm.drawPixmap(pos, styleSource);
- pos += QPoint(0, 2);
- ppm.drawPixmap(pos, styleSource);
-
- pos += QPoint(0, -1);
- ppm.drawPixmap(pos, source);
- ppm.end();
-
- return img;
-}
-
-/*!
- Draw \a styleSource below \a source at \a yOffset and return the new image.
-*/
-QPixmap QQuickTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource, int yOffset)
-{
- QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
- img.fill(Qt::transparent);
-
- QPainter ppm(&img);
-
- ppm.drawPixmap(QPoint(0, yOffset), styleSource);
- ppm.drawPixmap(0, 0, source);
-
- ppm.end();
-
- return img;
-}
-
-/*!
- \qmlclass Text QQuickText
- \inqmlmodule QtQuick 2
- \ingroup qml-basic-visual-elements
- \brief The Text item allows you to add formatted text to a scene.
- \inherits Item
-
- Text items can display both plain and rich text. For example, red text with
- a specific font and size can be defined like this:
-
- \qml
- Text {
- text: "Hello World!"
- font.family: "Helvetica"
- font.pointSize: 24
- color: "red"
- }
- \endqml
-
- Rich text is defined using HTML-style markup:
-
- \qml
- Text {
- text: "<b>Hello</b> <i>World!</i>"
- }
- \endqml
-
- \image declarative-text.png
-
- If height and width are not explicitly set, Text will attempt to determine how
- much room is needed and set it accordingly. Unless \l wrapMode is set, it will always
- prefer width to height (all text will be placed on a single line).
-
- The \l elide property can alternatively be used to fit a single line of
- plain text to a set width.
-
- Note that the \l{Supported HTML Subset} is limited. Also, if the text contains
- HTML img tags that load remote images, the text is reloaded.
-
- Text provides read-only text. For editable text, see \l TextEdit.
-
- \sa {declarative/text/fonts}{Fonts example}
-*/
-QQuickText::QQuickText(QQuickItem *parent)
-: QQuickImplicitSizeItem(*(new QQuickTextPrivate), parent)
-{
- Q_D(QQuickText);
- d->init();
-}
-
-QQuickText::~QQuickText()
-{
-}
-
-/*!
- \qmlproperty bool QtQuick2::Text::clip
- This property holds whether the text is clipped.
-
- Note that if the text does not fit in the bounding rectangle it will be abruptly chopped.
-
- If you want to display potentially long text in a limited space, you probably want to use \c elide instead.
-*/
-
-/*!
- \qmlproperty bool QtQuick2::Text::smooth
-
- This property holds whether the text is smoothly scaled or transformed.
-
- Smooth filtering gives better visual quality, but is slower. If
- the item is displayed at its natural size, this property has no visual or
- performance effect.
-
- \note Generally scaling artifacts are only visible if the item is stationary on
- the screen. A common pattern when animating an item is to disable smooth
- filtering at the beginning of the animation and reenable it at the conclusion.
-*/
-
-/*!
- \qmlsignal QtQuick2::Text::onLineLaidOut(line)
-
- This handler is called for every line during the layout process.
- This gives the opportunity to position and resize a line as it is being laid out.
- It can for example be used to create columns or lay out text around objects.
-
- The properties of a line are:
- \list
- \o number (read-only)
- \o x
- \o y
- \o width
- \o height
- \endlist
-
- For example, this will move the first 5 lines of a text element by 100 pixels to the right:
- \code
- onLineLaidOut: {
- if (line.number < 5) {
- line.x = line.x + 100
- line.width = line.width - 100
- }
- }
- \endcode
-*/
-
-/*!
- \qmlsignal QtQuick2::Text::onLinkActivated(string link)
-
- This handler is called when the user clicks on a link embedded in the text.
- The link must be in rich text or HTML format and the
- \a link string provides access to the particular link.
-
- \snippet doc/src/snippets/declarative/text/onLinkActivated.qml 0
-
- The example code will display the text
- "The main website is at \l{http://qt.nokia.com}{Nokia Qt DF}."
-
- Clicking on the highlighted link will output
- \tt{http://qt.nokia.com link activated} to the console.
-*/
-
-/*!
- \qmlproperty string QtQuick2::Text::font.family
-
- Sets the family name of the font.
-
- The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
- If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
- If the family isn't available a family will be set using the font matching algorithm.
-*/
-
-/*!
- \qmlproperty bool QtQuick2::Text::font.bold
-
- Sets whether the font weight is bold.
-*/
-
-/*!
- \qmlproperty enumeration QtQuick2::Text::font.weight
-
- Sets the font's weight.
-
- The weight can be one of:
- \list
- \o Font.Light
- \o Font.Normal - the default
- \o Font.DemiBold
- \o Font.Bold
- \o Font.Black
- \endlist
-
- \qml
- Text { text: "Hello"; font.weight: Font.DemiBold }
- \endqml
-*/
-
-/*!
- \qmlproperty bool QtQuick2::Text::font.italic
-
- Sets whether the font has an italic style.
-*/
-
-/*!
- \qmlproperty bool QtQuick2::Text::font.underline
-
- Sets whether the text is underlined.
-*/
-
-/*!
- \qmlproperty bool QtQuick2::Text::font.strikeout
-
- Sets whether the font has a strikeout style.
-*/
-
-/*!
- \qmlproperty real QtQuick2::Text::font.pointSize
-
- Sets the font size in points. The point size must be greater than zero.
-*/
-
-/*!
- \qmlproperty int QtQuick2::Text::font.pixelSize
-
- Sets the font size in pixels.
-
- Using this function makes the font device dependent.
- Use \c pointSize to set the size of the font in a device independent manner.
-*/
-
-/*!
- \qmlproperty real QtQuick2::Text::font.letterSpacing
-
- Sets the letter spacing for the font.
-
- Letter spacing changes the default spacing between individual letters in the font.
- A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
-*/
-
-/*!
- \qmlproperty real QtQuick2::Text::font.wordSpacing
-
- Sets the word spacing for the font.
-
- Word spacing changes the default spacing between individual words.
- A positive value increases the word spacing by a corresponding amount of pixels,
- while a negative value decreases the inter-word spacing accordingly.
-*/
-
-/*!
- \qmlproperty enumeration QtQuick2::Text::font.capitalization
-
- Sets the capitalization for the text.
-
- \list
- \o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
- \o Font.AllUppercase - This alters the text to be rendered in all uppercase type.
- \o Font.AllLowercase - This alters the text to be rendered in all lowercase type.
- \o Font.SmallCaps - This alters the text to be rendered in small-caps type.
- \o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
- \endlist
-
- \qml
- Text { text: "Hello"; font.capitalization: Font.AllLowercase }
- \endqml
-*/
-QFont QQuickText::font() const
-{
- Q_D(const QQuickText);
- return d->sourceFont;
-}
-
-void QQuickText::setFont(const QFont &font)
-{
- Q_D(QQuickText);
- if (d->sourceFont == font)
- return;
-
- d->sourceFont = font;
- QFont oldFont = d->font;
- d->font = font;
-
- if (d->font.pointSizeF() != -1) {
- // 0.5pt resolution
- qreal size = qRound(d->font.pointSizeF()*2.0);
- d->font.setPointSizeF(size/2.0);
- }
-
- if (oldFont != d->font)
- d->updateLayout();
-
- emit fontChanged(d->sourceFont);
-}
-
-/*!
- \qmlproperty string QtQuick2::Text::text
-
- The text to display. Text supports both plain and rich text strings.
-
- The item will try to automatically determine whether the text should
- be treated as styled text. This determination is made using Qt::mightBeRichText().
-*/
-QString QQuickText::text() const
-{
- Q_D(const QQuickText);
- return d->text;
-}
-
-void QQuickText::setText(const QString &n)
-{
- Q_D(QQuickText);
- if (d->text == n)
- return;
-
- d->richText = d->format == RichText;
- d->styledText = d->format == StyledText || (d->format == AutoText && Qt::mightBeRichText(n));
- d->text = n;
- if (isComponentComplete()) {
- if (d->richText) {
- d->ensureDoc();
- d->doc->setText(n);
- d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
- d->richTextAsImage = enableImageCache();
- } else {
- d->rightToLeftText = d->text.isRightToLeft();
- }
- d->determineHorizontalAlignment();
- }
- d->textHasChanged = true;
- d->updateLayout();
- emit textChanged(d->text);
-}
-
-/*!
- \qmlproperty color QtQuick2::Text::color
-
- The text color.
-
- An example of green text defined using hexadecimal notation:
- \qml
- Text {
- color: "#00FF00"
- text: "green text"
- }
- \endqml
-
- An example of steel blue text defined using an SVG color name:
- \qml
- Text {
- color: "steelblue"
- text: "blue text"
- }
- \endqml
-*/
-QColor QQuickText::color() const
-{
- Q_D(const QQuickText);
- return d->color;
-}
-
-void QQuickText::setColor(const QColor &color)
-{
- Q_D(QQuickText);
- if (d->color == color)
- return;
-
- d->color = color;
- d->invalidateImageCache();
- emit colorChanged(d->color);
-}
-/*!
- \qmlproperty enumeration QtQuick2::Text::style
-
- Set an additional text style.
-
- Supported text styles are:
- \list
- \o Text.Normal - the default
- \o Text.Outline
- \o Text.Raised
- \o Text.Sunken
- \endlist
-
- \qml
- Row {
- Text { font.pointSize: 24; text: "Normal" }
- Text { font.pointSize: 24; text: "Raised"; style: Text.Raised; styleColor: "#AAAAAA" }
- Text { font.pointSize: 24; text: "Outline";style: Text.Outline; styleColor: "red" }
- Text { font.pointSize: 24; text: "Sunken"; style: Text.Sunken; styleColor: "#AAAAAA" }
- }
- \endqml
-
- \image declarative-textstyle.png
-*/
-QQuickText::TextStyle QQuickText::style() const
-{
- Q_D(const QQuickText);
- return d->style;
-}
-
-void QQuickText::setStyle(QQuickText::TextStyle style)
-{
- Q_D(QQuickText);
- if (d->style == style)
- return;
-
- // changing to/from Normal requires the boundingRect() to change
- if (isComponentComplete() && (d->style == Normal || style == Normal))
- update();
- d->style = style;
- d->invalidateImageCache();
- emit styleChanged(d->style);
-}
-
-/*!
- \qmlproperty color QtQuick2::Text::styleColor
-
- Defines the secondary color used by text styles.
-
- \c styleColor is used as the outline color for outlined text, and as the
- shadow color for raised or sunken text. If no style has been set, it is not
- used at all.
-
- \qml
- Text { font.pointSize: 18; text: "hello"; style: Text.Raised; styleColor: "gray" }
- \endqml
-
- \sa style
- */
-QColor QQuickText::styleColor() const
-{
- Q_D(const QQuickText);
- return d->styleColor;
-}
-
-void QQuickText::setStyleColor(const QColor &color)
-{
- Q_D(QQuickText);
- if (d->styleColor == color)
- return;
-
- d->styleColor = color;
- d->invalidateImageCache();
- emit styleColorChanged(d->styleColor);
-}
-
-/*!
- \qmlproperty enumeration QtQuick2::Text::horizontalAlignment
- \qmlproperty enumeration QtQuick2::Text::verticalAlignment
- \qmlproperty enumeration QtQuick2::Text::effectiveHorizontalAlignment
-
- Sets the horizontal and vertical alignment of the text within the Text items
- width and height. By default, the text is vertically aligned to the top. Horizontal
- alignment follows the natural alignment of the text, for example text that is read
- from left to right will be aligned to the left.
-
- The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight, \c Text.AlignHCenter and
- \c Text.AlignJustify. The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom
- and \c Text.AlignVCenter.
-
- Note that for a single line of text, the size of the text is the area of the text. In this common case,
- all alignments are equivalent. If you want the text to be, say, centered in its parent, then you will
- need to either modify the Item::anchors, or set horizontalAlignment to Text.AlignHCenter and bind the width to
- that of the parent.
-
- When using the attached property LayoutMirroring::enabled to mirror application
- layouts, the horizontal alignment of text will also be mirrored. However, the property
- \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
- of Text, use the read-only property \c effectiveHorizontalAlignment.
-*/
-QQuickText::HAlignment QQuickText::hAlign() const
-{
- Q_D(const QQuickText);
- return d->hAlign;
-}
-
-void QQuickText::setHAlign(HAlignment align)
-{
- Q_D(QQuickText);
- bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
- d->hAlignImplicit = false;
- if (d->setHAlign(align, forceAlign) && isComponentComplete())
- d->updateLayout();
-}
-
-void QQuickText::resetHAlign()
-{
- Q_D(QQuickText);
- d->hAlignImplicit = true;
- if (isComponentComplete() && d->determineHorizontalAlignment())
- d->updateLayout();
-}
-
-QQuickText::HAlignment QQuickText::effectiveHAlign() const
-{
- Q_D(const QQuickText);
- QQuickText::HAlignment effectiveAlignment = d->hAlign;
- if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
- switch (d->hAlign) {
- case QQuickText::AlignLeft:
- effectiveAlignment = QQuickText::AlignRight;
- break;
- case QQuickText::AlignRight:
- effectiveAlignment = QQuickText::AlignLeft;
- break;
- default:
- break;
- }
- }
- return effectiveAlignment;
-}
-
-bool QQuickTextPrivate::setHAlign(QQuickText::HAlignment alignment, bool forceAlign)
-{
- Q_Q(QQuickText);
- if (hAlign != alignment || forceAlign) {
- QQuickText::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
- hAlign = alignment;
-
- emit q->horizontalAlignmentChanged(hAlign);
- if (oldEffectiveHAlign != q->effectiveHAlign())
- emit q->effectiveHorizontalAlignmentChanged();
- return true;
- }
- return false;
-}
-
-bool QQuickTextPrivate::determineHorizontalAlignment()
-{
- if (hAlignImplicit) {
- bool alignToRight = text.isEmpty() ? QGuiApplication::keyboardInputDirection() == Qt::RightToLeft : rightToLeftText;
- return setHAlign(alignToRight ? QQuickText::AlignRight : QQuickText::AlignLeft);
- }
- return false;
-}
-
-void QQuickTextPrivate::mirrorChange()
-{
- Q_Q(QQuickText);
- if (q->isComponentComplete()) {
- if (!hAlignImplicit && (hAlign == QQuickText::AlignRight || hAlign == QQuickText::AlignLeft)) {
- updateLayout();
- emit q->effectiveHorizontalAlignmentChanged();
- }
- }
-}
-
-QTextDocument *QQuickTextPrivate::textDocument()
-{
- return doc;
-}
-
-QQuickText::VAlignment QQuickText::vAlign() const
-{
- Q_D(const QQuickText);
- return d->vAlign;
-}
-
-void QQuickText::setVAlign(VAlignment align)
-{
- Q_D(QQuickText);
- if (d->vAlign == align)
- return;
-
- d->vAlign = align;
- emit verticalAlignmentChanged(align);
-}
-
-/*!
- \qmlproperty enumeration QtQuick2::Text::wrapMode
-
- Set this property to wrap the text to the Text item's width. The text will only
- wrap if an explicit width has been set. wrapMode can be one of:
-
- \list
- \o Text.NoWrap (default) - no wrapping will be performed. If the text contains insufficient newlines, then \l paintedWidth will exceed a set width.
- \o Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, \l paintedWidth will exceed a set width.
- \o Text.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
- \o Text.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
- \endlist
-*/
-QQuickText::WrapMode QQuickText::wrapMode() const
-{
- Q_D(const QQuickText);
- return d->wrapMode;
-}
-
-void QQuickText::setWrapMode(WrapMode mode)
-{
- Q_D(QQuickText);
- if (mode == d->wrapMode)
- return;
-
- d->wrapMode = mode;
- d->updateLayout();
-
- emit wrapModeChanged();
-}
-
-/*!
- \qmlproperty int QtQuick2::Text::lineCount
-
- Returns the number of lines visible in the text item.
-
- This property is not supported for rich text.
-
- \sa maximumLineCount
-*/
-int QQuickText::lineCount() const
-{
- Q_D(const QQuickText);
- return d->lineCount;
-}
-
-/*!
- \qmlproperty bool QtQuick2::Text::truncated
-
- Returns true if the text has been truncated due to \l maximumLineCount
- or \l elide.
-
- This property is not supported for rich text.
-
- \sa maximumLineCount, elide
-*/
-bool QQuickText::truncated() const
-{
- Q_D(const QQuickText);
- return d->truncated;
-}
-
-/*!
- \qmlproperty int QtQuick2::Text::maximumLineCount
-
- Set this property to limit the number of lines that the text item will show.
- If elide is set to Text.ElideRight, the text will be elided appropriately.
- By default, this is the value of the largest possible integer.
-
- This property is not supported for rich text.
-
- \sa lineCount, elide
-*/
-int QQuickText::maximumLineCount() const
-{
- Q_D(const QQuickText);
- return d->maximumLineCount;
-}
-
-void QQuickText::setMaximumLineCount(int lines)
-{
- Q_D(QQuickText);
-
- d->maximumLineCountValid = lines==INT_MAX ? false : true;
- if (d->maximumLineCount != lines) {
- d->maximumLineCount = lines;
- d->updateLayout();
- emit maximumLineCountChanged();
- }
-}
-
-void QQuickText::resetMaximumLineCount()
-{
- Q_D(QQuickText);
- setMaximumLineCount(INT_MAX);
- d->elidePos = QPointF();
- if (d->truncated != false) {
- d->truncated = false;
- emit truncatedChanged();
- }
-}
-
-/*!
- \qmlproperty enumeration QtQuick2::Text::textFormat
-
- The way the text property should be displayed.
-
- Supported text formats are:
-
- \list
- \o Text.AutoText (default)
- \o Text.PlainText
- \o Text.StyledText
- \o Text.RichText
- \endlist
-
- If the text format is \c Text.AutoText the text element
- will automatically determine whether the text should be treated as
- styled text. This determination is made using Qt::mightBeRichText().
-
- Text.StyledText is an optimized format supporting some basic text
- styling markup, in the style of html 3.2:
-
- \code
- <b></b> - bold
- <i></i> - italic
- <br> - new line
- <p> - paragraph
- <u> - underlined text
- <font color="color_name" size="1-7"></font>
- <h1> to <h6> - headers
- <a href=""> - anchor
- <ol type="">, <ul type=""> and <li> - ordered and unordered lists
- &gt; &lt; &amp;
- \endcode
-
- \c Text.StyledText parser is strict, requiring tags to be correctly nested.
-
- \table
- \row
- \o
- \qml
-Column {
- Text {
- font.pointSize: 24
- text: "<b>Hello</b> <i>World!</i>"
- }
- Text {
- font.pointSize: 24
- textFormat: Text.RichText
- text: "<b>Hello</b> <i>World!</i>"
- }
- Text {
- font.pointSize: 24
- textFormat: Text.PlainText
- text: "<b>Hello</b> <i>World!</i>"
- }
-}
- \endqml
- \o \image declarative-textformat.png
- \endtable
-*/
-QQuickText::TextFormat QQuickText::textFormat() const
-{
- Q_D(const QQuickText);
- return d->format;
-}
-
-void QQuickText::setTextFormat(TextFormat format)
-{
- Q_D(QQuickText);
- if (format == d->format)
- return;
- d->format = format;
- bool wasRich = d->richText;
- d->richText = format == RichText;
- d->styledText = format == StyledText || (format == AutoText && Qt::mightBeRichText(d->text));
-
- if (isComponentComplete()) {
- if (!wasRich && d->richText) {
- d->ensureDoc();
- d->doc->setText(d->text);
- d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
- d->richTextAsImage = enableImageCache();
- } else {
- d->rightToLeftText = d->text.isRightToLeft();
- }
- d->determineHorizontalAlignment();
- }
- d->updateLayout();
-
- emit textFormatChanged(d->format);
-}
-
-/*!
- \qmlproperty enumeration QtQuick2::Text::elide
-
- Set this property to elide parts of the text fit to the Text item's width.
- The text will only elide if an explicit width has been set.
-
- This property cannot be used with rich text.
-
- Eliding can be:
- \list
- \o Text.ElideNone - the default
- \o Text.ElideLeft
- \o Text.ElideMiddle
- \o Text.ElideRight
- \endlist
-
- If this property is set to Text.ElideRight, it can be used with multiline
- text. The text will only elide if \c maximumLineCount, or \c height has been set.
- If both \c maximumLineCount and \c height are set, \c maximumLineCount will
- apply unless the lines do not fit in the height allowed.
-
- If the text is a multi-length string, and the mode is not \c Text.ElideNone,
- the first string that fits will be used, otherwise the last will be elided.
-
- Multi-length strings are ordered from longest to shortest, separated by the
- Unicode "String Terminator" character \c U009C (write this in QML with \c{"\u009C"} or \c{"\x9C"}).
-*/
-QQuickText::TextElideMode QQuickText::elideMode() const
-{
- Q_D(const QQuickText);
- return d->elideMode;
-}
-
-void QQuickText::setElideMode(QQuickText::TextElideMode mode)
-{
- Q_D(QQuickText);
- if (mode == d->elideMode)
- return;
-
- d->elideMode = mode;
- d->updateLayout();
-
- emit elideModeChanged(d->elideMode);
-}
-
-/*! \internal */
-QRectF QQuickText::boundingRect() const
-{
- Q_D(const QQuickText);
-
- QRect rect = d->layedOutTextRect;
- if (d->style != Normal)
- rect.adjust(-1, 0, 1, 2);
-
- // Could include font max left/right bearings to either side of rectangle.
-
- int h = height();
- switch (d->vAlign) {
- case AlignTop:
- break;
- case AlignBottom:
- rect.moveTop(h - rect.height());
- break;
- case AlignVCenter:
- rect.moveTop((h - rect.height()) / 2);
- break;
- }
-
- return QRectF(rect);
-}
-
-/*! \internal */
-void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- Q_D(QQuickText);
- bool elide = d->elideMode != QQuickText::ElideNone && widthValid();
- if ((!d->internalWidthUpdate
- && (newGeometry.width() != oldGeometry.width() || (elide && newGeometry.height() != oldGeometry.height())))
- && (d->wrapMode != QQuickText::NoWrap
- || d->elideMode != QQuickText::ElideNone
- || d->hAlign != QQuickText::AlignLeft)) {
- if ((d->singleline || d->maximumLineCountValid || heightValid()) && elide) {
- // We need to re-elide
- d->updateLayout();
- } else {
- // We just need to re-layout
- d->updateSize();
- }
- }
-
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
-}
-
-QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
-{
- Q_UNUSED(data);
- Q_D(QQuickText);
-
- if (d->text.isEmpty()) {
- delete oldNode;
- return 0;
- }
-
- QRectF bounds = boundingRect();
-
- // We need to make sure the layout is done in the current thread
-#if defined(Q_OS_MAC)
- d->paintingThread = QThread::currentThread();
- if (d->layoutThread != d->paintingThread)
- d->updateLayout();
-#endif
-
- // XXX todo - some styled text can be done by the QQuickTextNode
- if (d->richTextAsImage || d->cacheAllTextAsImage || (qmlDisableDistanceField() && d->style != Normal)) {
- bool wasDirty = d->textureImageCacheDirty;
- d->textureImageCacheDirty = false;
-
- if (d->imageCache.isNull()) {
- delete oldNode;
- return 0;
- }
-
- QSGImageNode *node = 0;
- if (!oldNode || d->nodeType != QQuickTextPrivate::NodeIsTexture) {
- delete oldNode;
- node = QQuickItemPrivate::get(this)->sceneGraphContext()->createImageNode();
- d->texture = new QSGPlainTexture();
- wasDirty = true;
- d->nodeType = QQuickTextPrivate::NodeIsTexture;
- } else {
- node = static_cast<QSGImageNode *>(oldNode);
- Q_ASSERT(d->texture);
- }
-
- if (wasDirty) {
- qobject_cast<QSGPlainTexture *>(d->texture)->setImage(d->imageCache.toImage());
- node->setTexture(0);
- node->setTexture(d->texture);
- }
-
- node->setTargetRect(QRectF(bounds.x(), bounds.y(), d->imageCache.width(), d->imageCache.height()));
- node->setSourceRect(QRectF(0, 0, 1, 1));
- node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
- node->setVerticalWrapMode(QSGTexture::ClampToEdge);
- node->setFiltering(QSGTexture::Linear); // Nonsmooth text just ugly, so don't do that..
- node->update();
-
- return node;
-
- } else {
- QQuickTextNode *node = 0;
- if (!oldNode || d->nodeType != QQuickTextPrivate::NodeIsText) {
- delete oldNode;
- node = new QQuickTextNode(QQuickItemPrivate::get(this)->sceneGraphContext());
- d->nodeType = QQuickTextPrivate::NodeIsText;
- } else {
- node = static_cast<QQuickTextNode *>(oldNode);
- }
-
- node->deleteContent();
- node->setMatrix(QMatrix4x4());
-
- if (d->richText) {
- d->ensureDoc();
- node->addTextDocument(bounds.topLeft(), d->doc, d->color, d->style, d->styleColor);
-
- } else {
- node->addTextLayout(QPoint(0, bounds.y()), &d->layout, d->color, d->style, d->styleColor);
- if (d->elipsisLayout)
- node->addTextLayout(QPoint(0, bounds.y()), d->elipsisLayout, d->color, d->style, d->styleColor);
- }
-
- return node;
- }
-}
-
-bool QQuickText::event(QEvent *e)
-{
- Q_D(QQuickText);
- if (e->type() == QEvent::User) {
- d->checkImageCache();
- return true;
- } else {
- return QQuickImplicitSizeItem::event(e);
- }
-}
-
-/*!
- \qmlproperty real QtQuick2::Text::paintedWidth
-
- Returns the width of the text, including width past the width
- which is covered due to insufficient wrapping if WrapMode is set.
-*/
-qreal QQuickText::paintedWidth() const
-{
- Q_D(const QQuickText);
- return d->paintedSize.width();
-}
-
-/*!
- \qmlproperty real QtQuick2::Text::paintedHeight
-
- Returns the height of the text, including height past the height
- which is covered due to there being more text than fits in the set height.
-*/
-qreal QQuickText::paintedHeight() const
-{
- Q_D(const QQuickText);
- return d->paintedSize.height();
-}
-
-/*!
- \qmlproperty real QtQuick2::Text::lineHeight
-
- Sets the line height for the text.
- The value can be in pixels or a multiplier depending on lineHeightMode.
-
- The default value is a multiplier of 1.0.
- The line height must be a positive value.
-*/
-qreal QQuickText::lineHeight() const
-{
- Q_D(const QQuickText);
- return d->lineHeight;
-}
-
-void QQuickText::setLineHeight(qreal lineHeight)
-{
- Q_D(QQuickText);
-
- if ((d->lineHeight == lineHeight) || (lineHeight < 0.0))
- return;
-
- d->lineHeight = lineHeight;
- d->updateLayout();
- emit lineHeightChanged(lineHeight);
-}
-
-/*!
- \qmlproperty enumeration QtQuick2::Text::lineHeightMode
-
- This property determines how the line height is specified.
- The possible values are:
-
- \list
- \o Text.ProportionalHeight (default) - this sets the spacing proportional to the
- line (as a multiplier). For example, set to 2 for double spacing.
- \o Text.FixedHeight - this sets the line height to a fixed line height (in pixels).
- \endlist
-*/
-QQuickText::LineHeightMode QQuickText::lineHeightMode() const
-{
- Q_D(const QQuickText);
- return d->lineHeightMode;
-}
-
-void QQuickText::setLineHeightMode(LineHeightMode mode)
-{
- Q_D(QQuickText);
- if (mode == d->lineHeightMode)
- return;
-
- d->lineHeightMode = mode;
- d->updateLayout();
-
- emit lineHeightModeChanged(mode);
-}
-
-/*!
- Returns the number of resources (images) that are being loaded asynchronously.
-*/
-int QQuickText::resourcesLoading() const
-{
- Q_D(const QQuickText);
- return d->doc ? d->doc->resourcesLoading() : 0;
-}
-
-/*! \internal */
-void QQuickText::componentComplete()
-{
- Q_D(QQuickText);
- if (d->updateOnComponentComplete) {
- if (d->richText) {
- d->ensureDoc();
- d->doc->setText(d->text);
- d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
- d->richTextAsImage = enableImageCache();
- } else {
- d->rightToLeftText = d->text.isRightToLeft();
- }
- d->determineHorizontalAlignment();
- }
- QQuickItem::componentComplete();
- if (d->updateOnComponentComplete)
- d->updateLayout();
-}
-
-
-QString QQuickTextPrivate::anchorAt(const QPointF &mousePos)
-{
- if (styledText) {
- for (int i = 0; i < layout.lineCount(); ++i) {
- QTextLine line = layout.lineAt(i);
- if (line.naturalTextRect().contains(mousePos)) {
- int charPos = line.xToCursor(mousePos.x());
- foreach (const QTextLayout::FormatRange &formatRange, layout.additionalFormats()) {
- if (formatRange.format.isAnchor()
- && charPos >= formatRange.start
- && charPos <= formatRange.start + formatRange.length) {
- return formatRange.format.anchorHref();
- }
- }
- break;
- }
- }
- }
- return QString();
-}
-
-bool QQuickTextPrivate::isLinkActivatedConnected()
-{
- static int idx = this->signalIndex("linkActivated(QString)");
- return this->isSignalConnected(idx);
-}
-
-/*! \internal */
-void QQuickText::mousePressEvent(QMouseEvent *event)
-{
- Q_D(QQuickText);
-
- if (d->isLinkActivatedConnected()) {
- if (d->styledText)
- d->activeLink = d->anchorAt(event->localPos());
- else if (d->richText && d->doc)
- d->activeLink = d->doc->documentLayout()->anchorAt(event->localPos());
- }
-
- if (d->activeLink.isEmpty())
- event->setAccepted(false);
-
- // ### may malfunction if two of the same links are clicked & dragged onto each other)
-
- if (!event->isAccepted())
- QQuickItem::mousePressEvent(event);
-
-}
-
-/*! \internal */
-void QQuickText::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_D(QQuickText);
-
- // ### confirm the link, and send a signal out
-
- QString link;
- if (d->isLinkActivatedConnected()) {
- if (d->styledText)
- link = d->anchorAt(event->localPos());
- else if (d->richText && d->doc)
- link = d->doc->documentLayout()->anchorAt(event->localPos());
- }
-
- if (!link.isEmpty() && d->activeLink == link)
- emit linkActivated(d->activeLink);
- else
- event->setAccepted(false);
-
- if (!event->isAccepted())
- QQuickItem::mouseReleaseEvent(event);
-}
-
-QT_END_NAMESPACE
-
-#include "qquicktext.moc"