diff options
Diffstat (limited to 'src/printsupport/kernel')
-rw-r--r-- | src/printsupport/kernel/kernel.pri | 2 | ||||
-rw-r--r-- | src/printsupport/kernel/qplatformprintplugin.cpp | 22 | ||||
-rw-r--r-- | src/printsupport/kernel/qprintengine_win.cpp | 128 | ||||
-rw-r--r-- | src/printsupport/kernel/qprinter.cpp | 2 | ||||
-rw-r--r-- | src/printsupport/kernel/qprinterinfo.cpp | 29 | ||||
-rw-r--r-- | src/printsupport/kernel/qprinterinfo_p.h | 13 |
6 files changed, 124 insertions, 72 deletions
diff --git a/src/printsupport/kernel/kernel.pri b/src/printsupport/kernel/kernel.pri index 8bdccd0f5b..67fcc8597c 100644 --- a/src/printsupport/kernel/kernel.pri +++ b/src/printsupport/kernel/kernel.pri @@ -24,7 +24,7 @@ win32 { $$PWD/qprintengine_win_p.h SOURCES += \ $$PWD/qprintengine_win.cpp - LIBS += -lwinspool -lcomdlg32 -lgdi32 -luser32 + LIBS_PRIVATE += -lwinspool -lcomdlg32 -lgdi32 -luser32 } unix:!mac:contains(QT_CONFIG, cups): { diff --git a/src/printsupport/kernel/qplatformprintplugin.cpp b/src/printsupport/kernel/qplatformprintplugin.cpp index ce6d7a0f7e..f3e88e7cf7 100644 --- a/src/printsupport/kernel/qplatformprintplugin.cpp +++ b/src/printsupport/kernel/qplatformprintplugin.cpp @@ -40,7 +40,10 @@ ****************************************************************************/ #include "qplatformprintplugin.h" +#include "qplatformprintersupport.h" +#include "qprinterinfo.h" #include "private/qfactoryloader_p.h" +#include <qcoreapplication.h> QT_BEGIN_NAMESPACE @@ -58,6 +61,16 @@ QPlatformPrinterSupportPlugin::~QPlatformPrinterSupportPlugin() { } +static QPlatformPrinterSupport *printerSupport = 0; + +static void cleanupPrinterSupport() +{ +#ifndef QT_NO_PRINTER + delete printerSupport; +#endif + printerSupport = 0; +} + /*! \internal @@ -68,13 +81,14 @@ QPlatformPrinterSupportPlugin::~QPlatformPrinterSupportPlugin() */ QPlatformPrinterSupport *QPlatformPrinterSupportPlugin::get() { - static QPlatformPrinterSupport *singleton = 0; - if (!singleton) { + if (!printerSupport) { const QMultiMap<int, QString> keyMap = loader()->keyMap(); if (!keyMap.isEmpty()) - singleton = qLoadPlugin<QPlatformPrinterSupport, QPlatformPrinterSupportPlugin>(loader(), keyMap.constBegin().value()); + printerSupport = qLoadPlugin<QPlatformPrinterSupport, QPlatformPrinterSupportPlugin>(loader(), keyMap.constBegin().value()); + if (printerSupport) + qAddPostRoutine(cleanupPrinterSupport); } - return singleton; + return printerSupport; } QT_END_NAMESPACE diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index acaa32304e..e2446c19b1 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -67,6 +67,8 @@ QT_BEGIN_NAMESPACE Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0); extern QPainterPath qt_regionToPath(const QRegion ®ion); +Q_PRINTSUPPORT_EXPORT QSizeF qt_SizeFromUnitToMillimeter(const QSizeF &, QPrinter::Unit, double); +Q_PRINTSUPPORT_EXPORT double qt_multiplierForUnit(QPrinter::Unit unit, int resolution); // #define QT_DEBUG_DRAW @@ -114,6 +116,52 @@ static const struct { { 0, QPrinter::Custom } }; +// Return a list of printer paper sizes in millimeters with the corresponding dmPaperSize value +static QList<QPair<QSizeF, int> > printerPaperSizes(const QString &printerName) +{ + QList<QPair<QSizeF, int> > result; + const wchar_t *name = reinterpret_cast<const wchar_t*>(printerName.utf16()); + DWORD paperNameCount = DeviceCapabilities(name, NULL, DC_PAPERS, NULL, NULL); + if ((int)paperNameCount > 0) { + // If they are not equal, then there seems to be a problem with the driver + if (paperNameCount != DeviceCapabilities(name, NULL, DC_PAPERSIZE, NULL, NULL)) + return result; + QScopedArrayPointer<wchar_t> papersNames(new wchar_t[paperNameCount]); + paperNameCount = DeviceCapabilities(name, NULL, DC_PAPERS, papersNames.data(), NULL); + result.reserve(paperNameCount); + QScopedArrayPointer<POINT> paperSizes(new POINT[paperNameCount]); + paperNameCount = DeviceCapabilities(name, NULL, DC_PAPERSIZE, (wchar_t *)paperSizes.data(), NULL); + for (int i=0; i <(int)paperNameCount; i++) + result.push_back(qMakePair(QSizeF(paperSizes[i].x / 10, paperSizes[i].y / 10), papersNames[i])); + } + return result; +} + +// Find the best-matching printer paper for size in millimeters. +static inline int findCustomPaperSize(const QSizeF &needlePt, const QString &printerName) +{ + const QList<QPair<QSizeF, int> > sizes = printerPaperSizes(printerName); + const qreal nw = needlePt.width(); + const qreal nh = needlePt.height(); + for (int i = 0; i < sizes.size(); ++i) { + if (qAbs(nw - sizes.at(i).first.width()) <= 1 && qAbs(nh - sizes.at(i).first.height()) <= 1) + return sizes.at(i).second; + } + return -1; +} + +static inline void setDevModePaperFlags(DEVMODE *devMode, bool custom) +{ + if (custom) { + devMode->dmPaperSize = DMPAPER_USER; + devMode->dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH; + } else { + devMode->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH); + devMode->dmPaperLength = 0; + devMode->dmPaperWidth = 0; + } +} + QPrinter::PaperSize mapDevmodePaperSize(int s) { int i = 0; @@ -1293,6 +1341,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & break; d->devMode->dmPaperSize = mapPaperSizeDevmode(QPrinter::PaperSize(value.toInt())); d->has_custom_paper_size = (QPrinter::PaperSize(value.toInt()) == QPrinter::Custom); + setDevModePaperFlags(d->devMode, d->has_custom_paper_size); d->doReinit(); break; case PPK_PaperName: @@ -1320,9 +1369,19 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & wchar_t *papers = new wchar_t[size]; size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()), NULL, DC_PAPERS, papers, NULL); - d->has_custom_paper_size = false; - d->devMode->dmPaperSize = papers[paperPos]; - d->doReinit(); + QScopedArrayPointer<POINT> paperSizes(new POINT[size]); + DWORD paperNameCount = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()), NULL, DC_PAPERSIZE, (wchar_t *)paperSizes.data(), NULL); + if (paperNameCount == size) { + const double multiplier = qt_multiplierForUnit(QPrinter::Millimeter, d->resolution); + d->paper_size = QSizeF((paperSizes[paperPos].x / 10.0) * multiplier, (paperSizes[paperPos].y / 10.0) * multiplier); + // Our sizes may not match the paper name's size exactly + // So we treat it as custom so we know the paper size is correct + d->has_custom_paper_size = true; + d->devMode->dmPaperSize = papers[paperPos]; + setDevModePaperFlags(d->devMode, false); + d->doReinit(); + } + delete [] papers; } } @@ -1373,6 +1432,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & break; d->has_custom_paper_size = false; d->devMode->dmPaperSize = value.toInt(); + setDevModePaperFlags(d->devMode, d->has_custom_paper_size); d->doReinit(); break; @@ -1382,30 +1442,17 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & d->paper_size = value.toSizeF(); if (!d->devMode) break; - int orientation = d->devMode->dmOrientation; - DWORD needed = 0; - DWORD returned = 0; - if (!EnumForms(d->hPrinter, 1, 0, 0, &needed, &returned)) { - BYTE *forms = (BYTE *) malloc(needed); - if (EnumForms(d->hPrinter, 1, forms, needed, &needed, &returned)) { - for (DWORD i=0; i< returned; ++i) { - FORM_INFO_1 *formArray = reinterpret_cast<FORM_INFO_1 *>(forms); - // the form sizes are specified in 1000th of a mm, - // convert the size to Points - QSizeF size((formArray[i].Size.cx * 72/25.4)/1000.0, - (formArray[i].Size.cy * 72/25.4)/1000.0); - if (qAbs(d->paper_size.width() - size.width()) <= 2 - && qAbs(d->paper_size.height() - size.height()) <= 2) - { - d->devMode->dmPaperSize = i + 1; - break; - } - } - } - free(forms); + const QSizeF sizeMM = qt_SizeFromUnitToMillimeter(d->paper_size, QPrinter::Point, d->resolution); + const int match = findCustomPaperSize(sizeMM, d->name); + setDevModePaperFlags(d->devMode, (match >= 0) ? false : true); + if (match >= 0) { + d->devMode->dmPaperSize = match; + if (d->devMode->dmOrientation != DMORIENT_PORTRAIT) + qSwap(d->paper_size.rwidth(), d->paper_size.rheight()); + } else { + d->devMode->dmPaperLength = qRound(sizeMM.height() * 10.0); + d->devMode->dmPaperWidth = qRound(sizeMM.width() * 10.0); } - if (orientation != DMORIENT_PORTRAIT) - d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width()); break; } @@ -1692,7 +1739,7 @@ QList<QPair<QString, QSizeF> > QWin32PrintEngine::supportedSizesWithNames(const for (int i=0;i<(int)size;i++) { wchar_t *paper = papers + (i * 64); QString str = QString::fromWCharArray(paper, qwcsnlen(paper, 64)); - paperSizes << qMakePair(str, QSizeF(points[i].x / 10, points[i].y / 10)); + paperSizes << qMakePair(str, QSizeF(points[i].x / 10.0, points[i].y / 10.0)); } delete [] points; } @@ -1908,30 +1955,19 @@ static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC h SelectObject(hdc, old_font); } - void QWin32PrintEnginePrivate::updateCustomPaperSize() { - uint paperSize = devMode->dmPaperSize; + const uint paperSize = devMode->dmPaperSize; + has_custom_paper_size = true; if (paperSize > 0 && mapDevmodePaperSize(paperSize) == QPrinter::Custom) { - has_custom_paper_size = true; - DWORD needed = 0; - DWORD returned = 0; - if (!EnumForms(hPrinter, 1, 0, 0, &needed, &returned)) { - BYTE *forms = (BYTE *) malloc(needed); - if (EnumForms(hPrinter, 1, forms, needed, &needed, &returned)) { - if (paperSize <= returned) { - FORM_INFO_1 *formArray = (FORM_INFO_1 *) forms; - int width = formArray[paperSize - 1].Size.cx; // 1/1000 of a mm - int height = formArray[paperSize - 1].Size.cy; // 1/1000 of a mm - paper_size = QSizeF((width * 72 /25.4) / 1000.0, (height * 72 / 25.4) / 1000.0); - } else { - has_custom_paper_size = false; - } + const QList<QPair<QSizeF, int> > paperSizes = printerPaperSizes(name); + for (int i=0; i<paperSizes.size(); i++) { + if ((uint)paperSizes.at(i).second == paperSize) { + paper_size = paperSizes.at(paperSize).first; + has_custom_paper_size = false; + break; } - free(forms); } - } else { - has_custom_paper_size = false; } } diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index f90fa71b0f..0905cbb59f 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -538,7 +538,7 @@ QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode) void QPrinterPrivate::init(QPrinter::PrinterMode mode) { if (!QCoreApplication::instance()) { - qFatal("QPrinter: Must construct a QApplication before a QPaintDevice"); + qFatal("QPrinter: Must construct a QCoreApplication before a QPrinter"); return; } diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp index f863b23e34..e02617fe93 100644 --- a/src/printsupport/kernel/qprinterinfo.cpp +++ b/src/printsupport/kernel/qprinterinfo.cpp @@ -35,8 +35,17 @@ QT_BEGIN_NAMESPACE -QPrinterInfoPrivate QPrinterInfoPrivate::shared_null; +Q_GLOBAL_STATIC(QPrinterInfoPrivate, shared_null); +class QPrinterInfoPrivateDeleter +{ +public: + static inline void cleanup(QPrinterInfoPrivate *d) + { + if (d != shared_null) + delete d; + } +}; /*! \class QPrinterInfo @@ -83,7 +92,7 @@ QPrinterInfoPrivate QPrinterInfoPrivate::shared_null; \sa isNull() */ QPrinterInfo::QPrinterInfo() - : d_ptr(&QPrinterInfoPrivate::shared_null) + : d_ptr(shared_null) { } @@ -91,7 +100,7 @@ QPrinterInfo::QPrinterInfo() Constructs a copy of \a other. */ QPrinterInfo::QPrinterInfo(const QPrinterInfo &other) - : d_ptr(new QPrinterInfoPrivate(*other.d_ptr)) + : d_ptr((other.d_ptr.data() == shared_null) ? shared_null : new QPrinterInfoPrivate(*other.d_ptr)) { } @@ -99,12 +108,15 @@ QPrinterInfo::QPrinterInfo(const QPrinterInfo &other) Constructs a QPrinterInfo object from \a printer. */ QPrinterInfo::QPrinterInfo(const QPrinter &printer) - : d_ptr(&QPrinterInfoPrivate::shared_null) + : d_ptr(shared_null) { QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get(); if (ps) { QPrinterInfo pi = ps->printerInfo(printer.printerName()); - d_ptr.reset(new QPrinterInfoPrivate(*pi.d_ptr)); + if (pi.d_ptr.data() == shared_null) + d_ptr.reset(shared_null); + else + d_ptr.reset(new QPrinterInfoPrivate(*pi.d_ptr)); } } @@ -130,7 +142,10 @@ QPrinterInfo::~QPrinterInfo() QPrinterInfo &QPrinterInfo::operator=(const QPrinterInfo &other) { Q_ASSERT(d_ptr); - d_ptr.reset(new QPrinterInfoPrivate(*other.d_ptr)); + if (other.d_ptr.data() == shared_null) + d_ptr.reset(shared_null); + else + d_ptr.reset(new QPrinterInfoPrivate(*other.d_ptr)); return *this; } @@ -191,7 +206,7 @@ QString QPrinterInfo::makeAndModel() const bool QPrinterInfo::isNull() const { Q_D(const QPrinterInfo); - return d == &QPrinterInfoPrivate::shared_null; + return d == shared_null || d->name.isEmpty(); } /*! diff --git a/src/printsupport/kernel/qprinterinfo_p.h b/src/printsupport/kernel/qprinterinfo_p.h index d4bb08f1f5..6ae64b5653 100644 --- a/src/printsupport/kernel/qprinterinfo_p.h +++ b/src/printsupport/kernel/qprinterinfo_p.h @@ -72,8 +72,6 @@ public: ~QPrinterInfoPrivate() {} - static QPrinterInfoPrivate shared_null; - QString name; QString description; QString location; @@ -87,17 +85,6 @@ public: mutable QList<QPair<QString, QSizeF> > paperNames; }; - -class QPrinterInfoPrivateDeleter -{ -public: - static inline void cleanup(QPrinterInfoPrivate *d) - { - if (d != &QPrinterInfoPrivate::shared_null) - delete d; - } -}; - QT_END_NAMESPACE #endif // QT_NO_PRINTER |