/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qpdf_p.h"

#ifndef QT_NO_PDF

#include "qplatformdefs.h"

#include <private/qfont_p.h>
#include <private/qmath_p.h>
#include <private/qpainter_p.h>

#include <qbuffer.h>
#include <qcryptographichash.h>
#include <qdatetime.h>
#include <qdebug.h>
#include <qfile.h>
#include <qimagewriter.h>
#include <qnumeric.h>
#include <qtemporaryfile.h>
#include <quuid.h>

#ifndef QT_NO_COMPRESS
#include <zlib.h>
#endif

#ifdef QT_NO_COMPRESS
static const bool do_compress = false;
#else
static const bool do_compress = true;
#endif

// might be helpful for smooth transforms of images
// 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()
{
    QPaintEngine::PaintEngineFeatures f = QPaintEngine::AllFeatures;
    f &= ~(QPaintEngine::PorterDuff
           | QPaintEngine::PerspectiveTransform
           | QPaintEngine::ObjectBoundingModeGradients
           | QPaintEngine::ConicalGradientFill);
    return f;
}

extern bool qt_isExtendedRadialGradient(const QBrush &brush);

// helper function to remove transparency from brush in PDF/A-1b mode
static void removeTransparencyFromBrush(QBrush &brush)
{
    if (brush.style() == Qt::SolidPattern) {
        QColor color = brush.color();
        if (color.alpha() != 255) {
            color.setAlpha(255);
            brush.setColor(color);
        }

        return;
    }

    if (qt_isExtendedRadialGradient(brush)) {
        brush = QBrush(Qt::black); // the safest we can do so far...
        return;
    }

    if (brush.style() == Qt::LinearGradientPattern
        || brush.style() == Qt::RadialGradientPattern
        || brush.style() == Qt::ConicalGradientPattern) {

        QGradientStops stops = brush.gradient()->stops();
        for (int i = 0; i < stops.size(); ++i) {
            if (stops[i].second.alpha() != 255)
                stops[i].second.setAlpha(255);
        }

        const_cast<QGradient*>(brush.gradient())->setStops(stops);
        return;
    }

    if (brush.style() == Qt::TexturePattern) {
        // handled inside QPdfEnginePrivate::addImage() already
        return;
    }
}


/* also adds a space at the end of the number */
const char *qt_real_to_string(qreal val, char *buf) {
    const char *ret = buf;

    if (qIsNaN(val)) {
        *(buf++) = '0';
        *(buf++) = ' ';
        *buf = 0;
        return ret;
    }

    if (val < 0) {
        *(buf++) = '-';
        val = -val;
    }
    unsigned int ival = (unsigned int) val;
    qreal frac = val - (qreal)ival;

    int ifrac = (int)(frac * 1000000000);
    if (ifrac == 1000000000) {
        ++ival;
        ifrac = 0;
    }
    char output[256];
    int i = 0;
    while (ival) {
        output[i] = '0' + (ival % 10);
        ++i;
        ival /= 10;
    }
    int fact = 100000000;
    if (i == 0) {
        *(buf++) = '0';
    } else {
        while (i) {
            *(buf++) = output[--i];
            fact /= 10;
            ifrac /= 10;
        }
    }

    if (ifrac) {
        *(buf++) =  '.';
        while (fact) {
            *(buf++) = '0' + ((ifrac/fact) % 10);
            fact /= 10;
        }
    }
    *(buf++) = ' ';
    *buf = 0;
    return ret;
}

const char *qt_int_to_string(int val, char *buf) {
    const char *ret = buf;
    if (val < 0) {
        *(buf++) = '-';
        val = -val;
    }
    char output[256];
    int i = 0;
    while (val) {
        output[i] = '0' + (val % 10);
        ++i;
        val /= 10;
    }
    if (i == 0) {
        *(buf++) = '0';
    } else {
        while (i)
            *(buf++) = output[--i];
    }
    *(buf++) = ' ';
    *buf = 0;
    return ret;
}


namespace QPdf {
    ByteStream::ByteStream(QByteArray *byteArray, bool fileBacking)
            : dev(new QBuffer(byteArray)),
            fileBackingEnabled(fileBacking),
            fileBackingActive(false),
            handleDirty(false)
    {
        dev->open(QIODevice::ReadWrite | QIODevice::Append);
    }

    ByteStream::ByteStream(bool fileBacking)
            : dev(new QBuffer(&ba)),
            fileBackingEnabled(fileBacking),
            fileBackingActive(false),
            handleDirty(false)
    {
        dev->open(QIODevice::ReadWrite);
    }

    ByteStream::~ByteStream()
    {
        delete dev;
    }

    ByteStream &ByteStream::operator <<(char chr)
    {
        if (handleDirty) prepareBuffer();
        dev->write(&chr, 1);
        return *this;
    }

    ByteStream &ByteStream::operator <<(const char *str)
    {
        if (handleDirty) prepareBuffer();
        dev->write(str, strlen(str));
        return *this;
    }

    ByteStream &ByteStream::operator <<(const QByteArray &str)
    {
        if (handleDirty) prepareBuffer();
        dev->write(str);
        return *this;
    }

    ByteStream &ByteStream::operator <<(const ByteStream &src)
    {
        Q_ASSERT(!src.dev->isSequential());
        if (handleDirty) prepareBuffer();
        // We do play nice here, even though it looks ugly.
        // We save the position and restore it afterwards.
        ByteStream &s = const_cast<ByteStream&>(src);
        qint64 pos = s.dev->pos();
        s.dev->reset();
        while (!s.dev->atEnd()) {
            QByteArray buf = s.dev->read(chunkSize());
            dev->write(buf);
        }
        s.dev->seek(pos);
        return *this;
    }

    ByteStream &ByteStream::operator <<(qreal val) {
        char buf[256];
        qt_real_to_string(val, buf);
        *this << buf;
        return *this;
    }

    ByteStream &ByteStream::operator <<(int val) {
        char buf[256];
        qt_int_to_string(val, buf);
        *this << buf;
        return *this;
    }

    ByteStream &ByteStream::operator <<(const QPointF &p) {
        char buf[256];
        qt_real_to_string(p.x(), buf);
        *this << buf;
        qt_real_to_string(p.y(), buf);
        *this << buf;
        return *this;
    }

    QIODevice *ByteStream::stream()
    {
        dev->reset();
        handleDirty = true;
        return dev;
    }

    void ByteStream::clear()
    {
        dev->open(QIODevice::ReadWrite | QIODevice::Truncate);
    }

    void ByteStream::constructor_helper(QByteArray *ba)
    {
        delete dev;
        dev = new QBuffer(ba);
        dev->open(QIODevice::ReadWrite);
    }

    void ByteStream::prepareBuffer()
    {
        Q_ASSERT(!dev->isSequential());
        qint64 size = dev->size();
        if (fileBackingEnabled && !fileBackingActive
                && size > maxMemorySize()) {
            // Switch to file backing.
            QTemporaryFile *newFile = new QTemporaryFile;
            newFile->open();
            dev->reset();
            while (!dev->atEnd()) {
                QByteArray buf = dev->read(chunkSize());
                newFile->write(buf);
            }
            delete dev;
            dev = newFile;
            ba.clear();
            fileBackingActive = true;
        }
        if (dev->pos() != size) {
            dev->seek(size);
            handleDirty = false;
        }
    }
}

#define QT_PATH_ELEMENT(elm)

QByteArray QPdf::generatePath(const QPainterPath &path, const QTransform &matrix, PathFlags flags)
{
    QByteArray result;
    if (!path.elementCount())
        return result;

    ByteStream s(&result);

    int start = -1;
    for (int i = 0; i < path.elementCount(); ++i) {
        const QPainterPath::Element &elm = path.elementAt(i);
        switch (elm.type) {
        case QPainterPath::MoveToElement:
            if (start >= 0
                && path.elementAt(start).x == path.elementAt(i-1).x
                && path.elementAt(start).y == path.elementAt(i-1).y)
                s << "h\n";
            s << matrix.map(QPointF(elm.x, elm.y)) << "m\n";
            start = i;
                break;
        case QPainterPath::LineToElement:
            s << matrix.map(QPointF(elm.x, elm.y)) << "l\n";
            break;
        case QPainterPath::CurveToElement:
            Q_ASSERT(path.elementAt(i+1).type == QPainterPath::CurveToDataElement);
            Q_ASSERT(path.elementAt(i+2).type == QPainterPath::CurveToDataElement);
            s << matrix.map(QPointF(elm.x, elm.y))
              << matrix.map(QPointF(path.elementAt(i+1).x, path.elementAt(i+1).y))
              << matrix.map(QPointF(path.elementAt(i+2).x, path.elementAt(i+2).y))
              << "c\n";
            i += 2;
            break;
        default:
            qFatal("QPdf::generatePath(), unhandled type: %d", elm.type);
        }
    }
    if (start >= 0
        && path.elementAt(start).x == path.elementAt(path.elementCount()-1).x
        && path.elementAt(start).y == path.elementAt(path.elementCount()-1).y)
        s << "h\n";

    Qt::FillRule fillRule = path.fillRule();

    const char *op = "";
    switch (flags) {
    case ClipPath:
        op = (fillRule == Qt::WindingFill) ? "W n\n" : "W* n\n";
        break;
    case FillPath:
        op = (fillRule == Qt::WindingFill) ? "f\n" : "f*\n";
        break;
    case StrokePath:
        op = "S\n";
        break;
    case FillAndStrokePath:
        op = (fillRule == Qt::WindingFill) ? "B\n" : "B*\n";
        break;
    }
    s << op;
    return result;
}

QByteArray QPdf::generateMatrix(const QTransform &matrix)
{
    QByteArray result;
    ByteStream s(&result);
    s << matrix.m11()
      << matrix.m12()
      << matrix.m21()
      << matrix.m22()
      << matrix.dx()
      << matrix.dy()
      << "cm\n";
    return result;
}

QByteArray QPdf::generateDashes(const QPen &pen)
{
    QByteArray result;
    ByteStream s(&result);
    s << '[';

    QVector<qreal> dasharray = pen.dashPattern();
    qreal w = pen.widthF();
    if (w < 0.001)
        w = 1;
    for (int i = 0; i < dasharray.size(); ++i) {
        qreal dw = dasharray.at(i)*w;
        if (dw < 0.0001) dw = 0.0001;
        s << dw;
    }
    s << ']';
    s << pen.dashOffset() * w;
    s << " d\n";
    return result;
}



static const char* const pattern_for_brush[] = {
    nullptr, // NoBrush
    nullptr, // SolidPattern
    "0 J\n"
    "6 w\n"
    "[] 0 d\n"
    "4 0 m\n"
    "4 8 l\n"
    "0 4 m\n"
    "8 4 l\n"
    "S\n", // Dense1Pattern

    "0 J\n"
    "2 w\n"
    "[6 2] 1 d\n"
    "0 0 m\n"
    "0 8 l\n"
    "8 0 m\n"
    "8 8 l\n"
    "S\n"
    "[] 0 d\n"
    "2 0 m\n"
    "2 8 l\n"
    "6 0 m\n"
    "6 8 l\n"
    "S\n"
    "[6 2] -3 d\n"
    "4 0 m\n"
    "4 8 l\n"
    "S\n", // Dense2Pattern

    "0 J\n"
    "2 w\n"
    "[6 2] 1 d\n"
    "0 0 m\n"
    "0 8 l\n"
    "8 0 m\n"
    "8 8 l\n"
    "S\n"
    "[2 2] -1 d\n"
    "2 0 m\n"
    "2 8 l\n"
    "6 0 m\n"
    "6 8 l\n"
    "S\n"
    "[6 2] -3 d\n"
    "4 0 m\n"
    "4 8 l\n"
    "S\n", // Dense3Pattern

    "0 J\n"
    "2 w\n"
    "[2 2] 1 d\n"
    "0 0 m\n"
    "0 8 l\n"
    "8 0 m\n"
    "8 8 l\n"
    "S\n"
    "[2 2] -1 d\n"
    "2 0 m\n"
    "2 8 l\n"
    "6 0 m\n"
    "6 8 l\n"
    "S\n"
    "[2 2] 1 d\n"
    "4 0 m\n"
    "4 8 l\n"
    "S\n", // Dense4Pattern

    "0 J\n"
    "2 w\n"
    "[2 6] -1 d\n"
    "0 0 m\n"
    "0 8 l\n"
    "8 0 m\n"
    "8 8 l\n"
    "S\n"
    "[2 2] 1 d\n"
    "2 0 m\n"
    "2 8 l\n"
    "6 0 m\n"
    "6 8 l\n"
    "S\n"
    "[2 6] 3 d\n"
    "4 0 m\n"
    "4 8 l\n"
    "S\n", // Dense5Pattern

    "0 J\n"
    "2 w\n"
    "[2 6] -1 d\n"
    "0 0 m\n"
    "0 8 l\n"
    "8 0 m\n"
    "8 8 l\n"
    "S\n"
    "[2 6] 3 d\n"
    "4 0 m\n"
    "4 8 l\n"
    "S\n", // Dense6Pattern

    "0 J\n"
    "2 w\n"
    "[2 6] -1 d\n"
    "0 0 m\n"
    "0 8 l\n"
    "8 0 m\n"
    "8 8 l\n"
    "S\n", // Dense7Pattern

    "1 w\n"
    "0 4 m\n"
    "8 4 l\n"
    "S\n", // HorPattern

    "1 w\n"
    "4 0 m\n"
    "4 8 l\n"
    "S\n", // VerPattern

    "1 w\n"
    "4 0 m\n"
    "4 8 l\n"
    "0 4 m\n"
    "8 4 l\n"
    "S\n", // CrossPattern

    "1 w\n"
    "-1 5 m\n"
    "5 -1 l\n"
    "3 9 m\n"
    "9 3 l\n"
    "S\n", // BDiagPattern

    "1 w\n"
    "-1 3 m\n"
    "5 9 l\n"
    "3 -1 m\n"
    "9 5 l\n"
    "S\n", // FDiagPattern

    "1 w\n"
    "-1 3 m\n"
    "5 9 l\n"
    "3 -1 m\n"
    "9 5 l\n"
    "-1 5 m\n"
    "5 -1 l\n"
    "3 9 m\n"
    "9 3 l\n"
    "S\n", // DiagCrossPattern
};

QByteArray QPdf::patternForBrush(const QBrush &b)
{
    int style = b.style();
    if (style > Qt::DiagCrossPattern)
        return QByteArray();
    return pattern_for_brush[style];
}


static void moveToHook(qfixed x, qfixed y, void *data)
{
    QPdf::Stroker *t = (QPdf::Stroker *)data;
    if (!t->first)
        *t->stream << "h\n";
    if (!t->cosmeticPen)
        t->matrix.map(x, y, &x, &y);
    *t->stream << x << y << "m\n";
    t->first = false;
}

static void lineToHook(qfixed x, qfixed y, void *data)
{
    QPdf::Stroker *t = (QPdf::Stroker *)data;
    if (!t->cosmeticPen)
        t->matrix.map(x, y, &x, &y);
    *t->stream << x << y << "l\n";
}

static void cubicToHook(qfixed c1x, qfixed c1y,
                        qfixed c2x, qfixed c2y,
                        qfixed ex, qfixed ey,
                        void *data)
{
    QPdf::Stroker *t = (QPdf::Stroker *)data;
    if (!t->cosmeticPen) {
        t->matrix.map(c1x, c1y, &c1x, &c1y);
        t->matrix.map(c2x, c2y, &c2x, &c2y);
        t->matrix.map(ex, ey, &ex, &ey);
    }
    *t->stream << c1x << c1y
               << c2x << c2y
               << ex << ey
               << "c\n";
}

QPdf::Stroker::Stroker()
    : stream(nullptr),
    first(true),
    dashStroker(&basicStroker)
{
    stroker = &basicStroker;
    basicStroker.setMoveToHook(moveToHook);
    basicStroker.setLineToHook(lineToHook);
    basicStroker.setCubicToHook(cubicToHook);
    cosmeticPen = true;
    basicStroker.setStrokeWidth(.1);
}

void QPdf::Stroker::setPen(const QPen &pen, QPainter::RenderHints hints)
{
    if (pen.style() == Qt::NoPen) {
        stroker = nullptr;
        return;
    }
    qreal w = pen.widthF();
    bool zeroWidth = w < 0.0001;
    cosmeticPen = qt_pen_is_cosmetic(pen, hints);
    if (zeroWidth)
        w = .1;

    basicStroker.setStrokeWidth(w);
    basicStroker.setCapStyle(pen.capStyle());
    basicStroker.setJoinStyle(pen.joinStyle());
    basicStroker.setMiterLimit(pen.miterLimit());

    QVector<qreal> dashpattern = pen.dashPattern();
    if (zeroWidth) {
        for (int i = 0; i < dashpattern.size(); ++i)
            dashpattern[i] *= 10.;
    }
    if (!dashpattern.isEmpty()) {
        dashStroker.setDashPattern(dashpattern);
        dashStroker.setDashOffset(pen.dashOffset());
        stroker = &dashStroker;
    } else {
        stroker = &basicStroker;
    }
}

void QPdf::Stroker::strokePath(const QPainterPath &path)
{
    if (!stroker)
        return;
    first = true;

    stroker->strokePath(path, this, cosmeticPen ? matrix : QTransform());
    *stream << "h f\n";
}

QByteArray QPdf::ascii85Encode(const QByteArray &input)
{
    int isize = input.size()/4*4;
    QByteArray output;
    output.resize(input.size()*5/4+7);
    char *out = output.data();
    const uchar *in = (const uchar *)input.constData();
    for (int i = 0; i < isize; i += 4) {
        uint val = (((uint)in[i])<<24) + (((uint)in[i+1])<<16) + (((uint)in[i+2])<<8) + (uint)in[i+3];
        if (val == 0) {
            *out = 'z';
            ++out;
        } else {
            char base[5];
            base[4] = val % 85;
            val /= 85;
            base[3] = val % 85;
            val /= 85;
            base[2] = val % 85;
            val /= 85;
            base[1] = val % 85;
            val /= 85;
            base[0] = val % 85;
            *(out++) = base[0] + '!';
            *(out++) = base[1] + '!';
            *(out++) = base[2] + '!';
            *(out++) = base[3] + '!';
            *(out++) = base[4] + '!';
        }
    }
    //write the last few bytes
    int remaining = input.size() - isize;
    if (remaining) {
        uint val = 0;
        for (int i = isize; i < input.size(); ++i)
            val = (val << 8) + in[i];
        val <<= 8*(4-remaining);
        char base[5];
        base[4] = val % 85;
        val /= 85;
        base[3] = val % 85;
        val /= 85;
        base[2] = val % 85;
        val /= 85;
        base[1] = val % 85;
        val /= 85;
        base[0] = val % 85;
        for (int i = 0; i < remaining+1; ++i)
            *(out++) = base[i] + '!';
    }
    *(out++) = '~';
    *(out++) = '>';
    output.resize(out-output.data());
    return output;
}

const char *QPdf::toHex(ushort u, char *buffer)
{
    int i = 3;
    while (i >= 0) {
        ushort hex = (u & 0x000f);
        if (hex < 0x0a)
            buffer[i] = '0'+hex;
        else
            buffer[i] = 'A'+(hex-0x0a);
        u = u >> 4;
        i--;
    }
    buffer[4] = '\0';
    return buffer;
}

const char *QPdf::toHex(uchar u, char *buffer)
{
    int i = 1;
    while (i >= 0) {
        ushort hex = (u & 0x000f);
        if (hex < 0x0a)
            buffer[i] = '0'+hex;
        else
            buffer[i] = 'A'+(hex-0x0a);
        u = u >> 4;
        i--;
    }
    buffer[2] = '\0';
    return buffer;
}


QPdfPage::QPdfPage()
    : QPdf::ByteStream(true) // Enable file backing
{
}

void QPdfPage::streamImage(int w, int h, int object)
{
    *this << w << "0 0 " << -h << "0 " << h << "cm /Im" << object << " Do\n";
    if (!images.contains(object))
        images.append(object);
}


QPdfEngine::QPdfEngine(QPdfEnginePrivate &dd)
    : QPaintEngine(dd, qt_pdf_decide_features())
{
}

QPdfEngine::QPdfEngine()
    : QPaintEngine(*new QPdfEnginePrivate(), qt_pdf_decide_features())
{
}

void QPdfEngine::setOutputFilename(const QString &filename)
{
    Q_D(QPdfEngine);
    d->outputFileName = filename;
}


void QPdfEngine::drawPoints (const QPointF *points, int pointCount)
{
    if (!points)
        return;

    Q_D(QPdfEngine);
    QPainterPath p;
    for (int i=0; i!=pointCount;++i) {
        p.moveTo(points[i]);
        p.lineTo(points[i] + QPointF(0, 0.001));
    }

    bool hadBrush = d->hasBrush;
    d->hasBrush = false;
    drawPath(p);
    d->hasBrush = hadBrush;
}

void QPdfEngine::drawLines (const QLineF *lines, int lineCount)
{
    if (!lines)
        return;

    Q_D(QPdfEngine);
    QPainterPath p;
    for (int i=0; i!=lineCount;++i) {
        p.moveTo(lines[i].p1());
        p.lineTo(lines[i].p2());
    }
    bool hadBrush = d->hasBrush;
    d->hasBrush = false;
    drawPath(p);
    d->hasBrush = hadBrush;
}

void QPdfEngine::drawRects (const QRectF *rects, int rectCount)
{
    if (!rects)
        return;

    Q_D(QPdfEngine);

    if (d->clipEnabled && d->allClipped)
        return;
    if (!d->hasPen && !d->hasBrush)
        return;

    if (d->simplePen || !d->hasPen) {
        // draw strokes natively in this case for better output
        if(!d->simplePen && !d->stroker.matrix.isIdentity())
            *d->currentPage << "q\n" << QPdf::generateMatrix(d->stroker.matrix);
        for (int i = 0; i < rectCount; ++i)
            *d->currentPage << rects[i].x() << rects[i].y() << rects[i].width() << rects[i].height() << "re\n";
        *d->currentPage << (d->hasPen ? (d->hasBrush ? "B\n" : "S\n") : "f\n");
        if(!d->simplePen && !d->stroker.matrix.isIdentity())
            *d->currentPage << "Q\n";
    } else {
        QPainterPath p;
        for (int i=0; i!=rectCount; ++i)
            p.addRect(rects[i]);
        drawPath(p);
    }
}

void QPdfEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
{
    Q_D(QPdfEngine);

    if (!points || !pointCount)
        return;

    bool hb = d->hasBrush;
    QPainterPath p;

    switch(mode) {
        case OddEvenMode:
            p.setFillRule(Qt::OddEvenFill);
            break;
        case ConvexMode:
        case WindingMode:
            p.setFillRule(Qt::WindingFill);
            break;
        case PolylineMode:
            d->hasBrush = false;
            break;
        default:
            break;
    }

    p.moveTo(points[0]);
    for (int i = 1; i < pointCount; ++i)
        p.lineTo(points[i]);

    if (mode != PolylineMode)
        p.closeSubpath();
    drawPath(p);

    d->hasBrush = hb;
}

void QPdfEngine::drawPath (const QPainterPath &p)
{
    Q_D(QPdfEngine);

    if (d->clipEnabled && d->allClipped)
        return;
    if (!d->hasPen && !d->hasBrush)
        return;

    if (d->simplePen) {
        // draw strokes natively in this case for better output
        *d->currentPage << QPdf::generatePath(p, QTransform(), d->hasBrush ? QPdf::FillAndStrokePath : QPdf::StrokePath);
    } else {
        if (d->hasBrush)
            *d->currentPage << QPdf::generatePath(p, d->stroker.matrix, QPdf::FillPath);
        if (d->hasPen) {
            *d->currentPage << "q\n";
            QBrush b = d->brush;
            d->brush = d->pen.brush();
            setBrush();
            d->stroker.strokePath(p);
            *d->currentPage << "Q\n";
            d->brush = b;
        }
    }
}

void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr)
{
    if (sr.isEmpty() || rectangle.isEmpty() || pixmap.isNull())
        return;
    Q_D(QPdfEngine);

    QBrush b = d->brush;

    QRect sourceRect = sr.toRect();
    QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap;
    QImage image = pm.toImage();
    bool bitmap = true;
    const bool lossless = painter()->testRenderHint(QPainter::LosslessImageRendering);
    const int object = d->addImage(image, &bitmap, lossless, pm.cacheKey());
    if (object < 0)
        return;

    *d->currentPage << "q\n";

    if ((d->pdfVersion != QPdfEngine::Version_A1b) && (d->opacity != 1.0)) {
        int stateObject = d->addConstantAlphaObject(qRound(255 * d->opacity), qRound(255 * d->opacity));
        if (stateObject)
            *d->currentPage << "/GState" << stateObject << "gs\n";
        else
            *d->currentPage << "/GSa gs\n";
    } else {
        *d->currentPage << "/GSa gs\n";
    }

    *d->currentPage
        << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
                                           rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
    if (bitmap) {
        // set current pen as d->brush
        d->brush = d->pen.brush();
    }
    setBrush();
    d->currentPage->streamImage(image.width(), image.height(), object);
    *d->currentPage << "Q\n";

    d->brush = b;
}

void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags)
{
    if (sr.isEmpty() || rectangle.isEmpty() || image.isNull())
        return;
    Q_D(QPdfEngine);

    QRect sourceRect = sr.toRect();
    QImage im = sourceRect != image.rect() ? image.copy(sourceRect) : image;
    bool bitmap = true;
    const bool lossless = painter()->testRenderHint(QPainter::LosslessImageRendering);
    const int object = d->addImage(im, &bitmap, lossless, im.cacheKey());
    if (object < 0)
        return;

    *d->currentPage << "q\n";

    if ((d->pdfVersion != QPdfEngine::Version_A1b) && (d->opacity != 1.0)) {
        int stateObject = d->addConstantAlphaObject(qRound(255 * d->opacity), qRound(255 * d->opacity));
        if (stateObject)
            *d->currentPage << "/GState" << stateObject << "gs\n";
        else
            *d->currentPage << "/GSa gs\n";
    } else {
        *d->currentPage << "/GSa gs\n";
    }

    *d->currentPage
        << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
                                           rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
    setBrush();
    d->currentPage->streamImage(im.width(), im.height(), object);
    *d->currentPage << "Q\n";
}

void QPdfEngine::drawTiledPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QPointF &point)
{
    Q_D(QPdfEngine);

    bool bitmap = (pixmap.depth() == 1);
    QBrush b = d->brush;
    QPointF bo = d->brushOrigin;
    bool hp = d->hasPen;
    d->hasPen = false;
    bool hb = d->hasBrush;
    d->hasBrush = true;

    d->brush = QBrush(pixmap);
    if (bitmap)
        // #### fix bitmap case where we have a brush pen
        d->brush.setColor(d->pen.color());

    d->brushOrigin = -point;
    *d->currentPage << "q\n";
    setBrush();

    drawRects(&rectangle, 1);
    *d->currentPage << "Q\n";

    d->hasPen = hp;
    d->hasBrush = hb;
    d->brush = b;
    d->brushOrigin = bo;
}

void QPdfEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
{
    Q_D(QPdfEngine);

    if (!d->hasPen || (d->clipEnabled && d->allClipped))
        return;

    if (d->stroker.matrix.type() >= QTransform::TxProject) {
        QPaintEngine::drawTextItem(p, textItem);
        return;
    }

    *d->currentPage << "q\n";
    if(!d->simplePen)
        *d->currentPage << QPdf::generateMatrix(d->stroker.matrix);

    bool hp = d->hasPen;
    d->hasPen = false;
    QBrush b = d->brush;
    d->brush = d->pen.brush();
    setBrush();

    const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
    Q_ASSERT(ti.fontEngine->type() != QFontEngine::Multi);
    d->drawTextItem(p, ti);
    d->hasPen = hp;
    d->brush = b;
    *d->currentPage << "Q\n";
}

void QPdfEngine::drawHyperlink(const QRectF &r, const QUrl &url)
{
    Q_D(QPdfEngine);

    const uint annot = d->addXrefEntry(-1);
    const QByteArray urlascii = url.toEncoded();
    int len = urlascii.size();
    QVarLengthArray<char> url_esc;
    url_esc.reserve(len + 1);
    for (int j = 0; j < len; j++) {
        if (urlascii[j] == '(' || urlascii[j] == ')' || urlascii[j] == '\\')
            url_esc.append('\\');
        url_esc.append(urlascii[j]);
    }
    url_esc.append('\0');

    char buf[256];
    const QRectF rr = d->pageMatrix().mapRect(r);
    d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n");

    if (d->pdfVersion == QPdfEngine::Version_A1b)
        d->xprintf("/F 4\n"); // enable print flag, disable all other

    d->xprintf("/Rect [");
    d->xprintf("%s ", qt_real_to_string(rr.left(), buf));
    d->xprintf("%s ", qt_real_to_string(rr.top(), buf));
    d->xprintf("%s ", qt_real_to_string(rr.right(), buf));
    d->xprintf("%s", qt_real_to_string(rr.bottom(), buf));
    d->xprintf("]\n/Border [0 0 0]\n/A <<\n");
    d->xprintf("/Type /Action\n/S /URI\n/URI (%s)\n", url_esc.constData());
    d->xprintf(">>\n>>\n");
    d->xprintf("endobj\n");
    d->currentPage->annotations.append(annot);
}

void QPdfEngine::updateState(const QPaintEngineState &state)
{
    Q_D(QPdfEngine);

    QPaintEngine::DirtyFlags flags = state.state();

    if (flags & DirtyTransform)
        d->stroker.matrix = state.transform();

    if (flags & DirtyPen) {
        if (d->pdfVersion == QPdfEngine::Version_A1b) {
            QPen pen = state.pen();

            QColor penColor = pen.color();
            if (penColor.alpha() != 255)
                penColor.setAlpha(255);
            pen.setColor(penColor);

            QBrush penBrush = pen.brush();
            removeTransparencyFromBrush(penBrush);
            pen.setBrush(penBrush);

            d->pen = pen;
        } else {
            d->pen = state.pen();
        }
        d->hasPen = d->pen.style() != Qt::NoPen;
        d->stroker.setPen(d->pen, state.renderHints());
        QBrush penBrush = d->pen.brush();
        bool cosmeticPen = qt_pen_is_cosmetic(d->pen, state.renderHints());
        bool oldSimple = d->simplePen;
        d->simplePen = (d->hasPen && !cosmeticPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque() && d->opacity == 1.0);
        if (oldSimple != d->simplePen)
            flags |= DirtyTransform;
    } else if (flags & DirtyHints) {
        d->stroker.setPen(d->pen, state.renderHints());
    }
    if (flags & DirtyBrush) {
        if (d->pdfVersion == QPdfEngine::Version_A1b) {
            QBrush brush = state.brush();
            removeTransparencyFromBrush(brush);
            d->brush = brush;
        } else {
            d->brush = state.brush();
        }
        if (d->brush.color().alpha() == 0 && d->brush.style() == Qt::SolidPattern)
            d->brush.setStyle(Qt::NoBrush);
        d->hasBrush = d->brush.style() != Qt::NoBrush;
    }
    if (flags & DirtyBrushOrigin) {
        d->brushOrigin = state.brushOrigin();
        flags |= DirtyBrush;
    }
    if (flags & DirtyOpacity) {
        d->opacity = state.opacity();
        if (d->simplePen && d->opacity != 1.0) {
            d->simplePen = false;
            flags |= DirtyTransform;
        }
    }

    bool ce = d->clipEnabled;
    if (flags & DirtyClipPath) {
        d->clipEnabled = true;
        updateClipPath(state.clipPath(), state.clipOperation());
    } else if (flags & DirtyClipRegion) {
        d->clipEnabled = true;
        QPainterPath path;
        for (const QRect &rect : state.clipRegion())
            path.addRect(rect);
        updateClipPath(path, state.clipOperation());
        flags |= DirtyClipPath;
    } else if (flags & DirtyClipEnabled) {
        d->clipEnabled = state.isClipEnabled();
    }

    if (ce != d->clipEnabled)
        flags |= DirtyClipPath;
    else if (!d->clipEnabled)
        flags &= ~DirtyClipPath;

    setupGraphicsState(flags);
}

void QPdfEngine::setupGraphicsState(QPaintEngine::DirtyFlags flags)
{
    Q_D(QPdfEngine);
    if (flags & DirtyClipPath)
        flags |= DirtyTransform|DirtyPen|DirtyBrush;

    if (flags & DirtyTransform) {
        *d->currentPage << "Q\n";
        flags |= DirtyPen|DirtyBrush;
    }

    if (flags & DirtyClipPath) {
        *d->currentPage << "Q q\n";

        d->allClipped = false;
        if (d->clipEnabled && !d->clips.isEmpty()) {
            for (int i = 0; i < d->clips.size(); ++i) {
                if (d->clips.at(i).isEmpty()) {
                    d->allClipped = true;
                    break;
                }
            }
            if (!d->allClipped) {
                for (int i = 0; i < d->clips.size(); ++i) {
                    *d->currentPage << QPdf::generatePath(d->clips.at(i), QTransform(), QPdf::ClipPath);
                }
            }
        }
    }

    if (flags & DirtyTransform) {
        *d->currentPage << "q\n";
        if (d->simplePen && !d->stroker.matrix.isIdentity())
            *d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
    }
    if (flags & DirtyBrush)
        setBrush();
    if (d->simplePen && (flags & DirtyPen))
        setPen();
}

extern QPainterPath qt_regionToPath(const QRegion &region);

void QPdfEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
{
    Q_D(QPdfEngine);
    QPainterPath path = d->stroker.matrix.map(p);
    //qDebug() << "updateClipPath: " << d->stroker.matrix << p.boundingRect() << path.boundingRect() << op;

    if (op == Qt::NoClip) {
        d->clipEnabled = false;
        d->clips.clear();
    } else if (op == Qt::ReplaceClip) {
        d->clips.clear();
        d->clips.append(path);
    } else if (op == Qt::IntersectClip) {
        d->clips.append(path);
    } else { // UniteClip
        // ask the painter for the current clipping path. that's the easiest solution
        path = painter()->clipPath();
        path = d->stroker.matrix.map(path);
        d->clips.clear();
        d->clips.append(path);
    }
}

void QPdfEngine::setPen()
{
    Q_D(QPdfEngine);
    if (d->pen.style() == Qt::NoPen)
        return;
    QBrush b = d->pen.brush();
    Q_ASSERT(b.style() == Qt::SolidPattern && b.isOpaque());

    QColor rgba = b.color();
    if (d->grayscale) {
        qreal gray = qGray(rgba.rgba())/255.;
        *d->currentPage << gray << gray << gray;
    } else {
        *d->currentPage << rgba.redF()
                        << rgba.greenF()
                        << rgba.blueF();
    }
    *d->currentPage << "SCN\n";

    *d->currentPage << d->pen.widthF() << "w ";

    int pdfCapStyle = 0;
    switch(d->pen.capStyle()) {
    case Qt::FlatCap:
        pdfCapStyle = 0;
        break;
    case Qt::SquareCap:
        pdfCapStyle = 2;
        break;
    case Qt::RoundCap:
        pdfCapStyle = 1;
        break;
    default:
        break;
    }
    *d->currentPage << pdfCapStyle << "J ";

    int pdfJoinStyle = 0;
    switch(d->pen.joinStyle()) {
    case Qt::MiterJoin:
    case Qt::SvgMiterJoin:
        *d->currentPage << qMax(qreal(1.0), d->pen.miterLimit()) << "M ";
        pdfJoinStyle = 0;
        break;
    case Qt::BevelJoin:
        pdfJoinStyle = 2;
        break;
    case Qt::RoundJoin:
        pdfJoinStyle = 1;
        break;
    default:
        break;
    }
    *d->currentPage << pdfJoinStyle << "j ";

    *d->currentPage << QPdf::generateDashes(d->pen);
}


void QPdfEngine::setBrush()
{
    Q_D(QPdfEngine);
    Qt::BrushStyle style = d->brush.style();
    if (style == Qt::NoBrush)
        return;

    bool specifyColor;
    int gStateObject = 0;
    int patternObject = d->addBrushPattern(d->stroker.matrix, &specifyColor, &gStateObject);
    if (!patternObject && !specifyColor)
        return;

    *d->currentPage << (patternObject ? "/PCSp cs " : "/CSp cs ");
    if (specifyColor) {
        QColor rgba = d->brush.color();
        if (d->grayscale) {
            qreal gray = qGray(rgba.rgba())/255.;
            *d->currentPage << gray << gray << gray;
        } else {
            *d->currentPage << rgba.redF()
                            << rgba.greenF()
                            << rgba.blueF();
        }
    }
    if (patternObject)
        *d->currentPage << "/Pat" << patternObject;
    *d->currentPage << "scn\n";

    if (gStateObject)
        *d->currentPage << "/GState" << gStateObject << "gs\n";
    else
        *d->currentPage << "/GSa gs\n";
}


bool QPdfEngine::newPage()
{
    Q_D(QPdfEngine);
    if (!isActive())
        return false;
    d->newPage();

    setupGraphicsState(DirtyBrush|DirtyPen|DirtyClipPath);
    QFile *outfile = qobject_cast<QFile*> (d->outDevice);
    if (outfile && outfile->error() != QFile::NoError)
        return false;
    return true;
}

QPaintEngine::Type QPdfEngine::type() const
{
    return QPaintEngine::Pdf;
}

void QPdfEngine::setResolution(int resolution)
{
    Q_D(QPdfEngine);
    d->resolution = resolution;
}

int QPdfEngine::resolution() const
{
    Q_D(const QPdfEngine);
    return d->resolution;
}

void QPdfEngine::setPdfVersion(PdfVersion version)
{
    Q_D(QPdfEngine);
    d->pdfVersion = version;
}

void QPdfEngine::setDocumentXmpMetadata(const QByteArray &xmpMetadata)
{
    Q_D(QPdfEngine);
    d->xmpDocumentMetadata = xmpMetadata;
}

QByteArray QPdfEngine::documentXmpMetadata() const
{
    Q_D(const QPdfEngine);
    return d->xmpDocumentMetadata;
}

void QPdfEngine::setPageLayout(const QPageLayout &pageLayout)
{
    Q_D(QPdfEngine);
    d->m_pageLayout = pageLayout;
}

void QPdfEngine::setPageSize(const QPageSize &pageSize)
{
    Q_D(QPdfEngine);
    d->m_pageLayout.setPageSize(pageSize);
}

void QPdfEngine::setPageOrientation(QPageLayout::Orientation orientation)
{
    Q_D(QPdfEngine);
    d->m_pageLayout.setOrientation(orientation);
}

void QPdfEngine::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
{
    Q_D(QPdfEngine);
    d->m_pageLayout.setUnits(units);
    d->m_pageLayout.setMargins(margins);
}

QPageLayout QPdfEngine::pageLayout() const
{
    Q_D(const QPdfEngine);
    return d->m_pageLayout;
}

// Metrics are in Device Pixels
int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
{
    Q_D(const QPdfEngine);
    int val;
    switch (metricType) {
    case QPaintDevice::PdmWidth:
        val = d->m_pageLayout.paintRectPixels(d->resolution).width();
        break;
    case QPaintDevice::PdmHeight:
        val = d->m_pageLayout.paintRectPixels(d->resolution).height();
        break;
    case QPaintDevice::PdmDpiX:
    case QPaintDevice::PdmDpiY:
        val = d->resolution;
        break;
    case QPaintDevice::PdmPhysicalDpiX:
    case QPaintDevice::PdmPhysicalDpiY:
        val = 1200;
        break;
    case QPaintDevice::PdmWidthMM:
        val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).width());
        break;
    case QPaintDevice::PdmHeightMM:
        val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).height());
        break;
    case QPaintDevice::PdmNumColors:
        val = INT_MAX;
        break;
    case QPaintDevice::PdmDepth:
        val = 32;
        break;
    case QPaintDevice::PdmDevicePixelRatio:
        val = 1;
        break;
    case QPaintDevice::PdmDevicePixelRatioScaled:
        val = 1 * QPaintDevice::devicePixelRatioFScale();
        break;
    default:
        qWarning("QPdfWriter::metric: Invalid metric command");
        return 0;
    }
    return val;
}

QPdfEnginePrivate::QPdfEnginePrivate()
    : clipEnabled(false), allClipped(false), hasPen(true), hasBrush(false), simplePen(false),
      pdfVersion(QPdfEngine::Version_1_4),
      outDevice(nullptr), ownsDevice(false),
      embedFonts(true),
      grayscale(false),
      m_pageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(10, 10, 10, 10))
{
    initResources();
    resolution = 1200;
    currentObject = 1;
    currentPage = nullptr;
    stroker.stream = nullptr;

    streampos = 0;

    stream = new QDataStream;
}

bool QPdfEngine::begin(QPaintDevice *pdev)
{
    Q_D(QPdfEngine);
    d->pdev = pdev;

    if (!d->outDevice) {
        if (!d->outputFileName.isEmpty()) {
            QFile *file = new QFile(d->outputFileName);
            if (!file->open(QFile::WriteOnly|QFile::Truncate)) {
                delete file;
                return false;
            }
            d->outDevice = file;
        } else {
            return false;
        }
        d->ownsDevice = true;
    }

    d->currentObject = 1;

    d->currentPage = new QPdfPage;
    d->stroker.stream = d->currentPage;
    d->opacity = 1.0;

    d->stream->setDevice(d->outDevice);

    d->streampos = 0;
    d->hasPen = true;
    d->hasBrush = false;
    d->clipEnabled = false;
    d->allClipped = false;

    d->xrefPositions.clear();
    d->pageRoot = 0;
    d->embeddedfilesRoot = 0;
    d->namesRoot = 0;
    d->catalog = 0;
    d->info = 0;
    d->graphicsState = 0;
    d->patternColorSpace = 0;
    d->simplePen = false;

    d->pages.clear();
    d->imageCache.clear();
    d->alphaCache.clear();

    setActive(true);
    d->writeHeader();
    newPage();

    return true;
}

bool QPdfEngine::end()
{
    Q_D(QPdfEngine);
    d->writeTail();

    d->stream->setDevice(nullptr);

    qDeleteAll(d->fonts);
    d->fonts.clear();
    delete d->currentPage;
    d->currentPage = nullptr;

    if (d->outDevice && d->ownsDevice) {
        d->outDevice->close();
        delete d->outDevice;
        d->outDevice = nullptr;
    }

    d->fileCache.clear();

    setActive(false);
    return true;
}

void QPdfEngine::addFileAttachment(const QString &fileName, const QByteArray &data, const QString &mimeType)
{
    Q_D(QPdfEngine);
    d->fileCache.push_back({fileName, data, mimeType});
}

QPdfEnginePrivate::~QPdfEnginePrivate()
{
    qDeleteAll(fonts);
    delete currentPage;
    delete stream;
}

void QPdfEnginePrivate::writeHeader()
{
    addXrefEntry(0,false);

    // Keep in sync with QPdfEngine::PdfVersion!
    static const char mapping[][4] = {
        "1.4", // Version_1_4
        "1.4", // Version_A1b
        "1.6", // Version_1_6
    };
    static const size_t numMappings = sizeof mapping / sizeof *mapping;
    const char *verStr = mapping[size_t(pdfVersion) < numMappings ? pdfVersion : 0];

    xprintf("%%PDF-%s\n", verStr);
    xprintf("%%\303\242\303\243\n");

    writeInfo();

    int metaDataObj = -1;
    int outputIntentObj = -1;
    if (pdfVersion == QPdfEngine::Version_A1b || !xmpDocumentMetadata.isEmpty()) {
        metaDataObj = writeXmpDcumentMetaData();
    }
    if (pdfVersion == QPdfEngine::Version_A1b) {
        outputIntentObj = writeOutputIntent();
    }

    catalog = addXrefEntry(-1);
    pageRoot = requestObject();
    if (!fileCache.isEmpty()) {
        namesRoot = requestObject();
        embeddedfilesRoot = requestObject();
    }

    // catalog
    {
        QByteArray catalog;
        QPdf::ByteStream s(&catalog);
        s << "<<\n"
          << "/Type /Catalog\n"
          << "/Pages " << pageRoot << "0 R\n";

        // Embedded files, if any
        if (!fileCache.isEmpty())
            s << "/Names " << embeddedfilesRoot << "0 R\n";

        if (pdfVersion == QPdfEngine::Version_A1b || !xmpDocumentMetadata.isEmpty())
            s << "/Metadata " << metaDataObj << "0 R\n";

        if (pdfVersion == QPdfEngine::Version_A1b)
            s << "/OutputIntents [" << outputIntentObj << "0 R]\n";

        s << ">>\n"
          << "endobj\n";

        write(catalog);
    }

    if (!fileCache.isEmpty()) {
        addXrefEntry(embeddedfilesRoot);
        xprintf("<</EmbeddedFiles %d 0 R>>\n"
                "endobj\n", namesRoot);
    }

    // graphics state
    graphicsState = addXrefEntry(-1);
    xprintf("<<\n"
            "/Type /ExtGState\n"
            "/SA true\n"
            "/SM 0.02\n"
            "/ca 1.0\n"
            "/CA 1.0\n"
            "/AIS false\n"
            "/SMask /None"
            ">>\n"
            "endobj\n");

    // color space for pattern
    patternColorSpace = addXrefEntry(-1);
    xprintf("[/Pattern /DeviceRGB]\n"
            "endobj\n");
}

void QPdfEnginePrivate::writeInfo()
{
    info = addXrefEntry(-1);
    xprintf("<<\n/Title ");
    printString(title);
    xprintf("\n/Creator ");
    printString(creator);
    xprintf("\n/Producer ");
    printString(QString::fromLatin1("Qt " QT_VERSION_STR));
    QDateTime now = QDateTime::currentDateTime();
    QTime t = now.time();
    QDate d = now.date();
    xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d",
            d.year(),
            d.month(),
            d.day(),
            t.hour(),
            t.minute(),
            t.second());
    int offset = now.offsetFromUtc();
    int hours  = (offset / 60) / 60;
    int mins   = (offset / 60) % 60;
    if (offset < 0)
        xprintf("-%02d'%02d')\n", -hours, -mins);
    else if (offset > 0)
        xprintf("+%02d'%02d')\n", hours , mins);
    else
        xprintf("Z)\n");
    xprintf(">>\n"
            "endobj\n");
}

int QPdfEnginePrivate::writeXmpDcumentMetaData()
{
    const int metaDataObj = addXrefEntry(-1);
    QByteArray metaDataContent;

    if (xmpDocumentMetadata.isEmpty()) {
        const QString producer(QString::fromLatin1("Qt " QT_VERSION_STR));

        const QDateTime now = QDateTime::currentDateTime();
        const QDate date = now.date();
        const QTime time = now.time();
        const QString timeStr =
                QString::asprintf("%d-%02d-%02dT%02d:%02d:%02d",
                                  date.year(), date.month(), date.day(),
                                  time.hour(), time.minute(), time.second());

        const int offset = now.offsetFromUtc();
        const int hours  = (offset / 60) / 60;
        const int mins   = (offset / 60) % 60;
        QString tzStr;
        if (offset < 0)
            tzStr = QString::asprintf("-%02d:%02d", -hours, -mins);
        else if (offset > 0)
            tzStr = QString::asprintf("+%02d:%02d", hours , mins);
        else
            tzStr = QLatin1String("Z");

        const QString metaDataDate = timeStr + tzStr;

        QFile metaDataFile(QLatin1String(":/qpdf/qpdfa_metadata.xml"));
        metaDataFile.open(QIODevice::ReadOnly);
        metaDataContent = QString::fromUtf8(metaDataFile.readAll()).arg(producer.toHtmlEscaped(),
                                                                        title.toHtmlEscaped(),
                                                                        creator.toHtmlEscaped(),
                                                                        metaDataDate).toUtf8();
    }
    else
        metaDataContent = xmpDocumentMetadata;

    xprintf("<<\n"
            "/Type /Metadata /Subtype /XML\n"
            "/Length %d\n"
            ">>\n"
            "stream\n", metaDataContent.size());
    write(metaDataContent);
    xprintf("\nendstream\n"
            "endobj\n");

    return metaDataObj;
}

int QPdfEnginePrivate::writeOutputIntent()
{
    const int colorProfile = addXrefEntry(-1);
    {
        QFile colorProfileFile(QLatin1String(":/qpdf/sRGB2014.icc"));
        colorProfileFile.open(QIODevice::ReadOnly);
        const QByteArray colorProfileData = colorProfileFile.readAll();

        QByteArray data;
        QPdf::ByteStream s(&data);
        int length_object = requestObject();

        s << "<<\n";
        s << "/N 3\n";
        s << "/Alternate /DeviceRGB\n";
        s << "/Length " << length_object << "0 R\n";
        s << "/Filter /FlateDecode\n";
        s << ">>\n";
        s << "stream\n";
        write(data);
        const int len = writeCompressed(colorProfileData);
        write("\nendstream\n"
              "endobj\n");
        addXrefEntry(length_object);
        xprintf("%d\n"
                "endobj\n", len);
    }

    const int outputIntent = addXrefEntry(-1);
    {
        xprintf("<<\n");
        xprintf("/Type /OutputIntent\n");
        xprintf("/S/GTS_PDFA1\n");
        xprintf("/OutputConditionIdentifier (sRGB_IEC61966-2-1_black_scaled)\n");
        xprintf("/DestOutputProfile %d 0 R\n", colorProfile);
        xprintf("/Info(sRGB IEC61966 v2.1 with black scaling)\n");
        xprintf("/RegistryName(http://www.color.org)\n");
        xprintf(">>\n");
        xprintf("endobj\n");
    }

    return outputIntent;
}

void QPdfEnginePrivate::writePageRoot()
{
    addXrefEntry(pageRoot);

    xprintf("<<\n"
            "/Type /Pages\n"
            "/Kids \n"
            "[\n");
    int size = pages.size();
    for (int i = 0; i < size; ++i)
        xprintf("%d 0 R\n", pages[i]);
    xprintf("]\n");

    //xprintf("/Group <</S /Transparency /I true /K false>>\n");
    xprintf("/Count %d\n", pages.size());

    xprintf("/ProcSet [/PDF /Text /ImageB /ImageC]\n"
            ">>\n"
            "endobj\n");
}

void QPdfEnginePrivate::writeAttachmentRoot()
{
    if (fileCache.isEmpty())
        return;

    QVector<int> attachments;
    const int size = fileCache.size();
    for (int i = 0; i < size; ++i) {
        auto attachment = fileCache.at(i);
        const int attachmentID = addXrefEntry(-1);
        xprintf("<<\n");
        if (do_compress)
            xprintf("/Filter /FlateDecode\n");

        const int lenobj = requestObject();
        xprintf("/Length %d 0 R\n", lenobj);
        int len = 0;
        xprintf(">>\nstream\n");
        len = writeCompressed(attachment.data);
        xprintf("\nendstream\n"
                "endobj\n");
        addXrefEntry(lenobj);
        xprintf("%d\n"
                "endobj\n", len);

        attachments.push_back(addXrefEntry(-1));
        xprintf("<<\n"
                "/F (%s)", attachment.fileName.toLatin1().constData());

        xprintf("\n/EF <</F %d 0 R>>\n"
                "/Type/Filespec\n"
                 , attachmentID);
        if (!attachment.mimeType.isEmpty())
            xprintf("/Subtype/%s\n",
                    attachment.mimeType.replace(QLatin1String("/"),
                                                QLatin1String("#2F")).toLatin1().constData());
        xprintf(">>\nendobj\n");
    }

    // names
    addXrefEntry(namesRoot);
    xprintf("<</Names[");
    for (int i = 0; i < size; ++i) {
        auto attachment = fileCache.at(i);
        printString(attachment.fileName);
        xprintf("%d 0 R\n", attachments.at(i));
    }
    xprintf("]>>\n"
            "endobj\n");
}

void QPdfEnginePrivate::embedFont(QFontSubset *font)
{
    //qDebug() << "embedFont" << font->object_id;
    int fontObject = font->object_id;
    QByteArray fontData = font->toTruetype();
#ifdef FONT_DUMP
    static int i = 0;
    QString fileName("font%1.ttf");
    fileName = fileName.arg(i++);
    QFile ff(fileName);
    ff.open(QFile::WriteOnly);
    ff.write(fontData);
    ff.close();
#endif

    int fontDescriptor = requestObject();
    int fontstream = requestObject();
    int cidfont = requestObject();
    int toUnicode = requestObject();
    int cidset = requestObject();

    QFontEngine::Properties properties = font->fontEngine->properties();
    QByteArray postscriptName = properties.postscriptName.replace(' ', '_');

    {
        qreal scale = 1000/properties.emSquare.toReal();
        addXrefEntry(fontDescriptor);
        QByteArray descriptor;
        QPdf::ByteStream s(&descriptor);
        s << "<< /Type /FontDescriptor\n"
            "/FontName /Q";
        int tag = fontDescriptor;
        for (int i = 0; i < 5; ++i) {
            s << (char)('A' + (tag % 26));
            tag /= 26;
        }
        s <<  '+' << postscriptName << "\n"
            "/Flags " << 4 << "\n"
            "/FontBBox ["
          << properties.boundingBox.x()*scale
          << -(properties.boundingBox.y() + properties.boundingBox.height())*scale
          << (properties.boundingBox.x() + properties.boundingBox.width())*scale
          << -properties.boundingBox.y()*scale  << "]\n"
            "/ItalicAngle " << properties.italicAngle.toReal() << "\n"
            "/Ascent " << properties.ascent.toReal()*scale << "\n"
            "/Descent " << -properties.descent.toReal()*scale << "\n"
            "/CapHeight " << properties.capHeight.toReal()*scale << "\n"
            "/StemV " << properties.lineWidth.toReal()*scale << "\n"
            "/FontFile2 " << fontstream << "0 R\n"
            "/CIDSet " << cidset << "0 R\n"
            ">>\nendobj\n";
        write(descriptor);
    }
    {
        addXrefEntry(fontstream);
        QByteArray header;
        QPdf::ByteStream s(&header);

        int length_object = requestObject();
        s << "<<\n"
            "/Length1 " << fontData.size() << "\n"
            "/Length " << length_object << "0 R\n";
        if (do_compress)
            s << "/Filter /FlateDecode\n";
        s << ">>\n"
            "stream\n";
        write(header);
        int len = writeCompressed(fontData);
        write("\nendstream\n"
              "endobj\n");
        addXrefEntry(length_object);
        xprintf("%d\n"
                "endobj\n", len);
    }
    {
        addXrefEntry(cidfont);
        QByteArray cid;
        QPdf::ByteStream s(&cid);
        s << "<< /Type /Font\n"
            "/Subtype /CIDFontType2\n"
            "/BaseFont /" << postscriptName << "\n"
            "/CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>\n"
            "/FontDescriptor " << fontDescriptor << "0 R\n"
            "/CIDToGIDMap /Identity\n"
          << font->widthArray() <<
            ">>\n"
            "endobj\n";
        write(cid);
    }
    {
        addXrefEntry(toUnicode);
        QByteArray touc = font->createToUnicodeMap();
        xprintf("<< /Length %d >>\n"
                "stream\n", touc.length());
        write(touc);
        write("\nendstream\n"
              "endobj\n");
    }
    {
        addXrefEntry(fontObject);
        QByteArray font;
        QPdf::ByteStream s(&font);
        s << "<< /Type /Font\n"
            "/Subtype /Type0\n"
            "/BaseFont /" << postscriptName << "\n"
            "/Encoding /Identity-H\n"
            "/DescendantFonts [" << cidfont << "0 R]\n"
            "/ToUnicode " << toUnicode << "0 R"
            ">>\n"
            "endobj\n";
        write(font);
    }
    {
        QByteArray cidSetStream(font->nGlyphs() / 8 + 1, 0);
        int byteCounter = 0;
        int bitCounter = 0;
        for (int i = 0; i < font->nGlyphs(); ++i) {
            cidSetStream.data()[byteCounter] |= (1 << (7 - bitCounter));

            bitCounter++;
            if (bitCounter == 8) {
                bitCounter = 0;
                byteCounter++;
            }
        }

        addXrefEntry(cidset);
        xprintf("<<\n");
        xprintf("/Length %d\n", cidSetStream.size());
        xprintf(">>\n");
        xprintf("stream\n");
        write(cidSetStream);
        xprintf("\nendstream\n");
        xprintf("endobj\n");
    }
}

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()
{
    for (QHash<QFontEngine::FaceId, QFontSubset *>::iterator it = fonts.begin(); it != fonts.end(); ++it) {
        embedFont(*it);
        delete *it;
    }
    fonts.clear();
}

void QPdfEnginePrivate::writePage()
{
    if (pages.empty())
        return;

    *currentPage << "Q Q\n";

    uint pageStream = requestObject();
    uint pageStreamLength = requestObject();
    uint resources = requestObject();
    uint annots = requestObject();

    qreal userUnit = calcUserUnit();

    addXrefEntry(pages.constLast());
    xprintf("<<\n"
            "/Type /Page\n"
            "/Parent %d 0 R\n"
            "/Contents %d 0 R\n"
            "/Resources %d 0 R\n"
            "/Annots %d 0 R\n"
            "/MediaBox [0 0 %s %s]\n",
            pageRoot, pageStream, resources, annots,
            // make sure we use the pagesize from when we started the page, since the user may have changed it
            QByteArray::number(currentPage->pageSize.width() / userUnit, 'f').constData(),
            QByteArray::number(currentPage->pageSize.height() / userUnit, 'f').constData());

    if (pdfVersion >= QPdfEngine::Version_1_6)
        xprintf("/UserUnit %s\n", QByteArray::number(userUnit, 'f').constData());

    xprintf(">>\n"
            "endobj\n");

    addXrefEntry(resources);
    xprintf("<<\n"
            "/ColorSpace <<\n"
            "/PCSp %d 0 R\n"
            "/CSp /DeviceRGB\n"
            "/CSpg /DeviceGray\n"
            ">>\n"
            "/ExtGState <<\n"
            "/GSa %d 0 R\n",
            patternColorSpace, graphicsState);

    for (int i = 0; i < currentPage->graphicStates.size(); ++i)
        xprintf("/GState%d %d 0 R\n", currentPage->graphicStates.at(i), currentPage->graphicStates.at(i));
    xprintf(">>\n");

    xprintf("/Pattern <<\n");
    for (int i = 0; i < currentPage->patterns.size(); ++i)
        xprintf("/Pat%d %d 0 R\n", currentPage->patterns.at(i), currentPage->patterns.at(i));
    xprintf(">>\n");

    xprintf("/Font <<\n");
    for (int i = 0; i < currentPage->fonts.size();++i)
        xprintf("/F%d %d 0 R\n", currentPage->fonts[i], currentPage->fonts[i]);
    xprintf(">>\n");

    xprintf("/XObject <<\n");
    for (int i = 0; i<currentPage->images.size(); ++i) {
        xprintf("/Im%d %d 0 R\n", currentPage->images.at(i), currentPage->images.at(i));
    }
    xprintf(">>\n");

    xprintf(">>\n"
            "endobj\n");

    addXrefEntry(annots);
    xprintf("[ ");
    for (int i = 0; i<currentPage->annotations.size(); ++i) {
        xprintf("%d 0 R ", currentPage->annotations.at(i));
    }
    xprintf("]\nendobj\n");

    addXrefEntry(pageStream);
    xprintf("<<\n"
            "/Length %d 0 R\n", pageStreamLength); // object number for stream length object
    if (do_compress)
        xprintf("/Filter /FlateDecode\n");

    xprintf(">>\n");
    xprintf("stream\n");
    QIODevice *content = currentPage->stream();
    int len = writeCompressed(content);
    xprintf("\nendstream\n"
            "endobj\n");

    addXrefEntry(pageStreamLength);
    xprintf("%d\nendobj\n",len);
}

void QPdfEnginePrivate::writeTail()
{
    writePage();
    writeFonts();
    writePageRoot();
    writeAttachmentRoot();

    addXrefEntry(xrefPositions.size(),false);
    xprintf("xref\n"
            "0 %d\n"
            "%010d 65535 f \n", xrefPositions.size()-1, xrefPositions[0]);

    for (int i = 1; i < xrefPositions.size()-1; ++i)
        xprintf("%010d 00000 n \n", xrefPositions[i]);

    {
        QByteArray trailer;
        QPdf::ByteStream s(&trailer);

        s << "trailer\n"
          << "<<\n"
          << "/Size " << xrefPositions.size() - 1 << "\n"
          << "/Info " << info << "0 R\n"
          << "/Root " << catalog << "0 R\n";

        if (pdfVersion == QPdfEngine::Version_A1b) {
            const QString uniqueId = QUuid::createUuid().toString();
            const QByteArray fileIdentifier = QCryptographicHash::hash(uniqueId.toLatin1(), QCryptographicHash::Md5).toHex();
            s << "/ID [ <" << fileIdentifier << "> <" << fileIdentifier << "> ]\n";
        }

        s << ">>\n"
          << "startxref\n" << xrefPositions.constLast() << "\n"
          << "%%EOF\n";

        write(trailer);
    }
}

int QPdfEnginePrivate::addXrefEntry(int object, bool printostr)
{
    if (object < 0)
        object = requestObject();

    if (object>=xrefPositions.size())
        xrefPositions.resize(object+1);

    xrefPositions[object] = streampos;
    if (printostr)
        xprintf("%d 0 obj\n",object);

    return object;
}

void QPdfEnginePrivate::printString(const QString &string)
{
    if (string.isEmpty()) {
        write("()");
        return;
    }

    // The 'text string' type in PDF is encoded either as PDFDocEncoding, or
    // Unicode UTF-16 with a Unicode byte order mark as the first character
    // (0xfeff), with the high-order byte first.
    QByteArray array("(\xfe\xff");
    const ushort *utf16 = string.utf16();

    for (int i=0; i < string.size(); ++i) {
        char part[2] = {char((*(utf16 + i)) >> 8), char((*(utf16 + i)) & 0xff)};
        for(int j=0; j < 2; ++j) {
            if (part[j] == '(' || part[j] == ')' || part[j] == '\\')
                array.append('\\');
            array.append(part[j]);
        }
    }
    array.append(')');
    write(array);
}


void QPdfEnginePrivate::xprintf(const char* fmt, ...)
{
    if (!stream)
        return;

    const int msize = 10000;
    char buf[msize];

    va_list args;
    va_start(args, fmt);
    int bufsize = qvsnprintf(buf, msize, fmt, args);
    va_end(args);

    if (Q_LIKELY(bufsize < msize)) {
        stream->writeRawData(buf, bufsize);
    } else {
        // Fallback for abnormal cases
        QScopedArrayPointer<char> tmpbuf(new char[bufsize + 1]);
        va_start(args, fmt);
        bufsize = qvsnprintf(tmpbuf.data(), bufsize + 1, fmt, args);
        va_end(args);
        stream->writeRawData(tmpbuf.data(), bufsize);
    }
    streampos += bufsize;
}

int QPdfEnginePrivate::writeCompressed(QIODevice *dev)
{
#ifndef QT_NO_COMPRESS
    if (do_compress) {
        int size = QPdfPage::chunkSize();
        int sum = 0;
        ::z_stream zStruct;
        zStruct.zalloc = Z_NULL;
        zStruct.zfree = Z_NULL;
        zStruct.opaque = Z_NULL;
        if (::deflateInit(&zStruct, Z_DEFAULT_COMPRESSION) != Z_OK) {
            qWarning("QPdfStream::writeCompressed: Error in deflateInit()");
            return sum;
        }
        zStruct.avail_in = 0;
        QByteArray in, out;
        out.resize(size);
        while (!dev->atEnd() || zStruct.avail_in != 0) {
            if (zStruct.avail_in == 0) {
                in = dev->read(size);
                zStruct.avail_in = in.size();
                zStruct.next_in = reinterpret_cast<unsigned char*>(in.data());
                if (in.size() <= 0) {
                    qWarning("QPdfStream::writeCompressed: Error in read()");
                    ::deflateEnd(&zStruct);
                    return sum;
                }
            }
            zStruct.next_out = reinterpret_cast<unsigned char*>(out.data());
            zStruct.avail_out = out.size();
            if (::deflate(&zStruct, 0) != Z_OK) {
                qWarning("QPdfStream::writeCompressed: Error in deflate()");
                ::deflateEnd(&zStruct);
                return sum;
            }
            int written = out.size() - zStruct.avail_out;
            stream->writeRawData(out.constData(), written);
            streampos += written;
            sum += written;
        }
        int ret;
        do {
            zStruct.next_out = reinterpret_cast<unsigned char*>(out.data());
            zStruct.avail_out = out.size();
            ret = ::deflate(&zStruct, Z_FINISH);
            if (ret != Z_OK && ret != Z_STREAM_END) {
                qWarning("QPdfStream::writeCompressed: Error in deflate()");
                ::deflateEnd(&zStruct);
                return sum;
            }
            int written = out.size() - zStruct.avail_out;
            stream->writeRawData(out.constData(), written);
            streampos += written;
            sum += written;
        } while (ret == Z_OK);

        ::deflateEnd(&zStruct);

        return sum;
    } else
#endif
    {
        QByteArray arr;
        int sum = 0;
        while (!dev->atEnd()) {
            arr = dev->read(QPdfPage::chunkSize());
            stream->writeRawData(arr.constData(), arr.size());
            streampos += arr.size();
            sum += arr.size();
        }
        return sum;
    }
}

int QPdfEnginePrivate::writeCompressed(const char *src, int len)
{
#ifndef QT_NO_COMPRESS
    if(do_compress) {
        uLongf destLen = len + len/100 + 13; // zlib requirement
        Bytef* dest = new Bytef[destLen];
        if (Z_OK == ::compress(dest, &destLen, (const Bytef*) src, (uLongf)len)) {
            stream->writeRawData((const char*)dest, destLen);
        } else {
            qWarning("QPdfStream::writeCompressed: Error in compress()");
            destLen = 0;
        }
        delete [] dest;
        len = destLen;
    } else
#endif
    {
        stream->writeRawData(src,len);
    }
    streampos += len;
    return len;
}

int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height, int depth,
                                  int maskObject, int softMaskObject, bool dct, bool isMono)
{
    int image = addXrefEntry(-1);
    xprintf("<<\n"
            "/Type /XObject\n"
            "/Subtype /Image\n"
            "/Width %d\n"
            "/Height %d\n", width, height);

    if (depth == 1) {
        if (!isMono) {
            xprintf("/ImageMask true\n"
                    "/Decode [1 0]\n");
        } else {
            xprintf("/BitsPerComponent 1\n"
                    "/ColorSpace /DeviceGray\n");
        }
    } else {
        xprintf("/BitsPerComponent 8\n"
                "/ColorSpace %s\n", (depth == 32) ? "/DeviceRGB" : "/DeviceGray");
    }
    if (maskObject > 0)
        xprintf("/Mask %d 0 R\n", maskObject);
    if (softMaskObject > 0)
        xprintf("/SMask %d 0 R\n", softMaskObject);

    int lenobj = requestObject();
    xprintf("/Length %d 0 R\n", lenobj);
    if (interpolateImages)
        xprintf("/Interpolate true\n");
    int len = 0;
    if (dct) {
        //qDebug("DCT");
        xprintf("/Filter /DCTDecode\n>>\nstream\n");
        write(data);
        len = data.length();
    } else {
        if (do_compress)
            xprintf("/Filter /FlateDecode\n>>\nstream\n");
        else
            xprintf(">>\nstream\n");
        len = writeCompressed(data);
    }
    xprintf("\nendstream\n"
            "endobj\n");
    addXrefEntry(lenobj);
    xprintf("%d\n"
            "endobj\n", len);
    return image;
}

struct QGradientBound {
    qreal start;
    qreal stop;
    int function;
    bool reverse;
};
Q_DECLARE_TYPEINFO(QGradientBound, Q_PRIMITIVE_TYPE);

int QPdfEnginePrivate::createShadingFunction(const QGradient *gradient, int from, int to, bool reflect, bool alpha)
{
    QGradientStops stops = gradient->stops();
    if (stops.isEmpty()) {
        stops << QGradientStop(0, Qt::black);
        stops << QGradientStop(1, Qt::white);
    }
    if (stops.at(0).first > 0)
        stops.prepend(QGradientStop(0, stops.at(0).second));
    if (stops.at(stops.size() - 1).first < 1)
        stops.append(QGradientStop(1, stops.at(stops.size() - 1).second));

    QVector<int> functions;
    const int numStops = stops.size();
    functions.reserve(numStops - 1);
    for (int i = 0; i < numStops - 1; ++i) {
        int f = addXrefEntry(-1);
        QByteArray data;
        QPdf::ByteStream s(&data);
        s << "<<\n"
             "/FunctionType 2\n"
             "/Domain [0 1]\n"
             "/N 1\n";
        if (alpha) {
            s << "/C0 [" << stops.at(i).second.alphaF() << "]\n"
                 "/C1 [" << stops.at(i + 1).second.alphaF() << "]\n";
        } else {
            s << "/C0 [" << stops.at(i).second.redF() << stops.at(i).second.greenF() <<  stops.at(i).second.blueF() << "]\n"
                 "/C1 [" << stops.at(i + 1).second.redF() << stops.at(i + 1).second.greenF() <<  stops.at(i + 1).second.blueF() << "]\n";
        }
        s << ">>\n"
             "endobj\n";
        write(data);
        functions << f;
    }

    QVector<QGradientBound> gradientBounds;
    gradientBounds.reserve((to - from) * (numStops - 1));

    for (int step = from; step < to; ++step) {
        if (reflect && step % 2) {
            for (int i = numStops - 1; i > 0; --i) {
                QGradientBound b;
                b.start = step + 1 - qBound(qreal(0.), stops.at(i).first, qreal(1.));
                b.stop = step + 1 - qBound(qreal(0.), stops.at(i - 1).first, qreal(1.));
                b.function = functions.at(i - 1);
                b.reverse = true;
                gradientBounds << b;
            }
        } else {
            for (int i = 0; i < numStops - 1; ++i) {
                QGradientBound b;
                b.start = step + qBound(qreal(0.), stops.at(i).first, qreal(1.));
                b.stop = step + qBound(qreal(0.), stops.at(i + 1).first, qreal(1.));
                b.function = functions.at(i);
                b.reverse = false;
                gradientBounds << b;
            }
        }
    }

    // normalize bounds to [0..1]
    qreal bstart = gradientBounds.at(0).start;
    qreal bend = gradientBounds.at(gradientBounds.size() - 1).stop;
    qreal norm = 1./(bend - bstart);
    for (int i = 0; i < gradientBounds.size(); ++i) {
        gradientBounds[i].start = (gradientBounds[i].start - bstart)*norm;
        gradientBounds[i].stop = (gradientBounds[i].stop - bstart)*norm;
    }

    int function;
    if (gradientBounds.size() > 1) {
        function = addXrefEntry(-1);
        QByteArray data;
        QPdf::ByteStream s(&data);
        s << "<<\n"
             "/FunctionType 3\n"
             "/Domain [0 1]\n"
             "/Bounds [";
        for (int i = 1; i < gradientBounds.size(); ++i)
            s << gradientBounds.at(i).start;
        s << "]\n"
             "/Encode [";
        for (int i = 0; i < gradientBounds.size(); ++i)
            s << (gradientBounds.at(i).reverse ? "1 0 " : "0 1 ");
        s << "]\n"
             "/Functions [";
        for (int i = 0; i < gradientBounds.size(); ++i)
            s << gradientBounds.at(i).function << "0 R ";
        s << "]\n"
             ">>\n"
             "endobj\n";
        write(data);
    } else {
        function = functions.at(0);
    }
    return function;
}

int QPdfEnginePrivate::generateLinearGradientShader(const QLinearGradient *gradient, const QTransform &matrix, bool alpha)
{
    QPointF start = gradient->start();
    QPointF stop = gradient->finalStop();
    QPointF offset = stop - start;
    Q_ASSERT(gradient->coordinateMode() == QGradient::LogicalMode);

    int from = 0;
    int to = 1;
    bool reflect = false;
    switch (gradient->spread()) {
    case QGradient::PadSpread:
        break;
    case QGradient::ReflectSpread:
        reflect = true;
        Q_FALLTHROUGH();
    case QGradient::RepeatSpread: {
        // calculate required bounds
        QRectF pageRect = m_pageLayout.fullRectPixels(resolution);
        QTransform inv = matrix.inverted();
        QPointF page_rect[4] = { inv.map(pageRect.topLeft()),
                                 inv.map(pageRect.topRight()),
                                 inv.map(pageRect.bottomLeft()),
                                 inv.map(pageRect.bottomRight()) };

        qreal length = offset.x()*offset.x() + offset.y()*offset.y();

        // find the max and min values in offset and orth direction that are needed to cover
        // the whole page
        from = INT_MAX;
        to = INT_MIN;
        for (int i = 0; i < 4; ++i) {
            qreal off = ((page_rect[i].x() - start.x()) * offset.x() + (page_rect[i].y() - start.y()) * offset.y())/length;
            from = qMin(from, qFloor(off));
            to = qMax(to, qCeil(off));
        }

        stop = start + to * offset;
        start = start + from * offset;\
        break;
    }
    }

    int function = createShadingFunction(gradient, from, to, reflect, alpha);

    QByteArray shader;
    QPdf::ByteStream s(&shader);
    s << "<<\n"
        "/ShadingType 2\n"
        "/ColorSpace " << (alpha ? "/DeviceGray\n" : "/DeviceRGB\n") <<
        "/AntiAlias true\n"
        "/Coords [" << start.x() << start.y() << stop.x() << stop.y() << "]\n"
        "/Extend [true true]\n"
        "/Function " << function << "0 R\n"
        ">>\n"
        "endobj\n";
    int shaderObject = addXrefEntry(-1);
    write(shader);
    return shaderObject;
}

int QPdfEnginePrivate::generateRadialGradientShader(const QRadialGradient *gradient, const QTransform &matrix, bool alpha)
{
    QPointF p1 = gradient->center();
    qreal r1 = gradient->centerRadius();
    QPointF p0 = gradient->focalPoint();
    qreal r0 = gradient->focalRadius();

    Q_ASSERT(gradient->coordinateMode() == QGradient::LogicalMode);

    int from = 0;
    int to = 1;
    bool reflect = false;
    switch (gradient->spread()) {
    case QGradient::PadSpread:
        break;
    case QGradient::ReflectSpread:
        reflect = true;
        Q_FALLTHROUGH();
    case QGradient::RepeatSpread: {
        Q_ASSERT(qFuzzyIsNull(r0)); // QPainter emulates if this is not 0

        QRectF pageRect = m_pageLayout.fullRectPixels(resolution);
        QTransform inv = matrix.inverted();
        QPointF page_rect[4] = { inv.map(pageRect.topLeft()),
                                 inv.map(pageRect.topRight()),
                                 inv.map(pageRect.bottomLeft()),
                                 inv.map(pageRect.bottomRight()) };

        // increase to until the whole page fits into it
        bool done = false;
        while (!done) {
            QPointF center = QPointF(p0.x() + to*(p1.x() - p0.x()), p0.y() + to*(p1.y() - p0.y()));
            double radius = r0 + to*(r1 - r0);
            double r2 = radius*radius;
            done = true;
            for (int i = 0; i < 4; ++i) {
                QPointF off = page_rect[i] - center;
                if (off.x()*off.x() + off.y()*off.y() > r2) {
                    ++to;
                    done = false;
                    break;
                }
            }
        }
        p1 = QPointF(p0.x() + to*(p1.x() - p0.x()), p0.y() + to*(p1.y() - p0.y()));
        r1 = r0 + to*(r1 - r0);
        break;
    }
    }

    int function = createShadingFunction(gradient, from, to, reflect, alpha);

    QByteArray shader;
    QPdf::ByteStream s(&shader);
    s << "<<\n"
        "/ShadingType 3\n"
        "/ColorSpace " << (alpha ? "/DeviceGray\n" : "/DeviceRGB\n") <<
        "/AntiAlias true\n"
        "/Domain [0 1]\n"
        "/Coords [" << p0.x() << p0.y() << r0 << p1.x() << p1.y() << r1 << "]\n"
        "/Extend [true true]\n"
        "/Function " << function << "0 R\n"
        ">>\n"
        "endobj\n";
    int shaderObject = addXrefEntry(-1);
    write(shader);
    return shaderObject;
}

int QPdfEnginePrivate::generateGradientShader(const QGradient *gradient, const QTransform &matrix, bool alpha)
{
    switch (gradient->type()) {
    case QGradient::LinearGradient:
        return generateLinearGradientShader(static_cast<const QLinearGradient *>(gradient), matrix, alpha);
    case QGradient::RadialGradient:
        return generateRadialGradientShader(static_cast<const QRadialGradient *>(gradient), matrix, alpha);
    case QGradient::ConicalGradient:
        Q_UNIMPLEMENTED(); // ### Implement me!
        break;
    case QGradient::NoGradient:
        break;
    }
    return 0;
}

int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QTransform &matrix, int *gStateObject)
{
    const QGradient *gradient = b.gradient();

    if (!gradient || gradient->coordinateMode() != QGradient::LogicalMode)
        return 0;

    QRectF pageRect = m_pageLayout.fullRectPixels(resolution);

    QTransform m = b.transform() * matrix;
    int shaderObject = generateGradientShader(gradient, m);

    QByteArray str;
    QPdf::ByteStream s(&str);
    s << "<<\n"
        "/Type /Pattern\n"
        "/PatternType 2\n"
        "/Shading " << shaderObject << "0 R\n"
        "/Matrix ["
      << m.m11()
      << m.m12()
      << m.m21()
      << m.m22()
      << m.dx()
      << m.dy() << "]\n";
    s << ">>\n"
        "endobj\n";

    int patternObj = addXrefEntry(-1);
    write(str);
    currentPage->patterns.append(patternObj);

    if (!b.isOpaque()) {
        bool ca = true;
        QGradientStops stops = gradient->stops();
        int a = stops.at(0).second.alpha();
        for (int i = 1; i < stops.size(); ++i) {
            if (stops.at(i).second.alpha() != a) {
                ca = false;
                break;
            }
        }
        if (ca) {
            *gStateObject = addConstantAlphaObject(stops.at(0).second.alpha());
        } else {
            int alphaShaderObject = generateGradientShader(gradient, m, true);

            QByteArray content;
            QPdf::ByteStream c(&content);
            c << "/Shader" << alphaShaderObject << "sh\n";

            QByteArray form;
            QPdf::ByteStream f(&form);
            f << "<<\n"
                "/Type /XObject\n"
                "/Subtype /Form\n"
                "/BBox [0 0 " << pageRect.width() << pageRect.height() << "]\n"
                "/Group <</S /Transparency >>\n"
                "/Resources <<\n"
                "/Shading << /Shader" << alphaShaderObject << alphaShaderObject << "0 R >>\n"
                ">>\n";

            f << "/Length " << content.length() << "\n"
                ">>\n"
                "stream\n"
              << content
              << "\nendstream\n"
                "endobj\n";

            int softMaskFormObject = addXrefEntry(-1);
            write(form);
            *gStateObject = addXrefEntry(-1);
            xprintf("<< /SMask << /S /Alpha /G %d 0 R >> >>\n"
                    "endobj\n", softMaskFormObject);
            currentPage->graphicStates.append(*gStateObject);
        }
    }

    return patternObj;
}

int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha)
{
    if (brushAlpha == 255 && penAlpha == 255)
        return 0;
    int object = alphaCache.value(QPair<uint, uint>(brushAlpha, penAlpha), 0);
    if (!object) {
        object = addXrefEntry(-1);
        QByteArray alphaDef;
        QPdf::ByteStream s(&alphaDef);
        s << "<<\n/ca " << (brushAlpha/qreal(255.)) << '\n';
        s << "/CA " << (penAlpha/qreal(255.)) << "\n>>";
        xprintf("%s\nendobj\n", alphaDef.constData());
        alphaCache.insert(QPair<uint, uint>(brushAlpha, penAlpha), object);
    }
    if (currentPage->graphicStates.indexOf(object) < 0)
        currentPage->graphicStates.append(object);

    return object;
}


int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, int *gStateObject)
{
    Q_Q(QPdfEngine);

    int paintType = 2; // Uncolored tiling
    int w = 8;
    int h = 8;

    *specifyColor = true;
    *gStateObject = 0;

    QTransform matrix = m;
    matrix.translate(brushOrigin.x(), brushOrigin.y());
    matrix = matrix * pageMatrix();
    //qDebug() << brushOrigin << matrix;

    Qt::BrushStyle style = brush.style();
    if (style == Qt::LinearGradientPattern || style == Qt::RadialGradientPattern) {// && style <= Qt::ConicalGradientPattern) {
        *specifyColor = false;
        return gradientBrush(brush, matrix, gStateObject);
    }

    if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
        *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
                                               qRound(pen.color().alpha() * opacity));

    int imageObject = -1;
    QByteArray pattern = QPdf::patternForBrush(brush);
    if (pattern.isEmpty()) {
        if (brush.style() != Qt::TexturePattern)
            return 0;
        QImage image = brush.textureImage();
        bool bitmap = true;
        const bool lossless = q->painter()->testRenderHint(QPainter::LosslessImageRendering);
        imageObject = addImage(image, &bitmap, lossless, image.cacheKey());
        if (imageObject != -1) {
            QImage::Format f = image.format();
            if (f != QImage::Format_MonoLSB && f != QImage::Format_Mono) {
                paintType = 1; // Colored tiling
                *specifyColor = false;
            }
            w = image.width();
            h = image.height();
            QTransform m(w, 0, 0, -h, 0, h);
            QPdf::ByteStream s(&pattern);
            s << QPdf::generateMatrix(m);
            s << "/Im" << imageObject << " Do\n";
        }
    }

    QByteArray str;
    QPdf::ByteStream s(&str);
    s << "<<\n"
        "/Type /Pattern\n"
        "/PatternType 1\n"
        "/PaintType " << paintType << "\n"
        "/TilingType 1\n"
        "/BBox [0 0 " << w << h << "]\n"
        "/XStep " << w << "\n"
        "/YStep " << h << "\n"
        "/Matrix ["
      << matrix.m11()
      << matrix.m12()
      << matrix.m21()
      << matrix.m22()
      << matrix.dx()
      << matrix.dy() << "]\n"
        "/Resources \n<< "; // open resource tree
    if (imageObject > 0) {
        s << "/XObject << /Im" << imageObject << ' ' << imageObject << "0 R >> ";
    }
    s << ">>\n"
        "/Length " << pattern.length() << "\n"
        ">>\n"
        "stream\n"
      << pattern
      << "\nendstream\n"
        "endobj\n";

    int patternObj = addXrefEntry(-1);
    write(str);
    currentPage->patterns.append(patternObj);
    return patternObj;
}

static inline bool is_monochrome(const QVector<QRgb> &colorTable)
{
    return colorTable.size() == 2
        && colorTable.at(0) == QColor(Qt::black).rgba()
        && colorTable.at(1) == QColor(Qt::white).rgba()
        ;
}

/*!
 * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
 */
int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, bool lossless, qint64 serial_no)
{
    if (img.isNull())
        return -1;

    int object = imageCache.value(serial_no);
    if(object)
        return object;

    QImage image = img;
    QImage::Format format = image.format();

    if (pdfVersion == QPdfEngine::Version_A1b) {
        if (image.hasAlphaChannel()) {
            // transparent images are not allowed in PDF/A-1b, so we convert it to
            // a format without alpha channel first

            QImage alphaLessImage(image.width(), image.height(), QImage::Format_RGB32);
            alphaLessImage.fill(Qt::white);

            QPainter p(&alphaLessImage);
            p.drawImage(0, 0, image);

            image = alphaLessImage;
            format = image.format();
        }
    }

    if (image.depth() == 1 && *bitmap && is_monochrome(img.colorTable())) {
        if (format == QImage::Format_MonoLSB)
            image = image.convertToFormat(QImage::Format_Mono);
        format = QImage::Format_Mono;
    } else {
        *bitmap = false;
        if (format != QImage::Format_RGB32 && format != QImage::Format_ARGB32) {
            image = image.convertToFormat(QImage::Format_ARGB32);
            format = QImage::Format_ARGB32;
        }
    }

    int w = image.width();
    int h = image.height();
    int d = image.depth();

    if (format == QImage::Format_Mono) {
        int bytesPerLine = (w + 7) >> 3;
        QByteArray data;
        data.resize(bytesPerLine * h);
        char *rawdata = data.data();
        for (int y = 0; y < h; ++y) {
            memcpy(rawdata, image.constScanLine(y), bytesPerLine);
            rawdata += bytesPerLine;
        }
        object = writeImage(data, w, h, d, 0, 0, false, is_monochrome(img.colorTable()));
    } else {
        QByteArray softMaskData;
        bool dct = false;
        QByteArray imageData;
        bool hasAlpha = false;
        bool hasMask = false;

        if (QImageWriter::supportedImageFormats().contains("jpeg") && !grayscale && !lossless) {
            QBuffer buffer(&imageData);
            QImageWriter writer(&buffer, "jpeg");
            writer.setQuality(94);
            writer.write(image);
            dct = true;

            if (format != QImage::Format_RGB32) {
                softMaskData.resize(w * h);
                uchar *sdata = (uchar *)softMaskData.data();
                for (int y = 0; y < h; ++y) {
                    const QRgb *rgb = (const QRgb *)image.constScanLine(y);
                    for (int x = 0; x < w; ++x) {
                        uchar alpha = qAlpha(*rgb);
                        *sdata++ = alpha;
                        hasMask |= (alpha < 255);
                        hasAlpha |= (alpha != 0 && alpha != 255);
                        ++rgb;
                    }
                }
            }
        } else {
            imageData.resize(grayscale ? w * h : 3 * w * h);
            uchar *data = (uchar *)imageData.data();
            softMaskData.resize(w * h);
            uchar *sdata = (uchar *)softMaskData.data();
            for (int y = 0; y < h; ++y) {
                const QRgb *rgb = (const QRgb *)image.constScanLine(y);
                if (grayscale) {
                    for (int x = 0; x < w; ++x) {
                        *(data++) = qGray(*rgb);
                        uchar alpha = qAlpha(*rgb);
                        *sdata++ = alpha;
                        hasMask |= (alpha < 255);
                        hasAlpha |= (alpha != 0 && alpha != 255);
                        ++rgb;
                    }
                } else {
                    for (int x = 0; x < w; ++x) {
                        *(data++) = qRed(*rgb);
                        *(data++) = qGreen(*rgb);
                        *(data++) = qBlue(*rgb);
                        uchar alpha = qAlpha(*rgb);
                        *sdata++ = alpha;
                        hasMask |= (alpha < 255);
                        hasAlpha |= (alpha != 0 && alpha != 255);
                        ++rgb;
                    }
                }
            }
            if (format == QImage::Format_RGB32)
                hasAlpha = hasMask = false;
        }
        int maskObject = 0;
        int softMaskObject = 0;
        if (hasAlpha) {
            softMaskObject = writeImage(softMaskData, w, h, 8, 0, 0);
        } else if (hasMask) {
            // dither the soft mask to 1bit and add it. This also helps PDF viewers
            // without transparency support
            int bytesPerLine = (w + 7) >> 3;
            QByteArray mask(bytesPerLine * h, 0);
            uchar *mdata = (uchar *)mask.data();
            const uchar *sdata = (const uchar *)softMaskData.constData();
            for (int y = 0; y < h; ++y) {
                for (int x = 0; x < w; ++x) {
                    if (*sdata)
                        mdata[x>>3] |= (0x80 >> (x&7));
                    ++sdata;
                }
                mdata += bytesPerLine;
            }
            maskObject = writeImage(mask, w, h, 1, 0, 0);
        }
        object = writeImage(imageData, w, h, grayscale ? 8 : 32,
                            maskObject, softMaskObject, dct);
    }
    imageCache.insert(serial_no, object);
    return object;
}

void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)
{
    Q_Q(QPdfEngine);

    if (ti.charFormat.isAnchor()) {
        qreal size = ti.fontEngine->fontDef.pixelSize;
        int synthesized = ti.fontEngine->synthesized();
        qreal stretch = synthesized & QFontEngine::SynthesizedStretch ? ti.fontEngine->fontDef.stretch/100. : 1.;
        Q_ASSERT(stretch > qreal(0));

        QTransform trans;
        // Build text rendering matrix (Trm). We need it to map the text area to user
        // space units on the PDF page.
        trans = QTransform(size*stretch, 0, 0, size, 0, 0);
        // Apply text matrix (Tm).
        trans *= QTransform(1,0,0,-1,p.x(),p.y());
        // Apply page displacement (Identity for first page).
        trans *= stroker.matrix;
        // Apply Current Transformation Matrix (CTM)
        trans *= pageMatrix();
        qreal x1, y1, x2, y2;
        trans.map(0, 0, &x1, &y1);
        trans.map(ti.width.toReal()/size, (ti.ascent.toReal()-ti.descent.toReal())/size, &x2, &y2);

        uint annot = addXrefEntry(-1);
        QByteArray x1s, y1s, x2s, y2s;
        x1s.setNum(static_cast<double>(x1), 'f');
        y1s.setNum(static_cast<double>(y1), 'f');
        x2s.setNum(static_cast<double>(x2), 'f');
        y2s.setNum(static_cast<double>(y2), 'f');
        QByteArray rectData = x1s + ' ' + y1s + ' ' + x2s + ' ' + y2s;
        xprintf("<<\n/Type /Annot\n/Subtype /Link\n");

        if (pdfVersion == QPdfEngine::Version_A1b)
            xprintf("/F 4\n"); // enable print flag, disable all other

        xprintf("/Rect [");
        xprintf(rectData.constData());
#ifdef Q_DEBUG_PDF_LINKS
        xprintf("]\n/Border [16 16 1]\n/A <<\n");
#else
        xprintf("]\n/Border [0 0 0]\n/A <<\n");
#endif
        xprintf("/Type /Action\n/S /URI\n/URI (%s)\n",
                ti.charFormat.anchorHref().toLatin1().constData());
        xprintf(">>\n>>\n");
        xprintf("endobj\n");

        if (!currentPage->annotations.contains(annot)) {
            currentPage->annotations.append(annot);
        }
    }

    QFontEngine *fe = ti.fontEngine;

    QFontEngine::FaceId face_id = fe->faceId();
    bool noEmbed = false;
    if (!embedFonts
        || face_id.filename.isEmpty()
        || fe->fsType & 0x200 /* bitmap embedding only */
        || fe->fsType == 2 /* no embedding allowed */) {
        *currentPage << "Q\n";
        q->QPaintEngine::drawTextItem(p, ti);
        *currentPage << "q\n";
        if (face_id.filename.isEmpty())
            return;
        noEmbed = true;
    }

    QFontSubset *font = fonts.value(face_id, 0);
    if (!font) {
        font = new QFontSubset(fe, requestObject());
        font->noEmbed = noEmbed;
    }
    fonts.insert(face_id, font);

    if (!currentPage->fonts.contains(font->object_id))
        currentPage->fonts.append(font->object_id);

    qreal size = ti.fontEngine->fontDef.pixelSize;

    QVarLengthArray<glyph_t> glyphs;
    QVarLengthArray<QFixedPoint> positions;
    QTransform m = QTransform::fromTranslate(p.x(), p.y());
    ti.fontEngine->getGlyphPositions(ti.glyphs, m, ti.flags,
                                     glyphs, positions);
    if (glyphs.size() == 0)
        return;
    int synthesized = ti.fontEngine->synthesized();
    qreal stretch = synthesized & QFontEngine::SynthesizedStretch ? ti.fontEngine->fontDef.stretch/100. : 1.;
    Q_ASSERT(stretch > qreal(0));

    *currentPage << "BT\n"
                 << "/F" << font->object_id << size << "Tf "
                 << stretch << (synthesized & QFontEngine::SynthesizedItalic
                                ? "0 .3 -1 0 0 Tm\n"
                                : "0 0 -1 0 0 Tm\n");


#if 0
    // #### implement actual text for complex languages
    const unsigned short *logClusters = ti.logClusters;
    int pos = 0;
    do {
        int end = pos + 1;
        while (end < ti.num_chars && logClusters[end] == logClusters[pos])
            ++end;
        *currentPage << "/Span << /ActualText <FEFF";
        for (int i = pos; i < end; ++i) {
            s << toHex((ushort)ti.chars[i].unicode(), buf);
        }
        *currentPage << "> >>\n"
            "BDC\n"
            "<";
        int ge = end == ti.num_chars ? ti.num_glyphs : logClusters[end];
        for (int gs = logClusters[pos]; gs < ge; ++gs)
            *currentPage << toHex((ushort)ti.glyphs[gs].glyph, buf);
        *currentPage << "> Tj\n"
            "EMC\n";
        pos = end;
    } while (pos < ti.num_chars);
#else
    qreal last_x = 0.;
    qreal last_y = 0.;
    for (int i = 0; i < glyphs.size(); ++i) {
        qreal x = positions[i].x.toReal();
        qreal y = positions[i].y.toReal();
        if (synthesized & QFontEngine::SynthesizedItalic)
            x += .3*y;
        x /= stretch;
        char buf[5];
        int g = font->addGlyph(glyphs[i]);
        *currentPage << x - last_x << last_y - y << "Td <"
                     << QPdf::toHex((ushort)g, buf) << "> Tj\n";
        last_x = x;
        last_y = y;
    }
    if (synthesized & QFontEngine::SynthesizedBold) {
        *currentPage << stretch << (synthesized & QFontEngine::SynthesizedItalic
                            ? "0 .3 -1 0 0 Tm\n"
                            : "0 0 -1 0 0 Tm\n");
        *currentPage << "/Span << /ActualText <> >> BDC\n";
        last_x = 0.5*fe->lineThickness().toReal();
        last_y = 0.;
        for (int i = 0; i < glyphs.size(); ++i) {
            qreal x = positions[i].x.toReal();
            qreal y = positions[i].y.toReal();
            if (synthesized & QFontEngine::SynthesizedItalic)
                x += .3*y;
            x /= stretch;
            char buf[5];
            int g = font->addGlyph(glyphs[i]);
            *currentPage << x - last_x << last_y - y << "Td <"
                        << QPdf::toHex((ushort)g, buf) << "> Tj\n";
            last_x = x;
            last_y = y;
        }
        *currentPage << "EMC\n";
    }
#endif

    *currentPage << "ET\n";
}

QTransform QPdfEnginePrivate::pageMatrix() const
{
    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());
    }
    return tmp;
}

void QPdfEnginePrivate::newPage()
{
    if (currentPage && currentPage->pageSize.isEmpty())
        currentPage->pageSize = m_pageLayout.fullRectPoints().size();
    writePage();

    delete currentPage;
    currentPage = new QPdfPage;
    currentPage->pageSize = m_pageLayout.fullRectPoints().size();
    stroker.stream = currentPage;
    pages.append(requestObject());

    *currentPage << "/GSa gs /CSp cs /CSp CS\n"
                 << QPdf::generateMatrix(pageMatrix())
                 << "q q\n";
}

QT_END_NAMESPACE

#endif // QT_NO_PDF
