⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qpdf.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
void QPdfBaseEngine::drawRects (const QRectF *rects, int rectCount){    if (!rects)        return;    QPainterPath p;    for (int i=0; i!=rectCount; ++i) {        p.addRect(rects[i]);    }    drawPath(p);}void QPdfBaseEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode){    if (!points || !pointCount)        return;    Q_D(QPdfBaseEngine);    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 QPdfBaseEngine::drawPath (const QPainterPath &p){    Q_D(QPdfBaseEngine);    if (d->clipEnabled && d->allClipped)        return;    QBrush penBrush = d->pen.brush();    if (d->hasPen && penBrush == Qt::SolidPattern && penBrush.isOpaque()) {        // draw strokes natively in this case for better output        *d->currentPage << "q\n";        setPen();        *d->currentPage << QPdf::generateMatrix(d->stroker.matrix);        *d->currentPage << QPdf::generatePath(p, QMatrix(), d->hasBrush ? QPdf::FillAndStrokePath : QPdf::StrokePath);        *d->currentPage << "Q\n";    } 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 QPdfBaseEngine::drawTextItem(const QPointF &p, const QTextItem &textItem){    Q_D(QPdfBaseEngine);    if (!d->hasPen || (d->clipEnabled && d->allClipped))        return;    *d->currentPage << "q " << 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 QPdfBaseEngine::updateState(const QPaintEngineState &state){    Q_D(QPdfBaseEngine);    QPaintEngine::DirtyFlags flags = state.state();    if (flags & DirtyTransform)        d->stroker.matrix = state.matrix();        if (flags & DirtyPen) {        d->pen = state.pen();        d->hasPen = d->pen != Qt::NoPen;        d->stroker.setPen(d->pen);    }    if (flags & DirtyBrush) {        d->brush = state.brush();        d->hasBrush = d->brush != Qt::NoBrush;    }    if (flags & DirtyBrushOrigin) {        d->brushOrigin = state.brushOrigin();        flags |= DirtyBrush;    }    if (flags & DirtyBackground)        d->backgroundBrush = state.backgroundBrush();    if (flags & DirtyBackgroundMode)        d->backgroundMode = state.backgroundMode();    bool ce = d->clipEnabled;    if (flags & DirtyClipPath) {        d->clipEnabled = true;        updateClipPath(state.clipPath(), state.clipOperation());    } else if (flags & DirtyClipRegion) {        d->clipEnabled = true;        QPainterPath path;        QVector<QRect> rects = state.clipRegion().rects();        for (int i = 0; i < rects.size(); ++i)            path.addRect(rects.at(i));        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;    if (flags & DirtyClipPath) {        *d->currentPage << "Q q\n";        flags |= DirtyPen|DirtyBrush;    }    if (flags & DirtyClipPath) {        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), QMatrix(), QPdf::ClipPath);                }            }        }    }    if (flags & DirtyBrush)        setBrush();}void QPdfBaseEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op){    Q_D(QPdfBaseEngine);    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 QPdfBaseEngine::setPen(){    Q_D(QPdfBaseEngine);    QBrush b = d->pen.brush();    Q_ASSERT(b.style() == Qt::SolidPattern && b.isOpaque());    QColor rgba = b.color();    *d->currentPage << rgba.redF()                   << rgba.greenF()                   << rgba.blueF()                   << "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:        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) << " 0 d\n";}QPdfBaseEnginePrivate::QPdfBaseEnginePrivate(){    postscript = false;    currentObject = 1;    currentPage = new QPdfPage;    stroker.stream = currentPage;    backgroundMode = Qt::TransparentMode;}QPdfBaseEnginePrivate::~QPdfBaseEnginePrivate(){    qDeleteAll(fonts);    delete currentPage;}void QPdfBaseEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti){    Q_Q(QPdfBaseEngine);    QFontEngine *fe = ti.fontEngine;    QFontEngine::FaceId face_id = fe->faceId();    bool noEmbed = false;    if (face_id.filename.isEmpty()        || (!postscript && ((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;#ifdef Q_WS_WIN    size = ti.fontEngine->tm.w.tmHeight;#else    size = ti.fontEngine->fontDef.pixelSize;#endif    QVarLengthArray<glyph_t> glyphs;    QVarLengthArray<QFixedPoint> positions;    QMatrix m;    m.translate(p.x(), p.y());    ti.fontEngine->getGlyphPositions(ti.glyphs, ti.num_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.;    if (ti.flags & (QTextItem::Underline|QTextItem::StrikeOut|QTextItem::Overline)) {        qreal lw = fe->lineThickness().toReal();        if (ti.flags & (QTextItem::Underline))            *currentPage << p.x() << (p.y() + fe->underlinePosition().toReal())                           << ti.width.toReal() << lw << "re ";        if (ti.flags & (QTextItem::StrikeOut))            *currentPage  << p.x() << (p.y() - fe->ascent().toReal()/qreal(3.))                            << ti.width.toReal() << lw << "re ";        if (ti.flags & (QTextItem::Overline))            *currentPage  << p.x() << (p.y() - fe->ascent().toReal())                            << ti.width.toReal() << lw << "re ";        *currentPage << "f\n";    }    *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";}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -