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

📄 qpaintengine_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qplatformdefs.h"#include "private/qpixmap_p.h"#include "qapplication.h"#include "qdebug.h"#include "qfont.h"#include "qwidget.h"#include "qbitmap.h"#include "qpixmapcache.h"#include "qtextcodec.h"#include "qcoreevent.h"#include "qiodevice.h"#include "qpainter_p.h"#include <qtextlayout.h>#include <qvarlengtharray.h>#include <private/qfont_p.h>#include <private/qtextengine_p.h>#include <private/qpaintengine_x11_p.h>#include <private/qfontengine_p.h>#include "qpen.h"#include "qcolor.h"#include "qcolormap.h"#include "qmath_p.h"#include <private/qpaintengine_p.h>#include "qpaintengine_x11_p.h"#include <private/qt_x11_p.h>#include <private/qnumeric_p.h>#include <limits.h>extern Drawable qt_x11Handle(const QPaintDevice *pd);extern const QX11Info *qt_x11Info(const QPaintDevice *pd);extern QPixmap qt_pixmapForBrush(int brushStyle, bool invert); //in qbrush.cpp// hack, so we don't have to make QRegion::clipRectangles() public or include// X11 headers in qregion.hvoid *qt_getClipRects(const QRegion &r, int &num){    return r.clipRectangles(num);}static inline void x11SetClipRegion(Display *dpy, GC gc, GC gc2,#ifndef QT_NO_XRENDER                                    Picture picture,#else                                    Qt::HANDLE picture,#endif                                    const QRegion &r){    int num;    XRectangle *rects = (XRectangle *)qt_getClipRects(r, num);    if (gc)        XSetClipRectangles( dpy, gc, 0, 0, rects, num, YXBanded );    if (gc2)        XSetClipRectangles( dpy, gc2, 0, 0, rects, num, YXBanded );#ifndef QT_NO_XRENDER    if (picture)        XRenderSetPictureClipRectangles(dpy, picture, 0, 0, rects, num);#else    Q_UNUSED(picture);#endif // QT_NO_XRENDER}static inline int qpainterOpToXrender(QPainter::CompositionMode mode){#ifndef QT_NO_XRENDER    switch (mode) {    case QPainter::CompositionMode_SourceOver:        return PictOpOver;        break;    case QPainter::CompositionMode_DestinationOver:        return PictOpOverReverse;        break;    case QPainter::CompositionMode_Clear:        return PictOpClear;        break;    case QPainter::CompositionMode_Source:        return PictOpSrc;        break;    case QPainter::CompositionMode_Destination:        return PictOpDst;        break;    case QPainter::CompositionMode_SourceIn:        return PictOpIn;        break;    case QPainter::CompositionMode_DestinationIn:        return PictOpInReverse;        break;    case QPainter::CompositionMode_SourceOut:        return PictOpOut;        break;    case QPainter::CompositionMode_DestinationOut:        return PictOpOutReverse;        break;    case QPainter::CompositionMode_SourceAtop:        return PictOpAtop;        break;    case QPainter::CompositionMode_DestinationAtop:        return PictOpAtopReverse;        break;    case QPainter::CompositionMode_Xor:        return PictOpXor;        break;    default:        return PictOpOver;        break;    }#endif    return 0;}static inline void x11ClearClipRegion(Display *dpy, GC gc, GC gc2,#ifndef QT_NO_XRENDER                                    Picture picture#else                                    Qt::HANDLE picture#endif                                      ){    if (gc)        XSetClipMask(dpy, gc, XNone);    if (gc2)        XSetClipMask(dpy, gc2, XNone);#ifndef QT_NO_XRENDER    if (picture) {        XRenderPictureAttributes attrs;        attrs.clip_mask = XNone;        XRenderChangePicture (dpy, picture, CPClipMask, &attrs);    }#else    Q_UNUSED(picture);#endif // QT_NO_XRENDER}void qt_draw_transformed_rect(QPaintEngine *pe, int x, int y, int w, int h, bool fill){    QX11PaintEngine *p = static_cast<QX11PaintEngine *>(pe);    QMatrix matrix = p->d_func()->matrix;    XPoint points[5];    int xp = x, yp = y;    matrix.map(xp, yp, &xp, &yp);    points[0].x = xp;    points[0].y = yp;    xp = x + w; yp = y;    matrix.map(xp, yp, &xp, &yp);    points[1].x = xp;    points[1].y = yp;    xp = x + w; yp = y + h;    matrix.map(xp, yp, &xp, &yp);    points[2].x = xp;    points[2].y = yp;    xp = x; yp = y + h;    matrix.map(xp, yp, &xp, &yp);    points[3].x = xp;    points[3].y = yp;    points[4] = points[0];    if (fill)        XFillPolygon(p->d_func()->dpy, p->d_func()->hd, p->d_func()->gc, points,                     4, Convex, CoordModeOrigin);    else        XDrawLines(p->d_func()->dpy, p->d_func()->hd, p->d_func()->gc, points, 5, CoordModeOrigin);}#define DITHER_SIZE 16static const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE] = {  {   0,192, 48,240, 12,204, 60,252,  3,195, 51,243, 15,207, 63,255 },  { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },  {  32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },  { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },  {   8,200, 56,248,  4,196, 52,244, 11,203, 59,251,  7,199, 55,247 },  { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },  {  40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },  { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },  {   2,194, 50,242, 14,206, 62,254,  1,193, 49,241, 13,205, 61,253 },  { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },  {  34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },  { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },  {  10,202, 58,250,  6,198, 54,246,  9,201, 57,249,  5,197, 53,245 },  { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },  {  42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },  { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }};static QPixmap qt_patternForAlpha(uchar alpha){    static QPixmap pm;    QString key = "$qt-alpha-brush$" + QString::number(alpha);    if (!QPixmapCache::find(key, pm)) {        // #### why not use a mono image here????        QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32);        pattern.fill(0xffffffff);        for (int y = 0; y < DITHER_SIZE; ++y) {            for (int x = 0; x < DITHER_SIZE; ++x) {                if (base_dither_matrix[x][y] <= alpha)                    pattern.setPixel(x, y, 0x00000000);            }        }        pm = QBitmap::fromImage(pattern);        QPixmapCache::insert(key, pm);    }    return pm;}#if !defined(QT_NO_XRENDER)/* * Polygon tesselator - can probably be optimized a bit more *///#define QT_DEBUG_TESSELATOR#define FloatToXFixed(i) (int)((i) * 65536)#define IntToXFixed(i) ((i) << 16)Q_DECLARE_TYPEINFO(XTrapezoid, Q_PRIMITIVE_TYPE);// used by the edge point sort algorithmstatic qreal currentY = 0.f;struct QEdge {    XPointFixed p1, p2;    qreal m;    qreal b;    signed char winding;};Q_DECLARE_TYPEINFO(QEdge, Q_PRIMITIVE_TYPE);static inline bool compareEdges(const QEdge *e1, const QEdge *e2){    return e1->p1.y < e2->p1.y;}static inline bool isEqual(const XPointFixed &p1, const XPointFixed &p2){    return ((p1.x == p2.x) && (p1.y == p2.y));}struct QIntersectionPoint {    qreal x;    const QEdge *edge;};Q_DECLARE_TYPEINFO(QIntersectionPoint, Q_PRIMITIVE_TYPE);static inline bool compareIntersections(const QIntersectionPoint &i1, const QIntersectionPoint &i2){    if (qAbs(i1.x - i2.x) > 0.01) { // x != other.x in 99% of the cases        return i1.x < i2.x;    } else {        qreal x1 = !qIsFinite(i1.edge->b) ? XFixedToDouble(i1.edge->p1.x) :                   (currentY+1.f - i1.edge->b)*i1.edge->m;        qreal x2 = !qIsFinite(i2.edge->b) ? XFixedToDouble(i2.edge->p1.x) :                   (currentY+1.f - i2.edge->b)*i2.edge->m;        return x1 < x2;    }}#define qrealToXFixed FloatToXFixedstatic XTrapezoid QT_FASTCALL toXTrapezoid(XFixed y1, XFixed y2, const QEdge &left, const QEdge &right){    XTrapezoid trap;    trap.top = y1;    trap.bottom = y2;    trap.left.p1.y = left.p1.y;    trap.left.p2.y = left.p2.y;    trap.right.p1.y = right.p1.y;    trap.right.p2.y = right.p2.y;    trap.left.p1.x = left.p1.x;    trap.left.p2.x = left.p2.x;    trap.right.p1.x = right.p1.x;    trap.right.p2.x = right.p2.x;    return trap;}#ifdef QT_DEBUG_TESSELATORstatic QPointF xf_to_qt(XPointFixed pt){    return QPointF(XFixedToDouble(pt.x), XFixedToDouble(pt.y));}static void dump_edges(const QList<const QEdge *> &et){    for (int x = 0; x < et.size(); ++x) {        qDebug() << "edge#" << x << xf_to_qt(et.at(x)->p1) << xf_to_qt(et.at(x)->p2) << "b: " << et.at(x)->b << "m:" << et.at(x)->m << et.at(x);    }}static void dump_trap(const XTrapezoid &t){    qDebug() << "trap# t=" << XFixedToDouble(t.top) << "b=" << XFixedToDouble(t.bottom)  << "h="             << XFixedToDouble(t.bottom - t.top) << "\tleft p1: ("             << XFixedToDouble(t.left.p1.x) << ","<< XFixedToDouble(t.left.p1.y)             << ")" << "\tleft p2: (" << XFixedToDouble(t.left.p2.x) << ","             << XFixedToDouble(t.left.p2.y) << ")" << "\n\t\t\t\tright p1:("             << XFixedToDouble(t.right.p1.x) << "," << XFixedToDouble(t.right.p1.y) << ")"             << "\tright p2:(" << XFixedToDouble(t.right.p2.x) << ","             << XFixedToDouble(t.right.p2.y) << ")";}#endifstatic void qt_tesselate_polygon(QVector<XTrapezoid> *traps, const QPointF *pg, int pgSize,                                 bool winding, QRect *br){    QVector<QEdge> edges;    edges.reserve(128);    qreal ymin(INT_MAX/256);    qreal ymax(INT_MIN/256);    qreal xmin(INT_MAX/256);    qreal xmax(INT_MIN/256);    Q_ASSERT(pg[0] == pg[pgSize-1]);    // generate edge table    for (int x = 0; x < pgSize-1; ++x) {	QEdge edge;	edge.winding = pg[x].y() > pg[x+1].y() ? 1 : -1;        QPointF p1, p2;	if (edge.winding > 0) {	    p1 = pg[x+1];	    p2 = pg[x];	} else {	    p1 = pg[x];	    p2 = pg[x+1];	}        edge.p1.x = XDoubleToFixed(p1.x());        edge.p1.y = XDoubleToFixed(p1.y());        edge.p2.x = XDoubleToFixed(p2.x());        edge.p2.y = XDoubleToFixed(p2.y());	edge.m = (p1.y() - p2.y()) / (p1.x() - p2.x()); // line derivative	edge.b = p1.y() - edge.m * p1.x(); // intersection with y axis	edge.m = edge.m != 0.0 ? 1.0 / edge.m : 0.0; // inverted derivative	edges.append(edge);        xmin = qMin(xmin, XFixedToDouble(edge.p1.x));        xmax = qMax(xmax, XFixedToDouble(edge.p2.x));        ymin = qMin(ymin, XFixedToDouble(edge.p1.y));        ymax = qMax(ymax, XFixedToDouble(edge.p2.y));    }    br->setX(qRound(xmin));    br->setY(qRound(ymin));    br->setWidth(qRound(xmax - xmin));    br->setHeight(qRound(ymax - ymin));    QList<const QEdge *> et; 	    // edge list    for (int i = 0; i < edges.size(); ++i)        et.append(&edges.at(i));    // sort edge table by min y value    qSort(et.begin(), et.end(), compareEdges);

⌨️ 快捷键说明

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