summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qimagescale.cpp1
-rw-r--r--src/gui/painting/qimagescale_p.h9
-rw-r--r--src/gui/painting/qpagedpaintdevice.cpp3
-rw-r--r--src/gui/painting/qpagedpaintdevice.h2
-rw-r--r--src/gui/painting/qpainterpath.cpp2
-rw-r--r--src/gui/painting/qpdf.cpp47
-rw-r--r--src/gui/painting/qpdf_p.h4
-rw-r--r--src/gui/painting/qpdfwriter.cpp8
-rw-r--r--src/gui/painting/qtriangulator.cpp30
9 files changed, 67 insertions, 39 deletions
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 96da5e029c..8a5274bd37 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -239,7 +239,6 @@ static QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img,
isi = new QImageScaleInfo;
if (!isi)
return 0;
- memset(isi, 0, sizeof(QImageScaleInfo));
isi->xup_yup = (qAbs(dw) >= sw) + ((qAbs(dh) >= sh) << 1);
diff --git a/src/gui/painting/qimagescale_p.h b/src/gui/painting/qimagescale_p.h
index 415623a575..244d681718 100644
--- a/src/gui/painting/qimagescale_p.h
+++ b/src/gui/painting/qimagescale_p.h
@@ -61,10 +61,11 @@ QImage qSmoothScaleImage(const QImage &img, int w, int h);
namespace QImageScale {
struct QImageScaleInfo {
- int *xpoints;
- const unsigned int **ypoints;
- int *xapoints, *yapoints;
- int xup_yup;
+ int *xpoints{nullptr};
+ const unsigned int **ypoints{nullptr};
+ int *xapoints{nullptr};
+ int *yapoints{nullptr};
+ int xup_yup{0};
};
}
diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp
index 613a686848..72b2834470 100644
--- a/src/gui/painting/qpagedpaintdevice.cpp
+++ b/src/gui/painting/qpagedpaintdevice.cpp
@@ -290,7 +290,8 @@ QPagedPaintDevicePrivate *QPagedPaintDevice::dd()
\value PdfVersion_A1b A PDF/A-1b compatible document is produced.
- \since 5.10
+ \value PdfVersion_1_6 A PDF 1.6 compatible document is produced.
+ This value was added in Qt 5.12.
*/
/*!
diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h
index c8957edab8..1c37c17fa3 100644
--- a/src/gui/painting/qpagedpaintdevice.h
+++ b/src/gui/painting/qpagedpaintdevice.h
@@ -213,7 +213,7 @@ public:
Envelope10 = Comm10E
};
- enum PdfVersion { PdfVersion_1_4, PdfVersion_A1b };
+ enum PdfVersion { PdfVersion_1_4, PdfVersion_A1b, PdfVersion_1_6 };
// ### Qt6 Make these virtual
bool setPageLayout(const QPageLayout &pageLayout);
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 2574a00838..c5ccf0003d 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -2476,7 +2476,7 @@ QDataStream &operator>>(QDataStream &s, QPainterPath &p)
s >> p.d_func()->cStart;
int fillRule;
s >> fillRule;
- Q_ASSERT(fillRule == Qt::OddEvenFill || Qt::WindingFill);
+ Q_ASSERT(fillRule == Qt::OddEvenFill || fillRule == Qt::WindingFill);
p.d_func()->fillRule = Qt::FillRule(fillRule);
p.d_func()->dirtyBounds = true;
p.d_func()->dirtyControlBounds = true;
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 4fd0d3c8fe..b410e9b900 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -71,6 +71,11 @@ static const bool do_compress = true;
// Can't use it though, as gs generates completely wrong images if this is true.
static const bool interpolateImages = false;
+static void initResources()
+{
+ Q_INIT_RESOURCE(qpdf);
+}
+
QT_BEGIN_NAMESPACE
inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features()
@@ -1446,6 +1451,7 @@ QPdfEnginePrivate::QPdfEnginePrivate()
grayscale(false),
m_pageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(10, 10, 10, 10))
{
+ initResources();
resolution = 1200;
currentObject = 1;
currentPage = 0;
@@ -1541,7 +1547,14 @@ void QPdfEnginePrivate::writeHeader()
{
addXrefEntry(0,false);
- xprintf("%%PDF-1.4\n");
+ static const QHash<QPdfEngine::PdfVersion, const char *> mapping {
+ {QPdfEngine::Version_1_4, "1.4"},
+ {QPdfEngine::Version_A1b, "1.4"},
+ {QPdfEngine::Version_1_6, "1.6"}
+ };
+ const char *verStr = mapping.value(pdfVersion, "1.4");
+
+ xprintf("%%PDF-%s\n", verStr);
xprintf("%%\303\242\303\243\n");
writeInfo();
@@ -1874,6 +1887,19 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
}
}
+qreal QPdfEnginePrivate::calcUserUnit() const
+{
+ // PDF standards < 1.6 support max 200x200in pages (no UserUnit)
+ if (pdfVersion < QPdfEngine::Version_1_6)
+ return 1.0;
+
+ const int maxLen = qMax(currentPage->pageSize.width(), currentPage->pageSize.height());
+ if (maxLen <= 14400)
+ return 1.0; // for pages up to 200x200in (14400x14400 units) use default scaling
+
+ // for larger pages, rescale units so we can have up to 381x381km
+ return qMin(maxLen / 14400.0, 75000.0);
+}
void QPdfEnginePrivate::writeFonts()
{
@@ -1896,6 +1922,8 @@ void QPdfEnginePrivate::writePage()
uint resources = requestObject();
uint annots = requestObject();
+ qreal userUnit = calcUserUnit();
+
addXrefEntry(pages.constLast());
xprintf("<<\n"
"/Type /Page\n"
@@ -1903,12 +1931,16 @@ void QPdfEnginePrivate::writePage()
"/Contents %d 0 R\n"
"/Resources %d 0 R\n"
"/Annots %d 0 R\n"
- "/MediaBox [0 0 %d %d]\n"
- ">>\n"
- "endobj\n",
+ "/MediaBox [0 0 %f %f]\n",
pageRoot, pageStream, resources, annots,
// make sure we use the pagesize from when we started the page, since the user may have changed it
- currentPage->pageSize.width(), currentPage->pageSize.height());
+ currentPage->pageSize.width() / userUnit, currentPage->pageSize.height() / userUnit);
+
+ if (pdfVersion >= QPdfEngine::Version_1_6)
+ xprintf("/UserUnit %f\n", userUnit);
+
+ xprintf(">>\n"
+ "endobj\n");
addXrefEntry(resources);
xprintf("<<\n"
@@ -2977,8 +3009,9 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)
QTransform QPdfEnginePrivate::pageMatrix() const
{
- qreal scale = 72./resolution;
- QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height());
+ qreal userUnit = calcUserUnit();
+ qreal scale = 72. / userUnit / resolution;
+ QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height() / userUnit);
if (m_pageLayout.mode() != QPageLayout::FullPageMode) {
QRect r = m_pageLayout.paintRectPixels(resolution);
tmp.translate(r.left(), r.top());
diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h
index 5a909f2ede..e2526de67d 100644
--- a/src/gui/painting/qpdf_p.h
+++ b/src/gui/painting/qpdf_p.h
@@ -171,7 +171,8 @@ public:
enum PdfVersion
{
Version_1_4,
- Version_A1b
+ Version_A1b,
+ Version_1_6
};
QPdfEngine();
@@ -300,6 +301,7 @@ private:
void writePageRoot();
void writeFonts();
void embedFont(QFontSubset *font);
+ qreal calcUserUnit() const;
QVector<int> xrefPositions;
QDataStream* stream;
diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp
index 5f0fad2a4e..258939a763 100644
--- a/src/gui/painting/qpdfwriter.cpp
+++ b/src/gui/painting/qpdfwriter.cpp
@@ -170,11 +170,17 @@ void QPdfWriter::setPdfVersion(PdfVersion version)
{
Q_D(QPdfWriter);
+ static const QHash<QPdfWriter::PdfVersion, QPdfEngine::PdfVersion> engineMapping {
+ {QPdfWriter::PdfVersion_1_4, QPdfEngine::Version_1_4},
+ {QPdfWriter::PdfVersion_A1b, QPdfEngine::Version_A1b},
+ {QPdfWriter::PdfVersion_1_6, QPdfEngine::Version_1_6}
+ };
+
if (d->pdfVersion == version)
return;
d->pdfVersion = version;
- d->engine->setPdfVersion(d->pdfVersion == QPdfWriter::PdfVersion_1_4 ? QPdfEngine::Version_1_4 : QPdfEngine::Version_A1b);
+ d->engine->setPdfVersion(engineMapping.value(version, QPdfEngine::Version_1_4));
}
/*!
diff --git a/src/gui/painting/qtriangulator.cpp b/src/gui/painting/qtriangulator.cpp
index 6d57eba123..9be3eeaffd 100644
--- a/src/gui/painting/qtriangulator.cpp
+++ b/src/gui/painting/qtriangulator.cpp
@@ -472,7 +472,7 @@ class QInt64Set
{
public:
inline QInt64Set(int capacity = 64);
- inline ~QInt64Set() {if (m_array) delete[] m_array;}
+ inline ~QInt64Set() {delete[] m_array;}
inline bool isValid() const {return m_array;}
void insert(quint64 key);
bool contains(quint64 key) const;
@@ -493,10 +493,7 @@ inline QInt64Set::QInt64Set(int capacity)
{
m_capacity = primeForCount(capacity);
m_array = new quint64[m_capacity];
- if (m_array)
- clear();
- else
- m_capacity = 0;
+ clear();
}
bool QInt64Set::rehash(int capacity)
@@ -506,28 +503,19 @@ bool QInt64Set::rehash(int capacity)
m_capacity = capacity;
m_array = new quint64[m_capacity];
- if (m_array) {
- clear();
- if (oldArray) {
- for (int i = 0; i < oldCapacity; ++i) {
- if (oldArray[i] != UNUSED)
- insert(oldArray[i]);
- }
- delete[] oldArray;
- }
- return true;
- } else {
- m_capacity = oldCapacity;
- m_array = oldArray;
- return false;
+ clear();
+ for (int i = 0; i < oldCapacity; ++i) {
+ if (oldArray[i] != UNUSED)
+ insert(oldArray[i]);
}
+ delete[] oldArray;
+ return true;
}
void QInt64Set::insert(quint64 key)
{
if (m_count > 3 * m_capacity / 4)
rehash(primeForCount(2 * m_capacity));
- Q_ASSERT_X(m_array, "QInt64Hash<T>::insert", "Hash set not allocated.");
int index = int(key % m_capacity);
for (int i = 0; i < m_capacity; ++i) {
index += i;
@@ -546,7 +534,6 @@ void QInt64Set::insert(quint64 key)
bool QInt64Set::contains(quint64 key) const
{
- Q_ASSERT_X(m_array, "QInt64Hash<T>::contains", "Hash set not allocated.");
int index = int(key % m_capacity);
for (int i = 0; i < m_capacity; ++i) {
index += i;
@@ -562,7 +549,6 @@ bool QInt64Set::contains(quint64 key) const
inline void QInt64Set::clear()
{
- Q_ASSERT_X(m_array, "QInt64Hash<T>::clear", "Hash set not allocated.");
for (int i = 0; i < m_capacity; ++i)
m_array[i] = UNUSED;
m_count = 0;