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

📄 qpaintengine_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // eliminate shared edges    for (int i = 0; i < et.size(); ++i) {	for (int k = i+1; k < et.size(); ++k) {            const QEdge *edgeI = et.at(i);            const QEdge *edgeK = et.at(k);            if (edgeK->p1.y > edgeI->p1.y)                break;   	    if (edgeI->winding != edgeK->winding &&                isEqual(edgeI->p1, edgeK->p1) && isEqual(edgeI->p2, edgeK->p2)		) { 		et.removeAt(k);		et.removeAt(i);		--i;		break;	    }	}    }    if (ymax <= ymin)	return;    QList<const QEdge *> aet; 	    // edges that intersects the current scanline//     if (ymin < 0)// 	ymin = 0;//     if (paintEventClipRegion) // don't scan more lines than we have to// 	ymax = paintEventClipRegion->boundingRect().height();#ifdef QT_DEBUG_TESSELATOR    qDebug("==> ymin = %f, ymax = %f", ymin, ymax);#endif // QT_DEBUG_TESSELATOR    currentY = ymin; // used by the less than op    for (qreal y = ymin; y < ymax;) {	// fill active edge table with edges that intersect the current line	for (int i = 0; i < et.size(); ++i) {            const QEdge *edge = et.at(i);            if (edge->p1.y > XDoubleToFixed(y))                break;            aet.append(edge);            et.removeAt(i);            --i;	}	// remove processed edges from active edge table	for (int i = 0; i < aet.size(); ++i) {	    if (aet.at(i)->p2.y <= XDoubleToFixed(y)) {		aet.removeAt(i); 		--i;	    }	}        if (aet.size()%2 != 0) {#ifndef QT_NO_DEBUG            qWarning("QX11PaintEngine: aet out of sync - this should not happen.");#endif            return;        }	// done?	if (!aet.size()) {            if (!et.size()) {                break;	    } else { 		y = XFixedToDouble(et.at(0)->p1.y);                continue;	    }        }        // calculate the next y where we have to start a new set of trapezoids	qreal next_y(INT_MAX/256); 	for (int i = 0; i < aet.size(); ++i) {            const QEdge *edge = aet.at(i); 	    if (XFixedToDouble(edge->p2.y) < next_y) 		next_y = XFixedToDouble(edge->p2.y);        }	if (et.size() && next_y > XFixedToDouble(et.at(0)->p1.y))	    next_y = XFixedToDouble(et.at(0)->p1.y);        int aetSize = aet.size();	for (int i = 0; i < aetSize; ++i) {	    for (int k = i+1; k < aetSize; ++k) {                const QEdge *edgeI = aet.at(i);                const QEdge *edgeK = aet.at(k);		qreal m1 = edgeI->m;		qreal b1 = edgeI->b;		qreal m2 = edgeK->m;		qreal b2 = edgeK->b;		if (qAbs(m1 - m2) < 0.001)                    continue;                // ### intersect is not calculated correctly when optimized with -O2 (gcc)                volatile qreal intersect;                if (!qIsFinite(b1))                    intersect = (1.f / m2) * XFixedToDouble(edgeI->p1.x) + b2;                else if (!qIsFinite(b2))                    intersect = (1.f / m1) * XFixedToDouble(edgeK->p1.x) + b1;                else                    intersect = (b1*m1 - b2*m2) / (m1 - m2); 		if (intersect > y && intersect < next_y)		    next_y = intersect;	    }	}        XFixed yf, next_yf;        yf = qrealToXFixed(y);        next_yf = qrealToXFixed(next_y);        if (yf == next_yf) {            y = currentY = next_y;            continue;        }#ifdef QT_DEBUG_TESSELATOR        qDebug("###> y = %f, next_y = %f, %d active edges", y, next_y, aet.size());        qDebug("===> edges");        dump_edges(et);        qDebug("===> active edges");        dump_edges(aet);#endif	// calc intersection points 	QVarLengthArray<QIntersectionPoint> isects(aet.size()+1); 	for (int i = 0; i < isects.size()-1; ++i) {            const QEdge *edge = aet.at(i); 	    isects[i].x = (edge->p1.x != edge->p2.x) ?			  ((y - edge->b)*edge->m) : XFixedToDouble(edge->p1.x);	    isects[i].edge = edge;	}	Q_ASSERT(isects.size()%2 == 1);	// sort intersection points 	qSort(&isects[0], &isects[isects.size()-1], compareIntersections);        if (winding) {            // winding fill rule            for (int i = 0; i < isects.size()-1;) {                int winding = 0;                const QEdge *left = isects[i].edge;                const QEdge *right = 0;                winding += isects[i].edge->winding;                for (++i; i < isects.size()-1 && winding != 0; ++i) {                    winding += isects[i].edge->winding;                    right = isects[i].edge;                }                if (!left || !right)                    break;                traps->append(toXTrapezoid(yf, next_yf, *left, *right));            }        } else {            // odd-even fill rule            for (int i = 0; i < isects.size()-2; i += 2)                traps->append(toXTrapezoid(yf, next_yf, *isects[i].edge, *isects[i+1].edge));        }	y = currentY = next_y;    }#ifdef QT_DEBUG_TESSELATOR    qDebug("==> number of trapezoids: %d - edge table size: %d\n", traps->size(), et.size());    for (int i = 0; i < traps->size(); ++i)        dump_trap(traps->at(i));#endif    // optimize by unifying trapezoids that share left/right lines    // and have a common top/bottom edge//     for (int i = 0; i < tps.size(); ++i) {// 	for (int k = i+1; k < tps.size(); ++k) {// 	    if (i != k && tps.at(i).right == tps.at(k).right// 		&& tps.at(i).left == tps.at(k).left// 		&& (tps.at(i).top == tps.at(k).bottom// 		    || tps.at(i).bottom == tps.at(k).top))// 	    {// 		tps[i].bottom = tps.at(k).bottom;// 		tps.removeAt(k);//                 i = 0;// 		break;// 	    }// 	}//     }}#endif // !defined(QT_NO_XRENDER)#ifndef QT_NO_XRENDERstatic Picture getPatternFill(int screen, const QBrush &b, const QBrush &bg, bool opaque_bg){    if (!X11->use_xrender)        return XNone;    XRenderColor color = X11->preMultiply(b.color());    XRenderColor bg_color;    if (opaque_bg)        bg_color = X11->preMultiply(bg.color());    else        bg_color = X11->preMultiply(QColor(0, 0, 0, 0));    for (int i = 0; i < X11->pattern_fill_count; ++i) {        if (X11->pattern_fills[i].screen == screen            && X11->pattern_fills[i].opaque == opaque_bg            && X11->pattern_fills[i].style == b.style()            && X11->pattern_fills[i].color.alpha == color.alpha            && X11->pattern_fills[i].color.red == color.red            && X11->pattern_fills[i].color.green == color.green            && X11->pattern_fills[i].color.blue == color.blue            && X11->pattern_fills[i].bg_color.alpha == bg_color.alpha            && X11->pattern_fills[i].bg_color.red == bg_color.red            && X11->pattern_fills[i].bg_color.green == bg_color.green            && X11->pattern_fills[i].bg_color.blue == bg_color.blue)            return X11->pattern_fills[i].picture;    }    // none found, replace one    int i = rand() % 16;    if (X11->pattern_fills[i].screen != screen && X11->pattern_fills[i].picture) {	XRenderFreePicture (X11->display, X11->pattern_fills[i].picture);	X11->pattern_fills[i].picture = 0;    }    if (!X11->pattern_fills[i].picture) {        Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 8, 8, 32);        XRenderPictureAttributes attrs;        attrs.repeat = True;        X11->pattern_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,                                                              XRenderFindStandardFormat(X11->display, PictStandardARGB32),                                                              CPRepeat, &attrs);        XFreePixmap (X11->display, pixmap);    }    X11->pattern_fills[i].screen = screen;    X11->pattern_fills[i].color = color;    X11->pattern_fills[i].bg_color = bg_color;    X11->pattern_fills[i].opaque = opaque_bg;    X11->pattern_fills[i].style = b.style();    XRenderFillRectangle(X11->display, PictOpSrc, X11->pattern_fills[i].picture, &bg_color, 0, 0, 8, 8);    QPixmap pattern(qt_pixmapForBrush(b.style(), true));    XRenderPictureAttributes attrs;    attrs.repeat = true;    XRenderChangePicture(X11->display, pattern.x11PictureHandle(), CPRepeat, &attrs);    Picture fill_fg = X11->getSolidFill(screen, b.color());    XRenderComposite(X11->display, PictOpOver, fill_fg, pattern.x11PictureHandle(),                     X11->pattern_fills[i].picture,                     0, 0, 0, 0, 0, 0, 8, 8);    return X11->pattern_fills[i].picture;}static void qt_render_bitmap(Display *dpy, int scrn, Picture src, Picture dst,                      int sx, int sy, int x, int y, int sw, int sh,                      const QPen &pen, const QBrush &brush, bool opaque_bg){    if (opaque_bg) {        Picture fill_bg = X11->getSolidFill(scrn, brush.color());        XRenderComposite(dpy, PictOpOver,                         fill_bg, 0, dst, sx, sy, sx, sy, x, y, sw, sh);    }    Picture fill_fg = X11->getSolidFill(scrn, pen.color());    XRenderComposite(dpy, PictOpOver,                     fill_fg, src, dst, sx, sy, sx, sy, x, y, sw, sh);}#endifvoid QX11PaintEnginePrivate::init(){    dpy = 0;    scrn = 0;    hd = 0;    picture = 0;    xinfo = 0;#ifndef QT_NO_XRENDER    current_brush = 0;    composition_mode = PictOpOver;#endif}void QX11PaintEnginePrivate::setupAdaptedOrigin(const QPoint &p){    if (adapted_pen_origin)        XSetTSOrigin(dpy, gc, p.x(), p.y());    if (adapted_brush_origin)        XSetTSOrigin(dpy, gc_brush, p.x(), p.y());}void QX11PaintEnginePrivate::resetAdaptedOrigin(){    if (adapted_pen_origin)        XSetTSOrigin(dpy, gc, 0, 0);    if (adapted_brush_origin)        XSetTSOrigin(dpy, gc_brush, 0, 0);}void QX11PaintEnginePrivate::clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly){    int clipped_count = 0;    qt_float_point *clipped_points = 0;    polygonClipper.clipPolygon((qt_float_point *) poly.data(), poly.size(),                               &clipped_points, &clipped_count);    clipped_poly->resize(clipped_count);    for (int i=0; i<clipped_count; ++i)        (*clipped_poly)[i] = *((QPointF *)(&clipped_points[i]));}static QPaintEngine::PaintEngineFeatures qt_decide_features(){    QPaintEngine::PaintEngineFeatures features =        QPaintEngine::PrimitiveTransform        | QPaintEngine::PatternBrush        | QPaintEngine::AlphaBlend        | QPaintEngine::PainterPaths;    if (X11->use_xrender) {        features |= QPaintEngine::Antialiasing;        features |= QPaintEngine::PorterDuff;    }    return features;}/* * QX11PaintEngine members */QX11PaintEngine::QX11PaintEngine()    : QPaintEngine(*(new QX11PaintEnginePrivate), qt_decide_features()){    d_func()->init();}QX11PaintEngine::QX11PaintEngine(QX11PaintEnginePrivate &dptr)    : QPaintEngine(dptr, qt_decide_features()){    d_func()->init();}QX11PaintEngine::~QX11PaintEngine(){}bool QX11PaintEngine::begin(QPaintDevice *pdev){    Q_D(QX11PaintEngine);    d->xinfo = qt_x11Info(pdev);#ifndef QT_NO_XRENDER    if (pdev->devType() == QInternal::Widget) {        d->picture = (::Picture)static_cast<const QWidget *>(pdev)->x11PictureHandle();    } else if (pdev->devType() == QInternal::Pixmap) {        const QPixmap *pm = static_cast<const QPixmap *>(pdev);        if (X11->use_xrender && pm->data->d != 32 && pm->data->x11_mask)            pm->data->convertToARGB32();        d->picture = (::Picture)static_cast<const QPixmap *>(pdev)->x11PictureHandle();    }#else    d->picture = 0;#endif    d->hd = qt_x11Handle(pdev);    Q_ASSERT(d->xinfo != 0);    d->dpy = d->xinfo->display(); // get display variable    d->scrn = d->xinfo->screen(); // get screen variable    d->bg_col = Qt::white;    d->bg_mode = Qt::TransparentMode;    d->crgn = QRegion();    d->gc = XCreateGC(d->dpy, d->hd, 0, 0);    d->gc_brush = XCreateGC(d->dpy, d->hd, 0, 0);    d->has_alpha_brush = false;    d->has_alpha_pen = false;    d->has_clipping = false;    d->has_complex_xform = false;    d->has_custom_pen = false;    d->matrix = QMatrix();    d->pdev_depth = d->pdev->depth();    d->render_hints = 0;    d->txop = QPainterPrivate::TxNone;    d->use_path_fallback = false;#if !defined(QT_NO_XRENDER)    d->composition_mode = PictOpOver;

⌨️ 快捷键说明

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