summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-09-03 18:42:30 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-09-04 08:37:59 +0200
commit00a5629d8de18bc1a5dfb6e2526c03b4b021c903 (patch)
treed444ede3eb66e5455e09c4de3fda32bcd7437a4a /tests/auto
parent6b171dc6c0c0f0a822b212df77b58b28bd92716c (diff)
Remove deprecated QPrinter and QPagedPaintDevice APIs
Adjusting the QPrinter test case - some use cases no longer exist, or are already tested in QPageSize and QPageLayout tests. Adjust examples and manual tests. Change-Id: I01cbc65f3d8031aea2dac86dd942126ba708b111 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/gui/painting/qpdfwriter/tst_qpdfwriter.cpp91
-rw-r--r--tests/auto/gui/text/qtexttable/tst_qtexttable.cpp2
-rw-r--r--tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp696
3 files changed, 288 insertions, 501 deletions
diff --git a/tests/auto/gui/painting/qpdfwriter/tst_qpdfwriter.cpp b/tests/auto/gui/painting/qpdfwriter/tst_qpdfwriter.cpp
index 36b8a4726b..8c98a8ad98 100644
--- a/tests/auto/gui/painting/qpdfwriter/tst_qpdfwriter.cpp
+++ b/tests/auto/gui/painting/qpdfwriter/tst_qpdfwriter.cpp
@@ -65,50 +65,49 @@ void tst_QPdfWriter::basics()
QCOMPARE(writer.resolution(), 600);
QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::A4);
- QCOMPARE(writer.pageSize(), QPdfWriter::A4);
- QCOMPARE(writer.pageSizeMM(), QSizeF(210, 297));
+ QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::A4);
+ QCOMPARE(writer.pageLayout().pageSize().size(QPageSize::Millimeter), QSizeF(210, 297));
writer.setPageSize(QPageSize(QPageSize::A5));
QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::A5);
- QCOMPARE(writer.pageSize(), QPdfWriter::A5);
- QCOMPARE(writer.pageSizeMM(), QSizeF(148, 210));
+ QCOMPARE(writer.pageLayout().pageSize().size(QPageSize::Millimeter), QSizeF(148, 210));
writer.setPageSize(QPageSize(QPageSize::A3));
QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::A3);
- QCOMPARE(writer.pageSize(), QPdfWriter::A3);
- QCOMPARE(writer.pageSizeMM(), QSizeF(297, 420));
+ QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::A3);
+ QCOMPARE(writer.pageLayout().pageSize().size(QPageSize::Millimeter), QSizeF(297, 420));
writer.setPageSize(QPageSize(QSize(210, 297), QPageSize::Millimeter));
QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::A4);
- QCOMPARE(writer.pageSize(), QPdfWriter::A4);
- QCOMPARE(writer.pageSizeMM(), QSizeF(210, 297));
+ QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::A4);
+ QCOMPARE(writer.pageLayout().pageSize().size(QPageSize::Millimeter), QSizeF(210, 297));
QCOMPARE(writer.pageLayout().orientation(), QPageLayout::Portrait);
writer.setPageOrientation(QPageLayout::Landscape);
QCOMPARE(writer.pageLayout().orientation(), QPageLayout::Landscape);
- QCOMPARE(writer.pageSizeMM(), QSizeF(210, 297));
+ QCOMPARE(writer.pageLayout().pageSize().size(QPageSize::Millimeter), QSizeF(210, 297));
QCOMPARE(writer.pageLayout().margins(), QMarginsF(10, 10, 10, 10));
QCOMPARE(writer.pageLayout().units(), QPageLayout::Point);
- QCOMPARE(writer.margins().left(), 3.53); // mm
- QCOMPARE(writer.margins().right(), 3.53);
- QCOMPARE(writer.margins().top(), 3.53);
- QCOMPARE(writer.margins().bottom(), 3.53);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).left(), 3.53); // mm
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).right(), 3.53);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).top(), 3.53);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).bottom(), 3.53);
writer.setPageMargins(QMarginsF(20, 20, 20, 20), QPageLayout::Millimeter);
QCOMPARE(writer.pageLayout().margins(), QMarginsF(20, 20, 20, 20));
QCOMPARE(writer.pageLayout().units(), QPageLayout::Millimeter);
- QCOMPARE(writer.margins().left(), 20.0);
- QCOMPARE(writer.margins().right(), 20.0);
- QCOMPARE(writer.margins().top(), 20.0);
- QCOMPARE(writer.margins().bottom(), 20.0);
+ QCOMPARE(writer.pageLayout().margins().left(), 20.0);
+ QCOMPARE(writer.pageLayout().margins().right(), 20.0);
+ QCOMPARE(writer.pageLayout().margins().top(), 20.0);
+ QCOMPARE(writer.pageLayout().margins().bottom(), 20.0);
const QMarginsF margins = {50, 50, 50, 50};
writer.setPageMargins(margins, QPageLayout::Millimeter);
QCOMPARE(writer.pageLayout().margins(), margins);
QCOMPARE(writer.pageLayout().units(), QPageLayout::Millimeter);
- QCOMPARE(writer.margins().left(), 50.0);
- QCOMPARE(writer.margins().right(), 50.0);
- QCOMPARE(writer.margins().top(), 50.0);
- QCOMPARE(writer.margins().bottom(), 50.0);
+ QCOMPARE(writer.pageLayout().margins().left(), 50.0);
+ QCOMPARE(writer.pageLayout().margins().right(), 50.0);
+ QCOMPARE(writer.pageLayout().margins().top(), 50.0);
+ QCOMPARE(writer.pageLayout().margins().bottom(), 50.0);
QCOMPARE(writer.pageLayout().fullRect(QPageLayout::Millimeter), QRectF(0, 0, 297, 210));
QCOMPARE(writer.pageLayout().paintRect(QPageLayout::Millimeter), QRectF(50, 50, 197, 110));
@@ -185,10 +184,10 @@ void tst_QPdfWriter::testPageMetrics()
if (setMargins) {
// Setup the given margins
writer.setPageMargins({leftMMf, topMMf, rightMMf, bottomMMf}, QPageLayout::Millimeter);
- QCOMPARE(writer.margins().left(), leftMMf);
- QCOMPARE(writer.margins().right(), rightMMf);
- QCOMPARE(writer.margins().top(), topMMf);
- QCOMPARE(writer.margins().bottom(), bottomMMf);
+ QCOMPARE(writer.pageLayout().margins().left(), leftMMf);
+ QCOMPARE(writer.pageLayout().margins().right(), rightMMf);
+ QCOMPARE(writer.pageLayout().margins().top(), topMMf);
+ QCOMPARE(writer.pageLayout().margins().bottom(), bottomMMf);
}
// Set the given size, in Portrait mode
@@ -196,16 +195,16 @@ void tst_QPdfWriter::testPageMetrics()
? QPageSize(sizeMMf, QPageSize::Millimeter) : QPageSize(pageSizeId);
writer.setPageSize(pageSize);
QCOMPARE(writer.pageLayout().pageSize().id(), pageSizeId);
- QCOMPARE(int(writer.pageSize()), int(pageSizeId));
+ QCOMPARE(int(writer.pageLayout().pageSize().id()), int(pageSizeId));
QCOMPARE(writer.pageLayout().orientation(), QPageLayout::Portrait);
- QCOMPARE(writer.margins().left(), leftMMf);
- QCOMPARE(writer.margins().right(), rightMMf);
- QCOMPARE(writer.margins().top(), topMMf);
- QCOMPARE(writer.margins().bottom(), bottomMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).left(), leftMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).right(), rightMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).top(), topMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).bottom(), bottomMMf);
- // QPagedPaintDevice::pageSizeMM() always returns Portrait
- QCOMPARE(writer.pageSizeMM(), sizeMMf);
+ // QPagedPaintDevice::pageLayout().pageSize().size(QPageSize::Millimeter) always returns Portrait
+ QCOMPARE(writer.pageLayout().pageSize().size(QPageSize::Millimeter), sizeMMf);
// QPagedPaintDevice::widthMM() and heightMM() are paint metrics and always return set orientation
QCOMPARE(writer.widthMM(), qRound(widthMMf - leftMMf - rightMMf));
@@ -214,15 +213,15 @@ void tst_QPdfWriter::testPageMetrics()
// Now switch to Landscape mode, size should be unchanged, but rect and metrics should change
writer.setPageOrientation(QPageLayout::Landscape);
QCOMPARE(writer.pageLayout().pageSize().id(), pageSizeId);
- QCOMPARE(int(writer.pageSize()), int(pageSizeId));
+ QCOMPARE(int(writer.pageLayout().pageSize().id()), int(pageSizeId));
QCOMPARE(writer.pageLayout().orientation(), QPageLayout::Landscape);
- QCOMPARE(writer.margins().left(), leftMMf);
- QCOMPARE(writer.margins().right(), rightMMf);
- QCOMPARE(writer.margins().top(), topMMf);
- QCOMPARE(writer.margins().bottom(), bottomMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).left(), leftMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).right(), rightMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).top(), topMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).bottom(), bottomMMf);
- // QPagedPaintDevice::pageSizeMM() always returns Portrait
- QCOMPARE(writer.pageSizeMM(), sizeMMf);
+ // QPagedPaintDevice::pageLayout().pageSize().size(QPageSize::Millimeter) always returns Portrait
+ QCOMPARE(writer.pageLayout().pageSize().size(QPageSize::Millimeter), sizeMMf);
// QPagedPaintDevice::widthMM() and heightMM() are paint metrics and always return set orientation
QCOMPARE(writer.widthMM(), qRound(heightMMf - leftMMf - rightMMf));
@@ -238,15 +237,15 @@ void tst_QPdfWriter::testPageMetrics()
// Now while in Landscape mode, set the size again, results should be the same
writer.setPageSize(pageSize);
QCOMPARE(writer.pageLayout().pageSize().id(), pageSizeId);
- QCOMPARE(int(writer.pageSize()), int(pageSizeId));
+ QCOMPARE(int(writer.pageLayout().pageSize().id()), int(pageSizeId));
QCOMPARE(writer.pageLayout().orientation(), QPageLayout::Landscape);
- QCOMPARE(writer.margins().left(), leftMMf);
- QCOMPARE(writer.margins().right(), rightMMf);
- QCOMPARE(writer.margins().top(), topMMf);
- QCOMPARE(writer.margins().bottom(), bottomMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).left(), leftMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).right(), rightMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).top(), topMMf);
+ QCOMPARE(writer.pageLayout().margins(QPageLayout::Millimeter).bottom(), bottomMMf);
- // QPagedPaintDevice::pageSizeMM() always returns Portrait
- QCOMPARE(writer.pageSizeMM(), sizeMMf);
+ // QPagedPaintDevice::pageLayout().pageSize().size(QPageSize::Millimeter) always returns Portrait
+ QCOMPARE(writer.pageLayout().pageSize().size(QPageSize::Millimeter), sizeMMf);
// QPagedPaintDevice::widthMM() and heightMM() are paint metrics and always return set orientation
QCOMPARE(writer.widthMM(), qRound(heightMMf - leftMMf - rightMMf));
diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
index 474079037b..2b0236339c 100644
--- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
+++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
@@ -1161,7 +1161,7 @@ void tst_QTextTable::QTBUG31330_renderBackground()
}
QTBUG31330_PaintDevice::PaintEngine engine;
QTBUG31330_PaintDevice paintDevice(&engine);
- paintDevice.setPageSize(QPagedPaintDevice::A4);
+ paintDevice.setPageSize(QPageSize(QPageSize::A4));
doc.print(&paintDevice);
QVERIFY(paintDevice.pages >= 2);
diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
index f3a6c4c695..d6c236e76e 100644
--- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
+++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
@@ -52,8 +52,6 @@
typedef QSharedPointer<QPrinter> PrinterPtr;
Q_DECLARE_METATYPE(PrinterPtr)
-Q_DECLARE_METATYPE(QPrinter::Orientation)
-Q_DECLARE_METATYPE(QPrinter::PageSize)
#endif // printer
static int fileNumber = 0;
@@ -72,8 +70,8 @@ private slots:
void testMargins();
void testPageSetupDialog();
void testPrintPreviewDialog();
- void testMulitpleSets_data();
- void testMulitpleSets();
+ void testMultipleSets_data();
+ void testMultipleSets();
void testPageMargins_data();
void testPageMargins();
void outputFormatFromSuffix();
@@ -82,7 +80,6 @@ private slots:
void customPaperSizeAndMargins_data();
void customPaperSizeAndMargins();
void customPaperNameSettingBySize();
- void customPaperNameSettingByName();
#if QT_CONFIG(completer) && QT_CONFIG(filedialog)
void printDialogCompleter();
#endif
@@ -97,7 +94,6 @@ private slots:
void copyCount();
void creator();
void docName();
- void doubleSidedPrinting();
void duplex();
void fontEmbedding();
void fullPage();
@@ -105,7 +101,6 @@ private slots:
void outputFileName();
void pageOrder();
void pageSize();
- void paperSize();
void paperSource();
void printerName();
void printerSelectionOption();
@@ -114,7 +109,6 @@ private slots:
void resolution();
void supportedPaperSources();
void supportedResolutions();
- void windowsPageSize();
// Test QPrinter setters/getters for non-QPrintEngine options
void outputFormat();
@@ -198,61 +192,61 @@ void tst_QPrinter::testPrintPreviewDialog()
void tst_QPrinter::testPageRectAndPaperRect_data()
{
QTest::addColumn<PrinterPtr>("printer");
- QTest::addColumn<QPrinter::Orientation>("orientation");
+ QTest::addColumn<QPageLayout::Orientation>("orientation");
QTest::addColumn<bool>("withPainter");
QTest::addColumn<int>("resolution");
QTest::addColumn<bool>("doPaperRect");
const PrinterPtr printer(new QPrinter(QPrinter::HighResolution));
// paperrect
- QTest::newRow("paperRect0") << printer << QPrinter::Portrait << true << 300 << true;
- QTest::newRow("paperRect1") << printer << QPrinter::Portrait << false << 300 << true;
- QTest::newRow("paperRect2") << printer << QPrinter::Landscape << true << 300 << true;
- QTest::newRow("paperRect3") << printer << QPrinter::Landscape << false << 300 << true;
- QTest::newRow("paperRect4") << printer << QPrinter::Portrait << true << 600 << true;
- QTest::newRow("paperRect5") << printer << QPrinter::Portrait << false << 600 << true;
- QTest::newRow("paperRect6") << printer << QPrinter::Landscape << true << 600 << true;
- QTest::newRow("paperRect7") << printer << QPrinter::Landscape << false << 600 << true;
- QTest::newRow("paperRect8") << printer << QPrinter::Portrait << true << 1200 << true;
- QTest::newRow("paperRect9") << printer << QPrinter::Portrait << false << 1200 << true;
- QTest::newRow("paperRect10") << printer << QPrinter::Landscape << true << 1200 << true;
- QTest::newRow("paperRect11") << printer << QPrinter::Landscape << false << 1200 << true;
+ QTest::newRow("paperRect0") << printer << QPageLayout::Portrait << true << 300 << true;
+ QTest::newRow("paperRect1") << printer << QPageLayout::Portrait << false << 300 << true;
+ QTest::newRow("paperRect2") << printer << QPageLayout::Landscape << true << 300 << true;
+ QTest::newRow("paperRect3") << printer << QPageLayout::Landscape << false << 300 << true;
+ QTest::newRow("paperRect4") << printer << QPageLayout::Portrait << true << 600 << true;
+ QTest::newRow("paperRect5") << printer << QPageLayout::Portrait << false << 600 << true;
+ QTest::newRow("paperRect6") << printer << QPageLayout::Landscape << true << 600 << true;
+ QTest::newRow("paperRect7") << printer << QPageLayout::Landscape << false << 600 << true;
+ QTest::newRow("paperRect8") << printer << QPageLayout::Portrait << true << 1200 << true;
+ QTest::newRow("paperRect9") << printer << QPageLayout::Portrait << false << 1200 << true;
+ QTest::newRow("paperRect10") << printer << QPageLayout::Landscape << true << 1200 << true;
+ QTest::newRow("paperRect11") << printer << QPageLayout::Landscape << false << 1200 << true;
// page rect
- QTest::newRow("pageRect0") << printer << QPrinter::Portrait << true << 300 << false;
- QTest::newRow("pageRect1") << printer << QPrinter::Portrait << false << 300 << false;
- QTest::newRow("pageRect2") << printer << QPrinter::Landscape << true << 300 << false;
- QTest::newRow("pageRect3") << printer << QPrinter::Landscape << false << 300 << false;
- QTest::newRow("pageRect4") << printer << QPrinter::Portrait << true << 600 << false;
- QTest::newRow("pageRect5") << printer << QPrinter::Portrait << false << 600 << false;
- QTest::newRow("pageRect6") << printer << QPrinter::Landscape << true << 600 << false;
- QTest::newRow("pageRect7") << printer << QPrinter::Landscape << false << 600 << false;
- QTest::newRow("pageRect8") << printer << QPrinter::Portrait << true << 1200 << false;
- QTest::newRow("pageRect9") << printer << QPrinter::Portrait << false << 1200 << false;
- QTest::newRow("pageRect10") << printer << QPrinter::Landscape << true << 1200 << false;
- QTest::newRow("pageRect11") << printer << QPrinter::Landscape << false << 1200 << false;
+ QTest::newRow("pageRect0") << printer << QPageLayout::Portrait << true << 300 << false;
+ QTest::newRow("pageRect1") << printer << QPageLayout::Portrait << false << 300 << false;
+ QTest::newRow("pageRect2") << printer << QPageLayout::Landscape << true << 300 << false;
+ QTest::newRow("pageRect3") << printer << QPageLayout::Landscape << false << 300 << false;
+ QTest::newRow("pageRect4") << printer << QPageLayout::Portrait << true << 600 << false;
+ QTest::newRow("pageRect5") << printer << QPageLayout::Portrait << false << 600 << false;
+ QTest::newRow("pageRect6") << printer << QPageLayout::Landscape << true << 600 << false;
+ QTest::newRow("pageRect7") << printer << QPageLayout::Landscape << false << 600 << false;
+ QTest::newRow("pageRect8") << printer << QPageLayout::Portrait << true << 1200 << false;
+ QTest::newRow("pageRect9") << printer << QPageLayout::Portrait << false << 1200 << false;
+ QTest::newRow("pageRect10") << printer << QPageLayout::Landscape << true << 1200 << false;
+ QTest::newRow("pageRect11") << printer << QPageLayout::Landscape << false << 1200 << false;
}
void tst_QPrinter::testPageRectAndPaperRect()
{
QFETCH(PrinterPtr, printer);
QFETCH(bool, withPainter);
- QFETCH(QPrinter::Orientation, orientation);
+ QFETCH(QPageLayout::Orientation, orientation);
QFETCH(int, resolution);
QFETCH(bool, doPaperRect);
QPainter *painter = 0;
- printer->setOrientation(orientation);
+ printer->setPageOrientation(orientation);
printer->setOutputFileName(testFileName(QLatin1String("silly"), QString()));
- QRect pageRect = doPaperRect ? printer->paperRect() : printer->pageRect();
+ QRect pageRect = (doPaperRect ? printer->paperRect(QPrinter::DevicePixel) : printer->pageRect(QPrinter::DevicePixel)).toRect();
float inchesX = float(pageRect.width()) / float(printer->resolution());
float inchesY = float(pageRect.height()) / float(printer->resolution());
printer->setResolution(resolution);
if (withPainter)
painter = new QPainter(printer.data());
- QRect otherRect = doPaperRect ? printer->paperRect() : printer->pageRect();
+ QRect otherRect = (doPaperRect ? printer->paperRect(QPrinter::DevicePixel) : printer->pageRect(QPrinter::DevicePixel)).toRect();
float otherInchesX = float(otherRect.width()) / float(printer->resolution());
float otherInchesY = float(otherRect.height()) / float(printer->resolution());
if (painter != 0)
@@ -261,8 +255,8 @@ void tst_QPrinter::testPageRectAndPaperRect()
QVERIFY(qAbs(otherInchesX - inchesX) < 0.01);
QVERIFY(qAbs(otherInchesY - inchesY) < 0.01);
- QVERIFY(printer->orientation() == QPrinter::Portrait || pageRect.width() > pageRect.height());
- QVERIFY(printer->orientation() != QPrinter::Portrait || pageRect.width() < pageRect.height());
+ QVERIFY(printer->pageLayout().orientation() == QPageLayout::Portrait || pageRect.width() > pageRect.height());
+ QVERIFY(printer->pageLayout().orientation() != QPageLayout::Portrait || pageRect.width() < pageRect.height());
}
void tst_QPrinter::testSetOptions()
@@ -295,34 +289,34 @@ void tst_QPrinter::testSetOptions()
void tst_QPrinter::testMargins_data()
{
QTest::addColumn<PrinterPtr>("printer");
- QTest::addColumn<QPrinter::Orientation>("orientation");
+ QTest::addColumn<QPageLayout::Orientation>("orientation");
QTest::addColumn<bool>("fullpage");
- QTest::addColumn<QPrinter::PageSize>("pagesize");
+ QTest::addColumn<QPageSize::PageSizeId>("pagesize");
QTest::addColumn<bool>("withPainter");
const PrinterPtr printer(new QPrinter);
- QTest::newRow("data0") << printer << QPrinter::Portrait << true << QPrinter::A4 << false;
- QTest::newRow("data1") << printer << QPrinter::Landscape << true << QPrinter::A4 << false;
- QTest::newRow("data2") << printer << QPrinter::Landscape << false << QPrinter::A4 << false;
- QTest::newRow("data3") << printer << QPrinter::Portrait << false << QPrinter::A4 << false;
- QTest::newRow("data4") << printer << QPrinter::Portrait << true << QPrinter::A4 << true;
- QTest::newRow("data5") << printer << QPrinter::Landscape << true << QPrinter::A4 << true;
- QTest::newRow("data6") << printer << QPrinter::Landscape << false << QPrinter::A4 << true;
- QTest::newRow("data7") << printer << QPrinter::Portrait << false << QPrinter::A4 << true;
+ QTest::newRow("data0") << printer << QPageLayout::Portrait << true << QPageSize::A4 << false;
+ QTest::newRow("data1") << printer << QPageLayout::Landscape << true << QPageSize::A4 << false;
+ QTest::newRow("data2") << printer << QPageLayout::Landscape << false << QPageSize::A4 << false;
+ QTest::newRow("data3") << printer << QPageLayout::Portrait << false << QPageSize::A4 << false;
+ QTest::newRow("data4") << printer << QPageLayout::Portrait << true << QPageSize::A4 << true;
+ QTest::newRow("data5") << printer << QPageLayout::Landscape << true << QPageSize::A4 << true;
+ QTest::newRow("data6") << printer << QPageLayout::Landscape << false << QPageSize::A4 << true;
+ QTest::newRow("data7") << printer << QPageLayout::Portrait << false << QPageSize::A4 << true;
}
void tst_QPrinter::testMargins()
{
QFETCH(PrinterPtr, printer);
QFETCH(bool, withPainter);
- QFETCH(QPrinter::Orientation, orientation);
- QFETCH(QPrinter::PageSize, pagesize);
+ QFETCH(QPageLayout::Orientation, orientation);
+ QFETCH(QPageSize::PageSizeId, pagesize);
QFETCH(bool, fullpage);
QPainter *painter = 0;
printer->setOutputFileName(testFileName(QLatin1String("silly"), QString()));
- printer->setOrientation(orientation);
+ printer->setPageOrientation(orientation);
printer->setFullPage(fullpage);
- printer->setPageSize(pagesize);
+ printer->setPageSize(QPageSize(pagesize));
if (withPainter)
painter = new QPainter(printer.data());
@@ -330,57 +324,55 @@ void tst_QPrinter::testMargins()
delete painter;
}
-void tst_QPrinter::testMulitpleSets_data()
+void tst_QPrinter::testMultipleSets_data()
{
QTest::addColumn<int>("resolution");
- QTest::addColumn<int>("pageSize");
+ QTest::addColumn<QPageSize::PageSizeId>("pageSize");
QTest::addColumn<int>("widthMMAfter");
QTest::addColumn<int>("heightMMAfter");
- QTest::newRow("lowRes") << int(QPrinter::ScreenResolution) << int(QPrinter::A4) << 210 << 297;
- QTest::newRow("lowResLetter") << int(QPrinter::ScreenResolution) << int(QPrinter::Letter) << 216 << 279;
- QTest::newRow("lowResA5") << int(QPrinter::ScreenResolution) << int(QPrinter::A5) << 148 << 210;
- QTest::newRow("midRes") << int(QPrinter::PrinterResolution) << int(QPrinter::A4) << 210 << 297;
- QTest::newRow("midResLetter") << int(QPrinter::PrinterResolution) << int(QPrinter::Letter) << 216 << 279;
- QTest::newRow("midResA5") << int(QPrinter::PrinterResolution) << int(QPrinter::A5) << 148 << 210;
- QTest::newRow("highRes") << int(QPrinter::HighResolution) << int(QPrinter::A4) << 210 << 297;
- QTest::newRow("highResLetter") << int(QPrinter::HighResolution) << int(QPrinter::Letter) << 216 << 279;
- QTest::newRow("highResA5") << int(QPrinter::HighResolution) << int(QPrinter::A5) << 148 << 210;
+ QTest::newRow("lowRes") << int(QPrinter::ScreenResolution) << QPageSize::A4 << 210 << 297;
+ QTest::newRow("lowResLetter") << int(QPrinter::ScreenResolution) << QPageSize::Letter << 216 << 279;
+ QTest::newRow("lowResA5") << int(QPrinter::ScreenResolution) << QPageSize::A5 << 148 << 210;
+ QTest::newRow("midRes") << int(QPrinter::PrinterResolution) << QPageSize::A4 << 210 << 297;
+ QTest::newRow("midResLetter") << int(QPrinter::PrinterResolution) << QPageSize::Letter << 216 << 279;
+ QTest::newRow("midResA5") << int(QPrinter::PrinterResolution) << QPageSize::A5 << 148 << 210;
+ QTest::newRow("highRes") << int(QPrinter::HighResolution) << QPageSize::A4 << 210 << 297;
+ QTest::newRow("highResLetter") << int(QPrinter::HighResolution) << QPageSize::Letter << 216 << 279;
+ QTest::newRow("highResA5") << int(QPrinter::HighResolution) << QPageSize::A5 << 148 << 210;
}
-static void computePageValue(const QPrinter &printer, int &retWidth, int &retHeight)
-{
- const double Inch2MM = 25.4;
-
- double width = double(printer.paperRect().width()) / printer.logicalDpiX() * Inch2MM;
- double height = double(printer.paperRect().height()) / printer.logicalDpiY() * Inch2MM;
- retWidth = qRound(width);
- retHeight = qRound(height);
-}
-
-void tst_QPrinter::testMulitpleSets()
+void tst_QPrinter::testMultipleSets()
{
// A very simple test, but Mac needs to have its format "validated" if the format is changed
// This takes care of that.
QFETCH(int, resolution);
- QFETCH(int, pageSize);
+ QFETCH(QPageSize::PageSizeId, pageSize);
QFETCH(int, widthMMAfter);
QFETCH(int, heightMMAfter);
QPrinter::PrinterMode mode = QPrinter::PrinterMode(resolution);
- QPrinter::PageSize printerPageSize = QPrinter::PageSize(pageSize);
QPrinter printer(mode);
printer.setFullPage(true);
int paperWidth, paperHeight;
//const int Tolerance = 2;
- computePageValue(printer, paperWidth, paperHeight);
- printer.setPageSize(printerPageSize);
+ const auto computePageValue = [&printer](int &retWidth, int &retHeight)
+ {
+ const double Inch2MM = 25.4;
+ double width = double(printer.paperRect(QPrinter::DevicePixel).width()) / printer.logicalDpiX() * Inch2MM;
+ double height = double(printer.paperRect(QPrinter::DevicePixel).height()) / printer.logicalDpiY() * Inch2MM;
+ retWidth = qRound(width);
+ retHeight = qRound(height);
+ };
+
+ computePageValue(paperWidth, paperHeight);
+ printer.setPageSize(QPageSize(pageSize));
- if (printer.pageSize() != printerPageSize) {
+ if (printer.pageLayout().pageSize().id() != pageSize) {
QSKIP("Current page size is not supported on this printer");
return;
}
@@ -388,18 +380,18 @@ void tst_QPrinter::testMulitpleSets()
QVERIFY(qAbs(printer.widthMM() - widthMMAfter) <= 2);
QVERIFY(qAbs(printer.heightMM() - heightMMAfter) <= 2);
- computePageValue(printer, paperWidth, paperHeight);
+ computePageValue(paperWidth, paperHeight);
QVERIFY(qAbs(paperWidth - widthMMAfter) <= 2);
QVERIFY(qAbs(paperHeight - heightMMAfter) <= 2);
// Set it again and see if it still works.
- printer.setPageSize(printerPageSize);
+ printer.setPageSize(QPageSize(pageSize));
QVERIFY(qAbs(printer.widthMM() - widthMMAfter) <= 2);
QVERIFY(qAbs(printer.heightMM() - heightMMAfter) <= 2);
- printer.setOrientation(QPrinter::Landscape);
- computePageValue(printer, paperWidth, paperHeight);
+ printer.setPageOrientation(QPageLayout::Landscape);
+ computePageValue(paperWidth, paperHeight);
QVERIFY(qAbs(paperWidth - heightMMAfter) <= 2);
QVERIFY(qAbs(paperHeight - widthMMAfter) <= 2);
}
@@ -422,15 +414,15 @@ void tst_QPrinter::testPageMargins_data()
QTest::addColumn<qreal>("top");
QTest::addColumn<qreal>("right");
QTest::addColumn<qreal>("bottom");
- QTest::addColumn<int>("unit");
+ QTest::addColumn<QPageLayout::Unit>("unit");
// Use custom margins that will exceed most printers minimum allowed
- QTest::newRow("data0") << qreal(25.5) << qreal(26.5) << qreal(27.5) << qreal(28.5) << static_cast<int>(QPrinter::Millimeter);
- QTest::newRow("data1") << qreal(55.5) << qreal(56.5) << qreal(57.5) << qreal(58.5) << static_cast<int>(QPrinter::Point);
- QTest::newRow("data2") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << static_cast<int>(QPrinter::Inch);
- QTest::newRow("data3") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << static_cast<int>(QPrinter::Pica);
- QTest::newRow("data4") << qreal(55.5) << qreal(56.5) << qreal(57.5) << qreal(58.5) << static_cast<int>(QPrinter::Didot);
- QTest::newRow("data5") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << static_cast<int>(QPrinter::Cicero);
+ QTest::newRow("data0") << qreal(25.5) << qreal(26.5) << qreal(27.5) << qreal(28.5) << QPageLayout::Millimeter;
+ QTest::newRow("data1") << qreal(55.5) << qreal(56.5) << qreal(57.5) << qreal(58.5) << QPageLayout::Point;
+ QTest::newRow("data2") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << QPageLayout::Inch;
+ QTest::newRow("data3") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << QPageLayout::Pica;
+ QTest::newRow("data4") << qreal(55.5) << qreal(56.5) << qreal(57.5) << qreal(58.5) << QPageLayout::Didot;
+ QTest::newRow("data5") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << QPageLayout::Cicero;
}
void tst_QPrinter::testPageMargins()
@@ -441,50 +433,23 @@ void tst_QPrinter::testPageMargins()
QFETCH(qreal, top);
QFETCH(qreal, right);
QFETCH(qreal, bottom);
- QFETCH(int, unit);
+ QFETCH(QPageLayout::Unit, unit);
QPageLayout layout = QPageLayout(QPageSize(QPageSize::A0), QPageLayout::Portrait,
- QMarginsF(left, top, right, bottom), QPageLayout::Unit(unit));
-
- qreal nLeft, nTop, nRight, nBottom;
-
- obj1.setPageMargins(left, top, right, bottom, QPrinter::Unit(unit));
-
- obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Millimeter);
- QCOMPARE(nLeft, layout.margins(QPageLayout::Millimeter).left());
- QCOMPARE(nRight, layout.margins(QPageLayout::Millimeter).right());
- QCOMPARE(nTop, layout.margins(QPageLayout::Millimeter).top());
- QCOMPARE(nBottom, layout.margins(QPageLayout::Millimeter).bottom());
-
- obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Point);
- QCOMPARE(nLeft, layout.margins(QPageLayout::Point).left());
- QCOMPARE(nRight, layout.margins(QPageLayout::Point).right());
- QCOMPARE(nTop, layout.margins(QPageLayout::Point).top());
- QCOMPARE(nBottom, layout.margins(QPageLayout::Point).bottom());
-
- obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Inch);
- QCOMPARE(nLeft, layout.margins(QPageLayout::Inch).left());
- QCOMPARE(nRight, layout.margins(QPageLayout::Inch).right());
- QCOMPARE(nTop, layout.margins(QPageLayout::Inch).top());
- QCOMPARE(nBottom, layout.margins(QPageLayout::Inch).bottom());
-
- obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Pica);
- QCOMPARE(nLeft, layout.margins(QPageLayout::Pica).left());
- QCOMPARE(nRight, layout.margins(QPageLayout::Pica).right());
- QCOMPARE(nTop, layout.margins(QPageLayout::Pica).top());
- QCOMPARE(nBottom, layout.margins(QPageLayout::Pica).bottom());
-
- obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Didot);
- QCOMPARE(nLeft, layout.margins(QPageLayout::Didot).left());
- QCOMPARE(nRight, layout.margins(QPageLayout::Didot).right());
- QCOMPARE(nTop, layout.margins(QPageLayout::Didot).top());
- QCOMPARE(nBottom, layout.margins(QPageLayout::Didot).bottom());
-
- obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Cicero);
- QCOMPARE(nLeft, layout.margins(QPageLayout::Cicero).left());
- QCOMPARE(nRight, layout.margins(QPageLayout::Cicero).right());
- QCOMPARE(nTop, layout.margins(QPageLayout::Cicero).top());
- QCOMPARE(nBottom, layout.margins(QPageLayout::Cicero).bottom());
+ QMarginsF(left, top, right, bottom), unit);
+
+ const QMarginsF margins(left, top, right, bottom);
+ obj1.setPageMargins(margins, unit);
+
+ for (const auto compareUnit : { QPageLayout::Millimeter,
+ QPageLayout::Point,
+ QPageLayout::Inch,
+ QPageLayout::Pica,
+ QPageLayout::Didot,
+ QPageLayout::Cicero}) {
+ QMarginsF actualMargins = obj1.pageLayout().margins(compareUnit);
+ QCOMPARE(actualMargins, layout.margins(compareUnit));
+ }
}
void tst_QPrinter::errorReporting()
@@ -508,28 +473,29 @@ void tst_QPrinter::testCustomPageSizes()
{
QPrinter p;
- QSizeF customSize(7.0, 11.0);
- p.setPaperSize(customSize, QPrinter::Inch);
+ const QPageSize customSize(QSizeF(7.0, 11.0), QPageSize::Inch);
+ p.setPageSize(customSize);
- QSizeF paperSize = p.paperSize(QPrinter::Inch);
- QCOMPARE(paperSize.width(), customSize.width());
- QCOMPARE(paperSize.height(), customSize.height());
+ QSizeF paperSize = p.pageLayout().pageSize().size(QPageSize::Inch);
+ QCOMPARE(paperSize.width(), customSize.size(QPageSize::Inch).width());
+ QCOMPARE(paperSize.height(), customSize.size(QPageSize::Inch).height());
QPrinter p2(QPrinter::HighResolution);
- p2.setPaperSize(customSize, QPrinter::Inch);
- paperSize = p.paperSize(QPrinter::Inch);
- QCOMPARE(paperSize.width(), customSize.width());
- QCOMPARE(paperSize.height(), customSize.height());
+ p2.setPageSize(customSize);
+ paperSize = p.pageLayout().pageSize().size(QPageSize::Inch);
+ QCOMPARE(paperSize.width(), customSize.size(QPageSize::Inch).width());
+ QCOMPARE(paperSize.height(), customSize.size(QPageSize::Inch).height());
+
+ const QPageSize pageSize = customSize;
+ const QSizeF sizeInPixels = p.paperRect(QPrinter::DevicePixel).size();
- const QSizeF sizeInPixels = p.paperSize(QPrinter::DevicePixel);
QPrinter p3;
- p3.setPaperSize(sizeInPixels, QPrinter::DevicePixel);
- paperSize = p3.paperSize(QPrinter::Inch);
- QCOMPARE(paperSize.width(), customSize.width());
- QCOMPARE(paperSize.height(), customSize.height());
- QPageSize pageSize = p3.pageLayout().pageSize();
- QCOMPARE(pageSize.key(), QString("Custom.504x792"));
- QCOMPARE(pageSize.name(), QString("Custom (504pt x 792pt)"));
+ p3.setPageSize(QPageSize(sizeInPixels / p.resolution(), QPageSize::Inch));
+ paperSize = p3.pageLayout().pageSize().size(QPageSize::Inch);
+ QCOMPARE(paperSize.width(), customSize.size(QPageSize::Inch).width());
+ QCOMPARE(paperSize.height(), customSize.size(QPageSize::Inch).height());
+ QCOMPARE(p3.pageLayout().pageSize().key(), QString("Custom.7x11in"));
+ QCOMPARE(p3.pageLayout().pageSize().name(), QString("Custom (7in x 11in)"));
}
void tst_QPrinter::customPaperSizeAndMargins_data()
@@ -558,34 +524,27 @@ void tst_QPrinter::customPaperSizeAndMargins()
QFETCH(qreal, bottom);
qreal tolerance = 0.05;
- qreal getLeft = 0;
- qreal getRight = 0;
- qreal getTop = 0;
- qreal getBottom = 0;
// Use a custom page size that most printers should support, A4 is 210x297
// TODO Use print device api when available
QSizeF customSize(200.0, 300.0);
+ const QMarginsF margins(left, top, right, bottom);
QPrinter p;
if (pdf)
p.setOutputFormat(QPrinter::PdfFormat);
if (before)
- p.setPageMargins(left, top, right, bottom, QPrinter::Millimeter);
- p.setPaperSize(customSize, QPrinter::Millimeter);
- p.getPageMargins(&getLeft, &getTop, &getRight, &getBottom, QPrinter::Millimeter);
- if (before) {
- QVERIFY(fabs(left - getLeft) < tolerance);
- QVERIFY(fabs(left - getTop) < tolerance);
- QVERIFY(fabs(left - getRight) < tolerance);
- QVERIFY(fabs(left - getBottom) < tolerance);
- } else {
- p.setPageMargins(left, top, right, bottom, QPrinter::Millimeter);
- p.getPageMargins(&getLeft, &getTop, &getRight, &getBottom, QPrinter::Millimeter);
- QVERIFY(fabs(left - getLeft) < tolerance);
- QVERIFY(fabs(left - getTop) < tolerance);
- QVERIFY(fabs(left - getRight) < tolerance);
- QVERIFY(fabs(left - getBottom) < tolerance);
+ p.setPageMargins(margins, QPageLayout::Millimeter);
+ QPageSize customPageSize(customSize, QPageSize::Millimeter);
+ p.setPageSize(customPageSize);
+ QMarginsF actual = p.pageLayout().margins(QPageLayout::Millimeter);
+ if (!before) {
+ p.setPageMargins(margins, QPageLayout::Millimeter);
+ actual = p.pageLayout().margins(QPageLayout::Millimeter);
}
+ QVERIFY(fabs(left - actual.left()) < tolerance);
+ QVERIFY(fabs(top - actual.top()) < tolerance);
+ QVERIFY(fabs(right - actual.right()) < tolerance);
+ QVERIFY(fabs(bottom - actual.bottom()) < tolerance);
}
#if QT_CONFIG(completer) && QT_CONFIG(filedialog)
@@ -707,22 +666,22 @@ void tst_QPrinter::customPaperNameSettingBySize()
{
QPrinter printer(QPrinter::HighResolution);
QPrinterInfo info(printer);
- QList<QPageSize> sizes = info.supportedPageSizes();
+ const QList<QPageSize> sizes = info.supportedPageSizes();
if (sizes.size() == 0)
QSKIP("No printers installed on this machine");
- for (int i=0; i<sizes.size(); i++) {
- printer.setPaperSize(sizes.at(i).size(QPageSize::Millimeter), QPrinter::Millimeter);
- QCOMPARE(sizes.at(i).size(QPageSize::Millimeter), printer.paperSize(QPrinter::Millimeter));
+ for (const auto &pageSize : sizes) {
+ printer.setPageSize(pageSize);
+ QCOMPARE(pageSize.size(QPageSize::Millimeter), printer.pageLayout().pageSize().size(QPageSize::Millimeter));
// Some printers have the same size under different names which can cause a problem for the test
// So we look at all the other sizes to see if one also matches as we don't know which order they are in
- QSizeF paperSize = sizes.at(i).size(QPageSize::Millimeter);
- QString paperName = printer.paperName();
- bool paperNameFound = (sizes.at(i).name() == paperName);
+ const QSizeF paperSize = pageSize.size(QPageSize::Millimeter);
+ const QString paperName = printer.pageLayout().pageSize().name();
+ bool paperNameFound = (pageSize.name() == paperName);
if (!paperNameFound) {
- for (int j = 0; j < sizes.size(); ++j) {
- if (j != i
- && sizes.at(j).size(QPageSize::Millimeter) == paperSize
- && sizes.at(j).name() == paperName) {
+ for (const auto &pageSize2 : sizes) {
+ if (pageSize != pageSize2
+ && pageSize2.size(QPageSize::Millimeter) == paperSize
+ && pageSize2.name() == paperName) {
paperNameFound = true;
break;
}
@@ -732,34 +691,21 @@ void tst_QPrinter::customPaperNameSettingBySize()
if (!paperNameFound) {
qDebug() << "supportedPageSizes() = " << sizes;
QEXPECT_FAIL("", "Paper Name mismatch: please report this failure at bugreports.qt.io", Continue);
- QCOMPARE(sizes.at(i).name(), printer.paperName());
+ QCOMPARE(pageSize.name(), printer.pageLayout().pageSize().name());
}
}
// Check setting a custom size after setting a standard one works
- QSizeF customSize(200, 300);
- printer.setPaperSize(customSize, QPrinter::Millimeter);
- QCOMPARE(printer.paperSize(QPrinter::Millimeter), customSize);
- QCOMPARE(printer.paperSize(), QPrinter::Custom);
+ const QSizeF customSize(200, 300);
+ printer.setPageSize(QPageSize(customSize, QPageSize::Millimeter));
+ QCOMPARE(printer.pageLayout().pageSize().size(QPageSize::Millimeter), customSize);
+ QCOMPARE(printer.pageLayout().pageSize().id(), QPageSize::Custom);
// Finally check setting a standard size after a custom one works
- printer.setPaperSize(sizes.at(0).size(QPageSize::Millimeter), QPrinter::Millimeter);
- QCOMPARE(printer.paperName(), sizes.at(0).name());
- QCOMPARE(printer.paperSize(QPrinter::Millimeter), sizes.at(0).size(QPageSize::Millimeter));
-}
-
-void tst_QPrinter::customPaperNameSettingByName()
-{
- QPrinter printer(QPrinter::HighResolution);
- QPrinterInfo info(printer);
- QList<QPageSize> sizes = info.supportedPageSizes();
- if (sizes.size() == 0)
- QSKIP("No printers installed on this machine");
- for (int i=0; i<sizes.size(); i++) {
- printer.setPaperName(sizes.at(i).name());
- QCOMPARE(sizes.at(i).name(), printer.paperName());
- QCOMPARE(sizes.at(i).size(QPageSize::Millimeter), printer.paperSize(QPrinter::Millimeter));
- }
+ const QPageSize standardPageSize = sizes.first();
+ printer.setPageSize(standardPageSize);
+ QCOMPARE(printer.pageLayout().pageSize().name(), standardPageSize.name());
+ QCOMPARE(printer.pageLayout().pageSize().size(QPageSize::Millimeter), standardPageSize.size(QPageSize::Millimeter));
}
// Test QPrintEngine keys and their QPrinter setters/getters
@@ -772,21 +718,21 @@ void tst_QPrinter::testMultipleKeys()
if (native.outputFormat() == QPrinter::NativeFormat) {
// Check default values
QCOMPARE(native.fullPage(), false);
- QCOMPARE(native.orientation(), QPrinter::Portrait);
+ QCOMPARE(native.pageLayout().orientation(), QPageLayout::Portrait);
QCOMPARE(native.copyCount(), 1);
QCOMPARE(native.collateCopies(), true);
QCOMPARE(native.printRange(), QPrinter::AllPages);
// Change values
native.setFullPage(true);
- native.setOrientation(QPrinter::Landscape);
+ native.setPageOrientation(QPageLayout::Landscape);
native.setCopyCount(9);
native.setCollateCopies(false);
native.setPrintRange(QPrinter::CurrentPage);
// Check changed values
QCOMPARE(native.fullPage(), true);
- QCOMPARE(native.orientation(), QPrinter::Landscape);
+ QCOMPARE(native.pageLayout().orientation(), QPageLayout::Landscape);
QCOMPARE(native.copyCount(), 9);
QCOMPARE(native.collateCopies(), false);
QCOMPARE(native.printRange(), QPrinter::CurrentPage);
@@ -794,21 +740,21 @@ void tst_QPrinter::testMultipleKeys()
// Test value preservation
native.setOutputFormat(QPrinter::PdfFormat);
QCOMPARE(native.fullPage(), true);
- QCOMPARE(native.orientation(), QPrinter::Landscape);
+ QCOMPARE(native.pageLayout().orientation(), QPageLayout::Landscape);
QCOMPARE(native.copyCount(), 9);
QCOMPARE(native.collateCopies(), false);
QCOMPARE(native.printRange(), QPrinter::CurrentPage);
// Change values
native.setFullPage(false);
- native.setOrientation(QPrinter::Portrait);
+ native.setPageOrientation(QPageLayout::Portrait);
native.setCopyCount(5);
native.setCollateCopies(true);
native.setPrintRange(QPrinter::PageRange);
// Check changed values
QCOMPARE(native.fullPage(), false);
- QCOMPARE(native.orientation(), QPrinter::Portrait);
+ QCOMPARE(native.pageLayout().orientation(), QPageLayout::Portrait);
QCOMPARE(native.copyCount(), 5);
QCOMPARE(native.collateCopies(), true);
QCOMPARE(native.printRange(), QPrinter::PageRange);
@@ -891,56 +837,33 @@ void tst_QPrinter::colorMode()
void tst_QPrinter::copyCount()
{
- // copyCount() / setCopyCount() / PPK_CopyCount
- // numCopies() / setNumCopies() / PPK_NumberOfCopies
- // actualNumCopies() / supportsMultipleCopies()
- // PdfFormat: Supported, multiple copies unsupported, default 1
- // NativeFormat, Cups: Supported, multiple copies supported, default 1
- // NativeFormat, Win: Supported, multiple copies supported, default 1
- // NativeFormat, Mac: Supported, multiple copies supported, default 1
-
QPrinter pdf;
pdf.setOutputFormat(QPrinter::PdfFormat);
QCOMPARE(pdf.supportsMultipleCopies(), false);
QCOMPARE(pdf.copyCount(), 1);
- QCOMPARE(pdf.numCopies(), 1);
- QCOMPARE(pdf.actualNumCopies(), 1);
pdf.setCopyCount(9);
QCOMPARE(pdf.copyCount(), 9);
- QCOMPARE(pdf.numCopies(), 9);
- QCOMPARE(pdf.actualNumCopies(), 9);
- pdf.setNumCopies(7);
+ pdf.setCopyCount(7);
QCOMPARE(pdf.copyCount(), 7);
- QCOMPARE(pdf.numCopies(), 7);
- QCOMPARE(pdf.actualNumCopies(), 7);
QPrinter native;
if (native.outputFormat() == QPrinter::NativeFormat) {
// Test default
QCOMPARE(native.supportsMultipleCopies(), true);
QCOMPARE(native.copyCount(), 1);
- QCOMPARE(native.numCopies(), 1);
- QCOMPARE(native.actualNumCopies(), 1);
// Test set/get
native.setCopyCount(9);
QCOMPARE(native.copyCount(), 9);
- QCOMPARE(native.numCopies(), 1);
- QCOMPARE(native.actualNumCopies(), 9);
- native.setNumCopies(7);
+ native.setCopyCount(7);
QCOMPARE(native.copyCount(), 7);
- QCOMPARE(native.numCopies(), 1);
- QCOMPARE(native.actualNumCopies(), 7);
// Test value preservation
native.setOutputFormat(QPrinter::PdfFormat);
QCOMPARE(native.copyCount(), 7);
- QCOMPARE(native.numCopies(), 7);
- QCOMPARE(native.actualNumCopies(), 7);
+
native.setOutputFormat(QPrinter::NativeFormat);
QCOMPARE(native.copyCount(), 7);
- QCOMPARE(native.numCopies(), 1);
- QCOMPARE(native.actualNumCopies(), 7);
} else {
QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
}
@@ -1060,41 +983,6 @@ void tst_QPrinter::duplex()
}
}
-void tst_QPrinter::doubleSidedPrinting()
-{
- // PdfFormat: Supported, default false
- // NativeFormat, Cups: Supported, default to printer default
- // NativeFormat, Win: Supported, default to printer default
- // NativeFormat, Mac: Supported, default to printer default
-
- QPrinter pdf;
- pdf.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(pdf.doubleSidedPrinting(), false);
- pdf.setDoubleSidedPrinting(true);
- QCOMPARE(pdf.doubleSidedPrinting(), false); // pdf doesn't have the concept of duplex
-
- QPrinter native;
- if (native.outputFormat() == QPrinter::NativeFormat) {
- // Test default
- QPrinterInfo printerInfo(native);
- bool expected = (printerInfo.defaultDuplexMode() != QPrinter::DuplexNone);
- QCOMPARE(native.doubleSidedPrinting(), expected);
-
- // Test set/get, changing the expected value if possible
- expected = expected ? false : (printerInfo.supportedDuplexModes().count() > 1);
- native.setDoubleSidedPrinting(expected);
- QCOMPARE(native.doubleSidedPrinting(), expected);
-
- // Test value preservation
- native.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(native.doubleSidedPrinting(), expected);
- native.setOutputFormat(QPrinter::NativeFormat);
- QCOMPARE(native.doubleSidedPrinting(), expected);
- } else {
- QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
- }
-}
-
void tst_QPrinter::fontEmbedding()
{
// fontEmbeddingEnabled() / setFontEmbeddingEnabled() / PPK_FontEmbedding
@@ -1176,44 +1064,44 @@ void tst_QPrinter::fullPage()
void tst_QPrinter::orientation()
{
// orientation() / setOrientation() / PPK_Orientation
- // PdfFormat: Supported, default QPrinter::Portrait
- // NativeFormat, Cups: Supported, default QPrinter::Portrait
- // NativeFormat, Win: Supported, default QPrinter::Portrait
- // NativeFormat, Mac: Supported, default QPrinter::Portrait
+ // PdfFormat: Supported, default QPageLayout::Portrait
+ // NativeFormat, Cups: Supported, default QPageLayout::Portrait
+ // NativeFormat, Win: Supported, default QPageLayout::Portrait
+ // NativeFormat, Mac: Supported, default QPageLayout::Portrait
QPrinter pdf;
pdf.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(pdf.orientation(), QPrinter::Portrait);
- pdf.setOrientation(QPrinter::Landscape);
- QCOMPARE(pdf.orientation(), QPrinter::Landscape);
+ QCOMPARE(pdf.pageLayout().orientation(), QPageLayout::Portrait);
+ pdf.setPageOrientation(QPageLayout::Landscape);
+ QCOMPARE(pdf.pageLayout().orientation(), QPageLayout::Landscape);
QPrinter native;
if (native.outputFormat() == QPrinter::NativeFormat) {
// Test default
// TODO Printer specific, need QPrinterInfo::orientation()
- //QCOMPARE(native.orientation(), QPrinter::Portrait);
+ //QCOMPARE(native.orientation(), QPageLayout::Portrait);
// Test set/get
- QPrinter::Orientation expected = QPrinter::Landscape;
- native.setOrientation(expected);
- QCOMPARE(native.orientation(), expected);
+ QPageLayout::Orientation expected = QPageLayout::Landscape;
+ native.setPageOrientation(expected);
+ QCOMPARE(native.pageLayout().orientation(), expected);
// Test value preservation
native.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(native.orientation(), expected);
+ QCOMPARE(native.pageLayout().orientation(), expected);
native.setOutputFormat(QPrinter::NativeFormat);
- QCOMPARE(native.orientation(), expected);
+ QCOMPARE(native.pageLayout().orientation(), expected);
// Test set/get
- expected = QPrinter::Portrait;
- native.setOrientation(expected);
- QCOMPARE(native.orientation(), expected);
+ expected = QPageLayout::Portrait;
+ native.setPageOrientation(expected);
+ QCOMPARE(native.pageLayout().orientation(), expected);
// Test value preservation
native.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(native.orientation(), expected);
+ QCOMPARE(native.pageLayout().orientation(), expected);
native.setOutputFormat(QPrinter::NativeFormat);
- QCOMPARE(native.orientation(), expected);
+ QCOMPARE(native.pageLayout().orientation(), expected);
} else {
QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
}
@@ -1295,92 +1183,47 @@ void tst_QPrinter::pageSize()
{
// Note PPK_PaperSize == PPK_PageSize
// pageSize() / setPageSize() / PPK_PageSize
- // PdfFormat: Supported, defaults to QPrinter::A4
+ // PdfFormat: Supported, defaults to QPageSize::A4
// NativeFormat, Cups: Supported, defaults to printer default
// NativeFormat, Win: Supported, defaults to printer default
// NativeFormat, Mac: Supported, must be supported size, defaults to printer default
QPrinter pdf;
pdf.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(pdf.pageSize(), QPrinter::A4);
- pdf.setPageSize(QPrinter::A1);
- QCOMPARE(pdf.pageSize(), QPrinter::A1);
+ QCOMPARE(pdf.pageLayout().pageSize().id(), QPageSize::A4);
+ pdf.setPageSize(QPageSize(QPageSize::A1));
+ QCOMPARE(pdf.pageLayout().pageSize().id(), QPageSize::A1);
QPrinter native;
if (native.outputFormat() == QPrinter::NativeFormat) {
// Test default
// TODO Printer specific, need QPrinterInfo::paperSize()
- //QCOMPARE(native.pageSize(), QPrinter::A4);
+ //QCOMPARE(native.pageSize(), QPageSize::A4);
// Test set/get
- QPrinter::PaperSize expected = QPrinter::A4;
+ QPageSize expected(QPageSize::A4);
QPrinterInfo info = QPrinterInfo::printerInfo(native.printerName());
const auto &pageSizes = info.supportedPageSizes();
for (const auto &pageSize : pageSizes) {
- const QPrinter::PaperSize supported = QPrinter::PaperSize(pageSize.id());
- if (supported != QPrinter::Custom && supported != native.paperSize()) {
- expected = supported;
+ const auto supported = pageSize.id();
+ if (supported != QPageSize::Custom && supported != native.pageLayout().pageSize().id()) {
+ expected = QPageSize(supported);
break;
}
}
native.setPageSize(expected);
- QCOMPARE(native.pageSize(), expected);
+ QCOMPARE(native.pageLayout().pageSize().id(), expected.id());
// Test value preservation
native.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(native.pageSize(), expected);
+ QCOMPARE(native.pageLayout().pageSize().id(), expected.id());
native.setOutputFormat(QPrinter::NativeFormat);
- QCOMPARE(native.pageSize(), expected);
+ QCOMPARE(native.pageLayout().pageSize().id(), expected.id());
} else {
QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
}
}
-void tst_QPrinter::paperSize()
-{
- // PPK_PaperSize == PPK_PageSize
- // paperSize() / setPaperSize() / PPK_PaperSize
- // pageSize() / setPageSize() / PPK_PageSize
- // PdfFormat: Supported, defaults to QPrinter::A4
- // NativeFormat, Cups: Supported, defaults to printer default
- // NativeFormat, Win: Supported, defaults to printer default
- // NativeFormat, Mac: Supported, must be supported size, defaults to printer default
-
- QPrinter pdf;
- pdf.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(pdf.paperSize(), QPrinter::A4);
- pdf.setPaperSize(QPrinter::A1);
- QCOMPARE(pdf.paperSize(), QPrinter::A1);
-
- QPrinter native;
- if (native.outputFormat() == QPrinter::NativeFormat) {
- // Test default
- // TODO Printer specific, need QPrinterInfo::paperSize()
- //QCOMPARE(native.paperSize(), QPrinter::A4);
-
- // Test set/get
- QPrinter::PaperSize expected = QPrinter::A4;
- QPrinterInfo info = QPrinterInfo::printerInfo(native.printerName());
- const auto &pageSizes = info.supportedPageSizes();
- for (const auto &pageSize : pageSizes) {
- const QPrinter::PaperSize supported = QPrinter::PaperSize(pageSize.id());
- if (supported != QPrinter::Custom && supported != native.paperSize()) {
- expected = supported;
- break;
- }
- }
- native.setPaperSize(expected);
- QCOMPARE(native.paperSize(), expected);
-
- // Test value preservation
- native.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(native.paperSize(), expected);
- native.setOutputFormat(QPrinter::NativeFormat);
- QCOMPARE(native.paperSize(), expected);
- } else {
- QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
- }
-}
void tst_QPrinter::paperSource()
{
@@ -1693,51 +1536,6 @@ void tst_QPrinter::supportedResolutions()
}
}
-void tst_QPrinter::windowsPageSize()
-{
- // winPageSize() / setWinPageSize() / PPK_WindowsPageSize
- // PdfFormat: Supported, defaults to printer default
- // NativeFormat, Cups: Supported, defaults to printer default
- // NativeFormat, Win: Supported, defaults to printer default
- // NativeFormat, Mac: Supported, defaults to printer default
-
- QPrinter pdf;
- pdf.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(pdf.winPageSize(), 9); // DMPAPER_A4
- pdf.setWinPageSize(1); // DMPAPER_LETTER
- QCOMPARE(pdf.winPageSize(), 1);
-
- QPrinter native;
- if (native.outputFormat() == QPrinter::NativeFormat) {
- // Test set/get
- native.setPaperSize(QPrinter::A4);
- QCOMPARE(native.pageSize(), QPrinter::A4);
- QCOMPARE(native.winPageSize(), 9); // DMPAPER_A4
-
- native.setPaperSize(QPrinter::Letter);
- QCOMPARE(native.pageSize(), QPrinter::Letter);
- QCOMPARE(native.winPageSize(), 1); // DMPAPER_LETTER
-
- native.setWinPageSize(9); // DMPAPER_A4
- QCOMPARE(native.pageSize(), QPrinter::A4);
- QCOMPARE(native.winPageSize(), 9); // DMPAPER_A4
-
- native.setWinPageSize(1); // DMPAPER_LETTER
- QCOMPARE(native.pageSize(), QPrinter::Letter);
- QCOMPARE(native.winPageSize(), 1); // DMPAPER_LETTER
-
- // Test value preservation
- native.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(native.pageSize(), QPrinter::Letter);
- QCOMPARE(native.winPageSize(), 1); // DMPAPER_LETTER
- native.setOutputFormat(QPrinter::NativeFormat);
- QCOMPARE(native.pageSize(), QPrinter::Letter);
- QCOMPARE(native.winPageSize(), 1); // DMPAPER_LETTER
- } else {
- QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
- }
-}
-
// Test QPrinter setters/getters for non-QPrintEngine options
void tst_QPrinter::outputFormat()
@@ -1778,10 +1576,10 @@ void tst_QPrinter::testPageMetrics_data()
QTest::addColumn<qreal>("topMMf");
QTest::addColumn<qreal>("bottomMMf");
- QTest::newRow("PDF A4") << int(QPrinter::PdfFormat) << int(QPrinter::A4) << 210.0 << 297.0 << false << 0.0 << 0.0 << 0.0 << 0.0;
- QTest::newRow("PDF A4 Margins") << int(QPrinter::PdfFormat) << int(QPrinter::A4) << 210.0 << 297.0 << true << 20.0 << 30.0 << 40.0 << 50.0;
- QTest::newRow("Native A4") << int(QPrinter::NativeFormat) << int(QPrinter::A4) << 210.0 << 297.0 << false << 0.0 << 0.0 << 0.0 << 0.0;
- QTest::newRow("Native A4 Margins") << int(QPrinter::NativeFormat) << int(QPrinter::A4) << 210.0 << 297.0 << true << 20.0 << 30.0 << 40.0 << 50.0;
+ QTest::newRow("PDF A4") << int(QPrinter::PdfFormat) << int(QPageSize::A4) << 210.0 << 297.0 << false << 0.0 << 0.0 << 0.0 << 0.0;
+ QTest::newRow("PDF A4 Margins") << int(QPrinter::PdfFormat) << int(QPageSize::A4) << 210.0 << 297.0 << true << 20.0 << 30.0 << 40.0 << 50.0;
+ QTest::newRow("Native A4") << int(QPrinter::NativeFormat) << int(QPageSize::A4) << 210.0 << 297.0 << false << 0.0 << 0.0 << 0.0 << 0.0;
+ QTest::newRow("Native A4 Margins") << int(QPrinter::NativeFormat) << int(QPageSize::A4) << 210.0 << 297.0 << true << 20.0 << 30.0 << 40.0 << 50.0;
QTest::newRow("PDF Portrait") << int(QPrinter::PdfFormat) << -1 << 200.0 << 300.0 << false << 0.0 << 0.0 << 0.0 << 0.0;
QTest::newRow("PDF Portrait Margins") << int(QPrinter::PdfFormat) << -1 << 200.0 << 300.0 << true << 20.0 << 30.0 << 40.0 << 50.0;
@@ -1805,57 +1603,52 @@ void tst_QPrinter::testPageMetrics()
QFETCH(qreal, topMMf);
QFETCH(qreal, bottomMMf);
- QSizeF sizeMMf = QSizeF(widthMMf, heightMMf);
+ const QSizeF sizeMMf = QSizeF(widthMMf, heightMMf);
QPrinter printer;
printer.setOutputFormat(QPrinter::OutputFormat(outputFormat));
if (printer.outputFormat() != QPrinter::OutputFormat(outputFormat))
QSKIP("Please install a native printer to run this test");
QCOMPARE(printer.outputFormat(), QPrinter::OutputFormat(outputFormat));
- QCOMPARE(printer.orientation(), QPrinter::Portrait);
+ QCOMPARE(printer.pageLayout().orientation(), QPageLayout::Portrait);
if (setMargins) {
// Setup the given margins
QMarginsF margins(leftMMf, topMMf, rightMMf, bottomMMf);
- printer.setMargins(margins);
- QCOMPARE(printer.margins().left(), leftMMf);
- QCOMPARE(printer.margins().right(), rightMMf);
- QCOMPARE(printer.margins().top(), topMMf);
- QCOMPARE(printer.margins().bottom(), bottomMMf);
+ printer.setPageMargins(margins);
+ QCOMPARE(printer.pageLayout().margins(), margins);
}
-
// Set the given size, in Portrait mode
if (pageSize < 0) {
- printer.setPageSizeMM(sizeMMf);
- QCOMPARE(printer.pageSize(), QPrinter::Custom);
+ printer.setPageSize(QPageSize(sizeMMf, QPageSize::Millimeter));
+ QCOMPARE(printer.pageLayout().pageSize().id(), QPageSize::Custom);
} else {
- printer.setPageSize(QPrinter::PageSize(pageSize));
- QCOMPARE(printer.pageSize(), QPrinter::PageSize(pageSize));
+ printer.setPageSize(QPageSize(QPageSize::PageSizeId(pageSize)));
+ QCOMPARE(printer.pageLayout().pageSize().id(), QPageSize::PageSizeId(pageSize));
}
- QCOMPARE(printer.orientation(), QPrinter::Portrait);
+ QCOMPARE(printer.pageLayout().orientation(), QPageLayout::Portrait);
if (setMargins) {
// Check margins unchanged from page size change
- QCOMPARE(printer.margins().left(), leftMMf);
- QCOMPARE(printer.margins().right(), rightMMf);
- QCOMPARE(printer.margins().top(), topMMf);
- QCOMPARE(printer.margins().bottom(), bottomMMf);
+ QMarginsF margins(leftMMf, topMMf, rightMMf, bottomMMf);
+ QCOMPARE(printer.pageLayout().margins(), margins);
} else {
// Fetch the default margins for the printer and page size
// TODO Check against margins from print device when api added
- leftMMf = printer.margins().left();
- rightMMf = printer.margins().right();
- topMMf = printer.margins().top();
- bottomMMf = printer.margins().bottom();
+ leftMMf = printer.pageLayout().margins(QPageLayout::Millimeter).left();
+ rightMMf = printer.pageLayout().margins(QPageLayout::Millimeter).right();
+ topMMf = printer.pageLayout().margins(QPageLayout::Millimeter).top();
+ bottomMMf = printer.pageLayout().margins(QPageLayout::Millimeter).bottom();
}
- // QPagedPaintDevice::pageSizeMM() always returns Portrait
- QCOMPARE(printer.pageSizeMM(), sizeMMf);
+ // QPageLayout::pageSize() always returns Portrait
+ QCOMPARE(printer.pageLayout().pageSize().size(QPageSize::Millimeter), sizeMMf);
- // QPrinter::paperSize() always returns set orientation
- QCOMPARE(printer.paperSize(QPrinter::Millimeter), sizeMMf);
+ // QPrinter::paperRect() always returns set orientation
+ QCOMPARE(printer.paperRect(QPrinter::Millimeter).size(), sizeMMf);
- // QPagedPaintDevice::widthMM() and heightMM() are paint metrics and always return set orientation
+
+ // QPaintDevice::widthMM() and heightMM() are paint metrics and always return set orientation
QCOMPARE(printer.widthMM(), qRound(widthMMf - leftMMf - rightMMf));
QCOMPARE(printer.heightMM(), qRound(heightMMf - topMMf - bottomMMf));
@@ -1867,35 +1660,33 @@ void tst_QPrinter::testPageMetrics()
// Now switch to Landscape mode, size should be unchanged, but rect and metrics should change
- printer.setOrientation(QPrinter::Landscape);
+ printer.setPageOrientation(QPageLayout::Landscape);
if (pageSize < 0) {
- QCOMPARE(printer.pageSize(), QPrinter::Custom);
+ QCOMPARE(printer.pageLayout().pageSize().id(), QPageSize::Custom);
} else {
- QCOMPARE(printer.pageSize(), QPrinter::PageSize(pageSize));
+ QCOMPARE(printer.pageLayout().pageSize().id(), QPageSize::PageSizeId(pageSize));
}
- QCOMPARE(printer.orientation(), QPrinter::Landscape);
+ QCOMPARE(printer.pageLayout().orientation(), QPageLayout::Landscape);
if (setMargins) {
// Check margins unchanged from page size change
- QCOMPARE(printer.margins().left(), leftMMf);
- QCOMPARE(printer.margins().right(), rightMMf);
- QCOMPARE(printer.margins().top(), topMMf);
- QCOMPARE(printer.margins().bottom(), bottomMMf);
+ QMarginsF margins(leftMMf, topMMf, rightMMf, bottomMMf);
+ QCOMPARE(printer.pageLayout().margins(), margins);
} else {
// Fetch the default margins for the printer and page size
// TODO Check against margins from print device when api added
- leftMMf = printer.margins().left();
- rightMMf = printer.margins().right();
- topMMf = printer.margins().top();
- bottomMMf = printer.margins().bottom();
+ leftMMf = printer.pageLayout().margins(QPageLayout::Millimeter).left();
+ rightMMf = printer.pageLayout().margins(QPageLayout::Millimeter).right();
+ topMMf = printer.pageLayout().margins(QPageLayout::Millimeter).top();
+ bottomMMf = printer.pageLayout().margins(QPageLayout::Millimeter).bottom();
}
- // QPagedPaintDevice::pageSizeMM() always returns Portrait
- QCOMPARE(printer.pageSizeMM(), sizeMMf);
+ // QPageLayout::pageSize() always returns Portrait
+ QCOMPARE(printer.pageLayout().pageSize().size(QPageSize::Millimeter), sizeMMf);
- // QPrinter::paperSize() always returns set orientation
- QCOMPARE(printer.paperSize(QPrinter::Millimeter), sizeMMf.transposed());
+ // QPrinter::paperRect() always returns set orientation
+ QCOMPARE(printer.paperRect(QPrinter::Millimeter).size(), sizeMMf.transposed());
- // QPagedPaintDevice::widthMM() and heightMM() are paint metrics and always return set orientation
+ // QPaintDevice::widthMM() and heightMM() are paint metrics and always return set orientation
QCOMPARE(printer.widthMM(), qRound(heightMMf - leftMMf - rightMMf));
QCOMPARE(printer.heightMM(), qRound(widthMMf - topMMf - bottomMMf));
@@ -1905,36 +1696,33 @@ void tst_QPrinter::testPageMetrics()
// QPrinter::pageRect() always returns set orientation
QCOMPARE(printer.pageRect(QPrinter::Millimeter), QRectF(leftMMf, topMMf, heightMMf - leftMMf - rightMMf, widthMMf - topMMf - bottomMMf));
-
// Now while in Landscape mode, set the size again, results should be the same
if (pageSize < 0) {
- printer.setPageSizeMM(sizeMMf);
- QCOMPARE(printer.pageSize(), QPrinter::Custom);
+ printer.setPageSize(QPageSize(sizeMMf, QPageSize::Millimeter));
+ QCOMPARE(printer.pageLayout().pageSize().id(), QPageSize::Custom);
} else {
- printer.setPageSize(QPrinter::PageSize(pageSize));
- QCOMPARE(printer.pageSize(), QPrinter::PageSize(pageSize));
+ printer.setPageSize(QPageSize(QPageSize::PageSizeId(pageSize)));
+ QCOMPARE(printer.pageLayout().pageSize().id(), QPageSize::PageSizeId(pageSize));
}
- QCOMPARE(printer.orientation(), QPrinter::Landscape);
+ QCOMPARE(printer.pageLayout().orientation(), QPageLayout::Landscape);
if (setMargins) {
// Check margins unchanged from page size change
- QCOMPARE(printer.margins().left(), leftMMf);
- QCOMPARE(printer.margins().right(), rightMMf);
- QCOMPARE(printer.margins().top(), topMMf);
- QCOMPARE(printer.margins().bottom(), bottomMMf);
+ QMarginsF margins(leftMMf, topMMf, rightMMf, bottomMMf);
+ QCOMPARE(printer.pageLayout().margins(), margins);
} else {
// Fetch the default margins for the printer and page size
// TODO Check against margins from print device when api added
- leftMMf = printer.margins().left();
- rightMMf = printer.margins().right();
- topMMf = printer.margins().top();
- bottomMMf = printer.margins().bottom();
+ leftMMf = printer.pageLayout().margins(QPageLayout::Millimeter).left();
+ rightMMf = printer.pageLayout().margins(QPageLayout::Millimeter).right();
+ topMMf = printer.pageLayout().margins(QPageLayout::Millimeter).top();
+ bottomMMf = printer.pageLayout().margins(QPageLayout::Millimeter).bottom();
}
- // QPagedPaintDevice::pageSizeMM() always returns Portrait
- QCOMPARE(printer.pageSizeMM(), sizeMMf);
+ // QPageLayout::pageSize() always returns Portrait
+ QCOMPARE(printer.pageLayout().pageSize().size(QPageSize::Millimeter), sizeMMf);
- // QPrinter::paperSize() always returns set orientation
- QCOMPARE(printer.paperSize(QPrinter::Millimeter), sizeMMf.transposed());
+ // QPrinter::paperRect() always returns set orientation
+ QCOMPARE(printer.paperRect(QPrinter::Millimeter).size(), sizeMMf.transposed());
// QPagedPaintDevice::widthMM() and heightMM() are paint metrics and always return set orientation
QCOMPARE(printer.widthMM(), qRound(heightMMf - leftMMf - rightMMf));
/span>bits], 16, huff); bits >>= AccumulateHCode(htree_group->htrees[BLUE][bits], 0, huff); bits >>= AccumulateHCode(htree_group->htrees[ALPHA][bits], 24, huff); (void)bits; } } } static int ReadHuffmanCodeLengths( VP8LDecoder* const dec, const int* const code_length_code_lengths, int num_symbols, int* const code_lengths) { int ok = 0; VP8LBitReader* const br = &dec->br_; int symbol; int max_symbol; int prev_code_len = DEFAULT_CODE_LENGTH; HuffmanCode table[1 << LENGTHS_TABLE_BITS]; if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS, code_length_code_lengths, NUM_CODE_LENGTH_CODES)) { goto End; } if (VP8LReadBits(br, 1)) { // use length const int length_nbits = 2 + 2 * VP8LReadBits(br, 3); max_symbol = 2 + VP8LReadBits(br, length_nbits); if (max_symbol > num_symbols) { goto End; } } else { max_symbol = num_symbols; } symbol = 0; while (symbol < num_symbols) { const HuffmanCode* p; int code_len; if (max_symbol-- == 0) break; VP8LFillBitWindow(br); p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK]; VP8LSetBitPos(br, br->bit_pos_ + p->bits); code_len = p->value; if (code_len < kCodeLengthLiterals) { code_lengths[symbol++] = code_len; if (code_len != 0) prev_code_len = code_len; } else { const int use_prev = (code_len == kCodeLengthRepeatCode); const int slot = code_len - kCodeLengthLiterals; const int extra_bits = kCodeLengthExtraBits[slot]; const int repeat_offset = kCodeLengthRepeatOffsets[slot]; int repeat = VP8LReadBits(br, extra_bits) + repeat_offset; if (symbol + repeat > num_symbols) { goto End; } else { const int length = use_prev ? prev_code_len : 0; while (repeat-- > 0) code_lengths[symbol++] = length; } } } ok = 1; End: if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR; return ok; } // 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman // tree. static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec, int* const code_lengths, HuffmanCode* const table) { int ok = 0; int size = 0; VP8LBitReader* const br = &dec->br_; const int simple_code = VP8LReadBits(br, 1); memset(code_lengths, 0, alphabet_size * sizeof(*code_lengths)); if (simple_code) { // Read symbols, codes & code lengths directly. const int num_symbols = VP8LReadBits(br, 1) + 1; const int first_symbol_len_code = VP8LReadBits(br, 1); // The first code is either 1 bit or 8 bit code. int symbol = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8); code_lengths[symbol] = 1; // The second code (if present), is always 8 bit long. if (num_symbols == 2) { symbol = VP8LReadBits(br, 8); code_lengths[symbol] = 1; } ok = 1; } else { // Decode Huffman-coded code lengths. int i; int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 }; const int num_codes = VP8LReadBits(br, 4) + 4; if (num_codes > NUM_CODE_LENGTH_CODES) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; return 0; } for (i = 0; i < num_codes; ++i) { code_length_code_lengths[kCodeLengthCodeOrder[i]] = VP8LReadBits(br, 3); } ok = ReadHuffmanCodeLengths(dec, code_length_code_lengths, alphabet_size, code_lengths); } ok = ok && !br->eos_; if (ok) { size = VP8LBuildHuffmanTable(table, HUFFMAN_TABLE_BITS, code_lengths, alphabet_size); } if (!ok || size == 0) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; return 0; } return size; } static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize, int color_cache_bits, int allow_recursion) { int i, j; VP8LBitReader* const br = &dec->br_; VP8LMetadata* const hdr = &dec->hdr_; uint32_t* huffman_image = NULL; HTreeGroup* htree_groups = NULL; HuffmanCode* huffman_tables = NULL; HuffmanCode* next = NULL; int num_htree_groups = 1; int max_alphabet_size = 0; int* code_lengths = NULL; const int table_size = kTableSize[color_cache_bits]; if (allow_recursion && VP8LReadBits(br, 1)) { // use meta Huffman codes. const int huffman_precision = VP8LReadBits(br, 3) + 2; const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision); const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision); const int huffman_pixs = huffman_xsize * huffman_ysize; if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec, &huffman_image)) { goto Error; } hdr->huffman_subsample_bits_ = huffman_precision; for (i = 0; i < huffman_pixs; ++i) { // The huffman data is stored in red and green bytes. const int group = (huffman_image[i] >> 8) & 0xffff; huffman_image[i] = group; if (group >= num_htree_groups) { num_htree_groups = group + 1; } } } if (br->eos_) goto Error; // Find maximum alphabet size for the htree group. for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { int alphabet_size = kAlphabetSize[j]; if (j == 0 && color_cache_bits > 0) { alphabet_size += 1 << color_cache_bits; } if (max_alphabet_size < alphabet_size) { max_alphabet_size = alphabet_size; } } huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size, sizeof(*huffman_tables)); htree_groups = VP8LHtreeGroupsNew(num_htree_groups); code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size, sizeof(*code_lengths)); if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) { dec->status_ = VP8_STATUS_OUT_OF_MEMORY; goto Error; } next = huffman_tables; for (i = 0; i < num_htree_groups; ++i) { HTreeGroup* const htree_group = &htree_groups[i]; HuffmanCode** const htrees = htree_group->htrees; int size; int total_size = 0; int is_trivial_literal = 1; int max_bits = 0; for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { int alphabet_size = kAlphabetSize[j]; htrees[j] = next; if (j == 0 && color_cache_bits > 0) { alphabet_size += 1 << color_cache_bits; } size = ReadHuffmanCode(alphabet_size, dec, code_lengths, next); if (size == 0) { goto Error; } if (is_trivial_literal && kLiteralMap[j] == 1) { is_trivial_literal = (next->bits == 0); } total_size += next->bits; next += size; if (j <= ALPHA) { int local_max_bits = code_lengths[0]; int k; for (k = 1; k < alphabet_size; ++k) { if (code_lengths[k] > local_max_bits) { local_max_bits = code_lengths[k]; } } max_bits += local_max_bits; } } htree_group->is_trivial_literal = is_trivial_literal; htree_group->is_trivial_code = 0; if (is_trivial_literal) { const int red = htrees[RED][0].value; const int blue = htrees[BLUE][0].value; const int alpha = htrees[ALPHA][0].value; htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue; if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) { htree_group->is_trivial_code = 1; htree_group->literal_arb |= htrees[GREEN][0].value << 8; } } htree_group->use_packed_table = !htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS); if (htree_group->use_packed_table) BuildPackedTable(htree_group); } WebPSafeFree(code_lengths); // All OK. Finalize pointers and return. hdr->huffman_image_ = huffman_image; hdr->num_htree_groups_ = num_htree_groups; hdr->htree_groups_ = htree_groups; hdr->huffman_tables_ = huffman_tables; return 1; Error: WebPSafeFree(code_lengths); WebPSafeFree(huffman_image); WebPSafeFree(huffman_tables); VP8LHtreeGroupsFree(htree_groups); return 0; } //------------------------------------------------------------------------------ // Scaling. #if !defined(WEBP_REDUCE_SIZE) static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) { const int num_channels = 4; const int in_width = io->mb_w; const int out_width = io->scaled_width; const int in_height = io->mb_h; const int out_height = io->scaled_height; const uint64_t work_size = 2 * num_channels * (uint64_t)out_width; rescaler_t* work; // Rescaler work area. const uint64_t scaled_data_size = (uint64_t)out_width; uint32_t* scaled_data; // Temporary storage for scaled BGRA data. const uint64_t memory_size = sizeof(*dec->rescaler) + work_size * sizeof(*work) + scaled_data_size * sizeof(*scaled_data); uint8_t* memory = (uint8_t*)WebPSafeMalloc(memory_size, sizeof(*memory)); if (memory == NULL) { dec->status_ = VP8_STATUS_OUT_OF_MEMORY; return 0; } assert(dec->rescaler_memory == NULL); dec->rescaler_memory = memory; dec->rescaler = (WebPRescaler*)memory; memory += sizeof(*dec->rescaler); work = (rescaler_t*)memory; memory += work_size * sizeof(*work); scaled_data = (uint32_t*)memory; WebPRescalerInit(dec->rescaler, in_width, in_height, (uint8_t*)scaled_data, out_width, out_height, 0, num_channels, work); return 1; } #endif // WEBP_REDUCE_SIZE //------------------------------------------------------------------------------ // Export to ARGB #if !defined(WEBP_REDUCE_SIZE) // We have special "export" function since we need to convert from BGRA static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace, int rgba_stride, uint8_t* const rgba) { uint32_t* const src = (uint32_t*)rescaler->dst; const int dst_width = rescaler->dst_width; int num_lines_out = 0; while (WebPRescalerHasPendingOutput(rescaler)) { uint8_t* const dst = rgba + num_lines_out * rgba_stride; WebPRescalerExportRow(rescaler); WebPMultARGBRow(src, dst_width, 1); VP8LConvertFromBGRA(src, dst_width, colorspace, dst); ++num_lines_out; } return num_lines_out; } // Emit scaled rows. static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec, uint8_t* in, int in_stride, int mb_h, uint8_t* const out, int out_stride) { const WEBP_CSP_MODE colorspace = dec->output_->colorspace; int num_lines_in = 0; int num_lines_out = 0; while (num_lines_in < mb_h) { uint8_t* const row_in = in + num_lines_in * in_stride; uint8_t* const row_out = out + num_lines_out * out_stride; const int lines_left = mb_h - num_lines_in; const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left); int lines_imported; assert(needed_lines > 0 && needed_lines <= lines_left); WebPMultARGBRows(row_in, in_stride, dec->rescaler->src_width, needed_lines, 0); lines_imported = WebPRescalerImport(dec->rescaler, lines_left, row_in, in_stride); assert(lines_imported == needed_lines); num_lines_in += lines_imported; num_lines_out += Export(dec->rescaler, colorspace, out_stride, row_out); } return num_lines_out; } #endif // WEBP_REDUCE_SIZE // Emit rows without any scaling. static int EmitRows(WEBP_CSP_MODE colorspace, const uint8_t* row_in, int in_stride, int mb_w, int mb_h, uint8_t* const out, int out_stride) { int lines = mb_h; uint8_t* row_out = out; while (lines-- > 0) { VP8LConvertFromBGRA((const uint32_t*)row_in, mb_w, colorspace, row_out); row_in += in_stride; row_out += out_stride; } return mb_h; // Num rows out == num rows in. } //------------------------------------------------------------------------------ // Export to YUVA static void ConvertToYUVA(const uint32_t* const src, int width, int y_pos, const WebPDecBuffer* const output) { const WebPYUVABuffer* const buf = &output->u.YUVA; // first, the luma plane WebPConvertARGBToY(src, buf->y + y_pos * buf->y_stride, width); // then U/V planes { uint8_t* const u = buf->u + (y_pos >> 1) * buf->u_stride; uint8_t* const v = buf->v + (y_pos >> 1) * buf->v_stride; // even lines: store values // odd lines: average with previous values WebPConvertARGBToUV(src, u, v, width, !(y_pos & 1)); } // Lastly, store alpha if needed. if (buf->a != NULL) { uint8_t* const a = buf->a + y_pos * buf->a_stride; #if defined(WORDS_BIGENDIAN) WebPExtractAlpha((uint8_t*)src + 0, 0, width, 1, a, 0); #else WebPExtractAlpha((uint8_t*)src + 3, 0, width, 1, a, 0); #endif } } static int ExportYUVA(const VP8LDecoder* const dec, int y_pos) { WebPRescaler* const rescaler = dec->rescaler; uint32_t* const src = (uint32_t*)rescaler->dst; const int dst_width = rescaler->dst_width; int num_lines_out = 0; while (WebPRescalerHasPendingOutput(rescaler)) { WebPRescalerExportRow(rescaler); WebPMultARGBRow(src, dst_width, 1); ConvertToYUVA(src, dst_width, y_pos, dec->output_); ++y_pos; ++num_lines_out; } return num_lines_out; } static int EmitRescaledRowsYUVA(const VP8LDecoder* const dec, uint8_t* in, int in_stride, int mb_h) { int num_lines_in = 0; int y_pos = dec->last_out_row_; while (num_lines_in < mb_h) { const int lines_left = mb_h - num_lines_in; const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left); int lines_imported; WebPMultARGBRows(in, in_stride, dec->rescaler->src_width, needed_lines, 0); lines_imported = WebPRescalerImport(dec->rescaler, lines_left, in, in_stride); assert(lines_imported == needed_lines); num_lines_in += lines_imported; in += needed_lines * in_stride; y_pos += ExportYUVA(dec, y_pos); } return y_pos; } static int EmitRowsYUVA(const VP8LDecoder* const dec, const uint8_t* in, int in_stride, int mb_w, int num_rows) { int y_pos = dec->last_out_row_; while (num_rows-- > 0) { ConvertToYUVA((const uint32_t*)in, mb_w, y_pos, dec->output_); in += in_stride; ++y_pos; } return y_pos; } //------------------------------------------------------------------------------ // Cropping. // Sets io->mb_y, io->mb_h & io->mb_w according to start row, end row and // crop options. Also updates the input data pointer, so that it points to the // start of the cropped window. Note that pixels are in ARGB format even if // 'in_data' is uint8_t*. // Returns true if the crop window is not empty. static int SetCropWindow(VP8Io* const io, int y_start, int y_end, uint8_t** const in_data, int pixel_stride) { assert(y_start < y_end); assert(io->crop_left < io->crop_right); if (y_end > io->crop_bottom) { y_end = io->crop_bottom; // make sure we don't overflow on last row. } if (y_start < io->crop_top) { const int delta = io->crop_top - y_start; y_start = io->crop_top; *in_data += delta * pixel_stride; } if (y_start >= y_end) return 0; // Crop window is empty. *in_data += io->crop_left * sizeof(uint32_t); io->mb_y = y_start - io->crop_top; io->mb_w = io->crop_right - io->crop_left; io->mb_h = y_end - y_start; return 1; // Non-empty crop window. } //------------------------------------------------------------------------------ static WEBP_INLINE int GetMetaIndex( const uint32_t* const image, int xsize, int bits, int x, int y) { if (bits == 0) return 0; return image[xsize * (y >> bits) + (x >> bits)]; } static WEBP_INLINE HTreeGroup* GetHtreeGroupForPos(VP8LMetadata* const hdr, int x, int y) { const int meta_index = GetMetaIndex(hdr->huffman_image_, hdr->huffman_xsize_, hdr->huffman_subsample_bits_, x, y); assert(meta_index < hdr->num_htree_groups_); return hdr->htree_groups_ + meta_index; } //------------------------------------------------------------------------------ // Main loop, with custom row-processing function typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row); static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows, const uint32_t* const rows) { int n = dec->next_transform_; const int cache_pixs = dec->width_ * num_rows; const int start_row = dec->last_row_; const int end_row = start_row + num_rows; const uint32_t* rows_in = rows; uint32_t* const rows_out = dec->argb_cache_; // Inverse transforms. while (n-- > 0) { VP8LTransform* const transform = &dec->transforms_[n]; VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out); rows_in = rows_out; } if (rows_in != rows_out) { // No transform called, hence just copy. memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out)); } } // Processes (transforms, scales & color-converts) the rows decoded after the // last call. static void ProcessRows(VP8LDecoder* const dec, int row) { const uint32_t* const rows = dec->pixels_ + dec->width_ * dec->last_row_; const int num_rows = row - dec->last_row_; assert(row <= dec->io_->crop_bottom); // We can't process more than NUM_ARGB_CACHE_ROWS at a time (that's the size // of argb_cache_), but we currently don't need more than that. assert(num_rows <= NUM_ARGB_CACHE_ROWS); if (num_rows > 0) { // Emit output. VP8Io* const io = dec->io_; uint8_t* rows_data = (uint8_t*)dec->argb_cache_; const int in_stride = io->width * sizeof(uint32_t); // in unit of RGBA ApplyInverseTransforms(dec, num_rows, rows); if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) { // Nothing to output (this time). } else { const WebPDecBuffer* const output = dec->output_; if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA const WebPRGBABuffer* const buf = &output->u.RGBA; uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride; const int num_rows_out = #if !defined(WEBP_REDUCE_SIZE) io->use_scaling ? EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h, rgba, buf->stride) : #endif // WEBP_REDUCE_SIZE EmitRows(output->colorspace, rows_data, in_stride, io->mb_w, io->mb_h, rgba, buf->stride); // Update 'last_out_row_'. dec->last_out_row_ += num_rows_out; } else { // convert to YUVA dec->last_out_row_ = io->use_scaling ? EmitRescaledRowsYUVA(dec, rows_data, in_stride, io->mb_h) : EmitRowsYUVA(dec, rows_data, in_stride, io->mb_w, io->mb_h); } assert(dec->last_out_row_ <= output->height); } } // Update 'last_row_'. dec->last_row_ = row; assert(dec->last_row_ <= dec->height_); } // Row-processing for the special case when alpha data contains only one // transform (color indexing), and trivial non-green literals. static int Is8bOptimizable(const VP8LMetadata* const hdr) { int i; if (hdr->color_cache_size_ > 0) return 0; // When the Huffman tree contains only one symbol, we can skip the // call to ReadSymbol() for red/blue/alpha channels. for (i = 0; i < hdr->num_htree_groups_; ++i) { HuffmanCode** const htrees = hdr->htree_groups_[i].htrees; if (htrees[RED][0].bits > 0) return 0; if (htrees[BLUE][0].bits > 0) return 0; if (htrees[ALPHA][0].bits > 0) return 0; } return 1; } static void AlphaApplyFilter(ALPHDecoder* const alph_dec, int first_row, int last_row, uint8_t* out, int stride) { if (alph_dec->filter_ != WEBP_FILTER_NONE) { int y; const uint8_t* prev_line = alph_dec->prev_line_; assert(WebPUnfilters[alph_dec->filter_] != NULL); for (y = first_row; y < last_row; ++y) { WebPUnfilters[alph_dec->filter_](prev_line, out, out, stride); prev_line = out; out += stride; } alph_dec->prev_line_ = prev_line; } } static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int last_row) { // For vertical and gradient filtering, we need to decode the part above the // crop_top row, in order to have the correct spatial predictors. ALPHDecoder* const alph_dec = (ALPHDecoder*)dec->io_->opaque; const int top_row = (alph_dec->filter_ == WEBP_FILTER_NONE || alph_dec->filter_ == WEBP_FILTER_HORIZONTAL) ? dec->io_->crop_top : dec->last_row_; const int first_row = (dec->last_row_ < top_row) ? top_row : dec->last_row_; assert(last_row <= dec->io_->crop_bottom); if (last_row > first_row) { // Special method for paletted alpha data. We only process the cropped area. const int width = dec->io_->width; uint8_t* out = alph_dec->output_ + width * first_row; const uint8_t* const in = (uint8_t*)dec->pixels_ + dec->width_ * first_row; VP8LTransform* const transform = &dec->transforms_[0]; assert(dec->next_transform_ == 1); assert(transform->type_ == COLOR_INDEXING_TRANSFORM); VP8LColorIndexInverseTransformAlpha(transform, first_row, last_row, in, out); AlphaApplyFilter(alph_dec, first_row, last_row, out, width); } dec->last_row_ = dec->last_out_row_ = last_row; } //------------------------------------------------------------------------------ // Helper functions for fast pattern copy (8b and 32b) // cyclic rotation of pattern word static WEBP_INLINE uint32_t Rotate8b(uint32_t V) { #if defined(WORDS_BIGENDIAN) return ((V & 0xff000000u) >> 24) | (V << 8); #else return ((V & 0xffu) << 24) | (V >> 8); #endif } // copy 1, 2 or 4-bytes pattern static WEBP_INLINE void CopySmallPattern8b(const uint8_t* src, uint8_t* dst, int length, uint32_t pattern) { int i; // align 'dst' to 4-bytes boundary. Adjust the pattern along the way. while ((uintptr_t)dst & 3) { *dst++ = *src++; pattern = Rotate8b(pattern); --length; } // Copy the pattern 4 bytes at a time. for (i = 0; i < (length >> 2); ++i) { ((uint32_t*)dst)[i] = pattern; } // Finish with left-overs. 'pattern' is still correctly positioned, // so no Rotate8b() call is needed. for (i <<= 2; i < length; ++i) { dst[i] = src[i]; } } static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) { const uint8_t* src = dst - dist; if (length >= 8) { uint32_t pattern = 0; switch (dist) { case 1: pattern = src[0]; #if defined(__arm__) || defined(_M_ARM) // arm doesn't like multiply that much pattern |= pattern << 8; pattern |= pattern << 16; #elif defined(WEBP_USE_MIPS_DSP_R2) __asm__ volatile ("replv.qb %0, %0" : "+r"(pattern)); #else pattern = 0x01010101u * pattern; #endif break; case 2: memcpy(&pattern, src, sizeof(uint16_t)); #if defined(__arm__) || defined(_M_ARM) pattern |= pattern << 16; #elif defined(WEBP_USE_MIPS_DSP_R2) __asm__ volatile ("replv.ph %0, %0" : "+r"(pattern)); #else pattern = 0x00010001u * pattern; #endif break; case 4: memcpy(&pattern, src, sizeof(uint32_t)); break; default: goto Copy; break; } CopySmallPattern8b(src, dst, length, pattern); return; } Copy: if (dist >= length) { // no overlap -> use memcpy() memcpy(dst, src, length * sizeof(*dst)); } else { int i; for (i = 0; i < length; ++i) dst[i] = src[i]; } } // copy pattern of 1 or 2 uint32_t's static WEBP_INLINE void CopySmallPattern32b(const uint32_t* src, uint32_t* dst, int length, uint64_t pattern) { int i; if ((uintptr_t)dst & 4) { // Align 'dst' to 8-bytes boundary. *dst++ = *src++; pattern = (pattern >> 32) | (pattern << 32); --length; } assert(0 == ((uintptr_t)dst & 7)); for (i = 0; i < (length >> 1); ++i) { ((uint64_t*)dst)[i] = pattern; // Copy the pattern 8 bytes at a time. } if (length & 1) { // Finish with left-over. dst[i << 1] = src[i << 1]; } } static WEBP_INLINE void CopyBlock32b(uint32_t* const dst, int dist, int length) { const uint32_t* const src = dst - dist; if (dist <= 2 && length >= 4 && ((uintptr_t)dst & 3) == 0) { uint64_t pattern; if (dist == 1) { pattern = (uint64_t)src[0]; pattern |= pattern << 32; } else { memcpy(&pattern, src, sizeof(pattern)); } CopySmallPattern32b(src, dst, length, pattern); } else if (dist >= length) { // no overlap memcpy(dst, src, length * sizeof(*dst)); } else { int i; for (i = 0; i < length; ++i) dst[i] = src[i]; } } //------------------------------------------------------------------------------ static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data, int width, int height, int last_row) { int ok = 1; int row = dec->last_pixel_ / width; int col = dec->last_pixel_ % width; VP8LBitReader* const br = &dec->br_; VP8LMetadata* const hdr = &dec->hdr_; int pos = dec->last_pixel_; // current position const int end = width * height; // End of data const int last = width * last_row; // Last pixel to decode const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; const int mask = hdr->huffman_mask_; const HTreeGroup* htree_group = (pos < last) ? GetHtreeGroupForPos(hdr, col, row) : NULL; assert(pos <= end); assert(last_row <= height); assert(Is8bOptimizable(hdr)); while (!br->eos_ && pos < last) { int code; // Only update when changing tile. if ((col & mask) == 0) { htree_group = GetHtreeGroupForPos(hdr, col, row); } assert(htree_group != NULL); VP8LFillBitWindow(br); code = ReadSymbol(htree_group->htrees[GREEN], br); if (code < NUM_LITERAL_CODES) { // Literal data[pos] = code; ++pos; ++col; if (col >= width) { col = 0; ++row; if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) { ExtractPalettedAlphaRows(dec, row); } } } else if (code < len_code_limit) { // Backward reference int dist_code, dist; const int length_sym = code - NUM_LITERAL_CODES; const int length = GetCopyLength(length_sym, br); const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br); VP8LFillBitWindow(br); dist_code = GetCopyDistance(dist_symbol, br); dist = PlaneCodeToDistance(width, dist_code); if (pos >= dist && end - pos >= length) { CopyBlock8b(data + pos, dist, length); } else { ok = 0; goto End; } pos += length; col += length; while (col >= width) { col -= width; ++row; if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) { ExtractPalettedAlphaRows(dec, row); } } if (pos < last && (col & mask)) { htree_group = GetHtreeGroupForPos(hdr, col, row); } } else { // Not reached ok = 0; goto End; } br->eos_ = VP8LIsEndOfStream(br); } // Process the remaining rows corresponding to last row-block. ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row); End: br->eos_ = VP8LIsEndOfStream(br); if (!ok || (br->eos_ && pos < end)) { ok = 0; dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED : VP8_STATUS_BITSTREAM_ERROR; } else { dec->last_pixel_ = pos; } return ok; } static void SaveState(VP8LDecoder* const dec, int last_pixel) { assert(dec->incremental_); dec->saved_br_ = dec->br_; dec->saved_last_pixel_ = last_pixel; if (dec->hdr_.color_cache_size_ > 0) { VP8LColorCacheCopy(&dec->hdr_.color_cache_, &dec->hdr_.saved_color_cache_); } } static void RestoreState(VP8LDecoder* const dec) { assert(dec->br_.eos_); dec->status_ = VP8_STATUS_SUSPENDED; dec->br_ = dec->saved_br_; dec->last_pixel_ = dec->saved_last_pixel_; if (dec->hdr_.color_cache_size_ > 0) { VP8LColorCacheCopy(&dec->hdr_.saved_color_cache_, &dec->hdr_.color_cache_); } } #define SYNC_EVERY_N_ROWS 8 // minimum number of rows between check-points static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data, int width, int height, int last_row, ProcessRowsFunc process_func) { int row = dec->last_pixel_ / width; int col = dec->last_pixel_ % width; VP8LBitReader* const br = &dec->br_; VP8LMetadata* const hdr = &dec->hdr_; uint32_t* src = data + dec->last_pixel_; uint32_t* last_cached = src; uint32_t* const src_end = data + width * height; // End of data uint32_t* const src_last = data + width * last_row; // Last pixel to decode const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; const int color_cache_limit = len_code_limit + hdr->color_cache_size_; int next_sync_row = dec->incremental_ ? row : 1 << 24; VP8LColorCache* const color_cache = (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL; const int mask = hdr->huffman_mask_; const HTreeGroup* htree_group = (src < src_last) ? GetHtreeGroupForPos(hdr, col, row) : NULL; assert(dec->last_row_ < last_row); assert(src_last <= src_end); while (src < src_last) { int code; if (row >= next_sync_row) { SaveState(dec, (int)(src - data)); next_sync_row = row + SYNC_EVERY_N_ROWS; } // Only update when changing tile. Note we could use this test: // if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed // but that's actually slower and needs storing the previous col/row. if ((col & mask) == 0) { htree_group = GetHtreeGroupForPos(hdr, col, row); } assert(htree_group != NULL); if (htree_group->is_trivial_code) { *src = htree_group->literal_arb; goto AdvanceByOne; } VP8LFillBitWindow(br); if (htree_group->use_packed_table) { code = ReadPackedSymbols(htree_group, br, src); if (VP8LIsEndOfStream(br)) break; if (code == PACKED_NON_LITERAL_CODE) goto AdvanceByOne; } else { code = ReadSymbol(htree_group->htrees[GREEN], br); } if (VP8LIsEndOfStream(br)) break; if (code < NUM_LITERAL_CODES) { // Literal if (htree_group->is_trivial_literal) { *src = htree_group->literal_arb | (code << 8); } else { int red, blue, alpha; red = ReadSymbol(htree_group->htrees[RED], br); VP8LFillBitWindow(br); blue = ReadSymbol(htree_group->htrees[BLUE], br); alpha = ReadSymbol(htree_group->htrees[ALPHA], br); if (VP8LIsEndOfStream(br)) break; *src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue; } AdvanceByOne: ++src; ++col; if (col >= width) { col = 0; ++row; if (process_func != NULL) { if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) { process_func(dec, row); } } if (color_cache != NULL) { while (last_cached < src) { VP8LColorCacheInsert(color_cache, *last_cached++); } } } } else if (code < len_code_limit) { // Backward reference int dist_code, dist; const int length_sym = code - NUM_LITERAL_CODES; const int length = GetCopyLength(length_sym, br); const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br); VP8LFillBitWindow(br); dist_code = GetCopyDistance(dist_symbol, br); dist = PlaneCodeToDistance(width, dist_code); if (VP8LIsEndOfStream(br)) break; if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) { goto Error; } else { CopyBlock32b(src, dist, length); } src += length; col += length; while (col >= width) { col -= width; ++row; if (process_func != NULL) { if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) { process_func(dec, row); } } } // Because of the check done above (before 'src' was incremented by // 'length'), the following holds true. assert(src <= src_end); if (col & mask) htree_group = GetHtreeGroupForPos(hdr, col, row); if (color_cache != NULL) { while (last_cached < src) { VP8LColorCacheInsert(color_cache, *last_cached++); } } } else if (code < color_cache_limit) { // Color cache const int key = code - len_code_limit; assert(color_cache != NULL); while (last_cached < src) { VP8LColorCacheInsert(color_cache, *last_cached++); } *src = VP8LColorCacheLookup(color_cache, key); goto AdvanceByOne; } else { // Not reached goto Error; } } br->eos_ = VP8LIsEndOfStream(br); if (dec->incremental_ && br->eos_ && src < src_end) { RestoreState(dec); } else if (!br->eos_) { // Process the remaining rows corresponding to last row-block. if (process_func != NULL) { process_func(dec, row > last_row ? last_row : row); } dec->status_ = VP8_STATUS_OK; dec->last_pixel_ = (int)(src - data); // end-of-scan marker } else { // if not incremental, and we are past the end of buffer (eos_=1), then this // is a real bitstream error. goto Error; } return 1; Error: dec->status_ = VP8_STATUS_BITSTREAM_ERROR; return 0; } // ----------------------------------------------------------------------------- // VP8LTransform static void ClearTransform(VP8LTransform* const transform) { WebPSafeFree(transform->data_); transform->data_ = NULL; } // For security reason, we need to remap the color map to span // the total possible bundled values, and not just the num_colors. static int ExpandColorMap(int num_colors, VP8LTransform* const transform) { int i; const int final_num_colors = 1 << (8 >> transform->bits_); uint32_t* const new_color_map = (uint32_t*)WebPSafeMalloc((uint64_t)final_num_colors, sizeof(*new_color_map)); if (new_color_map == NULL) { return 0; } else { uint8_t* const data = (uint8_t*)transform->data_; uint8_t* const new_data = (uint8_t*)new_color_map; new_color_map[0] = transform->data_[0]; for (i = 4; i < 4 * num_colors; ++i) { // Equivalent to AddPixelEq(), on a byte-basis. new_data[i] = (data[i] + new_data[i - 4]) & 0xff; } for (; i < 4 * final_num_colors; ++i) { new_data[i] = 0; // black tail. } WebPSafeFree(transform->data_); transform->data_ = new_color_map; } return 1; } static int ReadTransform(int* const xsize, int const* ysize, VP8LDecoder* const dec) { int ok = 1; VP8LBitReader* const br = &dec->br_; VP8LTransform* transform = &dec->transforms_[dec->next_transform_]; const VP8LImageTransformType type = (VP8LImageTransformType)VP8LReadBits(br, 2); // Each transform type can only be present once in the stream. if (dec->transforms_seen_ & (1U << type)) { return 0; // Already there, let's not accept the second same transform. } dec->transforms_seen_ |= (1U << type); transform->type_ = type; transform->xsize_ = *xsize; transform->ysize_ = *ysize; transform->data_ = NULL; ++dec->next_transform_; assert(dec->next_transform_ <= NUM_TRANSFORMS); switch (type) { case PREDICTOR_TRANSFORM: case CROSS_COLOR_TRANSFORM: transform->bits_ = VP8LReadBits(br, 3) + 2; ok = DecodeImageStream(VP8LSubSampleSize(transform->xsize_, transform->bits_), VP8LSubSampleSize(transform->ysize_, transform->bits_), 0, dec, &transform->data_); break; case COLOR_INDEXING_TRANSFORM: { const int num_colors = VP8LReadBits(br, 8) + 1; const int bits = (num_colors > 16) ? 0 : (num_colors > 4) ? 1 : (num_colors > 2) ? 2 : 3; *xsize = VP8LSubSampleSize(transform->xsize_, bits); transform->bits_ = bits; ok = DecodeImageStream(num_colors, 1, 0, dec, &transform->data_); ok = ok && ExpandColorMap(num_colors, transform); break; } case SUBTRACT_GREEN: break; default: assert(0); // can't happen break; } return ok; } // ----------------------------------------------------------------------------- // VP8LMetadata static void InitMetadata(VP8LMetadata* const hdr) { assert(hdr != NULL); memset(hdr, 0, sizeof(*hdr)); } static void ClearMetadata(VP8LMetadata* const hdr) { assert(hdr != NULL); WebPSafeFree(hdr->huffman_image_); WebPSafeFree(hdr->huffman_tables_); VP8LHtreeGroupsFree(hdr->htree_groups_); VP8LColorCacheClear(&hdr->color_cache_); VP8LColorCacheClear(&hdr->saved_color_cache_); InitMetadata(hdr); } // ----------------------------------------------------------------------------- // VP8LDecoder VP8LDecoder* VP8LNew(void) { VP8LDecoder* const dec = (VP8LDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec)); if (dec == NULL) return NULL; dec->status_ = VP8_STATUS_OK; dec->state_ = READ_DIM; VP8LDspInit(); // Init critical function pointers. return dec; } void VP8LClear(VP8LDecoder* const dec) { int i; if (dec == NULL) return; ClearMetadata(&dec->hdr_); WebPSafeFree(dec->pixels_); dec->pixels_ = NULL; for (i = 0; i < dec->next_transform_; ++i) { ClearTransform(&dec->transforms_[i]); } dec->next_transform_ = 0; dec->transforms_seen_ = 0; WebPSafeFree(dec->rescaler_memory); dec->rescaler_memory = NULL; dec->output_ = NULL; // leave no trace behind } void VP8LDelete(VP8LDecoder* const dec) { if (dec != NULL) { VP8LClear(dec); WebPSafeFree(dec); } } static void UpdateDecoder(VP8LDecoder* const dec, int width, int height) { VP8LMetadata* const hdr = &dec->hdr_; const int num_bits = hdr->huffman_subsample_bits_; dec->width_ = width; dec->height_ = height; hdr->huffman_xsize_ = VP8LSubSampleSize(width, num_bits); hdr->huffman_mask_ = (num_bits == 0) ? ~0 : (1 << num_bits) - 1; } static int DecodeImageStream(int xsize, int ysize, int is_level0, VP8LDecoder* const dec, uint32_t** const decoded_data) { int ok = 1; int transform_xsize = xsize; int transform_ysize = ysize; VP8LBitReader* const br = &dec->br_; VP8LMetadata* const hdr = &dec->hdr_; uint32_t* data = NULL; int color_cache_bits = 0; // Read the transforms (may recurse). if (is_level0) { while (ok && VP8LReadBits(br, 1)) { ok = ReadTransform(&transform_xsize, &transform_ysize, dec); } } // Color cache if (ok && VP8LReadBits(br, 1)) { color_cache_bits = VP8LReadBits(br, 4); ok = (color_cache_bits >= 1 && color_cache_bits <= MAX_CACHE_BITS); if (!ok) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; goto End; } } // Read the Huffman codes (may recurse). ok = ok && ReadHuffmanCodes(dec, transform_xsize, transform_ysize, color_cache_bits, is_level0); if (!ok) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; goto End; } // Finish setting up the color-cache if (color_cache_bits > 0) { hdr->color_cache_size_ = 1 << color_cache_bits; if (!VP8LColorCacheInit(&hdr->color_cache_, color_cache_bits)) { dec->status_ = VP8_STATUS_OUT_OF_MEMORY;