src/gui/painting/qpaintengine_x11.cpp File Reference

#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>

Include dependency graph for qpaintengine_x11.cpp:

Go to the source code of this file.

Classes

struct  QEdge
struct  QIntersectionPoint

Defines

#define X11   qt_x11Data
#define DITHER_SIZE   16
#define FloatToXFixed(i)   (int)((i) * 65536)
#define IntToXFixed(i)   ((i) << 16)
#define qrealToXFixed   FloatToXFixed

Functions

Drawable qt_x11Handle (const QPaintDevice *pd)
const QX11Infoqt_x11Info (const QPaintDevice *pd)
QPixmap qt_pixmapForBrush (int brushStyle, bool invert)
Q_GUI_EXPORT GC qt_x11_get_pen_gc (QPainter *p)
Q_GUI_EXPORT GC qt_x11_get_brush_gc (QPainter *p)
static int qpainterOpToXrender (QPainter::CompositionMode mode)
void * qt_getClipRects (const QRegion &r, int &num)
static void x11SetClipRegion (Display *dpy, GC gc, GC gc2, Picture picture, const QRegion &r)
static void x11ClearClipRegion (Display *dpy, GC gc, GC gc2, Picture picture)
static QPixmap qt_patternForAlpha (uchar alpha, int screen)
 Q_DECLARE_TYPEINFO (XTrapezoid, Q_PRIMITIVE_TYPE)
 Q_DECLARE_TYPEINFO (QEdge, Q_PRIMITIVE_TYPE)
static bool compareEdges (const QEdge *e1, const QEdge *e2)
static bool isEqual (const XPointFixed &p1, const XPointFixed &p2)
 Q_DECLARE_TYPEINFO (QIntersectionPoint, Q_PRIMITIVE_TYPE)
static bool compareIntersections (const QIntersectionPoint &i1, const QIntersectionPoint &i2)
static XTrapezoid QT_FASTCALL toXTrapezoid (XFixed y1, XFixed y2, const QEdge &left, const QEdge &right)
static void qt_tesselate_polygon (QVector< XTrapezoid > *traps, const QPointF *pg, int pgSize, bool winding, QRect *br)
static Picture getPatternFill (int screen, const QBrush &b)
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)
static QPaintEngine::PaintEngineFeatures qt_decide_features ()
static bool clipLine (QLineF *line, const QRect &rect)
static void qt_XRenderCompositeTrapezoids (Display *dpy, int op, Picture src, Picture dst, _Xconst XRenderPictFormat *maskFormat, int xSrc, int ySrc, const QVector< XTrapezoid > &traps)
void qt_draw_tile (QPaintEngine *, qreal, qreal, qreal, qreal, const QPixmap &, qreal, qreal)

Variables

static const int compositionModeToRenderOp [QPainter::CompositionMode_Xor+1]
static const uchar base_dither_matrix [DITHER_SIZE][DITHER_SIZE]
static qreal currentY = 0.f


Define Documentation

#define DITHER_SIZE   16

Definition at line 175 of file qpaintengine_x11.cpp.

Referenced by qt_patternForAlpha().

#define FloatToXFixed (  )     (int)((i) * 65536)

Definition at line 223 of file qpaintengine_x11.cpp.

#define IntToXFixed (  )     ((i) << 16)

Definition at line 224 of file qpaintengine_x11.cpp.

#define qrealToXFixed   FloatToXFixed

Definition at line 269 of file qpaintengine_x11.cpp.

Referenced by qt_polygon_trapezoidation(), and qt_tesselate_polygon().

#define X11   qt_x11Data

Definition at line 93 of file qpaintengine_x11.cpp.


Function Documentation

static bool clipLine ( QLineF line,
const QRect rect 
) [static]

Definition at line 804 of file qpaintengine_x11.cpp.

References QCss::Bottom, QRect::height(), QTextStream::left(), QCss::Left, QCss::Right, QTextStream::right(), QCss::Top, QRect::width(), QRect::x(), QLineF::x1(), QLineF::x2(), QRect::y(), QLineF::y1(), and QLineF::y2().

Referenced by QX11PaintEngine::drawLines().

00805 {
00806     qreal x1 = line->x1();
00807     qreal x2 = line->x2();
00808     qreal y1 = line->y1();
00809     qreal y2 = line->y2();
00810 
00811     qreal left = rect.x();
00812     qreal right = rect.x() + rect.width() - 1;
00813     qreal top = rect.y();
00814     qreal bottom = rect.y() + rect.height() - 1;
00815 
00816     enum { Left, Right, Top, Bottom };
00817     // clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html
00818     int p1 = ((x1 < left) << Left)
00819              | ((x1 > right) << Right)
00820              | ((y1 < top) << Top)
00821              | ((y1 > bottom) << Bottom);
00822     int p2 = ((x2 < left) << Left)
00823              | ((x2 > right) << Right)
00824              | ((y2 < top) << Top)
00825              | ((y2 > bottom) << Bottom);
00826 
00827     if (p1 & p2)
00828         // completely outside
00829         return false;
00830 
00831     if (p1 | p2) {
00832         qreal dx = x2 - x1;
00833         qreal dy = y2 - y1;
00834 
00835         // clip x coordinates
00836         if (x1 < left) {
00837             y1 += dy/dx * (left - x1);
00838             x1 = left;
00839         } else if (x1 > right) {
00840             y1 -= dy/dx * (x1 - right);
00841             x1 = right;
00842         }
00843         if (x2 < left) {
00844             y2 += dy/dx * (left - x2);
00845             x2 = left;
00846         } else if (x2 > right) {
00847             y2 -= dy/dx * (x2 - right);
00848             x2 = right;
00849         }
00850         p1 = ((y1 < top) << Top)
00851              | ((y1 > bottom) << Bottom);
00852         p2 = ((y2 < top) << Top)
00853              | ((y2 > bottom) << Bottom);
00854         if (p1 & p2)
00855             return false;
00856         // clip y coordinates
00857         if (y1 < top) {
00858             x1 += dx/dy * (top - y1);
00859             y1 = top;
00860         } else if (y1 > bottom) {
00861             x1 -= dx/dy * (y1 - bottom);
00862             y1 = bottom;
00863         }
00864         if (y2 < top) {
00865             x2 += dx/dy * (top - y2);
00866             y2 = top;
00867         } else if (y2 > bottom) {
00868             x2 -= dx/dy * (y2 - bottom);
00869             y2 = bottom;
00870         }
00871         *line = QLineF(QPointF(x1, y1), QPointF(x2, y2));
00872     }
00873     return true;
00874 }

Here is the call graph for this function:

static bool compareEdges ( const QEdge e1,
const QEdge e2 
) [inline, static]

Definition at line 240 of file qpaintengine_x11.cpp.

References QEdge::p1.

Referenced by qt_polygon_trapezoidation(), and qt_tesselate_polygon().

00241 {
00242     return e1->p1.y < e2->p1.y;
00243 }

static bool compareIntersections ( const QIntersectionPoint i1,
const QIntersectionPoint i2 
) [inline, static]

Definition at line 256 of file qpaintengine_x11.cpp.

References QEdge::b, currentY, QIntersectionPoint::edge, QEdge::m, QEdge::p1, qIsFinite(), and QIntersectionPoint::x.

Referenced by qt_polygon_trapezoidation(), and qt_tesselate_polygon().

00257 {
00258     if (qAbs(i1.x - i2.x) > 0.01) { // x != other.x in 99% of the cases
00259         return i1.x < i2.x;
00260     } else {
00261         qreal x1 = !qIsFinite(i1.edge->b) ? XFixedToDouble(i1.edge->p1.x) :
00262                    (currentY+1.f - i1.edge->b)*i1.edge->m;
00263         qreal x2 = !qIsFinite(i2.edge->b) ? XFixedToDouble(i2.edge->p1.x) :
00264                    (currentY+1.f - i2.edge->b)*i2.edge->m;
00265         return x1 < x2;
00266     }
00267 }

Here is the call graph for this function:

static Picture getPatternFill ( int  screen,
const QBrush b 
) [static]

Definition at line 549 of file qpaintengine_x11.cpp.

References b, i, qt_pixmapForBrush(), X11, and XNone.

Referenced by QX11PaintEnginePrivate::fillPolygon_dev().

00550 {
00551     if (!X11->use_xrender)
00552         return XNone;
00553 
00554     XRenderColor color = X11->preMultiply(b.color());
00555     XRenderColor bg_color;
00556 
00557     bg_color = X11->preMultiply(QColor(0, 0, 0, 0));
00558 
00559     for (int i = 0; i < X11->pattern_fill_count; ++i) {
00560         if (X11->pattern_fills[i].screen == screen
00561             && X11->pattern_fills[i].opaque == false
00562             && X11->pattern_fills[i].style == b.style()
00563             && X11->pattern_fills[i].color.alpha == color.alpha
00564             && X11->pattern_fills[i].color.red == color.red
00565             && X11->pattern_fills[i].color.green == color.green
00566             && X11->pattern_fills[i].color.blue == color.blue
00567             && X11->pattern_fills[i].bg_color.alpha == bg_color.alpha
00568             && X11->pattern_fills[i].bg_color.red == bg_color.red
00569             && X11->pattern_fills[i].bg_color.green == bg_color.green
00570             && X11->pattern_fills[i].bg_color.blue == bg_color.blue)
00571             return X11->pattern_fills[i].picture;
00572     }
00573     // none found, replace one
00574     int i = rand() % 16;
00575 
00576     if (X11->pattern_fills[i].screen != screen && X11->pattern_fills[i].picture) {
00577   XRenderFreePicture (X11->display, X11->pattern_fills[i].picture);
00578   X11->pattern_fills[i].picture = 0;
00579     }
00580 
00581     if (!X11->pattern_fills[i].picture) {
00582         Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 8, 8, 32);
00583         XRenderPictureAttributes attrs;
00584         attrs.repeat = True;
00585         X11->pattern_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
00586                                                               XRenderFindStandardFormat(X11->display, PictStandardARGB32),
00587                                                               CPRepeat, &attrs);
00588         XFreePixmap (X11->display, pixmap);
00589     }
00590 
00591     X11->pattern_fills[i].screen = screen;
00592     X11->pattern_fills[i].color = color;
00593     X11->pattern_fills[i].bg_color = bg_color;
00594     X11->pattern_fills[i].opaque = false;
00595     X11->pattern_fills[i].style = b.style();
00596 
00597     XRenderFillRectangle(X11->display, PictOpSrc, X11->pattern_fills[i].picture, &bg_color, 0, 0, 8, 8);
00598 
00599     QPixmap pattern(qt_pixmapForBrush(b.style(), true));
00600     XRenderPictureAttributes attrs;
00601     attrs.repeat = true;
00602     XRenderChangePicture(X11->display, pattern.x11PictureHandle(), CPRepeat, &attrs);
00603 
00604     Picture fill_fg = X11->getSolidFill(screen, b.color());
00605     XRenderComposite(X11->display, PictOpOver, fill_fg, pattern.x11PictureHandle(),
00606                      X11->pattern_fills[i].picture,
00607                      0, 0, 0, 0, 0, 0, 8, 8);
00608 
00609     return X11->pattern_fills[i].picture;
00610 }

Here is the call graph for this function:

static bool isEqual ( const XPointFixed &  p1,
const XPointFixed &  p2 
) [inline, static]

Definition at line 245 of file qpaintengine_x11.cpp.

Referenced by QLineEdit::changeEvent(), Q3IconView::changeEvent(), Q3ListBox::changeEvent(), Q3ListView::changeEvent(), Q3TextEdit::changeEvent(), QWidget::event(), Q3MemArray< bool >::operator!=(), Q3MemArray< bool >::operator==(), qt_polygon_trapezoidation(), and qt_tesselate_polygon().

00246 {
00247     return ((p1.x == p2.x) && (p1.y == p2.y));
00248 }

Q_DECLARE_TYPEINFO ( QIntersectionPoint  ,
Q_PRIMITIVE_TYPE   
)

Q_DECLARE_TYPEINFO ( QEdge  ,
Q_PRIMITIVE_TYPE   
)

Q_DECLARE_TYPEINFO ( XTrapezoid  ,
Q_PRIMITIVE_TYPE   
)

static int qpainterOpToXrender ( QPainter::CompositionMode  mode  )  [inline, static]

Definition at line 111 of file qpaintengine_x11.cpp.

References QPainter::CompositionMode_Xor, and compositionModeToRenderOp.

Referenced by QX11PaintEngine::updateState().

00112 {
00113     Q_ASSERT(mode <= QPainter::CompositionMode_Xor);
00114     return compositionModeToRenderOp[mode];
00115 }

static QPaintEngine::PaintEngineFeatures qt_decide_features (  )  [static]

Definition at line 662 of file qpaintengine_x11.cpp.

References QPaintEngine::AlphaBlend, QPaintEngine::Antialiasing, QPaintEngine::LinearGradientFill, QPaintEngine::MaskedBrush, QPaintEngine::PainterPaths, QPaintEngine::PatternBrush, QPaintEngine::PorterDuff, QPaintEngine::PrimitiveTransform, and X11.

00663 {
00664     QPaintEngine::PaintEngineFeatures features =
00665         QPaintEngine::PrimitiveTransform
00666         | QPaintEngine::PatternBrush
00667         | QPaintEngine::AlphaBlend
00668         | QPaintEngine::PainterPaths;
00669 
00670     if (X11->use_xrender) {
00671         features |= QPaintEngine::Antialiasing;
00672         features |= QPaintEngine::PorterDuff;
00673         features |= QPaintEngine::MaskedBrush;
00674 #if 0
00675         if (X11->xrender_version > 10) {
00676             features |= QPaintEngine::LinearGradientFill;
00677             // ###
00678         }
00679 #endif
00680     }
00681 
00682     return features;
00683 }

void qt_draw_tile ( QPaintEngine ,
qreal  ,
qreal  ,
qreal  ,
qreal  ,
const QPixmap ,
qreal  ,
qreal   
)

Definition at line 436 of file qpaintengine.cpp.

References QPaintEngine::drawPixmap(), QPixmap::height(), and QPixmap::width().

Referenced by QPaintEngine::drawTiledPixmap(), and QX11PaintEngine::drawTiledPixmap().

00438 {
00439     qreal yPos, xPos, drawH, drawW, yOff, xOff;
00440     yPos = y;
00441     yOff = yOffset;
00442     while(yPos < y + h) {
00443         drawH = pixmap.height() - yOff;    // Cropping first row
00444         if (yPos + drawH > y + h)           // Cropping last row
00445             drawH = y + h - yPos;
00446         xPos = x;
00447         xOff = xOffset;
00448         while(xPos < x + w) {
00449             drawW = pixmap.width() - xOff; // Cropping first column
00450             if (xPos + drawW > x + w)           // Cropping last column
00451                 drawW = x + w - xPos;
00452             if (drawW > 0 && drawH > 0)
00453                 gc->drawPixmap(QRectF(xPos, yPos, drawW, drawH), pixmap, QRectF(xOff, yOff, drawW, drawH));
00454             xPos += drawW;
00455             xOff = 0;
00456         }
00457         yPos += drawH;
00458         yOff = 0;
00459     }
00460 }

Here is the call graph for this function:

void* qt_getClipRects ( const QRegion r,
int &  num 
)

Definition at line 120 of file qpaintengine_x11.cpp.

Referenced by QX11PaintEngine::drawPixmap(), QX11WindowSurface::flush(), and x11SetClipRegion().

00121 {
00122     return r.clipRectangles(num);
00123 }

static QPixmap qt_patternForAlpha ( uchar  alpha,
int  screen 
) [static]

Definition at line 195 of file qpaintengine_x11.cpp.

References base_dither_matrix, DITHER_SIZE, QImage::fill(), QPixmapCache::find(), QImage::Format_ARGB32, QBitmap::fromImage(), QPixmapCache::insert(), key, QString::number(), QImage::setPixel(), x, and y.

Referenced by QX11PaintEngine::updateBrush().

00196 {
00197     QPixmap pm;
00198     QString key = QLatin1String("$qt-alpha-brush$") + QString::number(alpha) + QString::number(screen);
00199     if (!QPixmapCache::find(key, pm)) {
00200         // #### why not use a mono image here????
00201         QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32);
00202         pattern.fill(0xffffffff);
00203         for (int y = 0; y < DITHER_SIZE; ++y) {
00204             for (int x = 0; x < DITHER_SIZE; ++x) {
00205                 if (base_dither_matrix[x][y] <= alpha)
00206                     pattern.setPixel(x, y, 0x00000000);
00207             }
00208         }
00209         pm = QBitmap::fromImage(pattern);
00210         pm.x11SetScreen(screen);
00211         QPixmapCache::insert(key, pm);
00212     }
00213     return pm;
00214 }

Here is the call graph for this function:

QPixmap qt_pixmapForBrush ( int  brushStyle,
bool  invert 
)

Definition at line 76 of file qbrush.cpp.

00077 {
00078     QPixmap pm;
00079     QString key = QLatin1String("$qt-brush$") + QString::number(brushStyle)
00080                   + QString::number((int)invert);
00081     if (!QPixmapCache::find(key, pm)) {
00082         pm = QBitmap::fromData(QSize(8, 8), qt_patternForBrush(brushStyle, invert),
00083                                QImage::Format_MonoLSB);
00084         QPixmapCache::insert(key, pm);
00085     }
00086 
00087     return pm;
00088 }

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 
) [static]

Definition at line 612 of file qpaintengine_x11.cpp.

References QPen::color(), and X11.

Referenced by QX11PaintEngine::drawPixmap(), and QX11PaintEngine::drawTiledPixmap().

00615 {
00616     Picture fill_fg = X11->getSolidFill(scrn, pen.color());
00617     XRenderComposite(dpy, PictOpOver,
00618                      fill_fg, src, dst, sx, sy, sx, sy, x, y, sw, sh);
00619 }

Here is the call graph for this function:

static void qt_tesselate_polygon ( QVector< XTrapezoid > *  traps,
const QPointF pg,
int  pgSize,
bool  winding,
QRect br 
) [static]

Definition at line 313 of file qpaintengine_x11.cpp.

References QVector< T >::append(), QList< T >::append(), QVector< T >::at(), QList< T >::at(), QEdge::b, QList< T >::begin(), compareEdges(), compareIntersections(), currentY, QList< T >::end(), i, isEqual(), QTextStream::left(), QEdge::m, QEdge::p1, QEdge::p2, qDebug(), qIsFinite(), qMax(), qMin(), qrealToXFixed, qRound(), qSort(), qWarning(), QList< T >::removeAt(), QVector< T >::reserve(), QTextStream::right(), QRect::setHeight(), QRect::setWidth(), QRect::setX(), QRect::setY(), QVector< T >::size(), QList< T >::size(), toXTrapezoid(), QEdge::winding, QPointF::x(), x, QPointF::y(), and y.

Referenced by QX11PaintEnginePrivate::fillPolygon_dev().

00315 {
00316     QVector<QEdge> edges;
00317     edges.reserve(128);
00318     qreal ymin(INT_MAX/256);
00319     qreal ymax(INT_MIN/256);
00320     qreal xmin(INT_MAX/256);
00321     qreal xmax(INT_MIN/256);
00322 
00323     Q_ASSERT(pg[0] == pg[pgSize-1]);
00324     // generate edge table
00325     for (int x = 0; x < pgSize-1; ++x) {
00326   QEdge edge;
00327   edge.winding = pg[x].y() > pg[x+1].y() ? 1 : -1;
00328         QPointF p1, p2;
00329   if (edge.winding > 0) {
00330       p1 = pg[x+1];
00331       p2 = pg[x];
00332   } else {
00333       p1 = pg[x];
00334       p2 = pg[x+1];
00335   }
00336         edge.p1.x = XDoubleToFixed(p1.x());
00337         edge.p1.y = XDoubleToFixed(p1.y());
00338         edge.p2.x = XDoubleToFixed(p2.x());
00339         edge.p2.y = XDoubleToFixed(p2.y());
00340 
00341   edge.m = (p1.x() == p2.x()) ? 1.e38 : (p1.y() - p2.y()) / (p1.x() - p2.x()); // line derivative
00342   edge.b = p1.y() - edge.m * p1.x(); // intersection with y axis
00343   edge.m = edge.m != 0.0 ? 1.0 / edge.m : 0.0; // inverted derivative
00344   edges.append(edge);
00345         xmin = qMin(xmin, XFixedToDouble(edge.p1.x));
00346         xmax = qMax(xmax, XFixedToDouble(edge.p2.x));
00347         ymin = qMin(ymin, XFixedToDouble(edge.p1.y));
00348         ymax = qMax(ymax, XFixedToDouble(edge.p2.y));
00349     }
00350     br->setX(qRound(xmin));
00351     br->setY(qRound(ymin));
00352     br->setWidth(qRound(xmax - xmin));
00353     br->setHeight(qRound(ymax - ymin));
00354 
00355     QList<const QEdge *> et;      // edge list
00356     for (int i = 0; i < edges.size(); ++i)
00357         et.append(&edges.at(i));
00358 
00359     // sort edge table by min y value
00360     qSort(et.begin(), et.end(), compareEdges);
00361 
00362     // eliminate shared edges
00363     for (int i = 0; i < et.size(); ++i) {
00364   for (int k = i+1; k < et.size(); ++k) {
00365             const QEdge *edgeI = et.at(i);
00366             const QEdge *edgeK = et.at(k);
00367             if (edgeK->p1.y > edgeI->p1.y)
00368                 break;
00369         if (edgeI->winding != edgeK->winding &&
00370                 isEqual(edgeI->p1, edgeK->p1) && isEqual(edgeI->p2, edgeK->p2)
00371     ) {
00372     et.removeAt(k);
00373     et.removeAt(i);
00374     --i;
00375     break;
00376       }
00377   }
00378     }
00379 
00380     if (ymax <= ymin)
00381   return;
00382     QList<const QEdge *> aet;       // edges that intersects the current scanline
00383 
00384 //     if (ymin < 0)
00385 //  ymin = 0;
00386 //     if (paintEventClipRegion) // don't scan more lines than we have to
00387 //  ymax = paintEventClipRegion->boundingRect().height();
00388 
00389 #ifdef QT_DEBUG_TESSELATOR
00390     qDebug("==> ymin = %f, ymax = %f", ymin, ymax);
00391 #endif // QT_DEBUG_TESSELATOR
00392 
00393     currentY = ymin; // used by the less than op
00394     for (qreal y = ymin; y < ymax;) {
00395   // fill active edge table with edges that intersect the current line
00396   for (int i = 0; i < et.size(); ++i) {
00397             const QEdge *edge = et.at(i);
00398             if (edge->p1.y > XDoubleToFixed(y))
00399                 break;
00400             aet.append(edge);
00401             et.removeAt(i);
00402             --i;
00403   }
00404 
00405   // remove processed edges from active edge table
00406   for (int i = 0; i < aet.size(); ++i) {
00407       if (aet.at(i)->p2.y <= XDoubleToFixed(y)) {
00408     aet.removeAt(i);
00409     --i;
00410       }
00411   }
00412         if (aet.size()%2 != 0) {
00413 #ifndef QT_NO_DEBUG
00414             qWarning("QX11PaintEngine: Internal error: aet out of sync");
00415 #endif
00416             return;
00417         }
00418 
00419   // done?
00420   if (!aet.size()) {
00421             if (!et.size()) {
00422                 break;
00423       } else {
00424     y = currentY = XFixedToDouble(et.at(0)->p1.y);
00425                 continue;
00426       }
00427         }
00428 
00429         // calculate the next y where we have to start a new set of trapezoids
00430   qreal next_y(INT_MAX/256);
00431   for (int i = 0; i < aet.size(); ++i) {
00432             const QEdge *edge = aet.at(i);
00433       if (XFixedToDouble(edge->p2.y) < next_y)
00434     next_y = XFixedToDouble(edge->p2.y);
00435         }
00436 
00437   if (et.size() && next_y > XFixedToDouble(et.at(0)->p1.y))
00438       next_y = XFixedToDouble(et.at(0)->p1.y);
00439 
00440         int aetSize = aet.size();
00441   for (int i = 0; i < aetSize; ++i) {
00442       for (int k = i+1; k < aetSize; ++k) {
00443                 const QEdge *edgeI = aet.at(i);
00444                 const QEdge *edgeK = aet.at(k);
00445     qreal m1 = edgeI->m;
00446     qreal b1 = edgeI->b;
00447     qreal m2 = edgeK->m;
00448     qreal b2 = edgeK->b;
00449 
00450     if (qAbs(m1 - m2) < 0.001)
00451                     continue;
00452 
00453                 // ### intersect is not calculated correctly when optimized with -O2 (gcc)
00454                 volatile qreal intersect;
00455                 if (!qIsFinite(b1))
00456                     intersect = (1.f / m2) * XFixedToDouble(edgeI->p1.x) + b2;
00457                 else if (!qIsFinite(b2))
00458                     intersect = (1.f / m1) * XFixedToDouble(edgeK->p1.x) + b1;
00459                 else
00460                     intersect = (b1*m1 - b2*m2) / (m1 - m2);
00461 
00462     if (intersect > y && intersect < next_y)
00463         next_y = intersect;
00464       }
00465   }
00466 
00467         XFixed yf, next_yf;
00468         yf = qrealToXFixed(y);
00469         next_yf = qrealToXFixed(next_y);
00470 
00471         if (yf == next_yf) {
00472             y = currentY = next_y;
00473             continue;
00474         }
00475 
00476 #ifdef QT_DEBUG_TESSELATOR
00477         qDebug("###> y = %f, next_y = %f, %d active edges", y, next_y, aet.size());
00478         qDebug("===> edges");
00479         dump_edges(et);
00480         qDebug("===> active edges");
00481         dump_edges(aet);
00482 #endif
00483   // calc intersection points
00484   QVarLengthArray<QIntersectionPoint> isects(aet.size()+1);
00485   for (int i = 0; i < isects.size()-1; ++i) {
00486             const QEdge *edge = aet.at(i);
00487       isects[i].x = (edge->p1.x != edge->p2.x) ?
00488         ((y - edge->b)*edge->m) : XFixedToDouble(edge->p1.x);
00489       isects[i].edge = edge;
00490   }
00491 
00492   Q_ASSERT(isects.size()%2 == 1);
00493 
00494   // sort intersection points
00495   qSort(&isects[0], &isects[isects.size()-1], compareIntersections);
00496 
00497         if (winding) {
00498             // winding fill rule
00499             for (int i = 0; i < isects.size()-1;) {
00500                 int winding = 0;
00501                 const QEdge *left = isects[i].edge;
00502                 const QEdge *right = 0;
00503                 winding += isects[i].edge->winding;
00504                 for (++i; i < isects.size()-1 && winding != 0; ++i) {
00505                     winding += isects[i].edge->winding;
00506                     right = isects[i].edge;
00507                 }
00508                 if (!left || !right)
00509                     break;
00510                 traps->append(toXTrapezoid(yf, next_yf, *left, *right));
00511             }
00512         } else {
00513             // odd-even fill rule
00514             for (int i = 0; i < isects.size()-2; i += 2)
00515                 traps->append(toXTrapezoid(yf, next_yf, *isects[i].edge, *isects[i+1].edge));
00516         }
00517   y = currentY = next_y;
00518     }
00519 
00520 #ifdef QT_DEBUG_TESSELATOR
00521     qDebug("==> number of trapezoids: %d - edge table size: %d\n", traps->size(), et.size());
00522 
00523     for (int i = 0; i < traps->size(); ++i)
00524         dump_trap(traps->at(i));
00525 #endif
00526 
00527     // optimize by unifying trapezoids that share left/right lines
00528     // and have a common top/bottom edge
00529 //     for (int i = 0; i < tps.size(); ++i) {
00530 //  for (int k = i+1; k < tps.size(); ++k) {
00531 //      if (i != k && tps.at(i).right == tps.at(k).right
00532 //    && tps.at(i).left == tps.at(k).left
00533 //    && (tps.at(i).top == tps.at(k).bottom
00534 //        || tps.at(i).bottom == tps.at(k).top))
00535 //      {
00536 //    tps[i].bottom = tps.at(k).bottom;
00537 //    tps.removeAt(k);
00538 //                 i = 0;
00539 //    break;
00540 //      }
00541 //  }
00542 //     }
00543 }

Here is the call graph for this function:

Q_GUI_EXPORT GC qt_x11_get_brush_gc ( QPainter p  ) 

Returns the X11 specific brush GC for the painter p. Note that QPainter::begin() must be called before this function returns a valid GC.

Definition at line 84 of file qpaintengine_x11.cpp.

References p, and QPaintEngine::X11.

00085 {
00086     if (p && p->paintEngine()
00087         && p->paintEngine()->isActive()
00088         && p->paintEngine()->type() == QPaintEngine::X11) {
00089         return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc_brush;
00090     }
00091     return 0;
00092 }

Q_GUI_EXPORT GC qt_x11_get_pen_gc ( QPainter p  ) 

Returns the X11 specific pen GC for the painter p. Note that QPainter::begin() must be called before this function returns a valid GC.

Definition at line 69 of file qpaintengine_x11.cpp.

References p, and QPaintEngine::X11.

00070 {
00071     if (p && p->paintEngine()
00072         && p->paintEngine()->isActive()
00073         && p->paintEngine()->type() == QPaintEngine::X11) {
00074         return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc;
00075     }
00076     return 0;
00077 }

Drawable qt_x11Handle ( const QPaintDevice pd  ) 

Definition at line 182 of file qpaintdevice_x11.cpp.

00183 {
00184     if (!pd) return 0;
00185     if (pd->devType() == QInternal::Widget)
00186         return static_cast<const QWidget *>(pd)->handle();
00187     else if (pd->devType() == QInternal::Pixmap)
00188         return static_cast<const QPixmap *>(pd)->handle();
00189     return 0;
00190 }

const QX11Info* qt_x11Info ( const QPaintDevice pd  )  [related]

Referenced by QX11PaintEngine::begin(), QGLContext::chooseContext(), QGLContext::doneCurrent(), QGLContext::makeCurrent(), QGLContext::overlayTransparentColor(), QFont::QFont(), QFontMetrics::QFontMetrics(), QFontMetricsF::QFontMetricsF(), QGLContext::reset(), and QGLContext::swapBuffers().

static void qt_XRenderCompositeTrapezoids ( Display dpy,
int  op,
Picture  src,
Picture  dst,
_Xconst XRenderPictFormat *  maskFormat,
int  xSrc,
int  ySrc,
const QVector< XTrapezoid > &  traps 
) [static]

Definition at line 1493 of file qpaintengine_x11.cpp.

References QVector< T >::constData(), and QVector< T >::size().

Referenced by QX11PaintEnginePrivate::fillPolygon_dev().

01501 {
01502     const int MAX_TRAPS = 50000;
01503     int traps_left = traps.size();
01504     while (traps_left) {
01505         int to_draw = traps_left;
01506         if (to_draw > MAX_TRAPS)
01507             to_draw = MAX_TRAPS;
01508         XRenderCompositeTrapezoids(dpy, op, src, dst,
01509                                    maskFormat,
01510                                    xSrc, ySrc,
01511                                    traps.constData()+traps.size()-traps_left, to_draw);
01512         traps_left -= to_draw;
01513     }
01514 }

Here is the call graph for this function:

static XTrapezoid QT_FASTCALL toXTrapezoid ( XFixed  y1,
XFixed  y2,
const QEdge left,
const QEdge right 
) [static]

Definition at line 271 of file qpaintengine_x11.cpp.

References QTextStream::left(), and QTextStream::right().

Referenced by qt_polygon_trapezoidation(), and qt_tesselate_polygon().

00272 {
00273     XTrapezoid trap;
00274     trap.top = y1;
00275     trap.bottom = y2;
00276     trap.left.p1.y = left.p1.y;
00277     trap.left.p2.y = left.p2.y;
00278     trap.right.p1.y = right.p1.y;
00279     trap.right.p2.y = right.p2.y;
00280     trap.left.p1.x = left.p1.x;
00281     trap.left.p2.x = left.p2.x;
00282     trap.right.p1.x = right.p1.x;
00283     trap.right.p2.x = right.p2.x;
00284     return trap;
00285 }

Here is the call graph for this function:

static void x11ClearClipRegion ( Display dpy,
GC  gc,
GC  gc2,
Picture  picture 
) [inline, static]

Definition at line 150 of file qpaintengine_x11.cpp.

References XNone.

Referenced by QX11PaintEngine::updateBrush(), QX11PaintEngine::updateClipRegion_dev(), and QX11PaintEngine::updatePen().

00157 {
00158     if (gc)
00159         XSetClipMask(dpy, gc, XNone);
00160     if (gc2)
00161         XSetClipMask(dpy, gc2, XNone);
00162 
00163 #ifndef QT_NO_XRENDER
00164     if (picture) {
00165         XRenderPictureAttributes attrs;
00166         attrs.clip_mask = XNone;
00167         XRenderChangePicture (dpy, picture, CPClipMask, &attrs);
00168     }
00169 #else
00170     Q_UNUSED(picture);
00171 #endif // QT_NO_XRENDER
00172 }

static void x11SetClipRegion ( Display dpy,
GC  gc,
GC  gc2,
Picture  picture,
const QRegion r 
) [inline, static]

Definition at line 125 of file qpaintengine_x11.cpp.

References num, and qt_getClipRects().

Referenced by QX11PaintEngine::updateBrush(), QX11PaintEngine::updateClipRegion_dev(), and QX11PaintEngine::updatePen().

00132 {
00133     int num;
00134     XRectangle *rects = (XRectangle *)qt_getClipRects(r, num);
00135 
00136     if (gc)
00137         XSetClipRectangles( dpy, gc, 0, 0, rects, num, YXBanded );
00138     if (gc2)
00139         XSetClipRectangles( dpy, gc2, 0, 0, rects, num, YXBanded );
00140 
00141 #ifndef QT_NO_XRENDER
00142     if (picture)
00143         XRenderSetPictureClipRectangles(dpy, picture, 0, 0, rects, num);
00144 #else
00145     Q_UNUSED(picture);
00146 #endif // QT_NO_XRENDER
00147 }

Here is the call graph for this function:


Variable Documentation

const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE] [static]

Initial value:

 {
  {   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 }
}

Definition at line 176 of file qpaintengine_x11.cpp.

Referenced by qt_patternForAlpha().

const int compositionModeToRenderOp[QPainter::CompositionMode_Xor+1] [static]

Initial value:

 {
    PictOpOver, 
    PictOpOverReverse, 
    PictOpClear, 
    PictOpSrc, 
    PictOpDst, 
    PictOpIn, 
    PictOpInReverse, 
    PictOpOut, 
    PictOpOutReverse, 
    PictOpAtop, 
    PictOpAtopReverse, 
    PictOpXor 
}

Definition at line 96 of file qpaintengine_x11.cpp.

Referenced by qpainterOpToXrender().

qreal currentY = 0.f [static]

Definition at line 229 of file qpaintengine_x11.cpp.

Referenced by compareIntersections(), qt_polygon_trapezoidation(), and qt_tesselate_polygon().


Generated on Thu Mar 15 13:35:03 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1