source: trunk/src/gui/text/qtextimagehandler.cpp@ 64

Last change on this file since 64 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 7.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42
43#include "qtextimagehandler_p.h"
44
45#include <qapplication.h>
46#include <qtextformat.h>
47#include <qpainter.h>
48#include <qdebug.h>
49#include <private/qtextengine_p.h>
50#include <qpalette.h>
51#include <qtextbrowser.h>
52#include <qthread.h>
53
54QT_BEGIN_NAMESPACE
55
56// set by the mime source factory in Qt3Compat
57QTextImageHandler::ExternalImageLoaderFunction QTextImageHandler::externalLoader = 0;
58
59static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format)
60{
61 QPixmap pm;
62
63 QString name = format.name();
64 if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
65 name.prepend(QLatin1String("qrc"));
66 QUrl url = QUrl::fromEncoded(name.toUtf8());
67 const QVariant data = doc->resource(QTextDocument::ImageResource, url);
68 if (data.type() == QVariant::Pixmap || data.type() == QVariant::Image) {
69 pm = qvariant_cast<QPixmap>(data);
70 } else if (data.type() == QVariant::ByteArray) {
71 pm.loadFromData(data.toByteArray());
72 }
73
74 if (pm.isNull()) {
75 QString context;
76#ifndef QT_NO_TEXTBROWSER
77 QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
78 if (browser)
79 context = browser->source().toString();
80#endif
81 QImage img;
82 if (QTextImageHandler::externalLoader)
83 img = QTextImageHandler::externalLoader(name, context);
84
85 if (img.isNull()) { // try direct loading
86 name = format.name(); // remove qrc:/ prefix again
87 if (name.isEmpty() || !img.load(name))
88 return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/file-16.png"));
89 }
90 pm = QPixmap::fromImage(img);
91 doc->addResource(QTextDocument::ImageResource, url, pm);
92 }
93
94 return pm;
95}
96
97static QSize getPixmapSize(QTextDocument *doc, const QTextImageFormat &format)
98{
99 QPixmap pm;
100
101 const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
102 const int width = qRound(format.width());
103 const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
104 const int height = qRound(format.height());
105
106 QSize size(width, height);
107 if (!hasWidth || !hasHeight) {
108 pm = getPixmap(doc, format);
109 if (!hasWidth) {
110 if (!hasHeight)
111 size.setWidth(pm.width());
112 else
113 size.setWidth(qRound(height * (pm.width() / (qreal) pm.height())));
114 }
115 if (!hasHeight) {
116 if (!hasWidth)
117 size.setHeight(pm.height());
118 else
119 size.setHeight(qRound(width * (pm.height() / (qreal) pm.width())));
120 }
121 }
122
123 qreal scale = 1.0;
124 QPaintDevice *pdev = doc->documentLayout()->paintDevice();
125 if (pdev) {
126 extern int qt_defaultDpi();
127 if (pm.isNull())
128 pm = getPixmap(doc, format);
129 if (!pm.isNull())
130 scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
131 }
132 size *= scale;
133
134 return size;
135}
136
137static QImage getImage(QTextDocument *doc, const QTextImageFormat &format)
138{
139 QImage image;
140
141 QString name = format.name();
142 if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
143 name.prepend(QLatin1String("qrc"));
144 QUrl url = QUrl::fromEncoded(name.toUtf8());
145 const QVariant data = doc->resource(QTextDocument::ImageResource, url);
146 if (data.type() == QVariant::Image) {
147 image = qvariant_cast<QImage>(data);
148 } else if (data.type() == QVariant::ByteArray) {
149 image.loadFromData(data.toByteArray());
150 }
151
152 if (image.isNull()) {
153 QString context;
154#ifndef QT_NO_TEXTBROWSER
155 QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
156 if (browser)
157 context = browser->source().toString();
158#endif
159 if (QTextImageHandler::externalLoader)
160 image = QTextImageHandler::externalLoader(name, context);
161
162 if (image.isNull()) { // try direct loading
163 name = format.name(); // remove qrc:/ prefix again
164 if (name.isEmpty() || !image.load(name))
165 return QImage(QLatin1String(":/trolltech/styles/commonstyle/images/file-16.png"));
166 }
167 doc->addResource(QTextDocument::ImageResource, url, image);
168 }
169
170 return image;
171}
172
173static QSize getImageSize(QTextDocument *doc, const QTextImageFormat &format)
174{
175 QImage image;
176
177 const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
178 const int width = qRound(format.width());
179 const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
180 const int height = qRound(format.height());
181
182 QSize size(width, height);
183 if (!hasWidth || !hasHeight) {
184 image = getImage(doc, format);
185 if (!hasWidth)
186 size.setWidth(image.width());
187 if (!hasHeight)
188 size.setHeight(image.height());
189 }
190
191 qreal scale = 1.0;
192 QPaintDevice *pdev = doc->documentLayout()->paintDevice();
193 if (pdev) {
194 extern int qt_defaultDpi();
195 if (image.isNull())
196 image = getImage(doc, format);
197 if (!image.isNull())
198 scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
199 }
200 size *= scale;
201
202 return size;
203}
204
205QTextImageHandler::QTextImageHandler(QObject *parent)
206 : QObject(parent)
207{
208}
209
210QSizeF QTextImageHandler::intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format)
211{
212 Q_UNUSED(posInDocument)
213 const QTextImageFormat imageFormat = format.toImageFormat();
214
215 if (qApp->thread() != QThread::currentThread())
216 return getImageSize(doc, imageFormat);
217 return getPixmapSize(doc, imageFormat);
218}
219
220void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format)
221{
222 Q_UNUSED(posInDocument)
223 const QTextImageFormat imageFormat = format.toImageFormat();
224
225 if (qApp->thread() != QThread::currentThread()) {
226 const QImage image = getImage(doc, imageFormat);
227 p->drawImage(rect, image, image.rect());
228 } else {
229 const QPixmap pixmap = getPixmap(doc, imageFormat);
230 p->drawPixmap(rect, pixmap, pixmap.rect());
231 }
232}
233
234QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.