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

📄 qpaintengine_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                             QPaintEngine::PolygonDrawMode mode){    int clippedCount = 0;    qt_float_point *clippedPoints = 0;    //can change if we switch to pen if gcMode != BrushGC    bool has_fill_texture = has_texture;    bool has_fill_pattern = has_pattern;#ifndef QT_NO_XRENDER    ::Picture src;#endif    QBrush fill;    GC fill_gc;    if (gcMode == BrushGC) {        fill = cbrush;        fill_gc = gc_brush;#ifndef QT_NO_XRENDER        if (current_brush)            src = current_brush;        else            src = X11->getSolidFill(scrn, fill.color());#endif    } else {        fill = QBrush(cpen.brush());        fill_gc = gc;#ifndef QT_NO_XRENDER        //we use the pens brush        has_fill_texture = (fill.style() == Qt::TexturePattern);        has_fill_pattern = (fill.style() >= Qt::Dense1Pattern && fill.style() <= Qt::DiagCrossPattern);        if (has_fill_texture)            src = fill.texture().x11PictureHandle();        else if (has_fill_pattern)            src = getPatternFill(scrn, fill, bg_brush, bg_mode == Qt::OpaqueMode);        else            src = X11->getSolidFill(scrn, fill.color());#endif    }    polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,                               &clippedPoints, &clippedCount);#if !defined(QT_NO_XRENDER)    bool solid_fill = fill.color().alpha() == 255;    if (has_fill_texture && fill.texture().depth() == 1 && solid_fill) {        has_fill_texture = false;        has_fill_pattern = true;    }    bool antialias = render_hints & QPainter::Antialiasing;    if (X11->use_xrender        && picture        && !has_fill_pattern        && (clippedCount > 0)        && (fill.style() != Qt::NoBrush)        && (has_fill_texture || antialias || !solid_fill || has_alpha_pen != has_alpha_brush))    {        QVector<XTrapezoid> traps;        traps.reserve(128);        QRect br;        qt_tesselate_polygon(&traps, (QPointF *)clippedPoints, clippedCount,                             mode == QPaintEngine::WindingMode, &br);        if (traps.size() > 0) {            XRenderPictureAttributes attrs;            attrs.poly_edge = antialias ? PolyEdgeSmooth : PolyEdgeSharp;            XRenderChangePicture(dpy, picture, CPPolyEdge, &attrs);            if (has_fill_texture) {                if (fill.texture().depth() == 1) {                    for (int i=0; i < traps.size(); ++i) {                        int x_offset = int(XFixedToDouble(traps.at(i).left.p1.x) - bg_origin.x());                        int y_offset = int(XFixedToDouble(traps.at(i).left.p1.y) - bg_origin.y());                        XRenderCompositeTrapezoids(dpy, composition_mode, src, picture,                                                   antialias ? XRenderFindStandardFormat(dpy, PictStandardA8) : 0,                                                   x_offset, y_offset,                                                   traps.constData() + i, 1);                    }                } else {                    int mask_w = br.width() + (br.x() > 0 ? br.x() : 0);                    int mask_h = br.height() + (br.y() > 0 ? br.y() : 0);                    Pixmap mask = XCreatePixmap (dpy, RootWindow(dpy, scrn),                                                 mask_w, mask_h, antialias ? 8 : 1);                    Picture mask_picture = XRenderCreatePicture (dpy, mask,                                                                 antialias ? XRenderFindStandardFormat(dpy, PictStandardA8)                                                                 : XRenderFindStandardFormat(dpy, PictStandardA1),                                                                 CPPolyEdge, &attrs);                    XRenderColor transparent;                    transparent.red = 0;                    transparent.green = 0;                    transparent.blue = 0;                    transparent.alpha = 0;                    XRenderFillRectangle(dpy, PictOpSrc, mask_picture, &transparent, 0, 0, mask_w, mask_h);                    Picture mask_src = X11->getSolidFill(scrn, Qt::white);                    qt_XRenderCompositeTrapezoids(dpy, PictOpOver, mask_src, mask_picture,                                                  antialias ? XRenderFindStandardFormat(dpy, PictStandardA8) : 0,                                                  0, 0,                                                  traps);                    XRenderComposite(dpy, composition_mode, src, mask_picture, picture,                                     qRound(bg_origin.x()), qRound(bg_origin.y()),                                     0, 0,                                     0, 0,                                     mask_w, mask_h);                    XFreePixmap(dpy, mask);                    XRenderFreePicture(dpy, mask_picture);                }            } else {                qt_XRenderCompositeTrapezoids(dpy, composition_mode, src, picture,                                              antialias ? XRenderFindStandardFormat(dpy, PictStandardA8) : 0,                                              0, 0,                                              traps);            }        }    } else#endif        if (fill.style() != Qt::NoBrush) {            if (clippedCount > 0) {                QVarLengthArray<XPoint> xpoints(clippedCount);                for (int i = 0; i < clippedCount; ++i) {                    xpoints[i].x = qFloor(clippedPoints[i].x);                    xpoints[i].y = qFloor(clippedPoints[i].y);                }                if (mode == QPaintEngine::WindingMode)                    XSetFillRule(dpy, fill_gc, WindingRule);                setupAdaptedOrigin(QPoint(xpoints[0].x, xpoints[0].y));                XFillPolygon(dpy, hd, fill_gc,                             xpoints.data(), clippedCount,                             mode == QPaintEngine::ConvexMode ? Convex : Complex, CoordModeOrigin);                resetAdaptedOrigin();                if (mode == QPaintEngine::WindingMode)                    XSetFillRule(dpy, fill_gc, EvenOddRule);            }        }}void QX11PaintEnginePrivate::strokePolygon_translated(const QPointF *polygonPoints, int pointCount, bool close){    QVarLengthArray<QPointF> translated_points(pointCount);    QPointF offset(matrix.dx(), matrix.dy());    for (int i = 0; i < pointCount; ++i)        translated_points[i] = polygonPoints[i] + offset;    strokePolygon_dev(translated_points.data(), pointCount, close);}void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int pointCount, bool close){    int clippedCount = 0;    qt_float_point *clippedPoints = 0;    polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,                               &clippedPoints, &clippedCount, close);    if (clippedCount > 0) {        QVarLengthArray<XPoint> xpoints(clippedCount);        for (int i = 0; i < clippedCount; ++i) {            xpoints[i].x = qFloor(clippedPoints[i].x);            xpoints[i].y = qFloor(clippedPoints[i].y);        }        uint numberPoints = qMin(clippedCount, xlibMaxLinePoints);        XPoint *pts = xpoints.data();        XDrawLines(dpy, hd, gc, pts, numberPoints, CoordModeOrigin);        pts += numberPoints;        clippedCount -= numberPoints;        numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);        while (clippedCount) {            XDrawLines(dpy, hd, gc, pts-1, numberPoints+1, CoordModeOrigin);            pts += numberPoints;            clippedCount -= numberPoints;            numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);        }    }}void QX11PaintEngine::drawPolygon(const QPointF *polygonPoints, int pointCount, PolygonDrawMode mode){    Q_D(QX11PaintEngine);    if (d->use_path_fallback) {        QPainterPath path(polygonPoints[0]);        for (int i = 1; i < pointCount; ++i)            path.lineTo(polygonPoints[i]);        if (mode == PolylineMode) {            QBrush oldBrush = d->cbrush;            d->cbrush = QBrush(Qt::NoBrush);            path.setFillRule(Qt::WindingFill);            drawPath(path);            d->cbrush = oldBrush;        } else {            path.setFillRule(mode == OddEvenMode ? Qt::OddEvenFill : Qt::WindingFill);            path.closeSubpath();            drawPath(path);        }        return;    }    if (mode != PolylineMode && d->has_brush)        d->fillPolygon_translated(polygonPoints, pointCount, QX11PaintEnginePrivate::BrushGC, mode);    if (d->has_pen)        d->strokePolygon_translated(polygonPoints, pointCount, mode != PolylineMode);}void QX11PaintEnginePrivate::fillPath(const QPainterPath &path, QX11PaintEnginePrivate::GCMode gc_mode, bool transform){    QList<QPolygonF> polys = path.toFillPolygons(transform ? matrix : QMatrix());    for (int i = 0; i < polys.size(); ++i) {        fillPolygon_dev(polys.at(i).data(), polys.at(i).size(), gc_mode,                        path.fillRule() == Qt::OddEvenFill ? QPaintEngine::OddEvenMode : QPaintEngine::WindingMode);    }}void QX11PaintEngine::drawPath(const QPainterPath &path){    Q_D(QX11PaintEngine);    if (path.isEmpty())        return;    bool adjust_coords = d->has_alpha_pen && !(d->render_hints & QPainter::Antialiasing);    QMatrix old_matrix = d->matrix;    if (adjust_coords) {        d->matrix = QMatrix(d->matrix.m11(), d->matrix.m12(), d->matrix.m21(), d->matrix.m22(),                            d->matrix.dx() + 0.5f, d->matrix.dy() + 0.5f);    }    if (d->has_brush)        d->fillPath(path, QX11PaintEnginePrivate::BrushGC, true);    if (d->has_pen        && ((X11->use_xrender && (d->has_alpha_pen                                  || (d->render_hints & QPainter::Antialiasing)))            || (d->cpen.widthF() > 0 && d->txop > QPainterPrivate::TxTranslate)            || (d->cpen.style() > Qt::SolidLine))) {        QPainterPathStroker stroker;        if (d->cpen.style() == Qt::CustomDashLine)            stroker.setDashPattern(d->cpen.dashPattern());        else            stroker.setDashPattern(d->cpen.style());        stroker.setCapStyle(d->cpen.capStyle());        stroker.setJoinStyle(d->cpen.joinStyle());        QPainterPath stroke;        qreal width = d->cpen.widthF();        QPolygonF poly;        // necessary to get aliased alphablended primitives to be drawn correctly        if (width == 0) {            stroker.setWidth(1);            stroke = stroker.createStroke(path * d->matrix);            if (stroke.isEmpty())                return;            stroke.setFillRule(Qt::WindingFill);            d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, false);        } else {            stroker.setWidth(width);            stroke = stroker.createStroke(path);            if (stroke.isEmpty())                return;            stroke.setFillRule(Qt::WindingFill);            d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, true);        }    } else if (d->has_pen) {        // if we have a pen width of 0 - use XDrawLine() for speed        QList<QPolygonF> polys = path.toSubpathPolygons(d->matrix);        for (int i = 0; i < polys.size(); ++i)            d->strokePolygon_dev(polys.at(i).data(), polys.at(i).size(), false);    }    if (adjust_coords)        d->matrix = old_matrix;}void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, const QRectF &_sr){    Q_D(QX11PaintEngine);    QRectF sr = _sr;    if (r.size() != sr.size()) {        QImage image = pixmap.toImage();        image = image.copy(sr.toRect());        image = image.scaled(qRound(r.width()), qRound(r.height()), Qt::IgnoreAspectRatio,                             d->render_hints & QPainter::SmoothPixmapTransform                             ? Qt::SmoothTransformation : Qt::FastTransformation);        sr = QRectF(0, 0, r.width(), r.height());        // this recursive call here prevents us from doing a pixmap assignment,        // and thus triggering a deep copy if pixmap is being painted on        // Nice trick to speed such things up...        drawPixmap(r, QPixmap::fromImage(image), sr);        return;    }    int x = qRound(r.x());    int y = qRound(r.y());    int sx = qRound(sr.x());    int sy = qRound(sr.y());    int sw = qRound(sr.width());    int sh = qRound(sr.height());    if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen())        || (pixmap.x11Info().screen() != DefaultScreen(X11->display))) {        QPixmap* p = const_cast<QPixmap *>(&pixmap);        p->x11SetScreen(d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display));    }    QPixmap::x11SetDefaultScreen(pixmap.x11Info().screen());#if !defined(QT_NO_XRENDER)    ::Picture src_pict = pixmap.data->picture;    if (src_pict && d->picture) {        if (pixmap.data->d == 1 && (d->has_alpha_pen || d->bg_brush != Qt::NoBrush)) {            qt_render_bitmap(d->dpy, d->scrn, src_pict, d->picture,                             sx, sy, x, y, sw, sh, d->cpen, d->bg_brush,                             d->bg_mode == Qt::OpaqueMode);            return;        } else if (pixmap.data->d != 1 && (pixmap.data->d == 32 || pixmap.data->d != d->pdev_depth)) {            XRenderComposite(d->dpy, d->composition_mode,                             src_pict, 0, d->picture, sx, sy, 0, 0, x, y, sw, sh);            return;        }    }#endif    bool mono_src = pixmap.data->d == 1;    bool mono_dst = d->pdev_depth == 1;    bool restore_clip = false;    if (pixmap.data->x11_mask) { // pixmap has a mask        QBitmap comb(sw, sh);        GC cgc = XCreateGC(d->dpy, comb.handle(), 0, 0);        XSetForeground(d->dpy, cgc, 0);        XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh);        XSetBackground(d->dpy, cgc, 0);        XSetForeground(d->dpy, cgc, 1);        if (!d->crgn.isEmpty()) {            int num;            XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);            XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted);        }        XSetFillStyle(d->dpy, cgc, FillOpaqueStippled);        XSetTSOrigin(d->dpy, cgc, -sx, -sy);        XSetStipple(d->dpy, cgc, pixmap.data->x11_mask);        XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh);        XFreeGC(d->dpy, cgc);        XSetClipOrigin(d->dpy, d->gc, x, y);        XSetClipMask(d->dpy, d->gc, comb.handle());        restore_clip = true;    }    if (mono_src) {        if (d->bg_mode == Qt::OpaqueMode) {            if (mono_dst)                XSetForeground(d->dpy, d->gc, qGray(d->bg_brush.color().rgb()) > 127 ? 0 : 1);            else                XSetForeground(d->dpy, d->gc, QColormap::instance(d->scrn).pixel(d->bg_brush.color()));            XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh);        }        if (!d->crgn.isEmpty()) {            Pixmap comb = XCreatePixmap(d->dpy, d->hd, sw, sh, 1);            GC cgc = XCreateGC(d->dpy, comb, 0, 0);            XSetForeground(d->dpy, cgc, 0);            XFillRectangle(d->dpy, comb, cgc, 0, 0, sw, sh);            int num;            XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);            XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted);            XCopyArea(d->dpy, pixmap.handle(), comb, cgc, 0, 0, sw, sh, 0, 0);            XFreeGC(d->dpy, cgc);            XSetClipMask(d->dpy, d->gc, comb);            XSetClipOrigin(d->dpy, d->gc, x, y);            XFreePixmap(d->dpy, comb);        } else {            XSetClipMask(d->dpy, d->gc, pixmap.handle());            XSetClipOrigin(d->dpy, d->gc, x, y);        }        if (mono_dst) {            XSetBackground(d->dpy, d->gc, qGray(d->bg_brush.color().rgb()) > 127 ? 0 : 1);            XSetForeground(d->dpy, d->gc, qGray(d->cpen.color().rgb()) > 127 ? 0 : 1);        } else {            QColormap cmap = QColormap::instance(d->scrn);            XSetBackground(d->dpy, d->gc, cmap.pixel(d->bg_brush.color()));            XSetForeground(d->dpy, d->gc, cmap.pixel(d->cpen.color()));        }        XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh);        restore_clip = true;    } else {        XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);    }    if (d->pdev->devType() == QInternal::Pixmap) {        const QPixma

⌨️ 快捷键说明

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