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.cpp77
1 files changed, 54 insertions, 23 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 3f387d575b..3af8fdea2e 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -229,16 +229,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 +1106,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 +1118,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 +5039,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 +5055,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 +5619,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 +6436,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 +6464,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 +7420,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 +7450,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 +7468,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 +7494,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 +7526,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 +7714,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 +7727,7 @@ void QPainterState::init(QPainter *p) {
\snippet code/src_gui_painting_qpainter.cpp 20
\endtable
- \sa drawPixmap()
+ \sa drawPixmap(), QImage::devicePixelRatio()
*/
/*!