summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qpainter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting/qpainter.cpp')
-rw-r--r--src/gui/painting/qpainter.cpp107
1 files changed, 65 insertions, 42 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 3f387d575b..4a2898375e 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1,40 +1,32 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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.
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia 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.
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -229,16 +221,11 @@ QTransform QPainterPrivate::viewTransform() const
int QPainterPrivate::effectiveDevicePixelRatio() const
{
- // Limited feature introduction for Qt 5.0.0, remove ifdef in a later release.
-#ifdef Q_OS_MAC
// Special cases for devices that does not support PdmDevicePixelRatio go here:
if (device->devType() == QInternal::Printer)
return 1;
return qMax(1, device->metric(QPaintDevice::PdmDevicePixelRatio));
-#else
- return 1;
-#endif
}
QTransform QPainterPrivate::hidpiScaleTransform() const
@@ -1111,6 +1098,11 @@ void QPainterPrivate::updateState(QPainterState *newState)
\li \inlineimage qpainter-pathstroking.png
\endtable
+ Text drawing is done using drawText(). When you need
+ fine-grained positioning, boundingRect() tells you where a given
+ drawText() command will draw.
+
+ \section1 Drawing Pixmaps and Images
There are functions to draw pixmaps/images, namely drawPixmap(),
drawImage() and drawTiledPixmap(). Both drawPixmap() and drawImage()
@@ -1118,15 +1110,25 @@ void QPainterPrivate::updateState(QPainterState *newState)
on-screen while drawImage() may be faster on a QPrinter or other
devices.
- Text drawing is done using drawText(). When you need
- fine-grained positioning, boundingRect() tells you where a given
- drawText() command will draw.
-
There is a drawPicture() function that draws the contents of an
entire QPicture. The drawPicture() function is the only function
that disregards all the painter's settings as QPicture has its own
settings.
+ \section2 Drawing High Resolution Versions of Pixmaps and Images
+
+ High resolution versions of pixmaps have a \e{device pixel ratio} value larger
+ than 1 (see QImageReader, QPixmap::devicePixelRatio()). Should it match the value
+ of the underlying QPaintDevice, it is drawn directly onto the device with no
+ additional transformation applied.
+
+ This is for example the case when drawing a QPixmap of 64x64 pixels size with
+ a device pixel ratio of 2 onto a high DPI screen which also has
+ a device pixel ratio of 2. Note that the pixmap is then effectively 32x32
+ pixels in \e{user space}. Code paths in Qt that calculate layout geometry
+ based on the pixmap size will use this size. The net effect of this is that
+ the pixmap is displayed as high DPI pixmap rather than a large pixmap.
+
\section1 Rendering Quality
To get the optimal rendering result using QPainter, you should use
@@ -5029,6 +5031,8 @@ static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransfor
into the given \a target in the paint device.
\note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
+ \note See \l{Drawing High Resolution Versions of Pixmaps and Images} on how this is affected
+ by QPixmap::devicePixelRatio().
\table 100%
\row
@@ -5043,7 +5047,7 @@ static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransfor
transparent. Drawing bitmaps with gradient or texture colors is
not supported.
- \sa drawImage()
+ \sa drawImage(), QPixmap::devicePixelRatio()
*/
void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
{
@@ -5607,6 +5611,8 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positio
staticTextItem.numGlyphs = glyphCount;
staticTextItem.glyphs = reinterpret_cast<glyph_t *>(const_cast<glyph_t *>(glyphArray));
staticTextItem.glyphPositions = positions;
+ // The font property is meaningless, the fontengine must be used directly:
+ staticTextItem.usesRawFont = true;
extended->drawStaticTextItem(&staticTextItem);
} else {
@@ -6422,6 +6428,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText
continue;
+ multi->ensureEngineAt(which);
QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
ti2.width = 0;
// set the high byte to zero and calc the width
@@ -6449,6 +6456,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText
which = e;
}
+ multi->ensureEngineAt(which);
QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
ti2.width = 0;
// set the high byte to zero and calc the width
@@ -7404,8 +7412,6 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
tf |= Qt::TextDontPrint;
uint maxUnderlines = 0;
- int numUnderlines = 0;
- QVarLengthArray<int, 32> underlinePositions(1);
QFontMetricsF fm(fnt);
QString text = str;
@@ -7436,11 +7442,15 @@ start_lengthVariant:
}
}
+ // no need to do extra work for underlines if we don't paint
+ if (tf & Qt::TextDontPrint)
+ maxUnderlines = 0;
+
+ QList<QTextLayout::FormatRange> underlineFormats;
int length = offset - old_offset;
if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
- underlinePositions.resize(maxUnderlines + 1);
-
QChar *cout = text.data() + old_offset;
+ QChar *cout0 = cout;
QChar *cin = cout;
int l = length;
while (l) {
@@ -7450,8 +7460,24 @@ start_lengthVariant:
--l;
if (!l)
break;
- if (*cin != QLatin1Char('&') && !hidemnmemonic)
- underlinePositions[numUnderlines++] = cout - text.data() - old_offset;
+ if (*cin != QLatin1Char('&') && !hidemnmemonic) {
+ QTextLayout::FormatRange range;
+ range.start = cout - cout0;
+ range.length = 1;
+ range.format.setFontUnderline(true);
+ underlineFormats.append(range);
+ }
+ } else if (hidemnmemonic && *cin == QLatin1Char('(') && l >= 4 &&
+ cin[1] == QLatin1Char('&') && cin[2] != QLatin1Char('&') &&
+ cin[3] == QLatin1Char(')')) {
+ int n = 0;
+ while ((cout - n) > cout0 && (cout - n - 1)->isSpace())
+ ++n;
+ cout -= n;
+ cin += 4;
+ length -= n + 4;
+ l -= 4;
+ continue;
}
*cout = *cin;
++cout;
@@ -7460,11 +7486,6 @@ start_lengthVariant:
}
}
- // no need to do extra work for underlines if we don't paint
- if (tf & Qt::TextDontPrint)
- numUnderlines = 0;
-
- underlinePositions[numUnderlines] = -1;
qreal height = 0;
qreal width = 0;
@@ -7497,7 +7518,7 @@ start_lengthVariant:
engine.forceJustification = true;
QTextLayout textLayout(&engine);
textLayout.setCacheEnabled(true);
- textLayout.engine()->underlinePositions = underlinePositions.data();
+ textLayout.setAdditionalFormats(underlineFormats);
if (finalText.isEmpty()) {
height = fm.height();
@@ -7685,6 +7706,8 @@ void QPainterState::init(QPainter *p) {
into the \a target rectangle in the paint device.
\note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
+ \note See \l{Drawing High Resolution Versions of Pixmaps and Images} on how this is affected
+ by QImage::devicePixelRatio().
If the image needs to be modified to fit in a lower-resolution
result (e.g. converting from 32-bit to 8-bit), use the \a flags to
@@ -7696,7 +7719,7 @@ void QPainterState::init(QPainter *p) {
\snippet code/src_gui_painting_qpainter.cpp 20
\endtable
- \sa drawPixmap()
+ \sa drawPixmap(), QImage::devicePixelRatio()
*/
/*!