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

📄 qpaintengine_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#endif    d->xlibMaxLinePoints = 32762; // a safe number used to avoid, call to XMaxRequestSize(d->dpy) - 3;    // Set up the polygon clipper. Note: This will only work in    // polyline mode as long as we have a buffer zone, since a    // polyline may be clipped into several non-connected polylines.    const int BUFFERZONE = 100;    QRect devClipRect;    QRegion sysClip = systemClip();    if (!sysClip.isEmpty()) {        devClipRect = sysClip.boundingRect();        devClipRect.adjust(-BUFFERZONE, -BUFFERZONE, 2*BUFFERZONE, 2*BUFFERZONE);    } else {        devClipRect.setRect(-BUFFERZONE, -BUFFERZONE,                            pdev->width() + 2*BUFFERZONE, pdev->height() + 2 * BUFFERZONE);    }    d->polygonClipper.setBoundingRect(devClipRect);    setActive(true);    QPixmap::x11SetDefaultScreen(d->xinfo->screen());    QWidget *w = d->pdev->devType() == QInternal::Widget ? static_cast<QWidget *>(d->pdev) : 0;    if (w && w->testAttribute(Qt::WA_PaintUnclipped)) {  // paint direct on device 	updatePen(QPen(Qt::black)); 	updateBrush(QBrush(Qt::white), QPoint());        XSetSubwindowMode(d->dpy, d->gc, IncludeInferiors);        XSetSubwindowMode(d->dpy, d->gc_brush, IncludeInferiors);#ifndef QT_NO_XRENDER        XRenderPictureAttributes attrs;        attrs.subwindow_mode = IncludeInferiors;        XRenderChangePicture(d->dpy, d->picture, CPSubwindowMode, &attrs);#endif    }    setDirty(QPaintEngine::DirtyClipRegion);    setDirty(QPaintEngine::DirtyPen);    setDirty(QPaintEngine::DirtyBrush);    setDirty(QPaintEngine::DirtyBackground);    return true;}bool QX11PaintEngine::end(){    Q_D(QX11PaintEngine);#if !defined(QT_NO_XRENDER)    if (d->picture) {        // reset clipping/subwindow mode on our render picture	XRenderPictureAttributes attrs;	attrs.subwindow_mode = ClipByChildren;        attrs.clip_mask = XNone;	XRenderChangePicture(d->dpy, d->picture, CPClipMask|CPSubwindowMode, &attrs);    }#endif    if (d->gc_brush && d->pdev->painters < 2) {        XFreeGC(d->dpy, d->gc_brush);        d->gc_brush = 0;    }    if (d->gc && d->pdev->painters < 2) {        XFreeGC(d->dpy, d->gc);        d->gc = 0;    }    return true;}static bool clipLine(QLineF *line, const QRect &rect){    qreal x1 = line->x1();    qreal x2 = line->x2();    qreal y1 = line->y1();    qreal y2 = line->y2();    qreal left = rect.x();    qreal right = rect.x() + rect.width() - 1;    qreal top = rect.y();    qreal bottom = rect.y() + rect.height() - 1;    enum { Left, Right, Top, Bottom };    // clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html    int p1 = ((x1 < left) << Left)             | ((x1 > right) << Right)             | ((y1 < top) << Top)             | ((y1 > bottom) << Bottom);    int p2 = ((x2 < left) << Left)             | ((x2 > right) << Right)             | ((y2 < top) << Top)             | ((y2 > bottom) << Bottom);    if (p1 & p2)        // completely outside        return false;    if (p1 | p2) {        qreal dx = x2 - x1;        qreal dy = y2 - y1;        // clip x coordinates        if (x1 < left) {            y1 += dy/dx * (left - x1);            x1 = left;        } else if (x1 > right) {            y1 -= dy/dx * (x1 - right);            x1 = right;        }        if (x2 < left) {            y2 += dy/dx * (left - x2);            x2 = left;        } else if (x2 > right) {            y2 -= dy/dx * (x2 - right);            x2 = right;        }        p1 = ((y1 < top) << Top)             | ((y1 > bottom) << Bottom);        p2 = ((y2 < top) << Top)             | ((y2 > bottom) << Bottom);        if (p1 & p2)            return false;        // clip y coordinates        if (y1 < top) {            x1 += dx/dy * (top - y1);            y1 = top;        } else if (y1 > bottom) {            x1 -= dx/dy * (y1 - bottom);            y1 = bottom;        }        if (y2 < top) {            x2 += dx/dy * (top - y2);            y2 = top;        } else if (y2 > bottom) {            x2 -= dx/dy * (y2 - bottom);            y2 = bottom;        }        *line = QLineF(QPointF(x1, y1), QPointF(x2, y2));    }    return true;}void QX11PaintEngine::drawLines(const QLine *lines, int lineCount){    Q_ASSERT(lines);    Q_ASSERT(lineCount);    Q_D(QX11PaintEngine);    if (d->has_alpha_brush        || d->has_alpha_pen        || d->has_custom_pen        || (d->cpen.widthF() > 0 && d->has_complex_xform)        || (d->render_hints & QPainter::Antialiasing)) {        for (int i = 0; i < lineCount; ++i) {            QPainterPath path(lines[i].p1());            path.lineTo(lines[i].p2());            drawPath(path);        }        return;    }    if (d->has_pen) {        for (int i = 0; i < lineCount; ++i) {            QLineF linef;            if (d->txop == QPainterPrivate::TxNone) {                linef = lines[i];            } else {                linef = QLineF(d->matrix.map(lines[i].p1()), d->matrix.map(lines[i].p2()));            }            if (clipLine(&linef, d->polygonClipper.boundingRect())) {                XDrawLine(d->dpy, d->hd, d->gc,                          qFloor(linef.x1()), qFloor(linef.y1()),                          qFloor(linef.x2()), qFloor(linef.y2()));            }        }    }}void QX11PaintEngine::drawRects(const QRect *rects, int rectCount){    Q_D(QX11PaintEngine);    Q_ASSERT(rects);    Q_ASSERT(rectCount);    if (d->use_path_fallback) {        for (int i = 0; i < rectCount; ++i) {            QPainterPath path;            path.addRect(rects[i]);            drawPath(path);        }        return;    }    QRect clip(d->polygonClipper.boundingRect());    QPoint offset(qRound(d->matrix.dx()), qRound(d->matrix.dy()));#if !defined(QT_NO_XRENDER)    ::Picture pict = d->picture;    if (X11->use_xrender && pict && d->has_brush && d->pdev_depth != 1        && (d->has_texture || d->has_alpha_brush))    {        XRenderColor xc;        if (!d->has_texture && !d->has_pattern)            xc = X11->preMultiply(d->cbrush.color());        for (int i = 0; i < rectCount; ++i) {            QRect r(rects[i]);            if (d->txop == QPainterPrivate::TxTranslate)                r.translate(offset);            r = r.intersect(clip);            if (r.isEmpty())                continue;            if (d->has_texture || d->has_pattern) {                XRenderComposite(d->dpy, d->composition_mode, d->current_brush, 0, pict,                                 qRound(r.x() - d->bg_origin.x()), qRound(r.y() - d->bg_origin.y()),                                 0, 0, r.x(), r.y(), r.width(), r.height());            } else {                XRenderFillRectangle(d->dpy, d->composition_mode, pict, &xc, r.x(), r.y(), r.width(), r.height());            }            if (d->has_pen)                XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());        }    } else#endif // !QT_NO_XRENDER    {        if (d->has_brush & d->has_pen) {            for (int i = 0; i < rectCount; ++i) {                QRect r(rects[i]);                if (d->txop == QPainterPrivate::TxTranslate)                    r.translate(offset);                r = r.intersect(clip);                if (r.isEmpty())                    continue;                d->setupAdaptedOrigin(r.topLeft());                if (d->has_brush)                    XFillRectangle(d->dpy, d->hd, d->gc_brush, r.x(), r.y(), r.width(), r.height());                if (d->has_pen)                    XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());            }            d->resetAdaptedOrigin();        } else {            QVarLengthArray<XRectangle> xrects(rectCount);            int numClipped = rectCount;            for (int i = 0; i < rectCount; ++i) {                QRect r(rects[i]);                if (d->txop == QPainterPrivate::TxTranslate)                    r.translate(offset);                r = r.intersect(clip);                if (r.isEmpty()) {                    --numClipped;                    continue;                }                xrects[i].x = short(r.x());                xrects[i].y = short(r.y());                xrects[i].width = ushort(r.width());                xrects[i].height = ushort(r.height());            }            if (numClipped) {                d->setupAdaptedOrigin(rects[0].topLeft());                if (d->has_brush && !d->has_pen)                    XFillRectangles(d->dpy, d->hd, d->gc_brush, xrects.data(), numClipped);                else if (d->has_pen && !d->has_brush)                    XDrawRectangles(d->dpy, d->hd, d->gc, xrects.data(), numClipped);                d->resetAdaptedOrigin();            }        }    }}void QX11PaintEngine::drawPoints(const QPoint *points, int pointCount){    Q_ASSERT(points);    Q_ASSERT(pointCount);    Q_D(QX11PaintEngine);    if (!d->has_pen)        return;    if (d->cpen.widthF() > .0f        || d->has_alpha_brush        || d->has_alpha_pen        || d->has_custom_pen        || (d->render_hints & QPainter::Antialiasing)) {        const QPoint *end = points + pointCount;        while (points < end) {            QPainterPath path;            path.moveTo(*points);            path.lineTo(points->x()+.005, points->y());            drawPath(path);            ++points;        }        return;    }    static const int BUF_SIZE = 1024;    XPoint xPoints[BUF_SIZE];    int i = 0, j = 0;    while (i < pointCount) {        while (i < pointCount && j < BUF_SIZE) {            const QPoint &xformed = d->matrix.map(points[i]);            int x = xformed.x();            int y = xformed.y();            if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {                xPoints[j].x = x;                xPoints[j].y = y;                ++j;            }            ++i;        }        if (j)            XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);        j = 0;    }}void QX11PaintEngine::drawPoints(const QPointF *points, int pointCount){    Q_ASSERT(points);    Q_ASSERT(pointCount);    Q_D(QX11PaintEngine);    if (!d->has_pen)        return;    if (d->cpen.widthF() > .0f        || d->has_alpha_brush        || d->has_alpha_pen        || d->has_custom_pen        || (d->render_hints & QPainter::Antialiasing)) {        const QPointF *end = points + pointCount;        while (points < end) {            QPainterPath path;            path.moveTo(*points);            path.lineTo(points->x() + 0.005, points->y());            drawPath(path);            ++points;        }        return;    }    static const int BUF_SIZE = 1024;    XPoint xPoints[BUF_SIZE];    int i = 0, j = 0;    while (i < pointCount) {        while (i < pointCount && j < BUF_SIZE) {            const QPointF &xformed = d->matrix.map(points[i]);            int x = qFloor(xformed.x());            int y = qFloor(xformed.y());            if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {                xPoints[j].x = x;                xPoints[j].y = y;                ++j;            }            ++i;        }        if (j)            XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);        j = 0;    }}QPainter::RenderHints QX11PaintEngine::supportedRenderHints() const{#if !defined(QT_NO_XRENDER)    if (X11->use_xrender)        return QPainter::Antialiasing;#endif    return QFlag(0);}void QX11PaintEngine::updateState(const QPaintEngineState &state){    Q_D(QX11PaintEngine);    QPaintEngine::DirtyFlags flags = state.state();    if (flags & DirtyTransform) updateMatrix(state.matrix());    if (flags & (DirtyBackground | DirtyBackgroundMode))        updateBackground(state.backgroundMode(), state.backgroundBrush());    if (flags & DirtyPen) updatePen(state.pen());    if (flags & (DirtyBrush | DirtyBrushOrigin)) updateBrush(state.brush(), state.brushOrigin());    if (flags & DirtyFont) updateFont(state.font());    if (state.state() & DirtyClipEnabled) {

⌨️ 快捷键说明

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