8#include "qplatformdefs.h"
10#include <private/qcmyk_p.h>
11#include <private/qfont_p.h>
12#include <private/qmath_p.h>
13#include <private/qpainter_p.h>
65 if (
color.alpha() != 255) {
83 for (
int i = 0;
i < stops.
size(); ++
i) {
84 if (stops[
i].second.alpha() != 255)
85 stops[
i].second.setAlpha(255);
103 if (!
qIsFinite(
val) || std::abs(
val) > std::numeric_limits<quint32>::max()) {
117 int ifrac = (int)(frac * 1000000000);
118 if (ifrac == 1000000000) {
129 int fact = 100000000;
143 *(
buf++) =
'0' + ((ifrac/fact) % 10);
180 fileBackingEnabled(fileBacking),
181 fileBackingActive(
false),
189 fileBackingEnabled(fileBacking),
190 fileBackingActive(
false),
203 if (handleDirty) prepareBuffer();
210 if (handleDirty) prepareBuffer();
217 if (handleDirty) prepareBuffer();
225 if (handleDirty) prepareBuffer();
231 while (!
s.dev->atEnd()) {
274 void ByteStream::prepareBuffer()
278 if (fileBackingEnabled && !fileBackingActive
281 QTemporaryFile *newFile =
new QTemporaryFile;
282 if (newFile->open()) {
284 while (!dev->
atEnd()) {
291 fileBackingActive =
true;
301#define QT_PATH_ELEMENT(elm)
306 if (!
path.elementCount())
312 for (
int i = 0;
i <
path.elementCount(); ++
i) {
336 qFatal(
"QPdf::generatePath(), unhandled type: %d", elm.type);
389 for (
int i = 0;
i < dasharray.size(); ++
i) {
391 if (dw < 0.0001) dw = 0.0001;
557 int style =
b.style();
570 t->matrix.map(
x,
y, &
x, &
y);
580 *
t->stream <<
x <<
y <<
"l\n";
589 if (!
t->cosmeticPen) {
591 t->matrix.map(c2x, c2y, &c2x, &c2y);
592 t->matrix.map(ex, ey, &ex, &ey);
594 *
t->stream << c1x << c1y
603 dashStroker(&basicStroker)
605 stroker = &basicStroker;
620 bool zeroWidth =
w < 0.0001;
625 basicStroker.setStrokeWidth(
w);
626 basicStroker.setCapStyle(pen.
capStyle());
627 basicStroker.setJoinStyle(pen.
joinStyle());
632 for (
int i = 0;
i < dashpattern.size(); ++
i)
633 dashpattern[
i] *= 10.;
635 if (!dashpattern.isEmpty()) {
636 dashStroker.setDashPattern(dashpattern);
638 stroker = &dashStroker;
640 stroker = &basicStroker;
661 for (
int i = 0;
i < isize;
i += 4) {
685 int remaining =
input.size() - isize;
688 for (
int i = isize;
i <
input.size(); ++
i)
689 val = (val << 8) +
in[
i];
690 val <<= 8*(4-remaining);
701 for (
int i = 0;
i < remaining+1; ++
i)
744 :
QPdf::ByteStream(true)
750 *
this <<
w <<
"0 0 " << -
h <<
"0 " <<
h <<
"cm /Im" <<
object <<
" Do\n";
769 d->outputFileName = filename;
780 for (
int i=0;
i!=pointCount;++
i) {
785 bool hadBrush =
d->hasBrush;
788 d->hasBrush = hadBrush;
798 for (
int i=0;
i!=lineCount;++
i) {
800 p.lineTo(lines[
i].
p2());
802 bool hadBrush =
d->hasBrush;
805 d->hasBrush = hadBrush;
815 if (
d->clipEnabled &&
d->allClipped)
817 if (!
d->hasPen && !
d->hasBrush)
820 if ((
d->simplePen && !
d->needsTransform) || !
d->hasPen) {
822 if (!
d->hasPen &&
d->needsTransform)
824 for (
int i = 0;
i < rectCount; ++
i)
825 *
d->currentPage << rects[
i].
x() << rects[
i].
y() << rects[
i].
width() << rects[
i].
height() <<
"re\n";
826 *
d->currentPage << (
d->hasPen ? (
d->hasBrush ?
"B\n" :
"S\n") :
"f\n");
827 if (!
d->hasPen &&
d->needsTransform)
828 *
d->currentPage <<
"Q\n";
831 for (
int i=0;
i!=rectCount; ++
i)
841 if (!
points || !pointCount)
844 bool hb =
d->hasBrush;
863 for (
int i = 1;
i < pointCount; ++
i)
877 if (
d->clipEnabled &&
d->allClipped)
879 if (!
d->hasPen && !
d->hasBrush)
890 *
d->currentPage <<
"q\n";
892 d->brush =
d->pen.brush();
894 d->stroker.strokePath(
p);
895 *
d->currentPage <<
"Q\n";
909 QRect sourceRect = sr.toRect();
918 *
d->currentPage <<
"q\n";
921 int stateObject =
d->addConstantAlphaObject(
qRound(255 *
d->opacity),
qRound(255 *
d->opacity));
923 *
d->currentPage <<
"/GState" << stateObject <<
"gs\n";
925 *
d->currentPage <<
"/GSa gs\n";
927 *
d->currentPage <<
"/GSa gs\n";
932 rectangle.
x(), rectangle.
y()) * (!
d->needsTransform ?
QTransform() :
d->stroker.matrix));
935 d->brush =
d->pen.brush();
938 d->currentPage->streamImage(
image.width(),
image.height(),
object);
939 *
d->currentPage <<
"Q\n";
946 if (sr.isEmpty() || rectangle.
isEmpty() ||
image.isNull())
950 QRect sourceRect = sr.toRect();
958 *
d->currentPage <<
"q\n";
961 int stateObject =
d->addConstantAlphaObject(
qRound(255 *
d->opacity),
qRound(255 *
d->opacity));
963 *
d->currentPage <<
"/GState" << stateObject <<
"gs\n";
965 *
d->currentPage <<
"/GSa gs\n";
967 *
d->currentPage <<
"/GSa gs\n";
972 rectangle.
x(), rectangle.
y()) * (!
d->needsTransform ?
QTransform() :
d->stroker.matrix));
974 d->currentPage->streamImage(im.
width(), im.
height(),
object);
975 *
d->currentPage <<
"Q\n";
987 bool hb =
d->hasBrush;
993 d->brush.setColor(
d->pen.color());
995 d->brushOrigin = -point;
996 *
d->currentPage <<
"q\n";
1000 *
d->currentPage <<
"Q\n";
1005 d->brushOrigin = bo;
1012 if (!
d->hasPen || (
d->clipEnabled &&
d->allClipped))
1020 *
d->currentPage <<
"q\n";
1021 if (
d->needsTransform)
1024 bool hp =
d->hasPen;
1027 d->brush =
d->pen.brush();
1032 d->drawTextItem(
p, ti);
1035 *
d->currentPage <<
"Q\n";
1042 const uint annot =
d->addXrefEntry(-1);
1045 QVarLengthArray<char> url_esc;
1046 url_esc.reserve(
len + 1);
1047 for (
int j = 0;
j <
len;
j++) {
1048 if (urlascii[
j] ==
'(' || urlascii[
j] ==
')' || urlascii[
j] ==
'\\')
1049 url_esc.append(
'\\');
1050 url_esc.append(urlascii[
j]);
1052 url_esc.append(
'\0');
1055 const QRectF rr =
d->pageMatrix().mapRect(
r);
1056 d->xprintf(
"<<\n/Type /Annot\n/Subtype /Link\n");
1059 d->xprintf(
"/F 4\n");
1061 d->xprintf(
"/Rect [");
1066 d->xprintf(
"]\n/Border [0 0 0]\n/A <<\n");
1067 d->xprintf(
"/Type /Action\n/S /URI\n/URI (%s)\n", url_esc.constData());
1068 d->xprintf(
">>\n>>\n");
1069 d->xprintf(
"endobj\n");
1070 d->currentPage->annotations.append(annot);
1090 if (penColor.alpha() != 255)
1103 bool oldCosmetic =
d->stroker.cosmeticPen;
1105 QBrush penBrush =
d->pen.brush();
1106 bool oldSimple =
d->simplePen;
1107 d->simplePen = (
d->hasPen && (penBrush.style() ==
Qt::SolidPattern) && penBrush.isOpaque() &&
d->opacity == 1.0);
1108 if (oldSimple !=
d->simplePen || oldCosmetic !=
d->stroker.cosmeticPen)
1131 if (
d->simplePen &&
d->opacity != 1.0) {
1132 d->simplePen =
false;
1137 bool ce =
d->clipEnabled;
1139 d->clipEnabled =
true;
1142 d->clipEnabled =
true;
1152 if (ce !=
d->clipEnabled)
1154 else if (!
d->clipEnabled)
1155 flags &= ~DirtyClipPath;
1167 *
d->currentPage <<
"Q\n";
1172 *
d->currentPage <<
"Q q\n";
1174 d->allClipped =
false;
1175 if (
d->clipEnabled && !
d->clips.isEmpty()) {
1176 for (
int i = 0;
i <
d->clips.size(); ++
i) {
1177 if (
d->clips.at(
i).isEmpty()) {
1178 d->allClipped =
true;
1182 if (!
d->allClipped) {
1183 for (
int i = 0;
i <
d->clips.size(); ++
i) {
1191 *
d->currentPage <<
"q\n";
1192 d->needsTransform =
false;
1193 if (!
d->stroker.matrix.isIdentity()) {
1194 if (
d->simplePen && !
d->stroker.cosmeticPen)
1197 d->needsTransform =
true;
1216 d->clipEnabled =
false;
1221 d->clips.append(
path);
1224 d->clips.append(
path);
1237 d->writeColor(QPdfEnginePrivate::ColorDomain::Stroking,
b.color());
1238 *
d->currentPage <<
"SCN\n";
1239 *
d->currentPage <<
d->pen.widthF() <<
"w ";
1241 int pdfCapStyle = 0;
1242 switch(
d->pen.capStyle()) {
1255 *
d->currentPage << pdfCapStyle <<
"J ";
1257 int pdfJoinStyle = 0;
1258 switch(
d->pen.joinStyle()) {
1261 *
d->currentPage <<
qMax(
qreal(1.0),
d->pen.miterLimit()) <<
"M ";
1273 *
d->currentPage << pdfJoinStyle <<
"j ";
1287 int gStateObject = 0;
1288 int patternObject =
d->addBrushPattern(
d->stroker.matrix, &specifyColor, &gStateObject);
1289 if (!patternObject && !specifyColor)
1292 const auto domain = patternObject ? QPdfEnginePrivate::ColorDomain::NonStrokingPattern
1293 : QPdfEnginePrivate::ColorDomain::NonStroking;
1294 d->writeColor(domain, specifyColor ?
d->brush.color() :
QColor());
1296 *
d->currentPage <<
"/Pat" << patternObject;
1297 *
d->currentPage <<
"scn\n";
1300 *
d->currentPage <<
"/GState" << gStateObject <<
"gs\n";
1302 *
d->currentPage <<
"/GSa gs\n";
1314 QFile *outfile = qobject_cast<QFile*> (
d->outDevice);
1334 return d->resolution;
1340 d->pdfVersion = version;
1346 d->xmpDocumentMetadata = xmpMetadata;
1352 return d->xmpDocumentMetadata;
1364 d->m_pageLayout.setPageSize(pageSize);
1370 d->m_pageLayout.setOrientation(orientation);
1376 d->m_pageLayout.setUnits(
units);
1377 d->m_pageLayout.setMargins(margins);
1383 return d->m_pageLayout;
1391 switch (metricType) {
1393 val =
d->m_pageLayout.paintRectPixels(
d->resolution).width();
1396 val =
d->m_pageLayout.paintRectPixels(
d->resolution).height();
1400 val =
d->resolution;
1425 qWarning(
"QPdfWriter::metric: Invalid metric command");
1455 if (!
d->outDevice) {
1456 if (!
d->outputFileName.isEmpty()) {
1462 d->outDevice =
file;
1466 d->ownsDevice =
true;
1469 d->currentObject = 1;
1472 d->stroker.
stream =
d->currentPage;
1475 d->stream->setDevice(
d->outDevice);
1479 d->hasBrush =
false;
1480 d->clipEnabled =
false;
1481 d->allClipped =
false;
1483 d->xrefPositions.clear();
1487 d->attachmentsRoot = 0;
1490 d->graphicsState = 0;
1491 d->patternColorSpaceRGB = 0;
1492 d->patternColorSpaceGrayscale = 0;
1493 d->patternColorSpaceCMYK = 0;
1494 d->simplePen =
false;
1495 d->needsTransform =
false;
1498 d->imageCache.clear();
1499 d->alphaCache.clear();
1513 d->stream->setDevice(
nullptr);
1517 delete d->currentPage;
1518 d->currentPage =
nullptr;
1520 if (
d->outDevice &&
d->ownsDevice) {
1521 d->outDevice->close();
1522 delete d->outDevice;
1523 d->outDevice =
nullptr;
1526 d->destCache.clear();
1527 d->fileCache.clear();
1548 addXrefEntry(0,
false);
1551 static const char mapping[][4] = {
1556 static const size_t numMappings =
sizeof mapping /
sizeof *
mapping;
1559 xprintf(
"%%PDF-%s\n", verStr);
1560 xprintf(
"%%\303\242\303\243\n");
1564 int metaDataObj = -1;
1565 int outputIntentObj = -1;
1567 metaDataObj = writeXmpDcumentMetaData();
1570 outputIntentObj = writeOutputIntent();
1573 catalog = addXrefEntry(-1);
1582 <<
"/Type /Catalog\n"
1583 <<
"/Pages " << pageRoot <<
"0 R\n"
1584 <<
"/Names " << namesRoot <<
"0 R\n";
1587 s <<
"/Metadata " << metaDataObj <<
"0 R\n";
1590 s <<
"/OutputIntents [" << outputIntentObj <<
"0 R]\n";
1599 graphicsState = addXrefEntry(-1);
1601 "/Type /ExtGState\n"
1612 patternColorSpaceRGB = addXrefEntry(-1);
1613 xprintf(
"[/Pattern /DeviceRGB]\n"
1615 patternColorSpaceGrayscale = addXrefEntry(-1);
1616 xprintf(
"[/Pattern /DeviceGray]\n"
1618 patternColorSpaceCMYK = addXrefEntry(-1);
1619 xprintf(
"[/Pattern /DeviceCMYK]\n"
1631 switch (
color.spec()) {
1648void QPdfEnginePrivate::writeColor(ColorDomain domain,
const QColor &
color)
1654 switch (actualColorModel) {
1657 case ColorDomain::Stroking:
1659 case ColorDomain::NonStroking:
1661 case ColorDomain::NonStrokingPattern:
1667 case ColorDomain::Stroking:
1669 case ColorDomain::NonStroking:
1671 case ColorDomain::NonStrokingPattern:
1677 case ColorDomain::Stroking:
1679 case ColorDomain::NonStroking:
1681 case ColorDomain::NonStrokingPattern:
1686 Q_UNREACHABLE_RETURN();
1690 if (!
color.isValid())
1693 switch (actualColorModel) {
1711 Q_UNREACHABLE_RETURN();
1715void QPdfEnginePrivate::writeInfo()
1717 info = addXrefEntry(-1);
1718 xprintf(
"<<\n/Title ");
1720 xprintf(
"\n/Creator ");
1722 xprintf(
"\n/Producer ");
1727 xprintf(
"\n/CreationDate (D:%d%02d%02d%02d%02d%02d",
1735 int hours = (
offset / 60) / 60;
1736 int mins = (
offset / 60) % 60;
1738 xprintf(
"-%02d'%02d')\n", -hours, -mins);
1740 xprintf(
"+%02d'%02d')\n", hours , mins);
1747int QPdfEnginePrivate::writeXmpDcumentMetaData()
1749 const int metaDataObj = addXrefEntry(-1);
1752 if (xmpDocumentMetadata.
isEmpty()) {
1764 const int hours = (
offset / 60) / 60;
1765 const int mins = (
offset / 60) % 60;
1774 const QString metaDataDate = timeStr + tzStr;
1776 QFile metaDataFile(
":/qpdf/qpdfa_metadata.xml"_L1);
1779 metaDataContent =
QString::fromUtf8(metaDataFile.readAll()).arg(producer.toHtmlEscaped(),
1782 metaDataDate).toUtf8();
1785 metaDataContent = xmpDocumentMetadata;
1788 "/Type /Metadata /Subtype /XML\n"
1791 "stream\n", metaDataContent.size());
1792 write(metaDataContent);
1793 xprintf(
"\nendstream\n"
1799int QPdfEnginePrivate::writeOutputIntent()
1801 const int colorProfile = addXrefEntry(-1);
1803 QFile colorProfileFile(
":/qpdf/sRGB2014.icc"_L1);
1806 const QByteArray colorProfileData = colorProfileFile.readAll();
1814 s <<
"/Alternate /DeviceRGB\n";
1815 s <<
"/Length " << length_object <<
"0 R\n";
1816 s <<
"/Filter /FlateDecode\n";
1820 const int len = writeCompressed(colorProfileData);
1821 write(
"\nendstream\n"
1823 addXrefEntry(length_object);
1828 const int outputIntent = addXrefEntry(-1);
1831 xprintf(
"/Type /OutputIntent\n");
1832 xprintf(
"/S/GTS_PDFA1\n");
1833 xprintf(
"/OutputConditionIdentifier (sRGB_IEC61966-2-1_black_scaled)\n");
1834 xprintf(
"/DestOutputProfile %d 0 R\n", colorProfile);
1835 xprintf(
"/Info(sRGB IEC61966 v2.1 with black scaling)\n");
1836 xprintf(
"/RegistryName(http://www.color.org)\n");
1838 xprintf(
"endobj\n");
1841 return outputIntent;
1844void QPdfEnginePrivate::writePageRoot()
1846 addXrefEntry(pageRoot);
1853 for (
int i = 0;
i <
size; ++
i)
1854 xprintf(
"%d 0 R\n", pages[
i]);
1858 xprintf(
"/Count %d\n", pages.
size());
1860 xprintf(
"/ProcSet [/PDF /Text /ImageB /ImageC]\n"
1865void QPdfEnginePrivate::writeDestsRoot()
1870 QHash<QString, int> destObjects;
1872 for (
const DestInfo &destInfo :
std::as_const(destCache)) {
1873 int destObj = addXrefEntry(-1);
1874 xs.setNum(
static_cast<double>(destInfo.coords.x()),
'f');
1875 ys.setNum(
static_cast<double>(destInfo.coords.y()),
'f');
1876 xprintf(
"[%d 0 R /XYZ %s %s 0]\n", destInfo.pageObj, xs.constData(), ys.constData());
1877 xprintf(
"endobj\n");
1878 destObjects.insert(destInfo.anchor, destObj);
1882 destsRoot = addXrefEntry(-1);
1885 xprintf(
"<<\n/Limits [");
1886 printString(
anchors.constFirst());
1888 printString(
anchors.constLast());
1889 xprintf(
"]\n/Names [\n");
1891 printString(anchor);
1892 xprintf(
" %d 0 R\n", destObjects[anchor]);
1898void QPdfEnginePrivate::writeAttachmentRoot()
1905 for (
int i = 0;
i <
size; ++
i) {
1907 const int attachmentID = addXrefEntry(-1);
1910 xprintf(
"/Filter /FlateDecode\n");
1913 xprintf(
"/Length %d 0 R\n", lenobj);
1915 xprintf(
">>\nstream\n");
1917 xprintf(
"\nendstream\n"
1919 addXrefEntry(lenobj);
1925 "/F (%s)",
attachment.fileName.toLatin1().constData());
1927 xprintf(
"\n/EF <</F %d 0 R>>\n"
1931 xprintf(
"/Subtype/%s\n",
1932 attachment.mimeType.replace(
"/"_L1,
"#2F"_L1).toLatin1().constData());
1933 xprintf(
">>\nendobj\n");
1937 attachmentsRoot = addXrefEntry(-1);
1938 xprintf(
"<</Names[");
1939 for (
int i = 0;
i <
size; ++
i) {
1948void QPdfEnginePrivate::writeNamesRoot()
1950 addXrefEntry(namesRoot);
1953 if (attachmentsRoot)
1954 xprintf(
"/EmbeddedFiles %d 0 R\n", attachmentsRoot);
1957 xprintf(
"/Dests %d 0 R\n", destsRoot);
1960 xprintf(
"endobj\n");
1966 int fontObject =
font->object_id;
1989 addXrefEntry(fontDescriptor);
1992 s <<
"<< /Type /FontDescriptor\n"
1994 int tag = fontDescriptor;
1995 for (
int i = 0;
i < 5; ++
i) {
1996 s << (char)(
'A' + (
tag % 26));
1999 s <<
'+' << postscriptName <<
"\n"
2000 "/Flags " << 4 <<
"\n"
2006 "/ItalicAngle " <<
properties.italicAngle.toReal() <<
"\n"
2011 "/FontFile2 " << fontstream <<
"0 R\n"
2012 "/CIDSet " << cidset <<
"0 R\n"
2017 addXrefEntry(fontstream);
2023 "/Length1 " <<
fontData.size() <<
"\n"
2024 "/Length " << length_object <<
"0 R\n";
2026 s <<
"/Filter /FlateDecode\n";
2031 write(
"\nendstream\n"
2033 addXrefEntry(length_object);
2038 addXrefEntry(cidfont);
2041 s <<
"<< /Type /Font\n"
2042 "/Subtype /CIDFontType2\n"
2043 "/BaseFont /" << postscriptName <<
"\n"
2044 "/CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>\n"
2045 "/FontDescriptor " << fontDescriptor <<
"0 R\n"
2046 "/CIDToGIDMap /Identity\n"
2047 <<
font->widthArray() <<
2053 addXrefEntry(toUnicode);
2055 xprintf(
"<< /Length %d >>\n"
2056 "stream\n", touc.size());
2058 write(
"\nendstream\n"
2062 addXrefEntry(fontObject);
2065 s <<
"<< /Type /Font\n"
2067 "/BaseFont /" << postscriptName <<
"\n"
2068 "/Encoding /Identity-H\n"
2069 "/DescendantFonts [" << cidfont <<
"0 R]\n"
2070 "/ToUnicode " << toUnicode <<
"0 R"
2077 int byteCounter = 0;
2080 cidSetStream.data()[byteCounter] |= (1 << (7 - bitCounter));
2083 if (bitCounter == 8) {
2089 addXrefEntry(cidset);
2091 xprintf(
"/Length %d\n", cidSetStream.size());
2093 xprintf(
"stream\n");
2094 write(cidSetStream);
2095 xprintf(
"\nendstream\n");
2096 xprintf(
"endobj\n");
2100qreal QPdfEnginePrivate::calcUserUnit()
const
2107 if (maxLen <= 14400)
2111 return qMin(maxLen / 14400.0, 75000.0);
2114void QPdfEnginePrivate::writeFonts()
2123void QPdfEnginePrivate::writePage()
2135 qreal userUnit = calcUserUnit();
2141 "/Contents %d 0 R\n"
2142 "/Resources %d 0 R\n"
2144 "/MediaBox [0 0 %s %s]\n",
2145 pageRoot, pageStream, resources, annots,
2156 addXrefEntry(resources);
2161 "/PCSpcmyk %d 0 R\n"
2163 "/CSpg /DeviceGray\n"
2164 "/CSpcmyk /DeviceCMYK\n"
2168 patternColorSpaceRGB,
2169 patternColorSpaceGrayscale,
2170 patternColorSpaceCMYK,
2177 xprintf(
"/Pattern <<\n");
2182 xprintf(
"/Font <<\n");
2187 xprintf(
"/XObject <<\n");
2196 addXrefEntry(annots);
2201 xprintf(
"]\nendobj\n");
2203 addXrefEntry(pageStream);
2205 "/Length %d 0 R\n", pageStreamLength);
2207 xprintf(
"/Filter /FlateDecode\n");
2210 xprintf(
"stream\n");
2212 int len = writeCompressed(content);
2213 xprintf(
"\nendstream\n"
2216 addXrefEntry(pageStreamLength);
2217 xprintf(
"%d\nendobj\n",
len);
2226 writeAttachmentRoot();
2229 addXrefEntry(xrefPositions.
size(),
false);
2232 "%010d 65535 f \n", xrefPositions.
size()-1, xrefPositions[0]);
2234 for (
int i = 1;
i < xrefPositions.
size()-1; ++
i)
2235 xprintf(
"%010d 00000 n \n", xrefPositions[
i]);
2243 <<
"/Size " << xrefPositions.
size() - 1 <<
"\n"
2244 <<
"/Info " << info <<
"0 R\n"
2245 <<
"/Root " << catalog <<
"0 R\n";
2250 s <<
"/ID [ <" << fileIdentifier <<
"> <" << fileIdentifier <<
"> ]\n";
2254 <<
"startxref\n" << xrefPositions.
constLast() <<
"\n"
2261int QPdfEnginePrivate::addXrefEntry(
int object,
bool printostr)
2266 if (
object>=xrefPositions.
size())
2267 xrefPositions.
resize(
object+1);
2269 xrefPositions[
object] = streampos;
2271 xprintf(
"%d 0 obj\n",
object);
2276void QPdfEnginePrivate::printString(
QStringView string)
2278 if (
string.isEmpty()) {
2287 const char16_t *utf16 =
string.utf16();
2290 char part[2] = {char((*(utf16 +
i)) >> 8), char((*(utf16 +
i)) & 0xff)};
2291 for(
int j=0;
j < 2; ++
j) {
2292 if (part[
j] ==
'(' || part[
j] ==
')' || part[
j] ==
'\\')
2302void QPdfEnginePrivate::xprintf(
const char*
fmt, ...)
2307 const int msize = 10000;
2319 QScopedArrayPointer<char> tmpbuf(
new char[
bufsize + 1]);
2328int QPdfEnginePrivate::writeCompressed(
QIODevice *dev)
2330#ifndef QT_NO_COMPRESS
2335 zStruct.zalloc = Z_NULL;
2336 zStruct.zfree = Z_NULL;
2337 zStruct.opaque = Z_NULL;
2338 if (::deflateInit(&zStruct, Z_DEFAULT_COMPRESSION) != Z_OK) {
2339 qWarning(
"QPdfStream::writeCompressed: Error in deflateInit()");
2342 zStruct.avail_in = 0;
2345 while (!dev->
atEnd() || zStruct.avail_in != 0) {
2346 if (zStruct.avail_in == 0) {
2348 zStruct.avail_in =
in.size();
2349 zStruct.next_in =
reinterpret_cast<unsigned char*
>(
in.data());
2350 if (
in.size() <= 0) {
2351 qWarning(
"QPdfStream::writeCompressed: Error in read()");
2352 ::deflateEnd(&zStruct);
2356 zStruct.next_out =
reinterpret_cast<unsigned char*
>(
out.data());
2357 zStruct.avail_out =
out.size();
2359 qWarning(
"QPdfStream::writeCompressed: Error in deflate()");
2360 ::deflateEnd(&zStruct);
2363 int written =
out.size() - zStruct.avail_out;
2364 stream->writeRawData(
out.constData(), written);
2365 streampos += written;
2370 zStruct.next_out =
reinterpret_cast<unsigned char*
>(
out.data());
2371 zStruct.avail_out =
out.size();
2373 if (
ret != Z_OK &&
ret != Z_STREAM_END) {
2374 qWarning(
"QPdfStream::writeCompressed: Error in deflate()");
2375 ::deflateEnd(&zStruct);
2378 int written =
out.size() - zStruct.avail_out;
2379 stream->writeRawData(
out.constData(), written);
2380 streampos += written;
2382 }
while (
ret == Z_OK);
2384 ::deflateEnd(&zStruct);
2392 while (!dev->
atEnd()) {
2394 stream->writeRawData(arr.constData(), arr.size());
2395 streampos += arr.size();
2402int QPdfEnginePrivate::writeCompressed(
const char *
src,
int len)
2404#ifndef QT_NO_COMPRESS
2408 if (!
data.isNull()) {
2412 qWarning(
"QPdfStream::writeCompressed: Error in compress()");
2425 int maskObject,
int softMaskObject,
bool dct,
bool isMono)
2427 int image = addXrefEntry(-1);
2435 case WriteImageOption::Monochrome:
2437 xprintf(
"/ImageMask true\n"
2440 xprintf(
"/BitsPerComponent 1\n"
2441 "/ColorSpace /DeviceGray\n");
2444 case WriteImageOption::Grayscale:
2445 xprintf(
"/BitsPerComponent 8\n"
2446 "/ColorSpace /DeviceGray\n");
2448 case WriteImageOption::RGB:
2449 xprintf(
"/BitsPerComponent 8\n"
2450 "/ColorSpace /DeviceRGB\n");
2452 case WriteImageOption::CMYK:
2453 xprintf(
"/BitsPerComponent 8\n"
2454 "/ColorSpace /DeviceCMYK\n");
2459 xprintf(
"/Mask %d 0 R\n", maskObject);
2460 if (softMaskObject > 0)
2461 xprintf(
"/SMask %d 0 R\n", softMaskObject);
2464 xprintf(
"/Length %d 0 R\n", lenobj);
2466 xprintf(
"/Interpolate true\n");
2470 xprintf(
"/Filter /DCTDecode\n>>\nstream\n");
2475 xprintf(
"/Filter /FlateDecode\n>>\nstream\n");
2477 xprintf(
">>\nstream\n");
2480 xprintf(
"\nendstream\n"
2482 addXrefEntry(lenobj);
2498 *
stream <<
"/ColorSpace ";
2499 switch (colorModel) {
2501 *
stream <<
"/DeviceRGB\n";
break;
2503 *
stream <<
"/DeviceGray\n";
break;
2505 *
stream <<
"/DeviceCMYK\n";
break;
2507 Q_UNREACHABLE();
break;
2511QPdfEnginePrivate::ShadingFunctionResult
2512QPdfEnginePrivate::createShadingFunction(
const QGradient *gradient,
int from,
int to,
bool reflect,
bool alpha)
2519 if (stops.
at(0).first > 0)
2521 if (stops.
at(stops.
size() - 1).first < 1)
2535 const QColor::Spec referenceSpec = referenceColor.spec();
2536 bool warned =
false;
2538 if (stop.second.spec() != referenceSpec) {
2540 qWarning(
"QPdfEngine: unable to create a gradient between colors of different spec");
2543 stop.second = stop.second.convertTo(referenceSpec);
2550 ShadingFunctionResult
result;
2551 result.colorModel = colorModelForColor(referenceColor);
2553 QList<int> functions;
2554 const int numStops = stops.
size();
2555 functions.reserve(numStops - 1);
2556 for (
int i = 0;
i < numStops - 1; ++
i) {
2557 int f = addXrefEntry(-1);
2565 s <<
"/C0 [" << stops.
at(
i).second.alphaF() <<
"]\n"
2566 "/C1 [" << stops.
at(
i + 1).second.alphaF() <<
"]\n";
2568 switch (
result.colorModel) {
2570 s <<
"/C0 [" << stops.
at(
i).second.redF() << stops.
at(
i).second.greenF() << stops.
at(
i).second.blueF() <<
"]\n"
2571 "/C1 [" << stops.
at(
i + 1).second.redF() << stops.
at(
i + 1).second.greenF() << stops.
at(
i + 1).second.blueF() <<
"]\n";
2574 s <<
"/C0 [" << (
qGray(stops.
at(
i).second.rgba()) / 255.) <<
"]\n"
2575 "/C1 [" << (
qGray(stops.
at(
i + 1).second.rgba()) / 255.) <<
"]\n";
2578 s <<
"/C0 [" << stops.
at(
i).second.cyanF()
2579 << stops.
at(
i).second.magentaF()
2580 << stops.
at(
i).second.yellowF()
2581 << stops.
at(
i).second.blackF() <<
"]\n"
2582 "/C1 [" << stops.
at(
i + 1).second.cyanF()
2583 << stops.
at(
i + 1).second.magentaF()
2584 << stops.
at(
i + 1).second.yellowF()
2585 << stops.
at(
i + 1).second.blackF() <<
"]\n";
2600 QList<QGradientBound> gradientBounds;
2601 gradientBounds.reserve((to - from) * (numStops - 1));
2603 for (
int step = from; step < to; ++step) {
2604 if (reflect && step % 2) {
2605 for (
int i = numStops - 1;
i > 0; --
i) {
2609 b.function = functions.at(
i - 1);
2611 gradientBounds <<
b;
2614 for (
int i = 0;
i < numStops - 1; ++
i) {
2618 b.function = functions.at(
i);
2620 gradientBounds <<
b;
2626 qreal bstart = gradientBounds.at(0).start;
2627 qreal bend = gradientBounds.at(gradientBounds.size() - 1).stop;
2628 qreal norm = 1./(bend - bstart);
2629 for (
int i = 0;
i < gradientBounds.size(); ++
i) {
2630 gradientBounds[
i].start = (gradientBounds[
i].start - bstart)*norm;
2631 gradientBounds[
i].stop = (gradientBounds[
i].stop - bstart)*norm;
2635 if (gradientBounds.size() > 1) {
2636 function = addXrefEntry(-1);
2643 for (
int i = 1;
i < gradientBounds.size(); ++
i)
2644 s << gradientBounds.at(
i).start;
2647 for (
int i = 0;
i < gradientBounds.size(); ++
i)
2648 s << (gradientBounds.at(
i).reverse ?
"1 0 " :
"0 1 ");
2651 for (
int i = 0;
i < gradientBounds.size(); ++
i)
2652 s << gradientBounds.at(
i).function <<
"0 R ";
2658 function = functions.at(0);
2673 bool reflect =
false;
2674 switch (gradient->
spread()) {
2695 for (
int i = 0;
i < 4; ++
i) {
2707 const auto shadingFunctionResult = createShadingFunction(gradient, from, to, reflect,
alpha);
2715 s <<
"/ColorSpace /DeviceGray\n";
2717 shadingFunctionResult.writeColorSpace(&
s);
2719 s <<
"/AntiAlias true\n"
2720 "/Coords [" <<
start.x() <<
start.y() << stop.
x() << stop.
y() <<
"]\n"
2721 "/Extend [true true]\n"
2722 "/Function " << shadingFunctionResult.function <<
"0 R\n"
2725 int shaderObject = addXrefEntry(-1);
2727 return shaderObject;
2741 bool reflect =
false;
2742 switch (gradient->
spread()) {
2762 double radius = r0 + to*(
r1 - r0);
2763 double r2 = radius*radius;
2765 for (
int i = 0;
i < 4; ++
i) {
2767 if (off.
x()*off.
x() + off.
y()*off.
y() >
r2) {
2774 p1 =
QPointF(p0.x() + to*(
p1.x() - p0.x()), p0.y() + to*(
p1.y() - p0.y()));
2775 r1 = r0 + to*(
r1 - r0);
2780 const auto shadingFunctionResult = createShadingFunction(gradient, from, to, reflect,
alpha);
2788 s <<
"/ColorSpace /DeviceGray\n";
2790 shadingFunctionResult.writeColorSpace(&
s);
2792 s <<
"/AntiAlias true\n"
2794 "/Coords [" << p0.x() << p0.y() << r0 <<
p1.x() <<
p1.y() <<
r1 <<
"]\n"
2795 "/Extend [true true]\n"
2796 "/Function " << shadingFunctionResult.function <<
"0 R\n"
2799 int shaderObject = addXrefEntry(-1);
2801 return shaderObject;
2806 switch (gradient->
type()) {
2830 int shaderObject = generateGradientShader(gradient,
m);
2837 "/Shading " << shaderObject <<
"0 R\n"
2848 int patternObj = addXrefEntry(-1);
2852 if (!
b.isOpaque()) {
2855 int a = stops.
at(0).second.alpha();
2856 for (
int i = 1;
i < stops.
size(); ++
i) {
2857 if (stops.
at(
i).second.alpha() !=
a) {
2865 int alphaShaderObject = generateGradientShader(gradient,
m,
true);
2869 c <<
"/Shader" << alphaShaderObject <<
"sh\n";
2876 "/BBox [0 0 " << pageRect.
width() << pageRect.
height() <<
"]\n"
2877 "/Group <</S /Transparency >>\n"
2879 "/Shading << /Shader" << alphaShaderObject << alphaShaderObject <<
"0 R >>\n"
2882 f <<
"/Length " << content.
size() <<
"\n"
2889 int softMaskFormObject = addXrefEntry(-1);
2891 *gStateObject = addXrefEntry(-1);
2892 xprintf(
"<< /SMask << /S /Alpha /G %d 0 R >> >>\n"
2893 "endobj\n", softMaskFormObject);
2903 if (brushAlpha == 255 && penAlpha == 255)
2905 uint object = alphaCache.
value(QPair<uint, uint>(brushAlpha, penAlpha), 0);
2907 object = addXrefEntry(-1);
2910 s <<
"<<\n/ca " << (brushAlpha/
qreal(255.)) <<
'\n';
2911 s <<
"/CA " << (penAlpha/
qreal(255.)) <<
"\n>>";
2912 xprintf(
"%s\nendobj\n", alphaDef.constData());
2913 alphaCache.
insert(QPair<uint, uint>(brushAlpha, penAlpha),
object);
2930 *specifyColor =
true;
2943 *specifyColor =
false;
2944 return gradientBrush(
brush,
matrix, gStateObject);
2954 int imageObject = -1;
2963 if (imageObject != -1) {
2967 *specifyColor =
false;
2974 s <<
"/Im" << imageObject <<
" Do\n";
2983 "/PaintType " << paintType <<
"\n"
2985 "/BBox [0 0 " <<
w <<
h <<
"]\n"
2986 "/XStep " <<
w <<
"\n"
2987 "/YStep " <<
h <<
"\n"
2996 if (imageObject > 0) {
2997 s <<
"/XObject << /Im" << imageObject <<
' ' << imageObject <<
"0 R >> ";
3000 "/Length " <<
pattern.size() <<
"\n"
3007 int patternObj = addXrefEntry(-1);
3015 return colorTable.size() == 2
3029 int object = imageCache.
value(serial_no);
3038 if (
image.hasAlphaChannel()) {
3046 p.drawImage(0, 0,
image);
3048 image = alphaLessImage;
3069 int bytesPerLine = (
w + 7) >> 3;
3072 char *rawdata =
data.data();
3073 for (
int y = 0;
y <
h; ++
y) {
3074 memcpy(rawdata,
image.constScanLine(
y), bytesPerLine);
3075 rawdata += bytesPerLine;
3077 object = writeImage(
data,
w,
h, WriteImageOption::Monochrome, 0, 0,
false,
is_monochrome(
img.colorTable()));
3083 bool hasMask =
false;
3088 writer.setQuality(94);
3091 writer.setSubType(
"CMYK");
3093 writer.write(
image);
3097 softMaskData.resize(
w *
h);
3099 for (
int y = 0;
y <
h; ++
y) {
3101 for (
int x = 0;
x <
w; ++
x) {
3104 hasMask |= (
alpha < 255);
3116 for (
int y = 0;
y <
h; ++
y) {
3118 for (
int x = 0;
x <
w; ++
x)
3122 for (
int y = 0;
y <
h; ++
y) {
3124 memcpy(
start,
image.constScanLine(
y), bytesPerLine);
3130 softMaskData.resize(
w *
h);
3132 for (
int y = 0;
y <
h; ++
y) {
3135 for (
int x = 0;
x <
w; ++
x) {
3139 hasMask |= (
alpha < 255);
3144 for (
int x = 0;
x <
w; ++
x) {
3150 hasMask |= (
alpha < 255);
3161 int softMaskObject = 0;
3163 softMaskObject = writeImage(softMaskData,
w,
h, WriteImageOption::Grayscale, 0, 0);
3164 }
else if (hasMask) {
3167 int bytesPerLine = (
w + 7) >> 3;
3170 const uchar *sdata = (
const uchar *)softMaskData.constData();
3171 for (
int y = 0;
y <
h; ++
y) {
3172 for (
int x = 0;
x <
w; ++
x) {
3174 mdata[
x>>3] |= (0x80 >> (
x&7));
3177 mdata += bytesPerLine;
3179 maskObject = writeImage(
mask,
w,
h, WriteImageOption::Monochrome, 0, 0);
3182 const WriteImageOption
option = [&]() {
3184 return WriteImageOption::Grayscale;
3186 return WriteImageOption::CMYK;
3187 return WriteImageOption::RGB;
3191 maskObject, softMaskObject, dct);
3193 imageCache.
insert(serial_no,
object);
3203 if (isLink || isAnchor) {
3204 qreal size = ti.fontEngine->fontDef.pixelSize;
3205 int synthesized = ti.fontEngine->synthesized();
3221 trans.
map(ti.width.toReal()/
size, (ti.ascent.toReal()-ti.descent.toReal())/
size, &
x2, &
y2);
3224 uint annot = addXrefEntry(-1);
3226 x1s.
setNum(
static_cast<double>(
x1),
'f');
3227 y1s.
setNum(
static_cast<double>(
y1),
'f');
3228 x2s.
setNum(
static_cast<double>(
x2),
'f');
3229 y2s.
setNum(
static_cast<double>(
y2),
'f');
3230 QByteArray rectData = x1s +
' ' + y1s +
' ' + x2s +
' ' + y2s;
3231 xprintf(
"<<\n/Type /Annot\n/Subtype /Link\n");
3237 xprintf(rectData.constData());
3238#ifdef Q_DEBUG_PDF_LINKS
3239 xprintf(
"]\n/Border [16 16 1]\n");
3241 xprintf(
"]\n/Border [0 0 0]\n");
3243 const QString link = ti.charFormat.anchorHref();
3251 printString(link.
sliced(1));
3255 xprintf(
"endobj\n");
3261 const QString anchor = ti.charFormat.anchorNames().constFirst();
3270 bool noEmbed =
false;
3273 || fe->fsType & 0x200
3274 || fe->fsType == 2 ) {
3276 q->QPaintEngine::drawTextItem(
p, ti);
3286 font->noEmbed = noEmbed;
3293 qreal size = ti.fontEngine->fontDef.pixelSize;
3295 QVarLengthArray<glyph_t> glyphs;
3298 ti.fontEngine->getGlyphPositions(ti.glyphs,
m, ti.flags,
3300 if (glyphs.size() == 0)
3302 int synthesized = ti.fontEngine->synthesized();
3307 <<
"/F" <<
font->object_id <<
size <<
"Tf "
3309 ?
"0 .3 -1 0 0 Tm\n"
3310 :
"0 0 -1 0 0 Tm\n");
3315 const unsigned short *logClusters = ti.logClusters;
3319 while (
end < ti.num_chars && logClusters[
end] == logClusters[
pos])
3328 int ge =
end == ti.num_chars ? ti.num_glyphs : logClusters[
end];
3329 for (
int gs = logClusters[
pos]; gs < ge; ++gs)
3334 }
while (
pos < ti.num_chars);
3338 for (
int i = 0;
i < glyphs.size(); ++
i) {
3353 ?
"0 .3 -1 0 0 Tm\n"
3354 :
"0 0 -1 0 0 Tm\n");
3355 *
currentPage <<
"/Span << /ActualText <> >> BDC\n";
3356 last_x = 0.5*fe->lineThickness().toReal();
3358 for (
int i = 0;
i < glyphs.size(); ++
i) {
3380 qreal userUnit = calcUserUnit();
void setStyle(Qt::BrushStyle)
Sets the brush style to style.
\inmodule QtCore \reentrant
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
QByteArray & setNum(short, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
void clear()
Clears the contents of the byte array and makes it null.
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
static constexpr QCmyk32 fromCmyk32(uint cmyk) noexcept
The QColor class provides colors based on RGB, HSV or CMYK values.
Spec
The type of color specified, either RGB, extended RGB, HSV, CMYK or HSL.
QRgb rgba() const noexcept
Returns the RGB value of the color, including its alpha.
int alpha() const noexcept
Returns the alpha color component of this color.
void setAlpha(int alpha)
Sets the alpha of this color to alpha.
static QByteArray hash(QByteArrayView data, Algorithm method)
Returns the hash of data using method.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
static QDateTime currentDateTime()
This is an overloaded member function, provided for convenience. It differs from the above function o...
\inmodule QtCore \reentrant
int month() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int day() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int year() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Spread spread() const
Returns the spread method use by this gradient.
CoordinateMode coordinateMode() const
Type type() const
Returns the type of gradient.
QGradientStops stops() const
Returns the stop points for this gradient.
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
T value(const Key &key) const noexcept
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
\inmodule QtCore \reentrant
virtual bool open(QIODeviceBase::OpenMode mode)
Opens the device and sets its OpenMode to mode.
virtual qint64 size() const
For open random-access devices, this function returns the size of the device.
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success,...
virtual bool reset()
Seeks to the start of input for random-access devices.
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i....
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
The QImageWriter class provides a format independent interface for writing images to files or other d...
static QList< QByteArray > supportedImageFormats()
Returns the list of image formats supported by QImageWriter.
int width() const
Returns the width of the image.
int height() const
Returns the height of the image.
Format
The following image formats are available in Qt.
qint64 cacheKey() const
Returns a number that identifies the contents of this QImage object.
\inmodule QtCore\compares equality \compareswith equality QLine \endcompareswith
QPointF start() const
Returns the start point of this linear gradient in logical coordinates.
QPointF finalStop() const
Returns the final stop point of this linear gradient in logical coordinates.
qsizetype size() const noexcept
bool isEmpty() const noexcept
const T & constLast() const noexcept
bool empty() const noexcept
const_reference at(qsizetype i) const noexcept
void prepend(rvalue_ref t)
const T & constFirst() const noexcept
void resize(qsizetype size)
void append(parameter_type t)
QRect fullRectPoints() const
Returns the full page rectangle in Postscript Points (1/72 of an inch).
Mode mode() const
Returns the page layout mode.
Unit
This enum type is used to specify the measurement unit for page layout and margins.
QRect paintRectPixels(int resolution) const
Returns the paintable rectangle in rounded device pixels for the given resolution.
Orientation
This enum type defines the page orientation.
QRect fullRectPixels(int resolution) const
Returns the full page rectangle in device pixels for the given resolution.
@ PdmDevicePixelRatioScaled
static qreal devicePixelRatioFScale()
The QPaintEngineState class provides information about the active paint engine's current state....
QTransform transform() const
QPainterPath clipPath() const
Returns the clip path in the current paint engine state.
Qt::ClipOperation clipOperation() const
Returns the clip operation in the current paint engine state.
QPointF brushOrigin() const
Returns the brush origin in the current paint engine state.
bool isClipEnabled() const
Returns whether clipping is enabled or not in the current paint engine state.
QBrush brush() const
Returns the brush in the current paint engine state.
QRegion clipRegion() const
Returns the clip region in the current paint engine state.
QPainter::RenderHints renderHints() const
Returns the render hints in the current paint engine state.
QPen pen() const
Returns the pen in the current paint engine state.
QPaintEngine::DirtyFlags state() const
Returns a combination of flags identifying the set of properties that need to be updated when updatin...
void setActive(bool newState)
Sets the active state of the paint engine to state.
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem)
This function draws the text item textItem at position p.
PolygonDrawMode
\value OddEvenMode The polygon should be drawn using OddEven fill rule.
QPainter * painter() const
Returns the paint engine's painter.
@ ObjectBoundingModeGradients
QPaintEngineState * state
bool isActive() const
Returns true if the paint engine is actively drawing; otherwise returns false.
Type
\value X11 \value Windows \value MacPrinter \value CoreGraphics \macos's Quartz2D (CoreGraphics) \val...
void addRect(const QRectF &rect)
Adds the given rectangle to this path as a closed subpath.
void moveTo(const QPointF &p)
Moves the current point to the given point, implicitly starting a new subpath and closing the previou...
void setFillRule(Qt::FillRule fillRule)
Sets the fill rule of the painter path to the given fillRule.
void clear()
Clears the path elements stored.
The QPainter class performs low-level painting on widgets and other paint devices.
@ NonCosmeticBrushPatterns
bool testRenderHint(RenderHint hint) const
QTransform pageMatrix() const
int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject)
int addConstantAlphaObject(int brushAlpha, int penAlpha=255)
int addImage(const QImage &image, bool *bitmap, bool lossless, qint64 serial_no)
Adds an image to the pdf and return the pdf-object id.
QHash< QFontEngine::FaceId, QFontSubset * > fonts
QPdfEngine::PdfVersion pdfVersion
void drawTextItem(const QPointF &p, const QTextItemInt &ti)
QPdfEngine::ColorModel colorModel
void addFileAttachment(const QString &fileName, const QByteArray &data, const QString &mimeType)
QPageLayout pageLayout() const
void drawLines(const QLineF *lines, int lineCount) override
The default implementation splits the list of lines in lines into lineCount separate calls to drawPat...
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override
Reimplement this virtual function to draw the polygon defined by the pointCount first points in point...
int metric(QPaintDevice::PaintDeviceMetric metricType) const
void setupGraphicsState(QPaintEngine::DirtyFlags flags)
void drawPixmap(const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr) override
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r.
QByteArray documentXmpMetadata() const
void updateState(const QPaintEngineState &state) override
Reimplement this function to update the state of a paint engine.
void drawPoints(const QPointF *points, int pointCount) override
Draws the first pointCount points in the buffer points.
void drawRects(const QRectF *rects, int rectCount) override
Draws the first rectCount rectangles in the buffer rects.
Type type() const override
Reimplement this function to return the paint engine \l{Type}.
void setOutputFilename(const QString &filename)
void setPageOrientation(QPageLayout::Orientation orientation)
bool begin(QPaintDevice *pdev) override
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
void drawTextItem(const QPointF &p, const QTextItem &textItem) override
This function draws the text item textItem at position p.
bool end() override
Reimplement this function to finish painting on the current paint device.
void setPageMargins(const QMarginsF &margins, QPageLayout::Unit units=QPageLayout::Point)
void drawTiledPixmap(const QRectF &rectangle, const QPixmap &pixmap, const QPointF &point) override
Reimplement this function to draw the pixmap in the given rect, starting at the given p.
void setDocumentXmpMetadata(const QByteArray &xmpMetadata)
void drawPath(const QPainterPath &path) override
The default implementation ignores the path and does nothing.
void setPdfVersion(PdfVersion version)
void setPageLayout(const QPageLayout &pageLayout)
void drawHyperlink(const QRectF &r, const QUrl &url)
void setPageSize(const QPageSize &pageSize)
void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags=Qt::AutoColor) override
Reimplement this function to draw the part of the image specified by the sr rectangle in the given re...
void setResolution(int resolution)
void streamImage(int w, int h, uint object)
QList< uint > graphicStates
QList< uint > annotations
ByteStream & operator<<(char chr)
ByteStream(bool fileBacking=false)
static int maxMemorySize()
qreal widthF() const
Returns the pen width with floating point precision.
QList< qreal > dashPattern() const
Returns the dash pattern of this pen.
bool isCosmetic() const
Returns true if the pen is cosmetic; otherwise returns false.
QColor color() const
Returns the color of this pen's brush.
Qt::PenCapStyle capStyle() const
Returns the pen's cap style.
void setColor(const QColor &color)
Sets the color of this pen's brush to the given color.
void setBrush(const QBrush &brush)
Sets the brush used to fill strokes generated with this pen to the given brush.
Qt::PenJoinStyle joinStyle() const
Returns the pen's join style.
qreal miterLimit() const
Returns the miter limit of the pen.
QBrush brush() const
Returns the brush used to fill strokes generated with this pen.
qreal dashOffset() const
Returns the dash offset for the pen.
Qt::PenStyle style() const
Returns the pen style.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
QImage toImage() const
Converts the pixmap to a QImage.
qint64 cacheKey() const
Returns a number that identifies this QPixmap.
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
QPointF center() const
Returns the center of this radial gradient in logical coordinates.
qreal focalRadius() const
QPointF focalPoint() const
Returns the focal point of this radial gradient in logical coordinates.
qreal centerRadius() const
\inmodule QtCore\reentrant
constexpr bool isEmpty() const noexcept
Returns true if the rectangle is empty, otherwise returns false.
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr qreal y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal width() const noexcept
Returns the width of the rectangle.
constexpr qreal x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr QPointF bottomLeft() const noexcept
Returns the position of the rectangle's bottom-left corner.
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
constexpr QPointF bottomRight() const noexcept
Returns the position of the rectangle's bottom-right corner.
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr QPointF topRight() const noexcept
Returns the position of the rectangle's top-right corner.
constexpr qreal right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
\inmodule QtCore\reentrant
constexpr int height() const noexcept
Returns the height of the rectangle.
constexpr QSize size() const noexcept
Returns the size of the rectangle.
The QRegion class specifies a clip region for a painter.
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QByteArray toLatin1() const &
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
QString sliced(qsizetype pos) const &
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString static QString asprintf(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
QString toHtmlEscaped() const
void setCubicToHook(qStrokerCubicToHook cubicToHook)
void setMoveToHook(qStrokerMoveToHook moveToHook)
void setLineToHook(qStrokerLineToHook lineToHook)
void setStrokeWidth(qfixed width)
\inmodule QtCore \reentrant
int hour() const
Returns the hour part (0 to 23) of the time.
int minute() const
Returns the minute part (0 to 59) of the time.
int second() const
Returns the second part (0 to 59) of the time.
QByteArray toEncoded(FormattingOptions options=FullyEncoded) const
Returns the encoded representation of the URL if it's valid; otherwise an empty QByteArray is returne...
static QUuid createUuid()
On any platform other than Windows, this function returns a new UUID with variant QUuid::DCE and vers...
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
const char * toHex(ushort u, char *buffer)
QByteArray generatePath(const QPainterPath &path, const QTransform &matrix, PathFlags flags)
QByteArray ascii85Encode(const QByteArray &input)
QByteArray generateDashes(const QPen &pen)
QByteArray patternForBrush(const QBrush &b)
QByteArray generateMatrix(const QTransform &matrix)
Combined button and popup list for selecting options.
QTextStream & center(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignCenter) on stream and returns stream.
QPair< qreal, QColor > QGradientStop
QByteArray qCompress(const uchar *data, qsizetype nbytes, int compressionLevel)
Q_CORE_EXPORT int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
AudioChannelLayoutTag tag
static const QCssKnownValue positions[NumKnownPositionModes - 1]
static const QCssKnownValue properties[NumProperties - 1]
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
static QString header(const QString &name)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
bool qIsFinite(qfloat16 f) noexcept
bool qFuzzyIsNull(qfloat16 f) noexcept
int qRound(qfloat16 d) noexcept
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLfloat GLfloat GLfloat x1
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei const GLenum * attachments
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLenum GLsizeiptr const void * fontData
GLfloat GLfloat GLfloat GLfloat h
GLfixed GLfixed GLint GLint GLfixed points
GLfixed GLfixed GLfixed y2
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
GLdouble GLdouble GLdouble GLdouble q
GLsizei const GLchar *const * path
GLenum GLenum GLenum GLenum mapping
GLfloat GLfloat GLfloat alpha
GLenum GLenum GLenum GLenum GLenum scale
GLenum GLenum GLenum input
bool qt_isExtendedRadialGradient(const QBrush &brush)
const char * qt_int_to_string(int val, char *buf)
static void initResources()
static bool is_monochrome(const QList< QRgb > &colorTable)
static void removeTransparencyFromBrush(QBrush &brush)
static const char *const pattern_for_brush[]
static void lineToHook(qfixed x, qfixed y, void *data)
static const bool interpolateImages
static const bool do_compress
const char * qt_real_to_string(qreal val, char *buf)
QPainterPath qt_regionToPath(const QRegion ®ion)
constexpr QPaintEngine::PaintEngineFeatures qt_pdf_decide_features()
static void moveToHook(qfixed x, qfixed y, void *data)
static void cubicToHook(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey, void *data)
QT_BEGIN_NAMESPACE const char * qt_real_to_string(qreal val, char *buf)
static bool hasAlpha(const QImage &image)
static void grayscale(const QImage &image, QImage &dest, const QRect &rect=QRect())
static constexpr qint64 HeaderSize
QQuickAnchors * anchors(QQuickItem *item)
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
constexpr int qRed(QRgb rgb)
constexpr int qGreen(QRgb rgb)
constexpr int qGray(int r, int g, int b)
constexpr int qBlue(QRgb rgb)
constexpr int qAlpha(QRgb rgb)
QT_BEGIN_NAMESPACE typedef qreal qfixed
#define Q_UNIMPLEMENTED()
#define Q_INIT_RESOURCE(name)
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
QVideoFrameFormat::PixelFormat fmt
QT_BEGIN_NAMESPACE typedef uchar * output
static int deflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)
QTextStream out(stdout)
[7]
QUrl url("example.com")
[constructor-url-reference]
\inmodule QtCore \reentrant
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
bool contains(const AT &t) const noexcept
void setPen(const QPen &pen, QPainter::RenderHints hints)
void strokePath(const QPainterPath &path)