QTextDocument: Fix device scaling for QTextFrameFormat margins, padding and border
Those values must be scaled to device coordinates - otherwise borders, margins etc. will be too small when rendered on high dpi devices (printers etc.). This change will add the scaling to those values. QTextDocument::print applies 2cm margins to the root frame of a unpaginated QTextDocument. Those margins were previously scaled to device coordinates in order to give the correct result. But because scaling is now done inside QTextDocumentLayout that scaling must be removed and pixel values based on qt_defaultDpi are provided instead. Fixes: QTBUG-78318 Change-Id: I6fe6dcc25f846341f6a2fe5df2f54baea473fdfd Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
6cee284001
commit
4a240bb67e
src/gui/text
tests/auto/widgets/widgets/qtextedit
@ -1970,9 +1970,12 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
|
||||
QRectF body = QRectF(QPointF(0, 0), d->pageSize);
|
||||
QPointF pageNumberPos;
|
||||
|
||||
qreal sourceDpiX = qt_defaultDpiX();
|
||||
qreal sourceDpiY = qt_defaultDpiY();
|
||||
const qreal dpiScaleX = qreal(printer->logicalDpiX()) / sourceDpiX;
|
||||
const qreal dpiScaleY = qreal(printer->logicalDpiY()) / sourceDpiY;
|
||||
|
||||
if (documentPaginated) {
|
||||
qreal sourceDpiX = qt_defaultDpi();
|
||||
qreal sourceDpiY = sourceDpiX;
|
||||
|
||||
QPaintDevice *dev = doc->documentLayout()->paintDevice();
|
||||
if (dev) {
|
||||
@ -1980,9 +1983,6 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
|
||||
sourceDpiY = dev->logicalDpiY();
|
||||
}
|
||||
|
||||
const qreal dpiScaleX = qreal(printer->logicalDpiX()) / sourceDpiX;
|
||||
const qreal dpiScaleY = qreal(printer->logicalDpiY()) / sourceDpiY;
|
||||
|
||||
// scale to dpi
|
||||
p.scale(dpiScaleX, dpiScaleY);
|
||||
|
||||
@ -2011,15 +2011,21 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
|
||||
// copy the custom object handlers
|
||||
layout->d_func()->handlers = documentLayout()->d_func()->handlers;
|
||||
|
||||
int dpiy = p.device()->logicalDpiY();
|
||||
int margin = (int) ((2/2.54)*dpiy); // 2 cm margins
|
||||
// 2 cm margins, scaled to device in QTextDocumentLayoutPrivate::layoutFrame
|
||||
const int horizontalMargin = int((2/2.54)*sourceDpiX);
|
||||
const int verticalMargin = int((2/2.54)*sourceDpiY);
|
||||
QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
|
||||
fmt.setMargin(margin);
|
||||
fmt.setLeftMargin(horizontalMargin);
|
||||
fmt.setRightMargin(horizontalMargin);
|
||||
fmt.setTopMargin(verticalMargin);
|
||||
fmt.setBottomMargin(verticalMargin);
|
||||
doc->rootFrame()->setFrameFormat(fmt);
|
||||
|
||||
// pageNumberPos must be in device coordinates, so scale to device here
|
||||
const int dpiy = p.device()->logicalDpiY();
|
||||
body = QRectF(0, 0, printer->width(), printer->height());
|
||||
pageNumberPos = QPointF(body.width() - margin,
|
||||
body.height() - margin
|
||||
pageNumberPos = QPointF(body.width() - horizontalMargin * dpiScaleX,
|
||||
body.height() - verticalMargin * dpiScaleY
|
||||
+ QFontMetrics(doc->defaultFont(), p.device()).ascent()
|
||||
+ 5 * dpiy / 72.0);
|
||||
clonedDoc->setPageSize(body.size());
|
||||
|
@ -2915,24 +2915,24 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in
|
||||
{
|
||||
QTextFrameFormat fformat = f->frameFormat();
|
||||
// set sizes of this frame from the format
|
||||
QFixed tm = QFixed::fromReal(fformat.topMargin());
|
||||
QFixed tm = QFixed::fromReal(scaleToDevice(fformat.topMargin())).round();
|
||||
if (tm != fd->topMargin) {
|
||||
fd->topMargin = tm;
|
||||
fullLayout = true;
|
||||
}
|
||||
QFixed bm = QFixed::fromReal(fformat.bottomMargin());
|
||||
QFixed bm = QFixed::fromReal(scaleToDevice(fformat.bottomMargin())).round();
|
||||
if (bm != fd->bottomMargin) {
|
||||
fd->bottomMargin = bm;
|
||||
fullLayout = true;
|
||||
}
|
||||
fd->leftMargin = QFixed::fromReal(fformat.leftMargin());
|
||||
fd->rightMargin = QFixed::fromReal(fformat.rightMargin());
|
||||
QFixed b = QFixed::fromReal(fformat.border());
|
||||
fd->leftMargin = QFixed::fromReal(scaleToDevice(fformat.leftMargin())).round();
|
||||
fd->rightMargin = QFixed::fromReal(scaleToDevice(fformat.rightMargin())).round();
|
||||
QFixed b = QFixed::fromReal(scaleToDevice(fformat.border())).round();
|
||||
if (b != fd->border) {
|
||||
fd->border = b;
|
||||
fullLayout = true;
|
||||
}
|
||||
QFixed p = QFixed::fromReal(fformat.padding());
|
||||
QFixed p = QFixed::fromReal(scaleToDevice(fformat.padding())).round();
|
||||
if (p != fd->padding) {
|
||||
fd->padding = p;
|
||||
fullLayout = true;
|
||||
|
@ -1978,8 +1978,23 @@ void tst_QTextEdit::fullWidthSelection_data()
|
||||
#endif
|
||||
|
||||
#ifdef QT_BUILD_INTERNAL
|
||||
|
||||
// With the fix for QTBUG-78318 scaling of documentMargin is added. The testing framework
|
||||
// forces qt_defaultDpi() to always return 96 DPI. For systems where the actual DPI differs
|
||||
// (typically 72 DPI) this would now cause scaling of the documentMargin when
|
||||
// drawing QTextEdit into QImage. In order to avoid the need of multiple reference PNGs
|
||||
// for comparison we disable the Qt::AA_Use96Dpi attribute for these tests.
|
||||
|
||||
struct ForceSystemDpiHelper {
|
||||
ForceSystemDpiHelper() { QCoreApplication::setAttribute(Qt::AA_Use96Dpi, false); }
|
||||
~ForceSystemDpiHelper() { QCoreApplication::setAttribute(Qt::AA_Use96Dpi, old); }
|
||||
bool old = QCoreApplication::testAttribute(Qt::AA_Use96Dpi);
|
||||
};
|
||||
|
||||
void tst_QTextEdit::fullWidthSelection()
|
||||
{
|
||||
ForceSystemDpiHelper useSystemDpi;
|
||||
|
||||
QFETCH(int, cursorFrom);
|
||||
QFETCH(int, cursorTo);
|
||||
QFETCH(QString, imageFileName);
|
||||
@ -2048,6 +2063,8 @@ void tst_QTextEdit::fullWidthSelection()
|
||||
#ifdef QT_BUILD_INTERNAL
|
||||
void tst_QTextEdit::fullWidthSelection2()
|
||||
{
|
||||
ForceSystemDpiHelper useSystemDpi;
|
||||
|
||||
QPalette myPalette;
|
||||
myPalette.setColor(QPalette::All, QPalette::HighlightedText, QColor(0,0,0,0));
|
||||
myPalette.setColor(QPalette::All, QPalette::Highlight, QColor(239,221,85));
|
||||
|
Loading…
Reference in New Issue
Block a user