📄 qpaintengine_x11.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 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://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** 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_x11_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>#ifndef QT_NO_XRENDER#include <private/qtessellator_p.h>#endifextern 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#undef X11 // defined in qt_x11_p.h/*! Returns the X11 specific pen GC for the painter \a p. Note that QPainter::begin() must be called before this function returns a valid GC.*/Q_GUI_EXPORT GC qt_x11_get_pen_gc(QPainter *p){ if (p && p->paintEngine() && p->paintEngine()->isActive() && p->paintEngine()->type() == QPaintEngine::X11) { return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc; } return 0;}/*! Returns the X11 specific brush GC for the painter \a p. Note that QPainter::begin() must be called before this function returns a valid GC.*/Q_GUI_EXPORT GC qt_x11_get_brush_gc(QPainter *p){ if (p && p->paintEngine() && p->paintEngine()->isActive() && p->paintEngine()->type() == QPaintEngine::X11) { return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc_brush; } return 0;}#define X11 qt_x11Data#ifndef QT_NO_XRENDERstatic const int compositionModeToRenderOp[QPainter::CompositionMode_Xor + 1] = { PictOpOver, //CompositionMode_SourceOver, PictOpOverReverse, //CompositionMode_DestinationOver, PictOpClear, //CompositionMode_Clear, PictOpSrc, //CompositionMode_Source, PictOpDst, //CompositionMode_Destination, PictOpIn, //CompositionMode_SourceIn, PictOpInReverse, //CompositionMode_DestinationIn, PictOpOut, //CompositionMode_SourceOut, PictOpOutReverse, //CompositionMode_DestinationOut, PictOpAtop, //CompositionMode_SourceAtop, PictOpAtopReverse, //CompositionMode_DestinationAtop, PictOpXor //CompositionMode_Xor};static inline int qpainterOpToXrender(QPainter::CompositionMode mode){ Q_ASSERT(mode <= QPainter::CompositionMode_Xor); return compositionModeToRenderOp[mode];}#endif// 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 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}#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, int screen){ QPixmap pm; QString key = QLatin1String("$qt-alpha-brush$") + QString::number(alpha) + QString::number(screen); 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); pm.x11SetScreen(screen); QPixmapCache::insert(key, pm); } return pm;}#if !defined(QT_NO_XRENDER)class QXRenderTessellator : public QTessellator{public: QXRenderTessellator() : traps(0), allocated(0), size(0) {} ~QXRenderTessellator() { free(traps); } XTrapezoid *traps; int allocated; int size; void addTrap(const Trapezoid &trap); QRect tessellate(const QPointF *points, int nPoints, bool winding) { size = 0; setWinding(winding); return QTessellator::tessellate(points, nPoints).toRect(); } void done() { if (allocated > 64) { free(traps); traps = 0; allocated = 0; } }};void QXRenderTessellator::addTrap(const Trapezoid &trap){ if (size == allocated) { allocated = qMax(2*allocated, 64); traps = (XTrapezoid *)realloc(traps, allocated * sizeof(XTrapezoid)); } traps[size].top = Q27Dot5ToXFixed(trap.top); traps[size].bottom = Q27Dot5ToXFixed(trap.bottom); traps[size].left.p1.x = Q27Dot5ToXFixed(trap.topLeft->x); traps[size].left.p1.y = Q27Dot5ToXFixed(trap.topLeft->y); traps[size].left.p2.x = Q27Dot5ToXFixed(trap.bottomLeft->x); traps[size].left.p2.y = Q27Dot5ToXFixed(trap.bottomLeft->y); traps[size].right.p1.x = Q27Dot5ToXFixed(trap.topRight->x); traps[size].right.p1.y = Q27Dot5ToXFixed(trap.topRight->y); traps[size].right.p2.x = Q27Dot5ToXFixed(trap.bottomRight->x); traps[size].right.p2.y = Q27Dot5ToXFixed(trap.bottomRight->y); ++size;}#endif // !defined(QT_NO_XRENDER)#ifndef QT_NO_XRENDERstatic Picture getPatternFill(int screen, const QBrush &b){ if (!X11->use_xrender) return XNone; XRenderColor color = X11->preMultiply(b.color()); XRenderColor bg_color; 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 == false && 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 = false; 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){ 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; tessellator = new QXRenderTessellator;#endif}void QX11PaintEnginePrivate::setupAdaptedOrigin(const QPoint &p){ if (adapted_pen_origin) XSetTSOrigin(dpy, gc, p.x(), p.y());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -