diff options
Diffstat (limited to 'src/gui/painting')
107 files changed, 806 insertions, 29007 deletions
diff --git a/src/gui/painting/makepsheader.pl b/src/gui/painting/makepsheader.pl deleted file mode 100755 index 267c183606..0000000000 --- a/src/gui/painting/makepsheader.pl +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/perl -############################################################################# -## -## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -## All rights reserved. -## Contact: Nokia Corporation (qt-info@nokia.com) -## -## This file is part of the QtGui module of the Qt Toolkit. -## -## $QT_BEGIN_LICENSE:LGPL$ -## GNU Lesser General Public License Usage -## This file may be used under the terms of the GNU Lesser General Public -## License version 2.1 as published by the Free Software Foundation and -## appearing in the file LICENSE.LGPL included in the packaging of this -## file. Please review the following information to ensure the GNU Lesser -## General Public License version 2.1 requirements will be met: -## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -## -## In addition, as a special exception, Nokia gives you certain additional -## rights. These rights are described in the Nokia Qt LGPL Exception -## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -## -## GNU General Public License Usage -## Alternatively, this file may be used under the terms of the GNU General -## Public License version 3.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 the GNU General -## Public License version 3.0 requirements will be met: -## http://www.gnu.org/copyleft/gpl.html. -## -## Other Usage -## Alternatively, this file may be used in accordance with the terms and -## conditions contained in a signed written agreement between you and Nokia. -## -## -## -## -## -## $QT_END_LICENSE$ -## -############################################################################# - -open(INPUT, 'qpsprinter.ps') - or die "Can't open qpsprinter.ps"; - -$dontcompress = 1; -while(<INPUT>) { - $line = $_; - chomp $line; - if ( /ENDUNCOMPRESS/ ) { - $dontcompress = 0; - } - $line =~ s/%.*$//; - $line = $line; - if ( $dontcompress eq 1 ) { - push(@uncompressed, $line); - } else { - push(@lines, $line); - } -# print "$line\n"; -} - -$uc = join(" ", @uncompressed); -$uc =~ s,\t+, ,g; -$uc=~ s, +, ,g; - -$h = join(" ", @lines); -$h =~ s,\t+, ,g; -$h =~ s, +, ,g; -$h = $h.' '; - -# now compress as much as possible -$h =~ s/ bind def / BD /g; -$h =~ s/ dup dup / d2 /g; -$h =~ s/ exch def / ED /g; -$h =~ s/ setfont / F /g; -$h =~ s/ rlineto / RL /g; -$h =~ s/ newpath / n /g; -$h =~ s/ currentmatrix / CM /g; -$h =~ s/ setmatrix / SM /g; -$h =~ s/ translate / TR /g; -$h =~ s/ setdash / SD /g; -$h =~ s/ aload pop setrgbcolor / SC /g; -$h =~ s/ currentfile read pop / CR /g; -$h =~ s/ index / i /g; -$h =~ s/ bitshift / bs /g; -$h =~ s/ setcolorspace / scs /g; -$h =~ s/ dict dup begin / DB /g; -$h =~ s/ end def / DE /g; -$h =~ s/ ifelse / ie /g; - -# PDF compatible naming -$h =~ s/ setlinewidth / w /g; -$h =~ s/ setdash / d /g; - -$h =~ s/ lineto / l /g; -$h =~ s/ moveto / m /g; -$h =~ s/ curveto / c /g; -$h =~ s/ closepath / h /g; -$h =~ s/ clip / W /g; -$h =~ s/ eoclip / W* /g; - -$h =~ s/ gsave / gs /g; -$h =~ s/ grestore / gr /g; - -# add the uncompressed part of the header before -$h = $uc.' '.$h; - - - -#print $h; - -# wordwrap at col 76 -@head = split(' ', $h); -$line = shift @head; -while( @head ) { - $token = shift @head; - chomp $token; -# print "\nl=$l, len=$len, token=$token."; - $newline = $line.' '.$token; - $newline =~ s, /,/,g; - $newline =~ s, \{,\{,g; - $newline =~ s, \},\},g; - $newline =~ s, \[,\[,g; - $newline =~ s, \],\],g; - $newline =~ s,\{ ,\{,g; - $newline =~ s,\} ,\},g; - $newline =~ s,\[ ,\[,g; - $newline =~ s,\] ,\],g; - if ( length( $newline ) > 76 ) { -# print "\nline=$line\n"; - $header = $header."\n\"".$line."\\n\""; - $newline = $token; - } - $line = $newline; -} -$header = $header."\n\"".$line."\\n\""; - - -print "static const char *const ps_header ="; -print $header.";\n\n"; - -close(INPUT); -exit; - -open(INPUT, 'qpsprinter.agl') - or die "Can't open qpsprinter.ps"; - -print "static const char * const agl =\n"; - -$str = "\""; -$string =""; -$i = 0; -while(<INPUT>) { - $line = $_; - chomp $line; - $line =~ s/#.*//; - if(length($line) ne 0) { - $num = $line; - $name = $line; - $num =~ s/,.*//; - $name =~ s/.*, \"//; - $name =~ s/\".*//; - push(@qchar, $num); - push(@index, $i); - if(length($str.$name) > 76) { - $str = $str."\"\n"; - $string = $string.$str; - $str = "\""; - } - $str = $str.$name."\\0"; - $i += length($name)+1; - } -} - -print $string.";\n\n"; - -print "static const struct { quint16 u; quint16 index; } unicodetoglyph[] = {\n "; - -$loop = 0; -while( @qchar ) { - $loop = $loop + 1; - $ch = shift @qchar; - $i = shift @index; - print "{".$ch.", ".$i."}"; - if($ch ne "0xFFFF") { - print ", "; - } - if(!($loop % 4)) { - print "\n "; - } -}; - -print "\n};\n\n"; - diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 13a9ba1c73..dfc1f88d6d 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -1,15 +1,14 @@ # Qt gui library, paint module HEADERS += \ + painting/qbackingstore.h \ painting/qbezier_p.h \ painting/qbrush.h \ painting/qcolor.h \ painting/qcolor_p.h \ painting/qcolormap.h \ painting/qcosmeticstroker_p.h \ - painting/qdrawutil.h \ painting/qemulationpaintengine_p.h \ - painting/qgraphicssystem_p.h \ painting/qmatrix.h \ painting/qmemrotate_p.h \ painting/qoutlinemapper_p.h \ @@ -30,8 +29,6 @@ HEADERS += \ painting/qpolygon.h \ painting/qpolygonclipper_p.h \ painting/qprintengine.h \ - painting/qprintengine_pdf_p.h \ - painting/qprintengine_ps_p.h \ painting/qprinter.h \ painting/qprinter_p.h \ painting/qprinterinfo.h \ @@ -39,16 +36,15 @@ HEADERS += \ painting/qrasterizer_p.h \ painting/qregion.h \ painting/qstroker_p.h \ - painting/qstylepainter.h \ painting/qtessellator_p.h \ painting/qtextureglyphcache_p.h \ painting/qtransform.h \ - painting/qwindowsurface_p.h \ - painting/qwmatrix.h \ + painting/qplatformbackingstore_qpa.h \ painting/qpaintbuffer_p.h SOURCES += \ + painting/qbackingstore.cpp \ painting/qbezier.cpp \ painting/qblendfunctions.cpp \ painting/qbrush.cpp \ @@ -56,9 +52,7 @@ SOURCES += \ painting/qcolor_p.cpp \ painting/qcosmeticstroker.cpp \ painting/qcssutil.cpp \ - painting/qdrawutil.cpp \ painting/qemulationpaintengine.cpp \ - painting/qgraphicssystem.cpp \ painting/qmatrix.cpp \ painting/qmemrotate.cpp \ painting/qoutlinemapper.cpp \ @@ -74,17 +68,15 @@ SOURCES += \ painting/qpen.cpp \ painting/qpolygon.cpp \ painting/qprintengine_pdf.cpp \ - painting/qprintengine_ps.cpp \ painting/qprinter.cpp \ painting/qprinterinfo.cpp \ painting/qrasterizer.cpp \ painting/qregion.cpp \ painting/qstroker.cpp \ - painting/qstylepainter.cpp \ painting/qtessellator.cpp \ painting/qtextureglyphcache.cpp \ painting/qtransform.cpp \ - painting/qwindowsurface.cpp \ + painting/qplatformbackingstore_qpa.cpp \ painting/qpaintbuffer.cpp SOURCES += \ @@ -104,40 +96,17 @@ SOURCES += \ painting/qpaintengine_blitter_p.h \ painting/qblittable_p.h \ -win32 { +win32:!qpa { HEADERS += painting/qprintengine_win_p.h SOURCES += \ painting/qcolormap_win.cpp \ painting/qpaintdevice_win.cpp \ - painting/qprintengine_win.cpp \ - painting/qprinterinfo_win.cpp + painting/qprintengine_win.cpp !win32-borland:!wince*:LIBS += -lmsimg32 } -embedded { - HEADERS += \ - painting/qgraphicssystem_qws_p.h \ - - SOURCES += \ - painting/qgraphicssystem_qws.cpp \ - -} else: if(!qpa) { - HEADERS += \ - painting/qgraphicssystem_raster_p.h \ - painting/qgraphicssystem_runtime_p.h \ - painting/qgraphicssystemfactory_p.h \ - painting/qgraphicssystemplugin_p.h \ - painting/qwindowsurface_raster_p.h - - SOURCES += \ - painting/qgraphicssystem_raster.cpp \ - painting/qgraphicssystem_runtime.cpp \ - painting/qgraphicssystemfactory.cpp \ - painting/qgraphicssystemplugin.cpp \ - painting/qwindowsurface_raster.cpp -} unix:x11 { HEADERS += \ @@ -149,50 +118,33 @@ unix:x11 { painting/qpaintengine_x11.cpp } -!embedded:!qpa:!x11:mac { +!qpa:!x11:mac { HEADERS += \ painting/qpaintengine_mac_p.h \ - painting/qgraphicssystem_mac_p.h \ painting/qprintengine_mac_p.h SOURCES += \ painting/qcolormap_mac.cpp \ painting/qpaintdevice_mac.cpp \ painting/qpaintengine_mac.cpp \ - painting/qgraphicssystem_mac.cpp \ painting/qprinterinfo_mac.cpp OBJECTIVE_SOURCES += \ painting/qprintengine_mac.mm \ } -unix:!mac:!symbian|qpa { +unix:!symbian { HEADERS += \ painting/qprinterinfo_unix_p.h SOURCES += \ painting/qprinterinfo_unix.cpp } -win32|x11|mac|embedded|qpa|symbian { - SOURCES += painting/qbackingstore.cpp - HEADERS += painting/qbackingstore_p.h -} - -embedded { - contains(QT_CONFIG,qtopia) { - DEFINES += QTOPIA_PRINTENGINE - HEADERS += painting/qprintengine_qws_p.h - SOURCES += painting/qprintengine_qws.cpp - } - - SOURCES += \ - painting/qcolormap_qws.cpp \ - painting/qpaintdevice_qws.cpp -} - qpa { + HEADERS += painting/qplatformprintersupport_qpa.h SOURCES += \ painting/qcolormap_qpa.cpp \ - painting/qpaintdevice_qpa.cpp + painting/qpaintdevice_qpa.cpp \ + painting/qplatformprintersupport_qpa.cpp } symbian { @@ -205,7 +157,7 @@ symbian { painting/qpaintengine_s60_p.h } -x11|embedded|qpa { +x11|qpa:!win32 { contains(QT_CONFIG,qtopia) { DEFINES += QT_NO_CUPS QT_NO_LPR } else { @@ -230,29 +182,8 @@ if(mmx|3dnow|sse|sse2|iwmmxt) { IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp } -x11 { - HEADERS += painting/qwindowsurface_x11_p.h - SOURCES += painting/qwindowsurface_x11.cpp -} - -!embedded:!qpa:mac { - HEADERS += painting/qwindowsurface_mac_p.h \ - painting/qunifiedtoolbarsurface_mac_p.h - SOURCES += painting/qwindowsurface_mac.cpp \ - painting/qunifiedtoolbarsurface_mac.cpp -} - -embedded { - HEADERS += painting/qwindowsurface_qws_p.h - SOURCES += painting/qwindowsurface_qws.cpp -} - - - symbian { - HEADERS += painting/qwindowsurface_s60_p.h \ - painting/qdrawhelper_arm_simd_p.h - SOURCES += painting/qwindowsurface_s60.cpp + HEADERS += painting/qdrawhelper_arm_simd_p.h armccIfdefBlock = \ "$${LITERAL_HASH}if defined(ARMV6)" \ "MACRO QT_HAVE_ARM_SIMD" \ diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 6fbb59fc89..776e33a1a8 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -39,1630 +39,212 @@ ** ****************************************************************************/ +#include <qbackingstore.h> +#include <qwindow.h> +#include <qpixmap.h> +#include <qplatformbackingstore_qpa.h> -#include "qplatformdefs.h" - -#include "qbackingstore_p.h" - -#include <QtCore/qglobal.h> -#include <QtCore/qdebug.h> -#include <QtCore/qvarlengtharray.h> -#include <QtGui/qevent.h> -#include <QtGui/qapplication.h> -#include <QtGui/qpaintengine.h> -#include <QtGui/qgraphicsproxywidget.h> - -#include <private/qwidget_p.h> -#include <private/qwindowsurface_raster_p.h> -#include <private/qapplication_p.h> -#include <private/qpaintengine_raster_p.h> -#include <private/qgraphicseffect_p.h> - -#include "qgraphicssystem_p.h" - -#ifdef Q_WS_QWS -#include <QtGui/qwsmanager_qws.h> -#include <private/qwsmanager_p.h> -#endif +#include <private/qguiapplication_p.h> +#include <private/qwindow_p.h> QT_BEGIN_NAMESPACE -extern QRegion qt_dirtyRegion(QWidget *); - -/* - A version of QRect::intersects() that does not normalize the rects. -*/ -static inline bool qRectIntersects(const QRect &r1, const QRect &r2) -{ - return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) - && qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom())); -} - -/** - * Flushes the contents of the \a windowSurface into the screen area of \a widget. - * \a tlwOffset is the position of the top level widget relative to the window surface. - * \a region is the region to be updated in \a widget coordinates. - */ -static inline void qt_flush(QWidget *widget, const QRegion ®ion, QWindowSurface *windowSurface, - QWidget *tlw, const QPoint &tlwOffset) -{ - Q_ASSERT(widget); - Q_ASSERT(!region.isEmpty()); - Q_ASSERT(windowSurface); - Q_ASSERT(tlw); - -#if !defined(QT_NO_PAINT_DEBUG) && !defined(Q_WS_QWS) - // QWS does flush update in QWindowSurface::flush (because it needs to lock the surface etc). - static int flushUpdate = qgetenv("QT_FLUSH_UPDATE").toInt(); - if (flushUpdate > 0) - QWidgetBackingStore::showYellowThing(widget, region, flushUpdate * 10, false); -#endif - - //The performance hit by doing this should be negligible. However, be aware that - //using this FPS when you have > 1 windowsurface can give you inaccurate FPS - static bool fpsDebug = qgetenv("QT_DEBUG_FPS").toInt(); - if (fpsDebug) { - static QTime time = QTime::currentTime(); - static int frames = 0; - - frames++; - - if(time.elapsed() > 5000) { - double fps = double(frames * 1000) /time.restart(); - fprintf(stderr,"FPS: %.1f\n",fps); - frames = 0; - } - } - if (widget != tlw) - windowSurface->flush(widget, region, tlwOffset + widget->mapTo(tlw, QPoint())); - else - windowSurface->flush(widget, region, tlwOffset); -} - -#ifndef QT_NO_PAINT_DEBUG -#ifdef Q_WS_WIN -static void showYellowThing_win(QWidget *widget, const QRegion ®ion, int msec) -{ - HBRUSH brush; - static int i = 0; - switch (i) { - case 0: - brush = CreateSolidBrush(RGB(255, 255, 0)); - break; - case 1: - brush = CreateSolidBrush(RGB(255, 200, 55)); - break; - case 2: - brush = CreateSolidBrush(RGB(200, 255, 55)); - break; - case 3: - brush = CreateSolidBrush(RGB(200, 200, 0)); - break; - } - i = (i + 1) & 3; - - HDC hdc = widget->getDC(); - - const QVector<QRect> &rects = region.rects(); - foreach (QRect rect, rects) { - RECT winRect; - SetRect(&winRect, rect.left(), rect.top(), rect.right(), rect.bottom()); - FillRect(hdc, &winRect, brush); - } - - widget->releaseDC(hdc); - ::Sleep(msec); -} -#endif - -void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePainted, int msec, bool unclipped) +class QBackingStorePrivate { -#ifdef Q_WS_QWS - Q_UNUSED(widget); - Q_UNUSED(unclipped); - static QWSYellowSurface surface(true); - surface.setDelay(msec); - surface.flush(widget, toBePainted, QPoint()); -#else - QRegion paintRegion = toBePainted; - QRect widgetRect = widget->rect(); - - if (!widget->internalWinId()) { - QWidget *nativeParent = widget->nativeParentWidget(); - const QPoint offset = widget->mapTo(nativeParent, QPoint(0, 0)); - paintRegion.translate(offset); - widgetRect.translate(offset); - widget = nativeParent; - } - -#ifdef Q_WS_WIN - Q_UNUSED(unclipped); - showYellowThing_win(widget, paintRegion, msec); -#else - //flags to fool painter - bool paintUnclipped = widget->testAttribute(Qt::WA_PaintUnclipped); - if (unclipped && !widget->d_func()->paintOnScreen()) - widget->setAttribute(Qt::WA_PaintUnclipped); - - const bool setFlag = !widget->testAttribute(Qt::WA_WState_InPaintEvent); - if (setFlag) - widget->setAttribute(Qt::WA_WState_InPaintEvent); - - //setup the engine - QPaintEngine *pe = widget->paintEngine(); - if (pe) { - pe->setSystemClip(paintRegion); - { - QPainter p(widget); - p.setClipRegion(paintRegion); - static int i = 0; - switch (i) { - case 0: - p.fillRect(widgetRect, QColor(255,255,0)); - break; - case 1: - p.fillRect(widgetRect, QColor(255,200,55)); - break; - case 2: - p.fillRect(widgetRect, QColor(200,255,55)); - break; - case 3: - p.fillRect(widgetRect, QColor(200,200,0)); - break; - } - i = (i+1) & 3; - p.end(); - } +public: + QBackingStorePrivate(QWindow *w) + : window(w) + { } - if (setFlag) - widget->setAttribute(Qt::WA_WState_InPaintEvent, false); - - //restore - widget->setAttribute(Qt::WA_PaintUnclipped, paintUnclipped); - - if (pe) - pe->setSystemClip(QRegion()); - - QApplication::syncX(); - -#if defined(Q_OS_UNIX) - ::usleep(1000 * msec); -#endif -#endif // Q_WS_WIN -#endif // Q_WS_QWS -} - -bool QWidgetBackingStore::flushPaint(QWidget *widget, const QRegion &rgn) -{ - if (!widget) - return false; - - int delay = 0; - if (widget->testAttribute(Qt::WA_WState_InPaintEvent)) { - static int flushPaintEvent = qgetenv("QT_FLUSH_PAINT_EVENT").toInt(); - if (!flushPaintEvent) - return false; - delay = flushPaintEvent; - } else { - static int flushPaint = qgetenv("QT_FLUSH_PAINT").toInt(); - if (!flushPaint) - return false; - delay = flushPaint; - } - - QWidgetBackingStore::showYellowThing(widget, rgn, delay * 10, true); - return true; -} - -void QWidgetBackingStore::unflushPaint(QWidget *widget, const QRegion &rgn) -{ - if (widget->d_func()->paintOnScreen() || rgn.isEmpty()) - return; - - QWidget *tlw = widget->window(); - QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData(); - if (!tlwExtra) - return; - - const QPoint offset = widget->mapTo(tlw, QPoint()); - qt_flush(widget, rgn, tlwExtra->backingStore->windowSurface, tlw, offset); -} -#endif // QT_NO_PAINT_DEBUG - -/* - Moves the whole rect by (dx, dy) in widget's coordinate system. - Doesn't generate any updates. -*/ -bool QWidgetBackingStore::bltRect(const QRect &rect, int dx, int dy, QWidget *widget) -{ - const QPoint pos(tlwOffset + widget->mapTo(tlw, rect.topLeft())); - const QRect tlwRect(QRect(pos, rect.size())); - if (fullUpdatePending || dirty.intersects(tlwRect)) - return false; // We don't want to scroll junk. - return windowSurface->scroll(tlwRect, dx, dy); -} - -void QWidgetBackingStore::releaseBuffer() -{ - if (windowSurface) -#if defined(Q_WS_QPA) - windowSurface->resize(QSize()); -#else - windowSurface->setGeometry(QRect()); -#endif -#ifdef Q_BACKINGSTORE_SUBSURFACES - for (int i = 0; i < subSurfaces.size(); ++i) - subSurfaces.at(i)->setGeometry(QRect()); -#endif -} + QWindow *window; + QPlatformBackingStore *platformBackingStore; + QRegion staticContents; + QSize size; +}; /*! - Prepares the window surface to paint a\ toClean region of the \a widget and - updates the BeginPaintInfo struct accordingly. + \class QBackingStore + \since 5.0 - The \a toClean region might be clipped by the window surface. + \brief The QBackingStore class provides the drawing area for top-level windows. */ -void QWidgetBackingStore::beginPaint(QRegion &toClean, QWidget *widget, QWindowSurface *windowSurface, - BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates) -{ -#ifdef Q_WS_QWS - QWSWindowSurface *surface = static_cast<QWSWindowSurface *>(windowSurface); - QWidget *surfaceWidget = surface->window(); - - if (!surface->isValid()) { - // this looks strange but it really just releases the surface - surface->releaseSurface(); - // the old window surface is deleted in setWindowSurface, which is - // called from QWindowSurface constructor. - windowSurface = tlw->d_func()->createDefaultWindowSurface(); - surface = static_cast<QWSWindowSurface *>(windowSurface); - // createDefaultWindowSurface() will set topdata->windowSurface on the - // widget to zero. However, if this is a sub-surface, it should point - // to the widget's sub windowSurface, so we set that here: - if (!surfaceWidget->isWindow()) - surfaceWidget->d_func()->topData()->windowSurface = windowSurface; - surface->setGeometry(topLevelRect()); - returnInfo->windowSurfaceRecreated = true; - } - - const QRegion toCleanUnclipped(toClean); - - if (surfaceWidget->isWindow()) - tlwOffset = surface->painterOffset(); -#ifdef Q_BACKINGSTORE_SUBSURFACES - else if (toCleanIsInTopLevelCoordinates) - toClean &= surface->clipRegion().translated(surfaceWidget->mapTo(tlw, QPoint())); - if (!toCleanIsInTopLevelCoordinates && windowSurface == this->windowSurface) - toClean &= surface->clipRegion().translated(-widget->mapTo(surfaceWidget, QPoint())); -#else - toClean &= surface->clipRegion(); -#endif - - if (toClean.isEmpty()) { - if (surfaceWidget->isWindow()) { - dirtyFromPreviousSync += toCleanUnclipped; - hasDirtyFromPreviousSync = true; - } - - returnInfo->nothingToPaint = true; - // Nothing to repaint. However, we might have newly exposed areas on the - // screen, so we have to make sure those are flushed. - flush(); - return; - } - - if (surfaceWidget->isWindow()) { - if (toCleanUnclipped != toClean) { - dirtyFromPreviousSync += (toCleanUnclipped - surface->clipRegion()); - hasDirtyFromPreviousSync = true; - } - if (hasDirtyFromPreviousSync) { - dirtyFromPreviousSync -= toClean; - hasDirtyFromPreviousSync = !dirtyFromPreviousSync.isEmpty(); - } - } - -#endif // Q_WS_QWS - Q_UNUSED(widget); - Q_UNUSED(toCleanIsInTopLevelCoordinates); - - // Always flush repainted areas. - dirtyOnScreen += toClean; - -#if defined(Q_WS_QWS) && !defined(Q_BACKINGSTORE_SUBSURFACES) - toClean.translate(tlwOffset); -#endif - -#ifdef QT_NO_PAINT_DEBUG - windowSurface->beginPaint(toClean); -#else - returnInfo->wasFlushed = QWidgetBackingStore::flushPaint(tlw, toClean); - // Avoid deadlock with QT_FLUSH_PAINT: the server will wait for - // the BackingStore lock, so if we hold that, the server will - // never release the Communication lock that we are waiting for in - // sendSynchronousCommand - if (!returnInfo->wasFlushed) - windowSurface->beginPaint(toClean); -#endif - - Q_UNUSED(returnInfo); -} - -void QWidgetBackingStore::endPaint(const QRegion &cleaned, QWindowSurface *windowSurface, - BeginPaintInfo *beginPaintInfo) -{ -#ifndef QT_NO_PAINT_DEBUG - if (!beginPaintInfo->wasFlushed) - windowSurface->endPaint(cleaned); - else - QWidgetBackingStore::unflushPaint(tlw, cleaned); -#else - Q_UNUSED(beginPaintInfo); - windowSurface->endPaint(cleaned); -#endif - -#ifdef Q_BACKINGSTORE_SUBSURFACES - flush(static_cast<QWSWindowSurface *>(windowSurface)->window(), windowSurface); -#else - flush(); -#endif -} /*! - Returns the region (in top-level coordinates) that needs repaint and/or flush. + \fn void QBackingStore::beginPaint(const QRegion ®ion) - If the widget is non-zero, only the dirty region for the widget is returned - and the region will be in widget coordinates. -*/ -QRegion QWidgetBackingStore::dirtyRegion(QWidget *widget) const -{ - const bool widgetDirty = widget && widget != tlw; - const QRect tlwRect(topLevelRect()); -#if defined(Q_WS_QPA) - const QRect surfaceGeometry(tlwRect.topLeft(), windowSurface->size()); -#else - const QRect surfaceGeometry(windowSurface->geometry()); -#endif - if (fullUpdatePending || (surfaceGeometry != tlwRect && surfaceGeometry.size() != tlwRect.size())) { - if (widgetDirty) { - const QRect dirtyTlwRect = QRect(QPoint(), tlwRect.size()); - const QPoint offset(widget->mapTo(tlw, QPoint())); - const QRect dirtyWidgetRect(dirtyTlwRect & widget->rect().translated(offset)); - return dirtyWidgetRect.translated(-offset); - } - return QRect(QPoint(), tlwRect.size()); - } + This function is called before painting onto the surface begins, + with the \a region in which the painting will occur. - // Calculate the region that needs repaint. - QRegion r(dirty); - for (int i = 0; i < dirtyWidgets.size(); ++i) { - QWidget *w = dirtyWidgets.at(i); - if (widgetDirty && w != widget && !widget->isAncestorOf(w)) - continue; - r += w->d_func()->dirty.translated(w->mapTo(tlw, QPoint())); - } - - // Append the region that needs flush. - r += dirtyOnScreen; - - if (dirtyOnScreenWidgets) { // Only in use with native child widgets. - for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) { - QWidget *w = dirtyOnScreenWidgets->at(i); - if (widgetDirty && w != widget && !widget->isAncestorOf(w)) - continue; - QWidgetPrivate *wd = w->d_func(); - Q_ASSERT(wd->needsFlush); - r += wd->needsFlush->translated(w->mapTo(tlw, QPoint())); - } - } - - if (widgetDirty) { - // Intersect with the widget geometry and translate to its coordinates. - const QPoint offset(widget->mapTo(tlw, QPoint())); - r &= widget->rect().translated(offset); - r.translate(-offset); - } - return r; -} - -/*! - Returns the static content inside the \a parent if non-zero; otherwise the static content - for the entire backing store is returned. The content will be clipped to \a withinClipRect - if non-empty. + \sa endPaint(), paintDevice() */ -QRegion QWidgetBackingStore::staticContents(QWidget *parent, const QRect &withinClipRect) const -{ - if (!parent && tlw->testAttribute(Qt::WA_StaticContents)) { -#if defined(Q_WS_QPA) - const QSize surfaceGeometry(windowSurface->size()); -#else - const QRect surfaceGeometry(windowSurface->geometry()); -#endif - QRect surfaceRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height()); - if (!withinClipRect.isEmpty()) - surfaceRect &= withinClipRect; - return QRegion(surfaceRect); - } - QRegion region; - if (parent && parent->d_func()->children.isEmpty()) - return region; - - const bool clipToRect = !withinClipRect.isEmpty(); - const int count = staticWidgets.count(); - for (int i = 0; i < count; ++i) { - QWidget *w = staticWidgets.at(i); - QWidgetPrivate *wd = w->d_func(); - if (!wd->isOpaque || !wd->extra || wd->extra->staticContentsSize.isEmpty() - || !w->isVisible() || (parent && !parent->isAncestorOf(w))) { - continue; - } - - QRect rect(0, 0, wd->extra->staticContentsSize.width(), wd->extra->staticContentsSize.height()); - const QPoint offset = w->mapTo(parent ? parent : tlw, QPoint()); - if (clipToRect) - rect &= withinClipRect.translated(-offset); - if (rect.isEmpty()) - continue; - - rect &= wd->clipRect(); - if (rect.isEmpty()) - continue; - - QRegion visible(rect); - wd->clipToEffectiveMask(visible); - if (visible.isEmpty()) - continue; - wd->subtractOpaqueSiblings(visible, 0, /*alsoNonOpaque=*/true); - - visible.translate(offset); - region += visible; - } - - return region; -} +/*! + \fn void QBackingStore::endPaint(const QRegion ®ion) -static inline void sendUpdateRequest(QWidget *widget, bool updateImmediately) -{ - if (!widget) - return; + This function is called after painting onto the surface has ended, + with the \a region in which the painting was performed. - if (updateImmediately) { - QEvent event(QEvent::UpdateRequest); - QApplication::sendEvent(widget, &event); - } else { - QApplication::postEvent(widget, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority); - } -} + \sa beginPaint(), paintDevice() +*/ /*! - Marks the region of the widget as dirty (if not already marked as dirty) and - posts an UpdateRequest event to the top-level widget (if not already posted). + \fn void QBackingStore::flush(QWindow *window, const QRegion ®ion, + const QPoint &offset) - If updateImmediately is true, the event is sent immediately instead of posted. + Flushes the given \a region from the specified \a window onto the + screen. - If invalidateBuffer is true, all widgets intersecting with the region will be dirty. - - If the widget paints directly on screen, the event is sent to the widget - instead of the top-level widget, and invalidateBuffer is completely ignored. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). + Note that the \a offset parameter is currently unused. */ -void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool updateImmediately, - bool invalidateBuffer) +void QBackingStore::flush(const QRegion ®ion, QWindow *win, const QPoint &offset) { - Q_ASSERT(tlw->d_func()->extra); - Q_ASSERT(tlw->d_func()->extra->topextra); - Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize); - Q_ASSERT(widget->isVisible() && widget->updatesEnabled()); - Q_ASSERT(widget->window() == tlw); - Q_ASSERT(!rgn.isEmpty()); - -#ifndef QT_NO_GRAPHICSEFFECT - widget->d_func()->invalidateGraphicsEffectsRecursively(); -#endif //QT_NO_GRAPHICSEFFECT - - if (widget->d_func()->paintOnScreen()) { - if (widget->d_func()->dirty.isEmpty()) { - widget->d_func()->dirty = rgn; - sendUpdateRequest(widget, updateImmediately); - return; - } else if (qt_region_strictContains(widget->d_func()->dirty, widget->rect())) { - if (updateImmediately) - sendUpdateRequest(widget, updateImmediately); - return; // Already dirty. - } - - const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty(); - widget->d_func()->dirty += rgn; - if (!eventAlreadyPosted || updateImmediately) - sendUpdateRequest(widget, updateImmediately); - return; - } - - if (fullUpdatePending) { - if (updateImmediately) - sendUpdateRequest(tlw, updateImmediately); - return; - } - - if (!windowSurface->hasFeature(QWindowSurface::PartialUpdates)) { - fullUpdatePending = true; - sendUpdateRequest(tlw, updateImmediately); - return; - } - - const QPoint offset = widget->mapTo(tlw, QPoint()); - const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect()); - if (qt_region_strictContains(dirty, widgetRect.translated(offset))) { - if (updateImmediately) - sendUpdateRequest(tlw, updateImmediately); - return; // Already dirty. - } - - if (invalidateBuffer) { - const bool eventAlreadyPosted = !dirty.isEmpty(); -#ifndef QT_NO_GRAPHICSEFFECT - if (widget->d_func()->graphicsEffect) - dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset); - else -#endif //QT_NO_GRAPHICSEFFECT - dirty += rgn.translated(offset); - if (!eventAlreadyPosted || updateImmediately) - sendUpdateRequest(tlw, updateImmediately); - return; - } - - if (dirtyWidgets.isEmpty()) { - addDirtyWidget(widget, rgn); - sendUpdateRequest(tlw, updateImmediately); - return; - } - - if (widget->d_func()->inDirtyList) { - if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) { -#ifndef QT_NO_GRAPHICSEFFECT - if (widget->d_func()->graphicsEffect) - widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()); - else -#endif //QT_NO_GRAPHICSEFFECT - widget->d_func()->dirty += rgn; - } - } else { - addDirtyWidget(widget, rgn); - } - - if (updateImmediately) - sendUpdateRequest(tlw, updateImmediately); + if (!win) + win = window(); + d_ptr->platformBackingStore->flush(win, region, offset); } /*! - This function is equivalent to calling markDirty(QRegion(rect), ...), but - is more efficient as it eliminates QRegion operations/allocations and can - use the rect more precisely for additional cut-offs. + \fn QPaintDevice* QBackingStore::paintDevice() - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). + Implement this function to return the appropriate paint device. */ -void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool updateImmediately, - bool invalidateBuffer) +QPaintDevice *QBackingStore::paintDevice() { - Q_ASSERT(tlw->d_func()->extra); - Q_ASSERT(tlw->d_func()->extra->topextra); - Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize); - Q_ASSERT(widget->isVisible() && widget->updatesEnabled()); - Q_ASSERT(widget->window() == tlw); - Q_ASSERT(!rect.isEmpty()); - -#ifndef QT_NO_GRAPHICSEFFECT - widget->d_func()->invalidateGraphicsEffectsRecursively(); -#endif //QT_NO_GRAPHICSEFFECT - - if (widget->d_func()->paintOnScreen()) { - if (widget->d_func()->dirty.isEmpty()) { - widget->d_func()->dirty = QRegion(rect); - sendUpdateRequest(widget, updateImmediately); - return; - } else if (qt_region_strictContains(widget->d_func()->dirty, rect)) { - if (updateImmediately) - sendUpdateRequest(widget, updateImmediately); - return; // Already dirty. - } - - const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty(); - widget->d_func()->dirty += rect; - if (!eventAlreadyPosted || updateImmediately) - sendUpdateRequest(widget, updateImmediately); - return; - } - - if (fullUpdatePending) { - if (updateImmediately) - sendUpdateRequest(tlw, updateImmediately); - return; - } - - if (!windowSurface->hasFeature(QWindowSurface::PartialUpdates)) { - fullUpdatePending = true; - sendUpdateRequest(tlw, updateImmediately); - return; - } - - const QRect widgetRect = widget->d_func()->effectiveRectFor(rect); - const QRect translatedRect(widgetRect.translated(widget->mapTo(tlw, QPoint()))); - if (qt_region_strictContains(dirty, translatedRect)) { - if (updateImmediately) - sendUpdateRequest(tlw, updateImmediately); - return; // Already dirty - } - - if (invalidateBuffer) { - const bool eventAlreadyPosted = !dirty.isEmpty(); - dirty += translatedRect; - if (!eventAlreadyPosted || updateImmediately) - sendUpdateRequest(tlw, updateImmediately); - return; - } - - if (dirtyWidgets.isEmpty()) { - addDirtyWidget(widget, rect); - sendUpdateRequest(tlw, updateImmediately); - return; - } - - if (widget->d_func()->inDirtyList) { - if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) - widget->d_func()->dirty += widgetRect; - } else { - addDirtyWidget(widget, rect); - } - - if (updateImmediately) - sendUpdateRequest(tlw, updateImmediately); + return d_ptr->platformBackingStore->paintDevice(); } /*! - Marks the \a region of the \a widget as dirty on screen. The \a region will be copied from - the backing store to the \a widget's native parent next time flush() is called. - - Paint on screen widgets are ignored. + Constructs an empty surface for the given top-level \a window. */ -void QWidgetBackingStore::markDirtyOnScreen(const QRegion ®ion, QWidget *widget, const QPoint &topLevelOffset) -{ - if (!widget || widget->d_func()->paintOnScreen() || region.isEmpty()) - return; - -#if defined(Q_WS_QWS) || defined(Q_WS_MAC) - if (!widget->testAttribute(Qt::WA_WState_InPaintEvent)) - dirtyOnScreen += region.translated(topLevelOffset); - return; -#endif - - // Top-level. - if (widget == tlw) { - if (!widget->testAttribute(Qt::WA_WState_InPaintEvent)) - dirtyOnScreen += region; - return; - } - - // Alien widgets. - if (!widget->internalWinId() && !widget->isWindow()) { - QWidget *nativeParent = widget->nativeParentWidget(); // Alien widgets with the top-level as the native parent (common case). - if (nativeParent == tlw) { - if (!widget->testAttribute(Qt::WA_WState_InPaintEvent)) - dirtyOnScreen += region.translated(topLevelOffset); - return; - } - - // Alien widgets with native parent != tlw. - QWidgetPrivate *nativeParentPrivate = nativeParent->d_func(); - if (!nativeParentPrivate->needsFlush) - nativeParentPrivate->needsFlush = new QRegion; - const QPoint nativeParentOffset = widget->mapTo(nativeParent, QPoint()); - *nativeParentPrivate->needsFlush += region.translated(nativeParentOffset); - appendDirtyOnScreenWidget(nativeParent); - return; - } - - // Native child widgets. - QWidgetPrivate *widgetPrivate = widget->d_func(); - if (!widgetPrivate->needsFlush) - widgetPrivate->needsFlush = new QRegion; - *widgetPrivate->needsFlush += region; - appendDirtyOnScreenWidget(widget); -} - -void QWidgetBackingStore::removeDirtyWidget(QWidget *w) -{ - if (!w) - return; - - dirtyWidgetsRemoveAll(w); - dirtyOnScreenWidgetsRemoveAll(w); - resetWidget(w); - - QWidgetPrivate *wd = w->d_func(); - const int n = wd->children.count(); - for (int i = 0; i < n; ++i) { - if (QWidget *child = qobject_cast<QWidget*>(wd->children.at(i))) - removeDirtyWidget(child); - } -} - -#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) -bool QWidgetBackingStore::hasDirtyWindowDecoration() const -{ - QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData(); - if (tlwExtra && tlwExtra->qwsManager) - return !tlwExtra->qwsManager->d_func()->dirtyRegions.isEmpty(); - return false; -} - -void QWidgetBackingStore::paintWindowDecoration() -{ - if (!hasDirtyWindowDecoration()) - return; - - QDecoration &decoration = QApplication::qwsDecoration(); - const QRect decorationRect = tlw->rect(); - QRegion decorationRegion = decoration.region(tlw, decorationRect); - - QWSManagerPrivate *managerPrivate = tlw->d_func()->topData()->qwsManager->d_func(); - const bool doClipping = !managerPrivate->entireDecorationNeedsRepaint - && !managerPrivate->dirtyClip.isEmpty(); - - if (doClipping) { - decorationRegion &= static_cast<QWSWindowSurface *>(windowSurface)->clipRegion(); - decorationRegion &= managerPrivate->dirtyClip; - } - - if (decorationRegion.isEmpty()) - return; - - //### The QWS decorations do not always paint the pixels they promise to paint. - // This causes painting problems with QWSMemorySurface. Since none of the other - // window surfaces actually use the region, passing an empty region is a safe - // workaround. - - windowSurface->beginPaint(QRegion()); - - QPaintEngine *engine = windowSurface->paintDevice()->paintEngine(); - Q_ASSERT(engine); - const QRegion oldSystemClip(engine->systemClip()); - engine->setSystemClip(decorationRegion.translated(tlwOffset)); - - QPainter painter(windowSurface->paintDevice()); - painter.setFont(QApplication::font()); - painter.translate(tlwOffset); - - const int numDirty = managerPrivate->dirtyRegions.size(); - for (int i = 0; i < numDirty; ++i) { - const int area = managerPrivate->dirtyRegions.at(i); - - QRegion clipRegion = decoration.region(tlw, decorationRect, area); - if (!clipRegion.isEmpty()) { - // Decoration styles changes the clip and assumes the old clip is non-empty, - // so we have to set it, but in theory it shouldn't be required. - painter.setClipRegion(clipRegion); - decoration.paint(&painter, tlw, area, managerPrivate->dirtyStates.at(i)); - } - } - markDirtyOnScreen(decorationRegion, tlw, QPoint()); - - painter.end(); - windowSurface->endPaint(decorationRegion); - managerPrivate->clearDirtyRegions(); - engine->setSystemClip(oldSystemClip); -} -#endif - -void QWidgetBackingStore::updateLists(QWidget *cur) +QBackingStore::QBackingStore(QWindow *window) + : d_ptr(new QBackingStorePrivate(window)) { - if (!cur) - return; - - QList<QObject*> children = cur->children(); - for (int i = 0; i < children.size(); ++i) { - QWidget *child = qobject_cast<QWidget*>(children.at(i)); - if (!child) - continue; - - updateLists(child); - } - - if (cur->testAttribute(Qt::WA_StaticContents)) - addStaticWidget(cur); - -#ifdef Q_BACKINGSTORE_SUBSURFACES - QTLWExtra *extra = cur->d_func()->maybeTopData(); - if (extra && extra->windowSurface && cur != tlw) - subSurfaces.append(extra->windowSurface); -#endif -} - -QWidgetBackingStore::QWidgetBackingStore(QWidget *topLevel) - : tlw(topLevel), dirtyOnScreenWidgets(0), hasDirtyFromPreviousSync(false) - , fullUpdatePending(0) -{ - windowSurface = tlw->windowSurface(); - if (!windowSurface) - windowSurface = topLevel->d_func()->createDefaultWindowSurface(); - - // The QWindowSurface constructor will call QWidget::setWindowSurface(), - // but automatically created surfaces should not be added to the topdata. -#ifdef Q_BACKINGSTORE_SUBSURFACES - Q_ASSERT(topLevel->d_func()->topData()->windowSurface == windowSurface); -#endif - topLevel->d_func()->topData()->windowSurface = 0; - - // Ensure all existing subsurfaces and static widgets are added to their respective lists. - updateLists(topLevel); + d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(window); } -QWidgetBackingStore::~QWidgetBackingStore() +/*! + Destroys this surface. +*/ +QBackingStore::~QBackingStore() { - for (int c = 0; c < dirtyWidgets.size(); ++c) { - resetWidget(dirtyWidgets.at(c)); - } - - delete windowSurface; - windowSurface = 0; - delete dirtyOnScreenWidgets; - dirtyOnScreenWidgets = 0; + delete d_ptr->platformBackingStore; } -//parent's coordinates; move whole rect; update parent and widget -//assume the screen blt has already been done, so we don't need to refresh that part -void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) +/*! + Returns a pointer to the top-level window associated with this + surface. +*/ +QWindow* QBackingStore::window() const { - Q_Q(QWidget); - if (!q->isVisible() || (dx == 0 && dy == 0)) - return; - - QWidget *tlw = q->window(); - QTLWExtra* x = tlw->d_func()->topData(); - if (x->inTopLevelResize) - return; - - static int accelEnv = -1; - if (accelEnv == -1) { - accelEnv = qgetenv("QT_NO_FAST_MOVE").toInt() == 0; - } - - QWidget *pw = q->parentWidget(); - QPoint toplevelOffset = pw->mapTo(tlw, QPoint()); - QWidgetPrivate *pd = pw->d_func(); - QRect clipR(pd->clipRect()); -#ifdef Q_WS_QWS - QWidgetBackingStore *wbs = x->backingStore.data(); - QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface); - clipR = clipR.intersected(surface->clipRegion().translated(-toplevelOffset).boundingRect()); -#endif - const QRect newRect(rect.translated(dx, dy)); - QRect destRect = rect.intersected(clipR); - if (destRect.isValid()) - destRect = destRect.translated(dx, dy).intersected(clipR); - const QRect sourceRect(destRect.translated(-dx, -dy)); - const QRect parentRect(rect & clipR); - - bool accelerateMove = accelEnv && isOpaque -#ifndef QT_NO_GRAPHICSVIEW - // No accelerate move for proxy widgets. - && !tlw->d_func()->extra->proxyWidget -#endif - && !isOverlapped(sourceRect) && !isOverlapped(destRect); - - if (!accelerateMove) { - QRegion parentR(effectiveRectFor(parentRect)); - if (!extra || !extra->hasMask) { - parentR -= newRect; - } else { - // invalidateBuffer() excludes anything outside the mask - parentR += newRect & clipR; - } - pd->invalidateBuffer(parentR); - invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft())); - } else { - - QWidgetBackingStore *wbs = x->backingStore.data(); - QRegion childExpose(newRect & clipR); - - if (sourceRect.isValid() && wbs->bltRect(sourceRect, dx, dy, pw)) - childExpose -= destRect; - - if (!pw->updatesEnabled()) - return; - - const bool childUpdatesEnabled = q->updatesEnabled(); - if (childUpdatesEnabled && !childExpose.isEmpty()) { - childExpose.translate(-data.crect.topLeft()); - wbs->markDirty(childExpose, q); - isMoved = true; - } - - QRegion parentExpose(parentRect); - parentExpose -= newRect; - if (extra && extra->hasMask) - parentExpose += QRegion(newRect) - extra->mask.translated(data.crect.topLeft()); - - if (!parentExpose.isEmpty()) { - wbs->markDirty(parentExpose, pw); - pd->isMoved = true; - } - - if (childUpdatesEnabled) { - QRegion needsFlush(sourceRect); - needsFlush += destRect; - wbs->markDirtyOnScreen(needsFlush, pw, toplevelOffset); - } - } + return d_ptr->window; } -//widget's coordinates; scroll within rect; only update widget -void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) +void QBackingStore::beginPaint(const QRegion ®ion) { - Q_Q(QWidget); - QWidget *tlw = q->window(); - QTLWExtra* x = tlw->d_func()->topData(); - if (x->inTopLevelResize) - return; - - QWidgetBackingStore *wbs = x->backingStore.data(); - if (!wbs) - return; - - static int accelEnv = -1; - if (accelEnv == -1) { - accelEnv = qgetenv("QT_NO_FAST_SCROLL").toInt() == 0; - } - - QRect scrollRect = rect & clipRect(); - bool overlapped = false; - bool accelerateScroll = accelEnv && isOpaque - && !(overlapped = isOverlapped(scrollRect.translated(data.crect.topLeft()))); - -#if defined(Q_WS_QWS) - QWSWindowSurface *surface; - surface = static_cast<QWSWindowSurface*>(wbs->windowSurface); - - if (accelerateScroll && !surface->isBuffered()) { - const QRegion surfaceClip = surface->clipRegion(); - const QRegion outsideClip = QRegion(rect) - surfaceClip; - if (!outsideClip.isEmpty()) { - const QVector<QRect> clipped = (surfaceClip & rect).rects(); - if (clipped.size() < 8) { - for (int i = 0; i < clipped.size(); ++i) - this->scrollRect(clipped.at(i), dx, dy); - return; - } else { - accelerateScroll = false; - } - } - } -#endif // Q_WS_QWS - - if (!accelerateScroll) { - if (overlapped) { - QRegion region(scrollRect); - subtractOpaqueSiblings(region); - invalidateBuffer(region); - }else { - invalidateBuffer(scrollRect); - } - } else { - const QPoint toplevelOffset = q->mapTo(tlw, QPoint()); -#ifdef Q_WS_QWS - QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface); - const QRegion clip = surface->clipRegion().translated(-toplevelOffset) & scrollRect; - const QRect clipBoundingRect = clip.boundingRect(); - scrollRect &= clipBoundingRect; -#endif - const QRect destRect = scrollRect.translated(dx, dy) & scrollRect; - const QRect sourceRect = destRect.translated(-dx, -dy); - - QRegion childExpose(scrollRect); - if (sourceRect.isValid()) { - if (wbs->bltRect(sourceRect, dx, dy, q)) - childExpose -= destRect; - } - - if (inDirtyList) { - if (rect == q->rect()) { - dirty.translate(dx, dy); - } else { - QRegion dirtyScrollRegion = dirty.intersected(scrollRect); - if (!dirtyScrollRegion.isEmpty()) { - dirty -= dirtyScrollRegion; - dirtyScrollRegion.translate(dx, dy); - dirty += dirtyScrollRegion; - } - } - } - - if (!q->updatesEnabled()) - return; - - if (!childExpose.isEmpty()) { - wbs->markDirty(childExpose, q); - isScrolled = true; - } - - // Instead of using native scroll-on-screen, we copy from - // backingstore, giving only one screen update for each - // scroll, and a solid appearance - wbs->markDirtyOnScreen(destRect, q, toplevelOffset); - } + d_ptr->platformBackingStore->beginPaint(region); } -static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra) +void QBackingStore::endPaint() { - if (!tlw || !tlwExtra) - return true; - -#ifdef Q_WS_X11 - // Delay the sync until we get an Expose event from X11 (initial show). - // Qt::WA_Mapped is set to true, but the actual mapping has not yet occurred. - // However, we must repaint immediately regardless of the state if someone calls repaint(). - if (tlwExtra->waitingForMapNotify && !tlwExtra->inRepaint) - return true; -#endif - - if (!tlw->testAttribute(Qt::WA_Mapped)) - return true; - - if (!tlw->isVisible() -#ifndef Q_WS_X11 - // If we're minimized on X11, WA_Mapped will be false and we - // will return in the case above. Some window managers on X11 - // sends us the PropertyNotify to change the minimized state - // *AFTER* we've received the expose event, which is baaad. - || tlw->isMinimized() -#endif - ) - return true; - - return false; + d_ptr->platformBackingStore->endPaint(); } /*! - Synchronizes the \a exposedRegion of the \a exposedWidget with the backing store. + Sets the size of the windowsurface to be \a size. - If there's nothing to repaint, the area is flushed and painting does not occur; - otherwise the area is marked as dirty on screen and will be flushed right after - we are done with all painting. + \sa size() */ -void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedRegion) +void QBackingStore::resize(const QSize &size) { - QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData(); - if (discardSyncRequest(tlw, tlwExtra) || tlwExtra->inTopLevelResize) - return; - - if (!exposedWidget || !exposedWidget->internalWinId() || !exposedWidget->isVisible() - || !exposedWidget->updatesEnabled() || exposedRegion.isEmpty()) { - return; - } - - // If there's no preserved contents support we always need - // to do a full repaint before flushing - if (!windowSurface->hasFeature(QWindowSurface::PreservedContents)) - fullUpdatePending = true; - - // Nothing to repaint. - if (!isDirty()) { - qt_flush(exposedWidget, exposedRegion, windowSurface, tlw, tlwOffset); - return; - } - - if (exposedWidget != tlw) - markDirtyOnScreen(exposedRegion, exposedWidget, exposedWidget->mapTo(tlw, QPoint())); - else - markDirtyOnScreen(exposedRegion, exposedWidget, QPoint()); - sync(); + d_ptr->size = size; + d_ptr->platformBackingStore->resize(size, d_ptr->staticContents); } /*! - Synchronizes the backing store, i.e. dirty areas are repainted and flushed. + Returns the current size of the windowsurface. */ -void QWidgetBackingStore::sync() +QSize QBackingStore::size() const { - QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData(); - if (discardSyncRequest(tlw, tlwExtra)) { - // If the top-level is minimized, it's not visible on the screen so we can delay the - // update until it's shown again. In order to do that we must keep the dirty states. - // These will be cleared when we receive the first expose after showNormal(). - // However, if the widget is not visible (isVisible() returns false), everything will - // be invalidated once the widget is shown again, so clear all dirty states. - if (!tlw->isVisible()) { - dirty = QRegion(); - for (int i = 0; i < dirtyWidgets.size(); ++i) - resetWidget(dirtyWidgets.at(i)); - dirtyWidgets.clear(); - fullUpdatePending = false; - } - return; - } - - const bool updatesDisabled = !tlw->updatesEnabled(); - bool repaintAllWidgets = false; - - const bool inTopLevelResize = tlwExtra->inTopLevelResize; - const QRect tlwRect(topLevelRect()); -#ifdef Q_WS_QPA - const QRect surfaceGeometry(tlwRect.topLeft(), windowSurface->size()); -#else - const QRect surfaceGeometry(windowSurface->geometry()); -#endif - if ((fullUpdatePending || inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) { - if (hasStaticContents()) { - // Repaint existing dirty area and newly visible area. - const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height()); - const QRegion staticRegion(staticContents(0, clipRect)); - QRegion newVisible(0, 0, tlwRect.width(), tlwRect.height()); - newVisible -= staticRegion; - dirty += newVisible; - windowSurface->setStaticContents(staticRegion); - } else { - // Repaint everything. - dirty = QRegion(0, 0, tlwRect.width(), tlwRect.height()); - for (int i = 0; i < dirtyWidgets.size(); ++i) - resetWidget(dirtyWidgets.at(i)); - dirtyWidgets.clear(); - repaintAllWidgets = true; - } - } - -#ifdef Q_WS_QPA - if (inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) - windowSurface->resize(tlwRect.size()); -#else - if (inTopLevelResize || surfaceGeometry != tlwRect) - windowSurface->setGeometry(tlwRect); -#endif - - if (updatesDisabled) - return; - - if (hasDirtyFromPreviousSync) - dirty += dirtyFromPreviousSync; - - // Contains everything that needs repaint. - QRegion toClean(dirty); - - // Loop through all update() widgets and remove them from the list before they are - // painted (in case someone calls update() in paintEvent). If the widget is opaque - // and does not have transparent overlapping siblings, append it to the - // opaqueNonOverlappedWidgets list and paint it directly without composition. - QVarLengthArray<QWidget *, 32> opaqueNonOverlappedWidgets; - for (int i = 0; i < dirtyWidgets.size(); ++i) { - QWidget *w = dirtyWidgets.at(i); - QWidgetPrivate *wd = w->d_func(); - if (wd->data.in_destructor) - continue; - - // Clip with mask() and clipRect(). - wd->dirty &= wd->clipRect(); - wd->clipToEffectiveMask(wd->dirty); - - // Subtract opaque siblings and children. - bool hasDirtySiblingsAbove = false; - // We know for sure that the widget isn't overlapped if 'isMoved' is true. - if (!wd->isMoved) - wd->subtractOpaqueSiblings(wd->dirty, &hasDirtySiblingsAbove); - // Scrolled and moved widgets must draw all children. - if (!wd->isScrolled && !wd->isMoved) - wd->subtractOpaqueChildren(wd->dirty, w->rect()); - - if (wd->dirty.isEmpty()) { - resetWidget(w); - continue; - } - - const QRegion widgetDirty(w != tlw ? wd->dirty.translated(w->mapTo(tlw, QPoint())) - : wd->dirty); - toClean += widgetDirty; - -#ifndef QT_NO_GRAPHICSVIEW - if (tlw->d_func()->extra->proxyWidget) { - resetWidget(w); - continue; - } -#endif - - if (!hasDirtySiblingsAbove && wd->isOpaque && !dirty.intersects(widgetDirty.boundingRect())) { - opaqueNonOverlappedWidgets.append(w); - } else { - resetWidget(w); - dirty += widgetDirty; - } - } - dirtyWidgets.clear(); - - fullUpdatePending = false; - - if (toClean.isEmpty()) { - // Nothing to repaint. However, we might have newly exposed areas on the - // screen if this function was called from sync(QWidget *, QRegion)), so - // we have to make sure those are flushed. - flush(); - return; - } - -#ifndef QT_NO_GRAPHICSVIEW - if (tlw->d_func()->extra->proxyWidget) { - updateStaticContentsSize(); - dirty = QRegion(); - const QVector<QRect> rects(toClean.rects()); - for (int i = 0; i < rects.size(); ++i) - tlw->d_func()->extra->proxyWidget->update(rects.at(i)); - return; - } -#endif - -#ifndef Q_BACKINGSTORE_SUBSURFACES - BeginPaintInfo beginPaintInfo; - beginPaint(toClean, tlw, windowSurface, &beginPaintInfo); - if (beginPaintInfo.nothingToPaint) { - for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i) - resetWidget(opaqueNonOverlappedWidgets[i]); - dirty = QRegion(); - return; - } -#endif - - // Must do this before sending any paint events because - // the size may change in the paint event. - updateStaticContentsSize(); - const QRegion dirtyCopy(dirty); - dirty = QRegion(); - - // Paint opaque non overlapped widgets. - for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i) { - QWidget *w = opaqueNonOverlappedWidgets[i]; - QWidgetPrivate *wd = w->d_func(); - - int flags = QWidgetPrivate::DrawRecursive; - // Scrolled and moved widgets must draw all children. - if (!wd->isScrolled && !wd->isMoved) - flags |= QWidgetPrivate::DontDrawOpaqueChildren; - if (w == tlw) - flags |= QWidgetPrivate::DrawAsRoot; - - QRegion toBePainted(wd->dirty); - resetWidget(w); - -#ifdef Q_BACKINGSTORE_SUBSURFACES - QWindowSurface *subSurface = w->windowSurface(); - BeginPaintInfo beginPaintInfo; - - QPoint off = w->mapTo(tlw, QPoint()); - toBePainted.translate(off); - beginPaint(toBePainted, w, subSurface, &beginPaintInfo, true); - toBePainted.translate(-off); - - if (beginPaintInfo.nothingToPaint) - continue; - - if (beginPaintInfo.windowSurfaceRecreated) { - // Eep the window surface has changed. The old one may have been - // deleted, in which case we will segfault on the call to - // painterOffset() below. Use the new window surface instead. - subSurface = w->windowSurface(); - } - - QPoint offset(tlwOffset); - if (subSurface == windowSurface) - offset += w->mapTo(tlw, QPoint()); - else - offset = static_cast<QWSWindowSurface*>(subSurface)->painterOffset(); - wd->drawWidget(subSurface->paintDevice(), toBePainted, offset, flags, 0, this); - - endPaint(toBePainted, subSurface, &beginPaintInfo); -#else - QPoint offset(tlwOffset); - if (w != tlw) - offset += w->mapTo(tlw, QPoint()); - wd->drawWidget(windowSurface->paintDevice(), toBePainted, offset, flags, 0, this); -#endif - } - - // Paint the rest with composition. -#ifndef Q_BACKINGSTORE_SUBSURFACES - if (repaintAllWidgets || !dirtyCopy.isEmpty()) { - const int flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive; - tlw->d_func()->drawWidget(windowSurface->paintDevice(), dirtyCopy, tlwOffset, flags, 0, this); - } - - endPaint(toClean, windowSurface, &beginPaintInfo); -#else - if (!repaintAllWidgets && dirtyCopy.isEmpty()) - return; // Nothing more to paint. - - QList<QWindowSurface *> surfaceList(subSurfaces); - surfaceList.prepend(windowSurface); - const QRect dirtyBoundingRect(dirtyCopy.boundingRect()); - - // Loop through all window surfaces (incl. the top-level surface) and - // repaint those intersecting with the bounding rect of the dirty region. - for (int i = 0; i < surfaceList.size(); ++i) { - QWindowSurface *subSurface = surfaceList.at(i); - QWidget *w = subSurface->window(); - QWidgetPrivate *wd = w->d_func(); - - const QRect clipRect = wd->clipRect().translated(w->mapTo(tlw, QPoint())); - if (!qRectIntersects(dirtyBoundingRect, clipRect)) - continue; - - toClean = dirtyCopy; - BeginPaintInfo beginPaintInfo; - beginPaint(toClean, w, subSurface, &beginPaintInfo); - if (beginPaintInfo.nothingToPaint) - continue; - - if (beginPaintInfo.windowSurfaceRecreated) { - // Eep the window surface has changed. The old one may have been - // deleted, in which case we will segfault on the call to - // painterOffset() below. Use the new window surface instead. - subSurface = w->windowSurface(); - } - - int flags = QWidgetPrivate::DrawRecursive; - if (w == tlw) - flags |= QWidgetPrivate::DrawAsRoot; - const QPoint painterOffset = static_cast<QWSWindowSurface*>(subSurface)->painterOffset(); - wd->drawWidget(subSurface->paintDevice(), toClean, painterOffset, flags, 0, this); - - endPaint(toClean, subSurface, &beginPaintInfo); - } -#endif + return d_ptr->size; } /*! - Flushes the contents of the backing store into the top-level widget. - If the \a widget is non-zero, the content is flushed to the \a widget. - If the \a surface is non-zero, the content of the \a surface is flushed. + Scrolls the given \a area \a dx pixels to the right and \a dy + downward; both \a dx and \a dy may be negative. + + Returns true if the area was scrolled successfully; false otherwise. */ -void QWidgetBackingStore::flush(QWidget *widget, QWindowSurface *surface) +bool QBackingStore::scroll(const QRegion &area, int dx, int dy) { -#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) - paintWindowDecoration(); -#endif - - if (!dirtyOnScreen.isEmpty()) { - QWidget *target = widget ? widget : tlw; - QWindowSurface *source = surface ? surface : windowSurface; - qt_flush(target, dirtyOnScreen, source, tlw, tlwOffset); - dirtyOnScreen = QRegion(); - } + Q_UNUSED(area); + Q_UNUSED(dx); + Q_UNUSED(dy); - if (!dirtyOnScreenWidgets || dirtyOnScreenWidgets->isEmpty()) - return; - - for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) { - QWidget *w = dirtyOnScreenWidgets->at(i); - QWidgetPrivate *wd = w->d_func(); - Q_ASSERT(wd->needsFlush); - qt_flush(w, *wd->needsFlush, windowSurface, tlw, tlwOffset); - *wd->needsFlush = QRegion(); - } - dirtyOnScreenWidgets->clear(); + return d_ptr->platformBackingStore->scroll(area, dx, dy); } -static inline bool discardInvalidateBufferRequest(QWidget *widget, QTLWExtra *tlwExtra) +void QBackingStore::setStaticContents(const QRegion ®ion) { - Q_ASSERT(widget); - if (QApplication::closingDown()) - return true; - - if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore) - return true; - - if (!widget->isVisible() || !widget->updatesEnabled()) - return true; - - return false; + d_ptr->staticContents = region; } -/*! - Invalidates the buffer when the widget is resized. - Static areas are never invalidated unless absolutely needed. -*/ -void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize) +QRegion QBackingStore::staticContents() const { - Q_Q(QWidget); - Q_ASSERT(!q->isWindow()); - Q_ASSERT(q->parentWidget()); - - const bool staticContents = q->testAttribute(Qt::WA_StaticContents); - const bool sizeDecreased = (data.crect.width() < oldSize.width()) - || (data.crect.height() < oldSize.height()); - - const QPoint offset(data.crect.x() - oldPos.x(), data.crect.y() - oldPos.y()); - const bool parentAreaExposed = !offset.isNull() || sizeDecreased; - const QRect newWidgetRect(q->rect()); - const QRect oldWidgetRect(0, 0, oldSize.width(), oldSize.height()); - - if (!staticContents || graphicsEffect) { - QRegion staticChildren; - QWidgetBackingStore *bs = 0; - if (offset.isNull() && (bs = maybeBackingStore())) - staticChildren = bs->staticContents(q, oldWidgetRect); - const bool hasStaticChildren = !staticChildren.isEmpty(); - - if (hasStaticChildren) { - QRegion dirty(newWidgetRect); - dirty -= staticChildren; - invalidateBuffer(dirty); - } else { - // Entire widget needs repaint. - invalidateBuffer(newWidgetRect); - } - - if (!parentAreaExposed) - return; - - // Invalidate newly exposed area of the parent. - if (!graphicsEffect && extra && extra->hasMask) { - QRegion parentExpose(extra->mask.translated(oldPos)); - parentExpose &= QRect(oldPos, oldSize); - if (hasStaticChildren) - parentExpose -= data.crect; // Offset is unchanged, safe to do this. - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); - } else { - if (hasStaticChildren && !graphicsEffect) { - QRegion parentExpose(QRect(oldPos, oldSize)); - parentExpose -= data.crect; // Offset is unchanged, safe to do this. - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); - } else { - q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize))); - } - } - return; - } - - // Move static content to its new position. - if (!offset.isNull()) { - if (sizeDecreased) { - const QSize minSize(qMin(oldSize.width(), data.crect.width()), - qMin(oldSize.height(), data.crect.height())); - moveRect(QRect(oldPos, minSize), offset.x(), offset.y()); - } else { - moveRect(QRect(oldPos, oldSize), offset.x(), offset.y()); - } - } - - // Invalidate newly visible area of the widget. - if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) { - QRegion newVisible(newWidgetRect); - newVisible -= oldWidgetRect; - invalidateBuffer(newVisible); - } - - if (!parentAreaExposed) - return; - - // Invalidate newly exposed area of the parent. - const QRect oldRect(oldPos, oldSize); - if (extra && extra->hasMask) { - QRegion parentExpose(oldRect); - parentExpose &= extra->mask.translated(oldPos); - parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect); - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); - } else { - QRegion parentExpose(oldRect); - parentExpose -= data.crect; - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); - } + return d_ptr->staticContents; } -/*! - Invalidates the \a rgn (in widget's coordinates) of the backing store, i.e. - all widgets intersecting with the region will be repainted when the backing store - is synced. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). -*/ -void QWidgetPrivate::invalidateBuffer(const QRegion &rgn) +bool QBackingStore::hasStaticContents() const { - Q_Q(QWidget); - - QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - if (discardInvalidateBufferRequest(q, tlwExtra) || rgn.isEmpty()) - return; - - QRegion wrgn(rgn); - wrgn &= clipRect(); - if (!graphicsEffect && extra && extra->hasMask) - wrgn &= extra->mask; - if (wrgn.isEmpty()) - return; - - tlwExtra->backingStore->markDirty(wrgn, q, false, true); + return !d_ptr->staticContents.isEmpty(); } -/*! - This function is equivalent to calling invalidateBuffer(QRegion(rect), ...), but - is more efficient as it eliminates QRegion operations/allocations and can - use the rect more precisely for additional cut-offs. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). -*/ -void QWidgetPrivate::invalidateBuffer(const QRect &rect) +void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset) { - Q_Q(QWidget); - - QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - if (discardInvalidateBufferRequest(q, tlwExtra) || rect.isEmpty()) - return; + // make sure we don't detach + uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits()); - QRect wRect(rect); - wRect &= clipRect(); - if (wRect.isEmpty()) - return; + int lineskip = img.bytesPerLine(); + int depth = img.depth() >> 3; - if (graphicsEffect || !extra || !extra->hasMask) { - tlwExtra->backingStore->markDirty(wRect, q, false, true); - return; - } + const QRect imageRect(0, 0, img.width(), img.height()); + const QRect r = rect & imageRect & imageRect.translated(-offset); + const QPoint p = rect.topLeft() + offset; - QRegion wRgn(extra->mask); - wRgn &= wRect; - if (wRgn.isEmpty()) + if (r.isEmpty()) return; - tlwExtra->backingStore->markDirty(wRgn, q, false, true); -} + const uchar *src; + uchar *dest; -void QWidgetPrivate::repaint_sys(const QRegion &rgn) -{ - if (data.in_destructor) - return; - - Q_Q(QWidget); - if (q->testAttribute(Qt::WA_StaticContents)) { - if (!extra) - createExtra(); - extra->staticContentsSize = data.crect.size(); + if (r.top() < p.y()) { + src = mem + r.bottom() * lineskip + r.left() * depth; + dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth; + lineskip = -lineskip; + } else { + src = mem + r.top() * lineskip + r.left() * depth; + dest = mem + p.y() * lineskip + p.x() * depth; } -#ifdef Q_WS_QPA //Dont even call q->p - QPaintEngine *engine = 0; -#else - QPaintEngine *engine = q->paintEngine(); -#endif - // QGLWidget does not support partial updates if: - // 1) The context is double buffered - // 2) The context is single buffered and auto-fill background is enabled. - const bool noPartialUpdateSupport = (engine && (engine->type() == QPaintEngine::OpenGL - || engine->type() == QPaintEngine::OpenGL2)) - && (usesDoubleBufferedGLContext || q->autoFillBackground()); - QRegion toBePainted(noPartialUpdateSupport ? q->rect() : rgn); - -#ifdef Q_WS_MAC - // No difference between update() and repaint() on the Mac. - update_sys(toBePainted); - return; -#endif - - toBePainted &= clipRect(); - clipToEffectiveMask(toBePainted); - if (toBePainted.isEmpty()) - return; // Nothing to repaint. - -#ifndef QT_NO_PAINT_DEBUG - bool flushed = QWidgetBackingStore::flushPaint(q, toBePainted); -#endif + const int w = r.width(); + int h = r.height(); + const int bytes = w * depth; - drawWidget(q, toBePainted, QPoint(), QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen, 0); - -#ifndef QT_NO_PAINT_DEBUG - if (flushed) - QWidgetBackingStore::unflushPaint(q, toBePainted); -#endif - - if (!q->testAttribute(Qt::WA_PaintOutsidePaintEvent) && q->paintingActive()) - qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent"); + // overlapping segments? + if (offset.y() == 0 && qAbs(offset.x()) < w) { + do { + ::memmove(dest, src, bytes); + dest += lineskip; + src += lineskip; + } while (--h); + } else { + do { + ::memcpy(dest, src, bytes); + dest += lineskip; + src += lineskip; + } while (--h); + } } - QT_END_NAMESPACE diff --git a/src/gui/painting/qwindowsurface_s60_p.h b/src/gui/painting/qbackingstore.h index a086ca424d..3ab0264b17 100644 --- a/src/gui/painting/qwindowsurface_s60_p.h +++ b/src/gui/painting/qbackingstore.h @@ -39,55 +39,52 @@ ** ****************************************************************************/ -#ifndef QWINDOWSURFACE_S60_P_H -#define QWINDOWSURFACE_S60_P_H +#ifndef QBACKINGSTORE_H +#define QBACKINGSTORE_H -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// +#include <QtCore/qrect.h> -#include <qglobal.h> -#include "private/qwindowsurface_p.h" - -class CFbsBitmap; +#include <QtGui/qwindow.h> +#include <QtGui/qregion.h> QT_BEGIN_NAMESPACE -struct QS60WindowSurfacePrivate; +class QRegion; +class QRect; +class QPoint; +class QImage; +class QBackingStorePrivate; -class QS60WindowSurface : public QWindowSurface +class Q_GUI_EXPORT QBackingStore { public: - QS60WindowSurface(QWidget *widget); - ~QS60WindowSurface(); + QBackingStore(QWindow *window); + ~QBackingStore(); + + QWindow *window() const; QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - bool scroll(const QRegion &area, int dx, int dy); - void beginPaint(const QRegion &); - void endPaint(const QRegion &); + // 'window' can be a child window, in which case 'region' is in child window coordinates and + // offset is the (child) window's offset in relation to the window surface. + void flush(const QRegion ®ion, QWindow *window = 0, const QPoint &offset = QPoint()); - QImage* buffer(const QWidget *widget); + void resize(const QSize &size); + QSize size() const; - void setGeometry(const QRect &rect); + bool scroll(const QRegion &area, int dx, int dy); - WindowSurfaceFeatures features() const; + void beginPaint(const QRegion &); + void endPaint(); - CFbsBitmap *symbianBitmap() const; + void setStaticContents(const QRegion ®ion); + QRegion staticContents() const; + bool hasStaticContents() const; private: - QS60WindowSurfacePrivate* d_ptr; - + QScopedPointer<QBackingStorePrivate> d_ptr; }; QT_END_NAMESPACE -#endif // QWINDOWSURFACE_S60_P_H +#endif // QBACKINGSTORE_H diff --git a/src/gui/painting/qbackingstore_p.h b/src/gui/painting/qbackingstore_p.h deleted file mode 100644 index 1ef2e4e1b0..0000000000 --- a/src/gui/painting/qbackingstore_p.h +++ /dev/null @@ -1,278 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBACKINGSTORE_P_H -#define QBACKINGSTORE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QDebug> -#include <QtGui/qwidget.h> -#include <private/qwidget_p.h> -#include <private/qwindowsurface_p.h> -#ifdef Q_WS_QWS -#include <private/qwindowsurface_qws_p.h> -#endif - -QT_BEGIN_NAMESPACE - -class QWindowSurface; - -struct BeginPaintInfo { - inline BeginPaintInfo() : wasFlushed(0), nothingToPaint(0), windowSurfaceRecreated(0) {} - uint wasFlushed : 1; - uint nothingToPaint : 1; - uint windowSurfaceRecreated : 1; -}; - -class Q_AUTOTEST_EXPORT QWidgetBackingStore -{ -public: - QWidgetBackingStore(QWidget *t); - ~QWidgetBackingStore(); - - static void showYellowThing(QWidget *widget, const QRegion &rgn, int msec, bool); - - void sync(QWidget *exposedWidget, const QRegion &exposedRegion); - void sync(); - void flush(QWidget *widget = 0, QWindowSurface *surface = 0); - - inline QPoint topLevelOffset() const { return tlwOffset; } - - QWindowSurface *surface() const { return windowSurface; } - - inline bool isDirty() const - { - return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && !hasDirtyFromPreviousSync - && !fullUpdatePending -#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) - && !hasDirtyWindowDecoration() -#endif - ); - } - - // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). - void markDirty(const QRegion &rgn, QWidget *widget, bool updateImmediately = false, - bool invalidateBuffer = false); - void markDirty(const QRect &rect, QWidget *widget, bool updateImmediately = false, - bool invalidateBuffer = false); - -private: - QWidget *tlw; - QRegion dirtyOnScreen; // needsFlush - QRegion dirty; // needsRepaint - QRegion dirtyFromPreviousSync; - QVector<QWidget *> dirtyWidgets; - QVector<QWidget *> *dirtyOnScreenWidgets; - QList<QWidget *> staticWidgets; - QWindowSurface *windowSurface; -#ifdef Q_BACKINGSTORE_SUBSURFACES - QList<QWindowSurface*> subSurfaces; -#endif - uint hasDirtyFromPreviousSync : 1; - uint fullUpdatePending : 1; - - QPoint tlwOffset; - - static bool flushPaint(QWidget *widget, const QRegion &rgn); - static void unflushPaint(QWidget *widget, const QRegion &rgn); - - bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget); - void releaseBuffer(); - - void beginPaint(QRegion &toClean, QWidget *widget, QWindowSurface *windowSurface, - BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates = true); - void endPaint(const QRegion &cleaned, QWindowSurface *windowSurface, BeginPaintInfo *beginPaintInfo); - - QRegion dirtyRegion(QWidget *widget = 0) const; - QRegion staticContents(QWidget *widget = 0, const QRect &withinClipRect = QRect()) const; - - void markDirtyOnScreen(const QRegion &dirtyOnScreen, QWidget *widget, const QPoint &topLevelOffset); - - void removeDirtyWidget(QWidget *w); - -#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) - bool hasDirtyWindowDecoration() const; - void paintWindowDecoration(); -#endif - void updateLists(QWidget *widget); - - inline void addDirtyWidget(QWidget *widget, const QRegion &rgn) - { - if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) { - QWidgetPrivate *widgetPrivate = widget->d_func(); -#ifndef QT_NO_GRAPHICSEFFECT - if (widgetPrivate->graphicsEffect) - widgetPrivate->dirty = widgetPrivate->effectiveRectFor(rgn.boundingRect()); - else -#endif //QT_NO_GRAPHICSEFFECT - widgetPrivate->dirty = rgn; - dirtyWidgets.append(widget); - widgetPrivate->inDirtyList = true; - } - } - - inline void dirtyWidgetsRemoveAll(QWidget *widget) - { - int i = 0; - while (i < dirtyWidgets.size()) { - if (dirtyWidgets.at(i) == widget) - dirtyWidgets.remove(i); - else - ++i; - } - } - - inline void addStaticWidget(QWidget *widget) - { - if (!widget) - return; - - Q_ASSERT(widget->testAttribute(Qt::WA_StaticContents)); - if (!staticWidgets.contains(widget)) - staticWidgets.append(widget); - } - - inline void removeStaticWidget(QWidget *widget) - { staticWidgets.removeAll(widget); } - - // Move the reparented widget and all its static children from this backing store - // to the new backing store if reparented into another top-level / backing store. - inline void moveStaticWidgets(QWidget *reparented) - { - Q_ASSERT(reparented); - QWidgetBackingStore *newBs = reparented->d_func()->maybeBackingStore(); - if (newBs == this) - return; - - int i = 0; - while (i < staticWidgets.size()) { - QWidget *w = staticWidgets.at(i); - if (reparented == w || reparented->isAncestorOf(w)) { - staticWidgets.removeAt(i); - if (newBs) - newBs->addStaticWidget(w); - } else { - ++i; - } - } - } - - inline QRect topLevelRect() const - { -#ifdef Q_WS_QWS - return tlw->frameGeometry(); -#else - return tlw->data->crect; -#endif - } - - inline void appendDirtyOnScreenWidget(QWidget *widget) - { - if (!widget) - return; - - if (!dirtyOnScreenWidgets) { - dirtyOnScreenWidgets = new QVector<QWidget *>; - dirtyOnScreenWidgets->append(widget); - } else if (!dirtyOnScreenWidgets->contains(widget)) { - dirtyOnScreenWidgets->append(widget); - } - } - - inline void dirtyOnScreenWidgetsRemoveAll(QWidget *widget) - { - if (!widget || !dirtyOnScreenWidgets) - return; - - int i = 0; - while (i < dirtyOnScreenWidgets->size()) { - if (dirtyOnScreenWidgets->at(i) == widget) - dirtyOnScreenWidgets->remove(i); - else - ++i; - } - } - - inline void resetWidget(QWidget *widget) - { - if (widget) { - widget->d_func()->inDirtyList = false; - widget->d_func()->isScrolled = false; - widget->d_func()->isMoved = false; - widget->d_func()->dirty = QRegion(); - } - } - - inline void updateStaticContentsSize() - { - for (int i = 0; i < staticWidgets.size(); ++i) { - QWidgetPrivate *wd = staticWidgets.at(i)->d_func(); - if (!wd->extra) - wd->createExtra(); - wd->extra->staticContentsSize = wd->data.crect.size(); - } - } - - inline bool hasStaticContents() const - { return !staticWidgets.isEmpty() && windowSurface->hasFeature(QWindowSurface::StaticContents); } - - friend QRegion qt_dirtyRegion(QWidget *); - friend class QWidgetPrivate; - friend class QWidget; - friend class QWSManagerPrivate; - friend class QETWidget; - friend class QWindowSurface; - friend class QWSWindowSurface; -}; - -QT_END_NAMESPACE - -#endif // QBACKINGSTORE_P_H diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 8599cb1d75..d644bbace1 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -48,7 +48,7 @@ #include "qline.h" #include "qdebug.h" #include <QtCore/qcoreapplication.h> -#include "private/qstylehelper_p.h" +#include "private/qhexstring_p.h" #include <QtCore/qnumeric.h> QT_BEGIN_NAMESPACE @@ -712,36 +712,6 @@ void QBrush::setColor(const QColor &c) Sets the brush color to the given \a color. */ - -#ifdef QT3_SUPPORT - -/*! - \fn void QBrush::setPixmap(const QPixmap &pixmap) - - \compat - - Sets a custom pattern for this brush. - - Use setTexture() instead. -*/ - -/*! - \fn QPixmap *QBrush::pixmap() const - - Returns a pointer to the custom brush pattern. - - Use texture() instead. -*/ -QPixmap *QBrush::pixmap() const -{ - if (d->style != Qt::TexturePattern) - return 0; - QTexturedBrushData *data = static_cast<QTexturedBrushData*>(d.data()); - QPixmap &pixmap = data->pixmap(); - return pixmap.isNull() ? 0 : &pixmap; -} -#endif - /*! \fn QPixmap QBrush::texture() const diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h index 4a0bfcc8e4..00c0ebfa3a 100644 --- a/src/gui/painting/qbrush.h +++ b/src/gui/painting/qbrush.h @@ -126,12 +126,6 @@ public: bool operator==(const QBrush &b) const; inline bool operator!=(const QBrush &b) const { return !(operator==(b)); } -#ifdef QT3_SUPPORT - inline QT3_SUPPORT operator const QColor&() const; - QT3_SUPPORT QPixmap *pixmap() const; - inline QT3_SUPPORT void setPixmap(const QPixmap &pixmap) { setTexture(pixmap); } -#endif - private: #if defined(Q_WS_X11) friend class QX11PaintEngine; @@ -185,10 +179,6 @@ inline const QMatrix &QBrush::matrix() const { return d->transform.toAffine(); } inline QTransform QBrush::transform() const { return d->transform; } inline bool QBrush::isDetached() const { return d->ref == 1; } -#ifdef QT3_SUPPORT -inline QBrush::operator const QColor&() const { return d->color; } -#endif - /******************************************************************************* * QGradients diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 3d895b7753..5235cb9013 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -2462,30 +2462,6 @@ void QColor::invalidate() ct.argb.pad = 0; } -#ifdef QT3_SUPPORT - -/*! - Returns the pixel value used by the underlying window system to refer to a - color. - - Use QColormap::pixel() instead. - - \oldcode - QColor myColor; - uint pixel = myColor.pixel(screen); - \newcode - QColormap cmap = QColormap::instance(screen); - uint pixel = cmap.pixel(*this); - \endcode -*/ -uint QColor::pixel(int screen) const -{ - QColormap cmap = QColormap::instance(screen); - return cmap.pixel(*this); -} - -#endif // QT3_SUPPORT - /***************************************************************************** QColor stream functions *****************************************************************************/ diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h index 533f6fe315..1dd6c2a099 100644 --- a/src/gui/painting/qcolor.h +++ b/src/gui/painting/qcolor.h @@ -208,30 +208,9 @@ public: static void setAllowX11ColorNames(bool enabled); #endif -#ifdef QT3_SUPPORT - inline QT3_SUPPORT_CONSTRUCTOR QColor(int x, int y, int z, Spec colorSpec) - { if (colorSpec == Hsv) setHsv(x, y, z); else setRgb(x, y, z); } - - inline QT3_SUPPORT void rgb(int *r, int *g, int *b) const - { getRgb(r, g, b); } - inline QT3_SUPPORT void hsv(int *h, int *s, int *v) const - { getHsv(h, s, v); } - - inline QT3_SUPPORT void setRgba(int r, int g, int b, int a) - { setRgb(r, g, b, a); } - inline QT3_SUPPORT void getRgba(int *r, int *g, int *b, int *a) const - { getRgb(r, g, b, a); } - - QT3_SUPPORT uint pixel(int screen = -1) const; -#endif - static bool isValidColor(const QString &name); private: -#ifndef QT3_SUPPORT - // do not allow a spec to be used as an alpha value - QColor(int, int, int, Spec); -#endif void invalidate(); bool setColorFromString(const QString &name); diff --git a/src/gui/painting/qcolormap_mac.cpp b/src/gui/painting/qcolormap_mac.cpp deleted file mode 100644 index 0c3fd70468..0000000000 --- a/src/gui/painting/qcolormap_mac.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qcolormap.h" -#include "qcolor.h" - -QT_BEGIN_NAMESPACE - -class QColormapPrivate -{ -public: - inline QColormapPrivate() - : ref(1) - { } - - QAtomicInt ref; -}; -static QColormap *qt_mac_global_map = 0; - -void QColormap::initialize() -{ - qt_mac_global_map = new QColormap; -} - -void QColormap::cleanup() -{ - delete qt_mac_global_map; - qt_mac_global_map = 0; -} - -QColormap QColormap::instance(int) -{ - return *qt_mac_global_map; -} - -QColormap::QColormap() : d(new QColormapPrivate) -{} - -QColormap::QColormap(const QColormap &colormap) :d (colormap.d) -{ d->ref.ref(); } - -QColormap::~QColormap() -{ - if (!d->ref.deref()) - delete d; -} - -QColormap::Mode QColormap::mode() const -{ return QColormap::Direct; } - -int QColormap::depth() const -{ - return 32; -} - -int QColormap::size() const -{ - return -1; -} - -uint QColormap::pixel(const QColor &color) const -{ return color.rgba(); } - -const QColor QColormap::colorAt(uint pixel) const -{ return QColor(pixel); } - -const QVector<QColor> QColormap::colormap() const -{ return QVector<QColor>(); } - -QColormap &QColormap::operator=(const QColormap &colormap) -{ qAtomicAssign(d, colormap.d); return *this; } - -QT_END_NAMESPACE diff --git a/src/gui/painting/qcolormap_qpa.cpp b/src/gui/painting/qcolormap_qpa.cpp index 40bf364c5a..31fc41b94d 100644 --- a/src/gui/painting/qcolormap_qpa.cpp +++ b/src/gui/painting/qcolormap_qpa.cpp @@ -42,8 +42,7 @@ #include "qcolormap.h" #include "qcolor.h" #include "qpaintdevice.h" -#include "private/qapplication_p.h" -#include "private/qgraphicssystem_p.h" +#include "private/qguiapplication_p.h" QT_BEGIN_NAMESPACE @@ -67,7 +66,7 @@ void QColormap::initialize() { screenMap = new QColormapPrivate; - QPlatformIntegration *pi = QApplicationPrivate::platformIntegration(); + QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); QList<QPlatformScreen*> screens = pi->screens(); screenMap->depth = screens.at(0)->depth(); diff --git a/src/gui/painting/qcolormap_qws.cpp b/src/gui/painting/qcolormap_qws.cpp deleted file mode 100644 index 00d3a43e4f..0000000000 --- a/src/gui/painting/qcolormap_qws.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qcolormap.h" -#include "qcolor.h" -#include "qpaintdevice.h" -#include "qscreen_qws.h" -#include "qwsdisplay_qws.h" - -QT_BEGIN_NAMESPACE - -class QColormapPrivate -{ -public: - inline QColormapPrivate() - : ref(1), mode(QColormap::Direct), depth(0), numcolors(0) - { } - - QAtomicInt ref; - - QColormap::Mode mode; - int depth; - int numcolors; -}; - -static QColormapPrivate *screenMap = 0; - -void QColormap::initialize() -{ - screenMap = new QColormapPrivate; - - screenMap->depth = QPaintDevice::qwsDisplay()->depth(); - if (screenMap->depth < 8) { - screenMap->mode = QColormap::Indexed; - screenMap->numcolors = 256; - } else { - screenMap->mode = QColormap::Direct; - screenMap->numcolors = -1; - } -} - -void QColormap::cleanup() -{ - delete screenMap; - screenMap = 0; -} - -QColormap QColormap::instance(int /*screen*/) -{ - return QColormap(); -} - -QColormap::QColormap() - : d(screenMap) -{ d->ref.ref(); } - -QColormap::QColormap(const QColormap &colormap) - :d (colormap.d) -{ d->ref.ref(); } - -QColormap::~QColormap() -{ - if (!d->ref.deref()) - delete d; -} - -QColormap::Mode QColormap::mode() const -{ return d->mode; } - - -int QColormap::depth() const -{ return d->depth; } - - -int QColormap::size() const -{ - return d->numcolors; -} - -uint QColormap::pixel(const QColor &color) const -{ - QRgb rgb = color.rgba(); - if (d->mode == QColormap::Direct) { - switch(d->depth) { - case 16: - return qt_convRgbTo16(rgb); - case 24: - case 32: - { - const int r = qRed(rgb); - const int g = qGreen(rgb); - const int b = qBlue(rgb); - const int red_shift = 16; - const int green_shift = 8; - const int red_mask = 0xff0000; - const int green_mask = 0x00ff00; - const int blue_mask = 0x0000ff; - const int tg = g << green_shift; -#ifdef QT_QWS_DEPTH_32_BGR - if (qt_screen->pixelType() == QScreen::BGRPixel) { - const int tb = b << red_shift; - return 0xff000000 | (r & blue_mask) | (tg & green_mask) | (tb & red_mask); - } -#endif - const int tr = r << red_shift; - return 0xff000000 | (b & blue_mask) | (tg & green_mask) | (tr & red_mask); - } - } - } - return qt_screen->alloc(qRed(rgb), qGreen(rgb), qBlue(rgb)); -} - -const QColor QColormap::colorAt(uint pixel) const -{ - if (d->mode == Direct) { - if (d->depth == 16) { - pixel = qt_conv16ToRgb(pixel); - } - const int red_shift = 16; - const int green_shift = 8; - const int red_mask = 0xff0000; - const int green_mask = 0x00ff00; - const int blue_mask = 0x0000ff; -#ifdef QT_QWS_DEPTH_32_BGR - if (qt_screen->pixelType() == QScreen::BGRPixel) { - return QColor((pixel & blue_mask), - (pixel & green_mask) >> green_shift, - (pixel & red_mask) >> red_shift); - } -#endif - return QColor((pixel & red_mask) >> red_shift, - (pixel & green_mask) >> green_shift, - (pixel & blue_mask)); - } - Q_ASSERT_X(int(pixel) < qt_screen->colorCount(), "QColormap::colorAt", "pixel out of bounds of palette"); - return QColor(qt_screen->clut()[pixel]); -} - -const QVector<QColor> QColormap::colormap() const -{ - return QVector<QColor>(); -} - -QColormap &QColormap::operator=(const QColormap &colormap) -{ qAtomicAssign(d, colormap.d); return *this; } - -QT_END_NAMESPACE diff --git a/src/gui/painting/qcolormap_s60.cpp b/src/gui/painting/qcolormap_s60.cpp deleted file mode 100644 index 9dd5135d29..0000000000 --- a/src/gui/painting/qcolormap_s60.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qcolormap.h" -#include "qcolor.h" - -QT_BEGIN_NAMESPACE - -class QColormapPrivate -{ -public: - inline QColormapPrivate() - : ref(1) - { } - - QAtomicInt ref; -}; - -void QColormap::initialize() -{ -} - -void QColormap::cleanup() -{ -} - -QColormap QColormap::instance(int) -{ - return QColormap(); -} - -QColormap::QColormap() : d(new QColormapPrivate) -{} - -QColormap::QColormap(const QColormap &colormap) :d (colormap.d) -{ d->ref.ref(); } - -QColormap::~QColormap() -{ - if (!d->ref.deref()) - delete d; -} - -QColormap::Mode QColormap::mode() const -{ return QColormap::Direct; } - -int QColormap::depth() const -{ - return 32; -} - -int QColormap::size() const -{ - return -1; -} - -uint QColormap::pixel(const QColor &color) const -{ return color.rgba(); } - -const QColor QColormap::colorAt(uint pixel) const -{ return QColor(pixel); } - -const QVector<QColor> QColormap::colormap() const -{ return QVector<QColor>(); } - -QColormap &QColormap::operator=(const QColormap &colormap) -{ qAtomicAssign(d, colormap.d); return *this; } - -QT_END_NAMESPACE diff --git a/src/gui/painting/qcolormap_win.cpp b/src/gui/painting/qcolormap_win.cpp deleted file mode 100644 index 4a95977438..0000000000 --- a/src/gui/painting/qcolormap_win.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qcolor.h" -#include "qcolormap.h" -#include "qvector.h" -#include "qt_windows.h" - -#if defined(Q_WS_WINCE) -#include "qguifunctions_wince.h" -#endif - -QT_BEGIN_NAMESPACE - -class QColormapPrivate -{ -public: - inline QColormapPrivate() - : ref(1), mode(QColormap::Direct), depth(0), hpal(0) - { } - - QAtomicInt ref; - - QColormap::Mode mode; - int depth; - int numcolors; - - HPALETTE hpal; - QVector<QColor> palette; -}; - -static QColormapPrivate *screenMap = 0; - -void QColormap::initialize() -{ - HDC dc = qt_win_display_dc(); - - screenMap = new QColormapPrivate; - screenMap->depth = GetDeviceCaps(dc, BITSPIXEL); - - screenMap->numcolors = -1; - if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) - screenMap->numcolors = GetDeviceCaps(dc, SIZEPALETTE); - - if (screenMap->numcolors <= 16 || screenMap->numcolors > 256) // no need to create palette - return; - - LOGPALETTE* pal = 0; - int numPalEntries = 6*6*6; // color cube - - pal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + numPalEntries * sizeof(PALETTEENTRY)); - // Make 6x6x6 color cube - int idx = 0; - for(int ir = 0x0; ir <= 0xff; ir+=0x33) { - for(int ig = 0x0; ig <= 0xff; ig+=0x33) { - for(int ib = 0x0; ib <= 0xff; ib+=0x33) { - pal->palPalEntry[idx].peRed = ir; - pal->palPalEntry[idx].peGreen = ig; - pal->palPalEntry[idx].peBlue = ib; - pal->palPalEntry[idx].peFlags = 0; - idx++; - } - } - } - - pal->palVersion = 0x300; - pal->palNumEntries = numPalEntries; - - screenMap->hpal = CreatePalette(pal); - if (!screenMap->hpal) - qErrnoWarning("QColor::initialize: Failed to create logical palette"); - free (pal); - - SelectPalette(dc, screenMap->hpal, FALSE); - RealizePalette(dc); - - PALETTEENTRY paletteEntries[256]; - screenMap->numcolors = GetPaletteEntries(screenMap->hpal, 0, 255, paletteEntries); - - screenMap->palette.resize(screenMap->numcolors); - for (int i = 0; i < screenMap->numcolors; i++) { - screenMap->palette[i] = qRgb(paletteEntries[i].peRed, - paletteEntries[i].peGreen, - paletteEntries[i].peBlue); - } -} - -void QColormap::cleanup() -{ - if (!screenMap) - return; - - if (screenMap->hpal) { // delete application global - DeleteObject(screenMap->hpal); // palette - screenMap->hpal = 0; - } - - delete screenMap; - screenMap = 0; -} - -QColormap QColormap::instance(int) -{ - Q_ASSERT_X(screenMap, "QColormap", - "A QApplication object needs to be constructed before QColormap is used."); - return QColormap(); -} - -QColormap::QColormap() - : d(screenMap) -{ d->ref.ref(); } - -QColormap::QColormap(const QColormap &colormap) - :d (colormap.d) -{ d->ref.ref(); } - -QColormap::~QColormap() -{ - if (!d->ref.deref()) - delete d; -} - -QColormap::Mode QColormap::mode() const -{ return d->mode; } - -int QColormap::depth() const -{ return d->depth; } - -int QColormap::size() const -{ return d->numcolors; } - -uint QColormap::pixel(const QColor &color) const -{ - const QColor c = color.toRgb(); - COLORREF rgb = RGB(c.red(), c.green(), c.blue()); - if (d->hpal) - return PALETTEINDEX(GetNearestPaletteIndex(d->hpal, rgb)); - return rgb; -} - -const QColor QColormap::colorAt(uint pixel) const -{ - if (d->hpal) { - if (pixel < uint(d->numcolors)) - return d->palette.at(pixel); - return QColor(); - } - return QColor(GetRValue(pixel), GetGValue(pixel), GetBValue(pixel)); -} - - -HPALETTE QColormap::hPal() -{ return screenMap ? screenMap->hpal : 0; } - - -const QVector<QColor> QColormap::colormap() const -{ return d->palette; } - -QColormap &QColormap::operator=(const QColormap &colormap) -{ qAtomicAssign(d, colormap.d); return *this; } - - -QT_END_NAMESPACE diff --git a/src/gui/painting/qcolormap_x11.cpp b/src/gui/painting/qcolormap_x11.cpp deleted file mode 100644 index 1d6d7b8adb..0000000000 --- a/src/gui/painting/qcolormap_x11.cpp +++ /dev/null @@ -1,670 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qcolormap.h" - -#include "qapplication.h" -#include "qdebug.h" -#include "qdesktopwidget.h" -#include "qvarlengtharray.h" - -#include "qx11info_x11.h" -#include <private/qt_x11_p.h> -#include <limits.h> - -QT_BEGIN_NAMESPACE - -class QColormapPrivate -{ -public: - QColormapPrivate() - : ref(1), mode(QColormap::Direct), depth(0), - colormap(0), defaultColormap(true), - visual(0), defaultVisual(true), - r_max(0), g_max(0), b_max(0), - r_shift(0), g_shift(0), b_shift(0) - {} - - QAtomicInt ref; - - QColormap::Mode mode; - int depth; - - Colormap colormap; - bool defaultColormap; - - Visual *visual; - bool defaultVisual; - - int r_max; - int g_max; - int b_max; - - uint r_shift; - uint g_shift; - uint b_shift; - - QVector<QColor> colors; - QVector<int> pixels; -}; - - -static uint right_align(uint v) -{ - while (!(v & 0x1)) - v >>= 1; - return v; -} - -static int lowest_bit(uint v) -{ - int i; - uint b = 1u; - for (i = 0; ((v & b) == 0u) && i < 32; ++i) - b <<= 1u; - return i == 32 ? -1 : i; -} - -static int cube_root(int v) -{ - if (v == 1) - return 1; - // brute force algorithm - int i = 1; - for (;;) { - const int b = i * i * i; - if (b <= v) { - ++i; - } else { - --i; - break; - } - } - return i; -} - -static Visual *find_visual(Display *display, - int screen, - int visual_class, - int visual_id, - int *depth, - bool *defaultVisual) -{ - XVisualInfo *vi, rvi; - int count; - - uint mask = VisualScreenMask; - rvi.screen = screen; - - if (visual_class != -1) { - rvi.c_class = visual_class; - mask |= VisualClassMask; - } - if (visual_id != -1) { - rvi.visualid = visual_id; - mask |= VisualIDMask; - } - - Visual *visual = DefaultVisual(display, screen); - *defaultVisual = true; - *depth = DefaultDepth(display, screen); - - vi = XGetVisualInfo(display, mask, &rvi, &count); - if (vi) { - int best = 0; - for (int x = 0; x < count; ++x) { - if (vi[x].depth > vi[best].depth) - best = x; - } - if (best >= 0 && best <= count && vi[best].visualid != XVisualIDFromVisual(visual)) { - visual = vi[best].visual; - *defaultVisual = (visual == DefaultVisual(display, screen)); - *depth = vi[best].depth; - } - } - if (vi) - XFree((char *)vi); - return visual; -} - -static void query_colormap(QColormapPrivate *d, int screen) -{ - Display *display = QX11Info::display(); - - // query existing colormap - int q_colors = (((1u << d->depth) > 256u) ? 256u : (1u << d->depth)); - XColor queried[256]; - memset(queried, 0, sizeof(queried)); - for (int x = 0; x < q_colors; ++x) - queried[x].pixel = x; - XQueryColors(display, d->colormap, queried, q_colors); - - d->colors.resize(q_colors); - for (int x = 0; x < q_colors; ++x) { - if (queried[x].red == 0 - && queried[x].green == 0 - && queried[x].blue == 0 - && queried[x].pixel != BlackPixel(display, screen)) { - // unallocated color cell, skip it - continue; - } - - d->colors[x] = QColor::fromRgbF(queried[x].red / float(USHRT_MAX), - queried[x].green / float(USHRT_MAX), - queried[x].blue / float(USHRT_MAX)); - } - - // for missing colors, find the closest color in the existing colormap - Q_ASSERT(d->pixels.size()); - for (int x = 0; x < d->pixels.size(); ++x) { - if (d->pixels.at(x) != -1) - continue; - - QRgb rgb; - if (d->mode == QColormap::Indexed) { - const int r = (x / (d->g_max * d->b_max)) % d->r_max; - const int g = (x / d->b_max) % d->g_max; - const int b = x % d->b_max; - rgb = qRgb((r * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1), - (g * 0xff + (d->g_max - 1) / 2) / (d->g_max - 1), - (b * 0xff + (d->b_max - 1) / 2) / (d->b_max - 1)); - } else { - rgb = qRgb(x, x, x); - } - - // find closest color - int mindist = INT_MAX, best = -1; - for (int y = 0; y < q_colors; ++y) { - int r = qRed(rgb) - (queried[y].red >> 8); - int g = qGreen(rgb) - (queried[y].green >> 8); - int b = qBlue(rgb) - (queried[y].blue >> 8); - int dist = (r * r) + (g * g) + (b * b); - if (dist < mindist) { - mindist = dist; - best = y; - } - } - - Q_ASSERT(best >= 0 && best < q_colors); - if (d->visual->c_class & 1) { - XColor xcolor; - xcolor.red = queried[best].red; - xcolor.green = queried[best].green; - xcolor.blue = queried[best].blue; - xcolor.pixel = queried[best].pixel; - - if (XAllocColor(display, d->colormap, &xcolor)) { - d->pixels[x] = xcolor.pixel; - } else { - // some weird stuff is going on... - d->pixels[x] = (qGray(rgb) < 127 - ? BlackPixel(display, screen) - : WhitePixel(display, screen)); - } - } else { - d->pixels[x] = best; - } - } -} - -static void init_gray(QColormapPrivate *d, int screen) -{ - d->pixels.resize(d->r_max); - - for (int g = 0; g < d->g_max; ++g) { - const int gray = (g * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1); - const QRgb rgb = qRgb(gray, gray, gray); - - d->pixels[g] = -1; - - if (d->visual->c_class & 1) { - XColor xcolor; - xcolor.red = qRed(rgb) * 0x101; - xcolor.green = qGreen(rgb) * 0x101; - xcolor.blue = qBlue(rgb) * 0x101; - xcolor.pixel = 0ul; - - if (XAllocColor(QX11Info::display(), d->colormap, &xcolor)) - d->pixels[g] = xcolor.pixel; - } - } - - query_colormap(d, screen); -} - -static void init_indexed(QColormapPrivate *d, int screen) -{ - d->pixels.resize(d->r_max * d->g_max * d->b_max); - - // create color cube - for (int x = 0, r = 0; r < d->r_max; ++r) { - for (int g = 0; g < d->g_max; ++g) { - for (int b = 0; b < d->b_max; ++b, ++x) { - const QRgb rgb = qRgb((r * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1), - (g * 0xff + (d->g_max - 1) / 2) / (d->g_max - 1), - (b * 0xff + (d->b_max - 1) / 2) / (d->b_max - 1)); - - d->pixels[x] = -1; - - if (d->visual->c_class & 1) { - XColor xcolor; - xcolor.red = qRed(rgb) * 0x101; - xcolor.green = qGreen(rgb) * 0x101; - xcolor.blue = qBlue(rgb) * 0x101; - xcolor.pixel = 0ul; - - if (XAllocColor(QX11Info::display(), d->colormap, &xcolor)) - d->pixels[x] = xcolor.pixel; - } - } - } - } - - query_colormap(d, screen); -} - -static void init_direct(QColormapPrivate *d, bool ownColormap) -{ - if (d->visual->c_class != DirectColor || !ownColormap) - return; - - // preallocate 768 on the stack, so that we don't have to malloc - // for the common case (<= 24 bpp) - QVarLengthArray<XColor, 768> colorTable(d->r_max + d->g_max + d->b_max); - int i = 0; - - for (int r = 0; r < d->r_max; ++r) { - colorTable[i].red = r << 8 | r; - colorTable[i].pixel = r << d->r_shift; - colorTable[i].flags = DoRed; - ++i; - } - - for (int g = 0; g < d->g_max; ++g) { - colorTable[i].green = g << 8 | g; - colorTable[i].pixel = g << d->g_shift; - colorTable[i].flags = DoGreen; - ++i; - } - - for (int b = 0; b < d->b_max; ++b) { - colorTable[i].blue = (b << 8 | b); - colorTable[i].pixel = b << d->b_shift; - colorTable[i].flags = DoBlue; - ++i; - } - - XStoreColors(X11->display, d->colormap, colorTable.data(), colorTable.count()); -} - -static QColormap **cmaps = 0; - -void QColormap::initialize() -{ - Display *display = QX11Info::display(); - const int screens = ScreenCount(display); - - cmaps = new QColormap*[screens]; - - for (int i = 0; i < screens; ++i) { - cmaps[i] = new QColormap; - QColormapPrivate * const d = cmaps[i]->d; - - bool use_stdcmap = false; - int color_count = X11->color_count; - - // defaults - d->depth = DefaultDepth(display, i); - d->colormap = DefaultColormap(display, i); - d->defaultColormap = true; - d->visual = DefaultVisual(display, i); - d->defaultVisual = true; - - Visual *argbVisual = 0; - - if (X11->visual && i == DefaultScreen(display)) { - // only use the outside colormap on the default screen - d->visual = find_visual(display, i, X11->visual->c_class, - XVisualIDFromVisual(X11->visual), - &d->depth, &d->defaultVisual); - } else if ((X11->visual_class != -1 && X11->visual_class >= 0 && X11->visual_class < 6) - || (X11->visual_id != -1)) { - // look for a specific visual or type of visual - d->visual = find_visual(display, i, X11->visual_class, X11->visual_id, - &d->depth, &d->defaultVisual); - } else if (QApplication::colorSpec() == QApplication::ManyColor) { - // look for a TrueColor w/ a depth higher than 8bpp - d->visual = find_visual(display, i, TrueColor, -1, &d->depth, &d->defaultVisual); - if (d->depth <= 8) { - d->visual = DefaultVisual(display, i); - d->defaultVisual = true; - color_count = 216; - } - } else if (!X11->custom_cmap) { - XStandardColormap *stdcmap = 0; - int ncmaps = 0; - -#ifndef QT_NO_XRENDER - if (X11->use_xrender) { - int nvi; - XVisualInfo templ; - templ.screen = i; - templ.depth = 32; - templ.c_class = TrueColor; - XVisualInfo *xvi = XGetVisualInfo(X11->display, VisualScreenMask | - VisualDepthMask | - VisualClassMask, &templ, &nvi); - for (int idx = 0; idx < nvi; ++idx) { - XRenderPictFormat *format = XRenderFindVisualFormat(X11->display, - xvi[idx].visual); - if (format->type == PictTypeDirect && format->direct.alphaMask) { - argbVisual = xvi[idx].visual; - break; - } - } - XFree(xvi); - } -#endif - if (XGetRGBColormaps(display, RootWindow(display, i), - &stdcmap, &ncmaps, XA_RGB_DEFAULT_MAP)) { - if (stdcmap) { - for (int c = 0; c < ncmaps; ++c) { - if (!stdcmap[c].red_max || - !stdcmap[c].green_max || - !stdcmap[c].blue_max || - !stdcmap[c].red_mult || - !stdcmap[c].green_mult || - !stdcmap[c].blue_mult) - continue; // invalid stdcmap - - XVisualInfo proto; - proto.visualid = stdcmap[c].visualid; - proto.screen = i; - - int nvisuals = 0; - XVisualInfo *vi = XGetVisualInfo(display, VisualIDMask | VisualScreenMask, - &proto, &nvisuals); - if (vi) { - if (nvisuals > 0) { - use_stdcmap = true; - - d->mode = ((vi[0].visual->c_class < StaticColor) - ? Gray - : ((vi[0].visual->c_class < TrueColor) - ? Indexed - : Direct)); - - d->depth = vi[0].depth; - d->colormap = stdcmap[c].colormap; - d->defaultColormap = true; - d->visual = vi[0].visual; - d->defaultVisual = (d->visual == DefaultVisual(display, i)); - - d->r_max = stdcmap[c].red_max + 1; - d->g_max = stdcmap[c].green_max + 1; - d->b_max = stdcmap[c].blue_max + 1; - - if (d->mode == Direct) { - // calculate offsets - d->r_shift = lowest_bit(d->visual->red_mask); - d->g_shift = lowest_bit(d->visual->green_mask); - d->b_shift = lowest_bit(d->visual->blue_mask); - } else { - d->r_shift = 0; - d->g_shift = 0; - d->b_shift = 0; - } - } - XFree(vi); - } - break; - } - XFree(stdcmap); - } - } - } - if (!use_stdcmap) { - switch (d->visual->c_class) { - case StaticGray: - d->mode = Gray; - - d->r_max = d->g_max = d->b_max = d->visual->map_entries; - break; - - case XGrayScale: - d->mode = Gray; - - // follow precedent set in libXmu... - if (color_count != 0) - d->r_max = d->g_max = d->b_max = color_count; - else if (d->visual->map_entries > 65000) - d->r_max = d->g_max = d->b_max = 4096; - else if (d->visual->map_entries > 4000) - d->r_max = d->g_max = d->b_max = 512; - else if (d->visual->map_entries > 250) - d->r_max = d->g_max = d->b_max = 12; - else - d->r_max = d->g_max = d->b_max = 4; - break; - - case StaticColor: - d->mode = Indexed; - - d->r_max = right_align(d->visual->red_mask) + 1; - d->g_max = right_align(d->visual->green_mask) + 1; - d->b_max = right_align(d->visual->blue_mask) + 1; - break; - - case PseudoColor: - d->mode = Indexed; - - // follow precedent set in libXmu... - if (color_count != 0) - d->r_max = d->g_max = d->b_max = cube_root(color_count); - else if (d->visual->map_entries > 65000) - d->r_max = d->g_max = d->b_max = 27; - else if (d->visual->map_entries > 4000) - d->r_max = d->g_max = d->b_max = 12; - else if (d->visual->map_entries > 250) - d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries - 125); - else - d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries); - break; - - case TrueColor: - case DirectColor: - d->mode = Direct; - - d->r_max = right_align(d->visual->red_mask) + 1; - d->g_max = right_align(d->visual->green_mask) + 1; - d->b_max = right_align(d->visual->blue_mask) + 1; - - d->r_shift = lowest_bit(d->visual->red_mask); - d->g_shift = lowest_bit(d->visual->green_mask); - d->b_shift = lowest_bit(d->visual->blue_mask); - break; - } - } - - bool ownColormap = false; - if (X11->colormap && i == DefaultScreen(display)) { - // only use the outside colormap on the default screen - d->colormap = X11->colormap; - d->defaultColormap = (d->colormap == DefaultColormap(display, i)); - } else if ((!use_stdcmap - && (((d->visual->c_class & 1) && X11->custom_cmap) - || d->visual != DefaultVisual(display, i))) - || d->visual->c_class == DirectColor) { - // allocate custom colormap (we always do this when using DirectColor visuals) - d->colormap = - XCreateColormap(display, RootWindow(display, i), d->visual, - d->visual->c_class == DirectColor ? AllocAll : AllocNone); - d->defaultColormap = false; - ownColormap = true; - } - - switch (d->mode) { - case Gray: - init_gray(d, i); - break; - case Indexed: - init_indexed(d, i); - break; - case Direct: - init_direct(d, ownColormap); - break; - } - - QX11InfoData *screen = X11->screens + i; - screen->depth = d->depth; - screen->visual = d->visual; - screen->defaultVisual = d->defaultVisual; - screen->colormap = d->colormap; - screen->defaultColormap = d->defaultColormap; - screen->cells = screen->visual->map_entries; - - if (argbVisual) { - X11->argbVisuals[i] = argbVisual; - X11->argbColormaps[i] = XCreateColormap(display, RootWindow(display, i), argbVisual, AllocNone); - } - - // ### - // We assume that 8bpp == pseudocolor, but this is not - // always the case (according to the X server), so we need - // to make sure that our internal data is setup in a way - // that is compatible with our assumptions - if (screen->visual->c_class == TrueColor && screen->depth == 8 && screen->cells == 8) - screen->cells = 256; - } -} - -void QColormap::cleanup() -{ - Display *display = QX11Info::display(); - const int screens = ScreenCount(display); - - for (int i = 0; i < screens; ++i) - delete cmaps[i]; - - delete [] cmaps; - cmaps = 0; -} - - -QColormap QColormap::instance(int screen) -{ - if (screen == -1) - screen = QX11Info::appScreen(); - return *cmaps[screen]; -} - -/*! \internal - Constructs a new colormap. -*/ -QColormap::QColormap() - : d(new QColormapPrivate) -{} - -QColormap::QColormap(const QColormap &colormap) - :d (colormap.d) -{ d->ref.ref(); } - -QColormap::~QColormap() -{ - if (!d->ref.deref()) { - if (!d->defaultColormap) - XFreeColormap(QX11Info::display(), d->colormap); - delete d; - } -} - -QColormap::Mode QColormap::mode() const -{ return d->mode; } - -int QColormap::depth() const -{ return d->depth; } - -int QColormap::size() const -{ - return (d->mode == Gray - ? d->r_max - : (d->mode == Indexed - ? d->r_max * d->g_max * d->b_max - : -1)); -} - -uint QColormap::pixel(const QColor &color) const -{ - const QColor c = color.toRgb(); - const uint r = (c.ct.argb.red * d->r_max) >> 16; - const uint g = (c.ct.argb.green * d->g_max) >> 16; - const uint b = (c.ct.argb.blue * d->b_max) >> 16; - if (d->mode != Direct) { - if (d->mode == Gray) - return d->pixels.at((r * 30 + g * 59 + b * 11) / 100); - return d->pixels.at(r * d->g_max * d->b_max + g * d->b_max + b); - } - return (r << d->r_shift) + (g << d->g_shift) + (b << d->b_shift); -} - -const QColor QColormap::colorAt(uint pixel) const -{ - if (d->mode != Direct) { - Q_ASSERT(pixel <= (uint)d->colors.size()); - return d->colors.at(pixel); - } - - const int r = (((pixel & d->visual->red_mask) >> d->r_shift) << 8) / d->r_max; - const int g = (((pixel & d->visual->green_mask) >> d->g_shift) << 8) / d->g_max; - const int b = (((pixel & d->visual->blue_mask) >> d->b_shift) << 8) / d->b_max; - return QColor(r, g, b); -} - -const QVector<QColor> QColormap::colormap() const -{ return d->colors; } - -QColormap &QColormap::operator=(const QColormap &colormap) -{ - qAtomicAssign(d, colormap.d); - return *this; -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qcssutil_p.h b/src/gui/painting/qcssutil_p.h index be206f35b8..fe5b7057b9 100644 --- a/src/gui/painting/qcssutil_p.h +++ b/src/gui/painting/qcssutil_p.h @@ -71,10 +71,10 @@ extern void qDrawRoundedCorners(QPainter *p, qreal x1, qreal y1, qreal x2, qreal const QSizeF& r1, const QSizeF& r2, QCss::Edge edge, QCss::BorderStyle s, QBrush c); -extern void qDrawBorder(QPainter *p, const QRect &rect, const QCss::BorderStyle *styles, +extern void Q_GUI_EXPORT qDrawBorder(QPainter *p, const QRect &rect, const QCss::BorderStyle *styles, const int *borders, const QBrush *colors, const QSize *radii); -extern void qNormalizeRadii(const QRect &br, const QSize *radii, +extern void Q_GUI_EXPORT qNormalizeRadii(const QRect &br, const QSize *radii, QSize *tlr, QSize *trr, QSize *blr, QSize *brr); QT_END_NAMESPACE diff --git a/src/gui/painting/qcups.cpp b/src/gui/painting/qcups.cpp index 3ec5f72395..76050d9d71 100644 --- a/src/gui/painting/qcups.cpp +++ b/src/gui/painting/qcups.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include <qdebug.h> #include "qcups_p.h" +#include "qprinterinfo_unix_p.h" #ifndef QT_NO_CUPS @@ -396,6 +397,50 @@ int QCUPSSupport::printFile(const char * printerName, const char * filename, con return _cupsPrintFile(printerName, filename, title, num_options, options); } +QCUPSSupport::Printer::Printer(const QString &n) : name(n), isDefault(false), cupsPrinterIndex(-1) +{ +} + +QList<QCUPSSupport::Printer> QCUPSSupport::availableUnixPrinters() +{ + QList<Printer> printers; + +#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) + if (QCUPSSupport::isAvailable()) { + QCUPSSupport cups; + int cupsPrinterCount = cups.availablePrintersCount(); + const cups_dest_t* cupsPrinters = cups.availablePrinters(); + for (int i = 0; i < cupsPrinterCount; ++i) { + QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name)); + if (cupsPrinters[i].instance) + printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance); + + Printer p(printerName); + if (cupsPrinters[i].is_default) + p.isDefault = true; + p.cupsPrinterIndex = i; + printers.append(p); + } + } else +#endif + { + QList<QPrinterDescription> lprPrinters; + int defprn = qt_getLprPrinters(lprPrinters); + // populating printer combo + foreach (const QPrinterDescription &description, lprPrinters) + printers.append(Printer(description.name)); + if (defprn >= 0 && defprn < printers.size()) + printers[defprn].isDefault = true; + } + + return printers; +} + +QList<QPrinter::PaperSize> QCUPSSupport::getCupsPrinterPaperSizes(int cupsPrinterIndex) +{ + return qt_getCupsPrinterPaperSizes(cupsPrinterIndex); +} + QT_END_NAMESPACE #endif // QT_NO_CUPS diff --git a/src/gui/painting/qcups_p.h b/src/gui/painting/qcups_p.h index 47ed7e14ef..6b6a55a440 100644 --- a/src/gui/painting/qcups_p.h +++ b/src/gui/painting/qcups_p.h @@ -54,6 +54,7 @@ // #include "QtCore/qstring.h" #include "QtCore/qstringlist.h" +#include "QtCore/qpair.h" #include "QtGui/qprinter.h" #ifndef QT_NO_CUPS @@ -65,9 +66,17 @@ QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(cups_option_t, Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE); -class QCUPSSupport +class Q_GUI_EXPORT QCUPSSupport { public: + struct Printer + { + Printer(const QString &name = QString()); + + QString name; + bool isDefault; + int cupsPrinterIndex; + }; QCUPSSupport(); ~QCUPSSupport(); @@ -100,6 +109,9 @@ public: int printFile(const char * printerName, const char * filename, const char * title, int num_options, cups_option_t * options); + static QList<Printer> availableUnixPrinters(); + static QList<QPrinter::PaperSize> getCupsPrinterPaperSizes(int cupsPrinterIndex); + private: void collectMarkedOptions(QStringList& list, const ppd_group_t* group = 0) const; void collectMarkedOptionsHelper(QStringList& list, const ppd_group_t* group) const; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index c97ef24622..cfd9934e9b 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -3285,9 +3285,6 @@ static void drawBufferSpan(QSpanData *data, const uint *buffer, int bufsize, int x, int y, int length, uint const_alpha) { -#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS) - data->rasterEngine->drawBufferSpan(buffer, bufsize, x, y, length, const_alpha); -#else Q_UNUSED(data); Q_UNUSED(buffer); Q_UNUSED(bufsize); @@ -3295,7 +3292,6 @@ void drawBufferSpan(QSpanData *data, const uint *buffer, int bufsize, Q_UNUSED(y); Q_UNUSED(length); Q_UNUSED(const_alpha); -#endif } #if !defined(Q_CC_SUN) @@ -3323,18 +3319,6 @@ void blend_color_generic(int count, const QSpan *spans, void *userData) } } -#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS) -static void blend_color_generic_callback(int count, const QSpan *spans, void *userData) -{ - // ### Falcon - Q_UNUSED(count); - Q_UNUSED(spans); - Q_UNUSED(userData); -// QSpanData *data = reinterpret_cast<QSpanData*>(userData); -// data->rasterEngine->drawColorSpans(spans, count, data->solid.color); -} -#endif // QT_NO_RASTERCALLBACKS - static void blend_color_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); @@ -4957,65 +4941,30 @@ void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userDat static void blend_untransformed_rgb888(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_24) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_RGB888) - blendUntransformed<qrgb888, qrgb888>(count, spans, userData); - else -#endif - blend_untransformed_generic<RegularSpans>(count, spans, userData); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_argb6666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendUntransformed<qargb6666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendUntransformed<qargb6666, qrgb666>(count, spans, userData); - else -#endif - blend_untransformed_generic<RegularSpans>(count, spans, userData); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_rgb666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendUntransformed<qrgb666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendUntransformed<qrgb666, qrgb666>(count, spans, userData); - else -#endif - blend_untransformed_generic<RegularSpans>(count, spans, userData); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_argb8565(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_16) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendUntransformed<qargb8565, qargb8565>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB16) - blendUntransformed<qargb8565, qrgb565>(count, spans, userData); - else -#endif - blend_untransformed_generic<RegularSpans>(count, spans, userData); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_rgb565(int count, const QSpan *spans, void *userData) { -#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) @@ -5023,68 +4972,31 @@ static void blend_untransformed_rgb565(int count, const QSpan *spans, else if (data->texture.format == QImage::Format_RGB16) blendUntransformed<qrgb565, qrgb565>(count, spans, userData); else -#endif blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_argb8555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendUntransformed<qargb8555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendUntransformed<qargb8555, qrgb555>(count, spans, userData); - else -#endif - blend_untransformed_generic<RegularSpans>(count, spans, userData); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_rgb555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendUntransformed<qrgb555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendUntransformed<qrgb555, qrgb555>(count, spans, userData); - else -#endif - blend_untransformed_generic<RegularSpans>(count, spans, userData); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_argb4444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendUntransformed<qargb4444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendUntransformed<qargb4444, qrgb444>(count, spans, userData); - else -#endif - blend_untransformed_generic<RegularSpans>(count, spans, userData); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_rgb444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendUntransformed<qrgb444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendUntransformed<qrgb444, qrgb444>(count, spans, userData); - else -#endif - blend_untransformed_generic<RegularSpans>(count, spans, userData); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } template <SpanMethod spanMethod> @@ -5300,61 +5212,26 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void * static void blend_tiled_rgb888(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_24) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_RGB888) - blendTiled<qrgb888, qrgb888>(count, spans, userData); - else -#endif - blend_tiled_generic<RegularSpans>(count, spans, userData); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendTiled<qargb6666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendTiled<qargb6666, qrgb666>(count, spans, userData); - else -#endif - blend_tiled_generic<RegularSpans>(count, spans, userData); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendTiled<qrgb666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendTiled<qrgb666, qrgb666>(count, spans, userData); - else -#endif - blend_tiled_generic<RegularSpans>(count, spans, userData); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_16) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendTiled<qargb8565, qargb8565>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB16) - blendTiled<qargb8565, qrgb565>(count, spans, userData); - else -#endif - blend_tiled_generic<RegularSpans>(count, spans, userData); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) { -#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) @@ -5362,64 +5239,27 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) else if (data->texture.format == QImage::Format_RGB16) blendTiled<qrgb565, qrgb565>(count, spans, userData); else -#endif blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendTiled<qargb8555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendTiled<qargb8555, qrgb555>(count, spans, userData); - else -#endif - blend_tiled_generic<RegularSpans>(count, spans, userData); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendTiled<qrgb555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendTiled<qrgb555, qrgb555>(count, spans, userData); - else -#endif - blend_tiled_generic<RegularSpans>(count, spans, userData); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendTiled<qargb4444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendTiled<qargb4444, qrgb444>(count, spans, userData); - else -#endif - blend_tiled_generic<RegularSpans>(count, spans, userData); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendTiled<qrgb444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendTiled<qrgb444, qrgb444>(count, spans, userData); - else -#endif - blend_tiled_generic<RegularSpans>(count, spans, userData); + blend_tiled_generic<RegularSpans>(count, spans, userData); } template <class DST, class SRC> @@ -5647,62 +5487,27 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan static void blend_transformed_bilinear_rgb888(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_24) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_RGB888) - blendTransformedBilinear<qrgb888, qrgb888>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendTransformedBilinear<qargb6666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendTransformedBilinear<qargb6666, qrgb666>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendTransformedBilinear<qrgb666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendTransformedBilinear<qrgb666, qrgb666>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_16) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendTransformedBilinear<qargb8565, qargb8565>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB16) - blendTransformedBilinear<qargb8565, qrgb565>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, void *userData) { -#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format == QImage::Format_RGB16) @@ -5710,64 +5515,27 @@ static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, else if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) blendTransformedBilinear<qrgb565, qargb8565>(count, spans, userData); else -#endif blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendTransformedBilinear<qargb8555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendTransformedBilinear<qargb8555, qrgb555>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendTransformedBilinear<qrgb555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendTransformedBilinear<qrgb555, qrgb555>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendTransformedBilinear<qargb4444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendTransformedBilinear<qargb4444, qrgb444>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendTransformedBilinear<qrgb444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendTransformedBilinear<qrgb444, qrgb444>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } template <SpanMethod spanMethod> @@ -6040,65 +5808,30 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans, static void blend_transformed_rgb888(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_24) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_RGB888) - blendTransformed<qrgb888, qrgb888>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_argb6666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendTransformed<qargb6666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendTransformed<qargb6666, qrgb666>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_rgb666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendTransformed<qrgb666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendTransformed<qrgb666, qrgb666>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_argb8565(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_16) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendTransformed<qargb8565, qargb8565>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB16) - blendTransformed<qargb8565, qrgb565>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_rgb565(int count, const QSpan *spans, void *userData) { -#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) @@ -6106,68 +5839,31 @@ static void blend_transformed_rgb565(int count, const QSpan *spans, else if (data->texture.format == QImage::Format_RGB16) blendTransformed<qrgb565, qrgb565>(count, spans, userData); else -#endif blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_argb8555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendTransformed<qargb8555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendTransformed<qargb8555, qrgb555>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_rgb555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendTransformed<qrgb555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendTransformed<qrgb555, qrgb555>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_argb4444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendTransformed<qargb4444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendTransformed<qargb4444, qrgb444>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_rgb444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendTransformed<qrgb444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendTransformed<qrgb444, qrgb444>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } template <SpanMethod spanMethod> @@ -6455,65 +6151,30 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp static void blend_transformed_tiled_rgb888(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_24) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_RGB888) - blendTransformedTiled<qrgb888, qrgb888>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_argb6666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendTransformedTiled<qargb6666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendTransformedTiled<qargb6666, qrgb666>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_rgb666(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_18) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB6666_Premultiplied) - blendTransformedTiled<qrgb666, qargb6666>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB666) - blendTransformedTiled<qrgb666, qrgb666>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_argb8565(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_16) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendTransformedTiled<qargb8565, qargb8565>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB16) - blendTransformedTiled<qargb8565, qrgb565>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *userData) { -#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) @@ -6521,68 +6182,31 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, else if (data->texture.format == QImage::Format_RGB16) blendTransformedTiled<qrgb565, qrgb565>(count, spans, userData); else -#endif blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_argb8555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendTransformedTiled<qargb8555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendTransformedTiled<qargb8555, qrgb555>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_rgb555(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_15) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB8555_Premultiplied) - blendTransformedTiled<qrgb555, qargb8555>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB555) - blendTransformedTiled<qrgb555, qrgb555>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_argb4444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendTransformedTiled<qargb4444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendTransformedTiled<qargb4444, qrgb444>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_rgb444(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_12) - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - if (data->texture.format == QImage::Format_ARGB4444_Premultiplied) - blendTransformedTiled<qrgb444, qargb4444>(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB444) - blendTransformedTiled<qrgb444, qrgb444>(count, spans, userData); - else -#endif - blend_src_generic<RegularSpans>(count, spans, userData); + blend_src_generic<RegularSpans>(count, spans, userData); } # define SPANFUNC_POINTER(Name, Arg) Name<Arg> @@ -6706,125 +6330,6 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats } }; -#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS) -static const ProcessSpans processTextureSpansCallback[NBlendTypes][QImage::NImageFormats] = { - // Untransformed - { - 0, // Invalid - blend_untransformed_generic<CallbackSpans>, // Mono - blend_untransformed_generic<CallbackSpans>, // MonoLsb - blend_untransformed_generic<CallbackSpans>, // Indexed8 - blend_untransformed_generic<CallbackSpans>, // RGB32 - blend_untransformed_generic<CallbackSpans>, // ARGB32 - blend_untransformed_argb<CallbackSpans>, // ARGB32_Premultiplied - blend_untransformed_generic<CallbackSpans>, // RGB16 - blend_untransformed_generic<CallbackSpans>, // ARGB8565_Premultiplied - blend_untransformed_generic<CallbackSpans>, // RGB666 - blend_untransformed_generic<CallbackSpans>, // ARGB6666_Premultiplied - blend_untransformed_generic<CallbackSpans>, // RGB555 - blend_untransformed_generic<CallbackSpans>, // ARGB8555_Premultiplied - blend_untransformed_generic<CallbackSpans>, // RGB888 - blend_untransformed_generic<CallbackSpans>, // RGB444 - blend_untransformed_generic<CallbackSpans> // ARGB4444_Premultiplied - }, - // Tiled - { - 0, // Invalid - blend_tiled_generic<CallbackSpans>, // Mono - blend_tiled_generic<CallbackSpans>, // MonoLsb - blend_tiled_generic<CallbackSpans>, // Indexed8 - blend_tiled_generic<CallbackSpans>, // RGB32 - blend_tiled_generic<CallbackSpans>, // ARGB32 - blend_tiled_argb<CallbackSpans>, // ARGB32_Premultiplied - blend_tiled_generic<CallbackSpans>, // RGB16 - blend_tiled_generic<CallbackSpans>, // ARGB8565_Premultiplied - blend_tiled_generic<CallbackSpans>, // RGB666 - blend_tiled_generic<CallbackSpans>, // ARGB6666_Premultiplied - blend_tiled_generic<CallbackSpans>, // RGB555 - blend_tiled_generic<CallbackSpans>, // ARGB8555_Premultiplied - blend_tiled_generic<CallbackSpans>, // RGB888 - blend_tiled_generic<CallbackSpans>, // RGB444 - blend_tiled_generic<CallbackSpans> // ARGB4444_Premultiplied - }, - // Transformed - { - 0, // Invalid - blend_src_generic<CallbackSpans>, // Mono - blend_src_generic<CallbackSpans>, // MonoLsb - blend_src_generic<CallbackSpans>, // Indexed8 - blend_src_generic<CallbackSpans>, // RGB32 - blend_src_generic<CallbackSpans>, // ARGB32 - blend_transformed_argb<CallbackSpans>, // ARGB32_Premultiplied - blend_src_generic<CallbackSpans>, // RGB16 - blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied - blend_src_generic<CallbackSpans>, // RGB666 - blend_src_generic<CallbackSpans>, // ARGB6666_Premultiplied - blend_src_generic<CallbackSpans>, // RGB555 - blend_src_generic<CallbackSpans>, // ARGB8555_Premultiplied - blend_src_generic<CallbackSpans>, // RGB888 - blend_src_generic<CallbackSpans>, // RGB444 - blend_src_generic<CallbackSpans>, // ARGB4444_Premultiplied - }, - // TransformedTiled - { - 0, - blend_src_generic<CallbackSpans>, // Mono - blend_src_generic<CallbackSpans>, // MonoLsb - blend_src_generic<CallbackSpans>, // Indexed8 - blend_src_generic<CallbackSpans>, // RGB32 - blend_src_generic<CallbackSpans>, // ARGB32 - blend_transformed_tiled_argb<CallbackSpans>, // ARGB32_Premultiplied - blend_src_generic<CallbackSpans>, // RGB16 - blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied - blend_src_generic<CallbackSpans>, // RGB666 - blend_src_generic<CallbackSpans>, // ARGB6666_Premultiplied - blend_src_generic<CallbackSpans>, // RGB555 - blend_src_generic<CallbackSpans>, // ARGB8555_Premultiplied - blend_src_generic<CallbackSpans>, // RGB888 - blend_src_generic<CallbackSpans>, // RGB444 - blend_src_generic<CallbackSpans> // ARGB4444_Premultiplied - }, - // Bilinear - { - 0, - blend_src_generic<CallbackSpans>, // Mono - blend_src_generic<CallbackSpans>, // MonoLsb - blend_src_generic<CallbackSpans>, // Indexed8 - blend_src_generic<CallbackSpans>, // RGB32 - blend_src_generic<CallbackSpans>, // ARGB32 - blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied - blend_src_generic<CallbackSpans>, // RGB16 - blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied - blend_src_generic<CallbackSpans>, // RGB666 - blend_src_generic<CallbackSpans>, // ARGB6666_Premultiplied - blend_src_generic<CallbackSpans>, // RGB555 - blend_src_generic<CallbackSpans>, // ARGB8555_Premultiplied - blend_src_generic<CallbackSpans>, // RGB888 - blend_src_generic<CallbackSpans>, // RGB444 - blend_src_generic<CallbackSpans> // ARGB4444_Premultiplied - }, - // BilinearTiled - { - 0, - blend_src_generic<CallbackSpans>, // Mono - blend_src_generic<CallbackSpans>, // MonoLsb - blend_src_generic<CallbackSpans>, // Indexed8 - blend_src_generic<CallbackSpans>, // RGB32 - blend_src_generic<CallbackSpans>, // ARGB32 - blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied - blend_src_generic<CallbackSpans>, // RGB16 - blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied - blend_src_generic<CallbackSpans>, // RGB666 - blend_src_generic<CallbackSpans>, // ARGB6666_Premultiplied - blend_src_generic<CallbackSpans>, // RGB555 - blend_src_generic<CallbackSpans>, // ARGB8555_Premultiplied - blend_src_generic<CallbackSpans>, // RGB888 - blend_src_generic<CallbackSpans>, // RGB444 - blend_src_generic<CallbackSpans> // ARGB4444_Premultiplied - } -}; -#endif // QT_NO_RASTERCALLBACKS - void qBlendTexture(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); @@ -6832,15 +6337,6 @@ void qBlendTexture(int count, const QSpan *spans, void *userData) proc(count, spans, userData); } -#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS) -void qBlendTextureCallback(int count, const QSpan *spans, void *userData) -{ - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - ProcessSpans proc = processTextureSpansCallback[getBlendType(data)][data->rasterBuffer->format]; - proc(count, spans, userData); -} -#endif // QT_NO_RASTERCALLBACKS - template <class DST> inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, int x, int y, quint32 color, @@ -7490,106 +6986,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = } }; -#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS) -DrawHelper qDrawHelperCallback[QImage::NImageFormats] = -{ - // Format_Invalid, - { 0, 0, 0, 0, 0, 0 }, - // Format_Mono, - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_MonoLSB, - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_Indexed8, - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_RGB32, - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_ARGB32, - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_ARGB32_Premultiplied - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_RGB16 - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_ARGB8565_Premultiplied - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_RGB666 - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_ARGB6666_Premultiplied - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_RGB555 - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_ARGB8555_Premultiplied - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_RGB888 - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_RGB444 - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - }, - // Format_ARGB4444_Premultiplied - { - blend_color_generic_callback, - blend_src_generic<CallbackSpans>, - 0, 0, 0, 0 - } -}; -#endif - - - #if defined(Q_CC_MSVC) && !defined(_MIPS_) template <class DST, class SRC> inline void qt_memfill_template(DST *dest, SRC color, int count) @@ -7889,64 +7285,4 @@ static void qt_memfill16_setup(quint16 *dest, quint16 value, int count) qt_memfill16(dest, value, count); } -#ifdef QT_QWS_DEPTH_GENERIC - -int qrgb::bpp = 0; -int qrgb::len_red = 0; -int qrgb::len_green = 0; -int qrgb::len_blue = 0; -int qrgb::len_alpha = 0; -int qrgb::off_red = 0; -int qrgb::off_green = 0; -int qrgb::off_blue = 0; -int qrgb::off_alpha = 0; - -template <typename SRC> -Q_STATIC_TEMPLATE_FUNCTION inline void qt_rectconvert_rgb(qrgb *dest, const SRC *src, - int x, int y, int width, int height, - int dstStride, int srcStride) -{ - quint8 *dest8 = reinterpret_cast<quint8*>(dest) - + y * dstStride + x * qrgb::bpp; - - srcStride = srcStride / sizeof(SRC) - width; - dstStride -= (width * qrgb::bpp); - - for (int j = 0; j < height; ++j) { - for (int i = 0; i < width; ++i) { - const quint32 v = qt_convertToRgb<SRC>(*src++); -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - for (int j = qrgb::bpp - 1; j >= 0; --j) - *dest8++ = (v >> (8 * j)) & 0xff; -#else - for (int j = 0; j < qrgb::bpp; ++j) - *dest8++ = (v >> (8 * j)) & 0xff; -#endif - } - - dest8 += dstStride; - src += srcStride; - } -} - -template <> -void qt_rectconvert(qrgb *dest, const quint32 *src, - int x, int y, int width, int height, - int dstStride, int srcStride) -{ - qt_rectconvert_rgb<quint32>(dest, src, x, y, width, height, - dstStride, srcStride); -} - -template <> -void qt_rectconvert(qrgb *dest, const quint16 *src, - int x, int y, int width, int height, - int dstStride, int srcStride) -{ - qt_rectconvert_rgb<quint16>(dest, src, x, y, width, height, - dstStride, srcStride); -} - -#endif // QT_QWS_DEPTH_GENERIC - QT_END_NAMESPACE diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 0766f2e96b..3d83ba8587 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -65,10 +65,6 @@ #include <private/qsimd_p.h> #include <private/qmath_p.h> -#ifdef Q_WS_QWS -#include "QtGui/qscreen_qws.h" -#endif - QT_BEGIN_NAMESPACE #if defined(Q_CC_MSVC) && _MSCVER <= 1300 && !defined(Q_CC_INTEL) @@ -171,10 +167,6 @@ extern MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3]; extern DrawHelper qDrawHelper[QImage::NImageFormats]; void qBlendTexture(int count, const QSpan *spans, void *userData); -#if defined(Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS) -extern DrawHelper qDrawHelperCallback[QImage::NImageFormats]; -void qBlendTextureCallback(int count, const QSpan *spans, void *userData); -#endif typedef void (QT_FASTCALL *CompositionFunction)(uint *dest, const uint *src, int length, uint const_alpha); typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha); @@ -271,13 +263,8 @@ struct QGradientData QConicalGradientData conical; }; -#ifdef Q_WS_QWS -#define GRADIENT_STOPTABLE_SIZE 256 -#define GRADIENT_STOPTABLE_SIZE_SHIFT 8 -#else #define GRADIENT_STOPTABLE_SIZE 1024 #define GRADIENT_STOPTABLE_SIZE_SHIFT 10 -#endif uint* colorTable; //[GRADIENT_STOPTABLE_SIZE]; @@ -314,9 +301,6 @@ struct QSpanData ~QSpanData() { delete tempImage; } QRasterBuffer *rasterBuffer; -#ifdef Q_WS_QWS - QRasterPaintEngine *rasterEngine; -#endif ProcessSpans blend; ProcessSpans unclipped_blend; BitmapBlitFunc bitmapBlit; @@ -1492,37 +1476,6 @@ inline quint32 qt_colorConvert(qrgb888 color, quint32 dummy) return quint32(color); } -#ifdef QT_QWS_DEPTH_8 -template <> -inline quint8 qt_colorConvert(quint32 color, quint8 dummy) -{ - Q_UNUSED(dummy); - - uchar r = ((qRed(color) & 0xf8) + 0x19) / 0x33; - uchar g = ((qGreen(color) &0xf8) + 0x19) / 0x33; - uchar b = ((qBlue(color) &0xf8) + 0x19) / 0x33; - - return r*6*6 + g*6 + b; -} - -template <> -inline quint8 qt_colorConvert(quint16 color, quint8 dummy) -{ - Q_UNUSED(dummy); - - uchar r = (color & 0xf800) >> (11-3); - uchar g = (color & 0x07c0) >> (6-3); - uchar b = (color & 0x001f) << 3; - - uchar tr = (r + 0x19) / 0x33; - uchar tg = (g + 0x19) / 0x33; - uchar tb = (b + 0x19) / 0x33; - - return tr*6*6 + tg*6 + tb; -} - -#endif // QT_QWS_DEPTH_8 - // hw: endianess?? class quint24 { @@ -1759,84 +1712,6 @@ qrgb444 qrgb444::byte_mul(quint8 a) const return result; } -#ifdef QT_QWS_DEPTH_GENERIC - -struct qrgb -{ -public: - static int bpp; - static int len_red; - static int len_green; - static int len_blue; - static int len_alpha; - static int off_red; - static int off_green; - static int off_blue; - static int off_alpha; -} Q_PACKED; - -template <typename SRC> -Q_STATIC_TEMPLATE_FUNCTION inline quint32 qt_convertToRgb(SRC color); - -template <> -inline quint32 qt_convertToRgb(quint32 color) -{ - const int r = qRed(color) >> (8 - qrgb::len_red); - const int g = qGreen(color) >> (8 - qrgb::len_green); - const int b = qBlue(color) >> (8 - qrgb::len_blue); - const int a = qAlpha(color) >> (8 - qrgb::len_alpha); - const quint32 v = (r << qrgb::off_red) - | (g << qrgb::off_green) - | (b << qrgb::off_blue) - | (a << qrgb::off_alpha); - - return v; -} - -template <> -inline quint32 qt_convertToRgb(quint16 color) -{ - return qt_convertToRgb(qt_colorConvert<quint32, quint16>(color, 0)); -} - -class qrgb_generic16 -{ -public: - inline qrgb_generic16(quint32 color) - { - const int r = qRed(color) >> (8 - qrgb::len_red); - const int g = qGreen(color) >> (8 - qrgb::len_green); - const int b = qBlue(color) >> (8 - qrgb::len_blue); - const int a = qAlpha(color) >> (8 - qrgb::len_alpha); - data = (r << qrgb::off_red) - | (g << qrgb::off_green) - | (b << qrgb::off_blue) - | (a << qrgb::off_alpha); - } - - inline operator quint16 () { return data; } - inline quint32 operator<<(int shift) const { return data << shift; } - -private: - quint16 data; -} Q_PACKED; - -template <> -inline qrgb_generic16 qt_colorConvert(quint32 color, qrgb_generic16 dummy) -{ - Q_UNUSED(dummy); - return qrgb_generic16(color); -} - -template <> -inline qrgb_generic16 qt_colorConvert(quint16 color, qrgb_generic16 dummy) -{ - Q_UNUSED(dummy); - return qrgb_generic16(qt_colorConvert<quint32, quint16>(color, 0)); -} - -#endif // QT_QWS_DEPTH_GENERIC - template <class T> void qt_memfill(T *dest, T value, int count); @@ -2044,16 +1919,6 @@ QT_RECTCONVERT_TRIVIAL_IMPL(qargb4444) QT_RECTCONVERT_TRIVIAL_IMPL(qrgb444) #undef QT_RECTCONVERT_TRIVIAL_IMPL -#ifdef QT_QWS_DEPTH_GENERIC -template <> void qt_rectconvert(qrgb *dest, const quint32 *src, - int x, int y, int width, int height, - int dstStride, int srcStride); - -template <> void qt_rectconvert(qrgb *dest, const quint16 *src, - int x, int y, int width, int height, - int dstStride, int srcStride); -#endif // QT_QWS_DEPTH_GENERIC - #define QT_MEMFILL_UINT(dest, length, color) \ qt_memfill<quint32>(dest, color, length); @@ -2116,16 +1981,6 @@ inline ushort qConvertRgb32To16(uint c) | (((c) >> 8) & 0xf800); } -#if defined(Q_WS_QWS) || (QT_VERSION >= 0x040400) -inline quint32 qConvertRgb32To16x2(quint64 c) -{ - c = (((c) >> 3) & Q_UINT64_C(0x001f0000001f)) - | (((c) >> 5) & Q_UINT64_C(0x07e0000007e0)) - | (((c) >> 8) & Q_UINT64_C(0xf8000000f800)); - return c | (c >> 16); -} -#endif - inline QRgb qConvertRgb16To32(uint c) { return 0xff000000 diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp deleted file mode 100644 index 98294cb62d..0000000000 --- a/src/gui/painting/qdrawutil.cpp +++ /dev/null @@ -1,1360 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdrawutil.h" -#include "qbitmap.h" -#include "qpixmapcache.h" -#include "qapplication.h" -#include "qpainter.h" -#include "qpalette.h" -#include <private/qpaintengineex_p.h> -#include <qvarlengtharray.h> -#include <qmath.h> -#include <private/qstylehelper_p.h> - -QT_BEGIN_NAMESPACE - -/*! - \headerfile <qdrawutil.h> - \title Drawing Utility Functions - - \sa QPainter -*/ - -/*! - \fn void qDrawShadeLine(QPainter *painter, int x1, int y1, int x2, int y2, - const QPalette &palette, bool sunken, - int lineWidth, int midLineWidth) - \relates <qdrawutil.h> - - Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2) - shaded line using the given \a painter. Note that nothing is - drawn if \a y1 != \a y2 and \a x1 != \a x2 (i.e. the line is - neither horizontal nor vertical). - - The provided \a palette specifies the shading colors (\l - {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l - {QPalette::mid()}{middle} colors). The given \a lineWidth - specifies the line width for each of the lines; it is not the - total line width. The given \a midLineWidth specifies the width of - a middle line drawn in the QPalette::mid() color. - - The line appears sunken if \a sunken is true, otherwise raised. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to - make widgets that follow the current GUI style. - - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a shaded line: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 0 - - \sa qDrawShadeRect(), qDrawShadePanel(), QStyle -*/ - -void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, - const QPalette &pal, bool sunken, - int lineWidth, int midLineWidth) -{ - if (!(p && lineWidth >= 0 && midLineWidth >= 0)) { - qWarning("qDrawShadeLine: Invalid parameters"); - return; - } - int tlw = lineWidth*2 + midLineWidth; // total line width - QPen oldPen = p->pen(); // save pen - if (sunken) - p->setPen(pal.color(QPalette::Dark)); - else - p->setPen(pal.light().color()); - QPolygon a; - int i; - if (y1 == y2) { // horizontal line - int y = y1 - tlw/2; - if (x1 > x2) { // swap x1 and x2 - int t = x1; - x1 = x2; - x2 = t; - } - x2--; - for (i=0; i<lineWidth; i++) { // draw top shadow - a.setPoints(3, x1+i, y+tlw-1-i, - x1+i, y+i, - x2-i, y+i); - p->drawPolyline(a); - } - if (midLineWidth > 0) { - p->setPen(pal.mid().color()); - for (i=0; i<midLineWidth; i++) // draw lines in the middle - p->drawLine(x1+lineWidth, y+lineWidth+i, - x2-lineWidth, y+lineWidth+i); - } - if (sunken) - p->setPen(pal.light().color()); - else - p->setPen(pal.dark().color()); - for (i=0; i<lineWidth; i++) { // draw bottom shadow - a.setPoints(3, x1+i, y+tlw-i-1, - x2-i, y+tlw-i-1, - x2-i, y+i+1); - p->drawPolyline(a); - } - } - else if (x1 == x2) { // vertical line - int x = x1 - tlw/2; - if (y1 > y2) { // swap y1 and y2 - int t = y1; - y1 = y2; - y2 = t; - } - y2--; - for (i=0; i<lineWidth; i++) { // draw left shadow - a.setPoints(3, x+i, y2, - x+i, y1+i, - x+tlw-1, y1+i); - p->drawPolyline(a); - } - if (midLineWidth > 0) { - p->setPen(pal.mid().color()); - for (i=0; i<midLineWidth; i++) // draw lines in the middle - p->drawLine(x+lineWidth+i, y1+lineWidth, x+lineWidth+i, y2); - } - if (sunken) - p->setPen(pal.light().color()); - else - p->setPen(pal.dark().color()); - for (i=0; i<lineWidth; i++) { // draw right shadow - a.setPoints(3, x+lineWidth, y2-i, - x+tlw-i-1, y2-i, - x+tlw-i-1, y1+lineWidth); - p->drawPolyline(a); - } - } - p->setPen(oldPen); -} - -/*! - \fn void qDrawShadeRect(QPainter *painter, int x, int y, int width, int height, - const QPalette &palette, bool sunken, - int lineWidth, int midLineWidth, - const QBrush *fill) - \relates <qdrawutil.h> - - Draws the shaded rectangle beginning at (\a x, \a y) with the - given \a width and \a height using the provided \a painter. - - The provide \a palette specifies the shading colors (\l - {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l - {QPalette::mid()}{middle} colors. The given \a lineWidth - specifies the line width for each of the lines; it is not the - total line width. The \a midLineWidth specifies the width of a - middle line drawn in the QPalette::mid() color. The rectangle's - interior is filled with the \a fill brush unless \a fill is 0. - - The rectangle appears sunken if \a sunken is true, otherwise - raised. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a shaded rectangle: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 1 - - \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle -*/ - -void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, - const QPalette &pal, bool sunken, - int lineWidth, int midLineWidth, - const QBrush *fill) -{ - if (w == 0 || h == 0) - return; - if (! (w > 0 && h > 0 && lineWidth >= 0 && midLineWidth >= 0)) { - qWarning("qDrawShadeRect: Invalid parameters"); - return; - } - QPen oldPen = p->pen(); - if (sunken) - p->setPen(pal.dark().color()); - else - p->setPen(pal.light().color()); - int x1=x, y1=y, x2=x+w-1, y2=y+h-1; - - if (lineWidth == 1 && midLineWidth == 0) {// standard shade rectangle - p->drawRect(x1, y1, w-2, h-2); - if (sunken) - p->setPen(pal.light().color()); - else - p->setPen(pal.dark().color()); - QLineF lines[4] = { QLineF(x1+1, y1+1, x2-2, y1+1), - QLineF(x1+1, y1+2, x1+1, y2-2), - QLineF(x1, y2, x2, y2), - QLineF(x2,y1, x2,y2-1) }; - p->drawLines(lines, 4); // draw bottom/right lines - } else { // more complicated - int m = lineWidth+midLineWidth; - int i, j=0, k=m; - for (i=0; i<lineWidth; i++) { // draw top shadow - QLineF lines[4] = { QLineF(x1+i, y2-i, x1+i, y1+i), - QLineF(x1+i, y1+i, x2-i, y1+i), - QLineF(x1+k, y2-k, x2-k, y2-k), - QLineF(x2-k, y2-k, x2-k, y1+k) }; - p->drawLines(lines, 4); - k++; - } - p->setPen(pal.mid().color()); - j = lineWidth*2; - for (i=0; i<midLineWidth; i++) { // draw lines in the middle - p->drawRect(x1+lineWidth+i, y1+lineWidth+i, w-j-1, h-j-1); - j += 2; - } - if (sunken) - p->setPen(pal.light().color()); - else - p->setPen(pal.dark().color()); - k = m; - for (i=0; i<lineWidth; i++) { // draw bottom shadow - QLineF lines[4] = { QLineF(x1+1+i, y2-i, x2-i, y2-i), - QLineF(x2-i, y2-i, x2-i, y1+i+1), - QLineF(x1+k, y2-k, x1+k, y1+k), - QLineF(x1+k, y1+k, x2-k, y1+k) }; - p->drawLines(lines, 4); - k++; - } - } - if (fill) { - QBrush oldBrush = p->brush(); - int tlw = lineWidth + midLineWidth; - p->setPen(Qt::NoPen); - p->setBrush(*fill); - p->drawRect(x+tlw, y+tlw, w-2*tlw, h-2*tlw); - p->setBrush(oldBrush); - } - p->setPen(oldPen); // restore pen -} - - -/*! - \fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height, - const QPalette &palette, bool sunken, - int lineWidth, const QBrush *fill) - \relates <qdrawutil.h> - - Draws the shaded panel beginning at (\a x, \a y) with the given \a - width and \a height using the provided \a painter and the given \a - lineWidth. - - The given \a palette specifies the shading colors (\l - {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l - {QPalette::mid()}{middle} colors). The panel's interior is filled - with the \a fill brush unless \a fill is 0. - - The panel appears sunken if \a sunken is true, otherwise raised. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a shaded panel: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 2 - - \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle -*/ - -void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, - const QPalette &pal, bool sunken, - int lineWidth, const QBrush *fill) -{ - if (w == 0 || h == 0) - return; - if (!(w > 0 && h > 0 && lineWidth >= 0)) { - qWarning("qDrawShadePanel: Invalid parameters"); - } - QColor shade = pal.dark().color(); - QColor light = pal.light().color(); - if (fill) { - if (fill->color() == shade) - shade = pal.shadow().color(); - if (fill->color() == light) - light = pal.midlight().color(); - } - QPen oldPen = p->pen(); // save pen - QVector<QLineF> lines; - lines.reserve(2*lineWidth); - - if (sunken) - p->setPen(shade); - else - p->setPen(light); - int x1, y1, x2, y2; - int i; - x1 = x; - y1 = y2 = y; - x2 = x+w-2; - for (i=0; i<lineWidth; i++) { // top shadow - lines << QLineF(x1, y1++, x2--, y2++); - } - x2 = x1; - y1 = y+h-2; - for (i=0; i<lineWidth; i++) { // left shado - lines << QLineF(x1++, y1, x2++, y2--); - } - p->drawLines(lines); - lines.clear(); - if (sunken) - p->setPen(light); - else - p->setPen(shade); - x1 = x; - y1 = y2 = y+h-1; - x2 = x+w-1; - for (i=0; i<lineWidth; i++) { // bottom shadow - lines << QLineF(x1++, y1--, x2, y2--); - } - x1 = x2; - y1 = y; - y2 = y+h-lineWidth-1; - for (i=0; i<lineWidth; i++) { // right shadow - lines << QLineF(x1--, y1++, x2--, y2); - } - p->drawLines(lines); - if (fill) // fill with fill color - p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill); - p->setPen(oldPen); // restore pen -} - - -/*! - \internal - This function draws a rectangle with two pixel line width. - It is called from qDrawWinButton() and qDrawWinPanel(). - - c1..c4 and fill are used: - - 1 1 1 1 1 2 - 1 3 3 3 4 2 - 1 3 F F 4 2 - 1 3 F F 4 2 - 1 4 4 4 4 2 - 2 2 2 2 2 2 -*/ - -static void qDrawWinShades(QPainter *p, - int x, int y, int w, int h, - const QColor &c1, const QColor &c2, - const QColor &c3, const QColor &c4, - const QBrush *fill) -{ - if (w < 2 || h < 2) // can't do anything with that - return; - QPen oldPen = p->pen(); - QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) }; - p->setPen(c1); - p->drawPolyline(a, 3); - QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) }; - p->setPen(c2); - p->drawPolyline(b, 3); - if (w > 4 && h > 4) { - QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) }; - p->setPen(c3); - p->drawPolyline(c, 3); - QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) }; - p->setPen(c4); - p->drawPolyline(d, 3); - if (fill) - p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill); - } - p->setPen(oldPen); -} - - -/*! - \fn void qDrawWinButton(QPainter *painter, int x, int y, int width, int height, - const QPalette &palette, bool sunken, - const QBrush *fill) - \relates <qdrawutil.h> - - Draws the Windows-style button specified by the given point (\a x, - \a y}, \a width and \a height using the provided \a painter with a - line width of 2 pixels. The button's interior is filled with the - \a{fill} brush unless \a fill is 0. - - The given \a palette specifies the shading colors (\l - {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l - {QPalette::mid()}{middle} colors). - - The button appears sunken if \a sunken is true, otherwise raised. - - \warning This function does not look at QWidget::style() or - QApplication::style()-> Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - \sa qDrawWinPanel(), QStyle -*/ - -void qDrawWinButton(QPainter *p, int x, int y, int w, int h, - const QPalette &pal, bool sunken, - const QBrush *fill) -{ - if (sunken) - qDrawWinShades(p, x, y, w, h, - pal.shadow().color(), pal.light().color(), pal.dark().color(), - pal.button().color(), fill); - else - qDrawWinShades(p, x, y, w, h, - pal.light().color(), pal.shadow().color(), pal.button().color(), - pal.dark().color(), fill); -} - -/*! - \fn void qDrawWinPanel(QPainter *painter, int x, int y, int width, int height, - const QPalette &palette, bool sunken, - const QBrush *fill) - \relates <qdrawutil.h> - - Draws the Windows-style panel specified by the given point(\a x, - \a y), \a width and \a height using the provided \a painter with a - line width of 2 pixels. The button's interior is filled with the - \a fill brush unless \a fill is 0. - - The given \a palette specifies the shading colors. The panel - appears sunken if \a sunken is true, otherwise raised. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a shaded panel: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 3 - - \sa qDrawShadePanel(), qDrawWinButton(), QStyle -*/ - -void qDrawWinPanel(QPainter *p, int x, int y, int w, int h, - const QPalette &pal, bool sunken, - const QBrush *fill) -{ - if (sunken) - qDrawWinShades(p, x, y, w, h, - pal.dark().color(), pal.light().color(), pal.shadow().color(), - pal.midlight().color(), fill); - else - qDrawWinShades(p, x, y, w, h, - pal.light().color(), pal.shadow().color(), pal.midlight().color(), - pal.dark().color(), fill); -} - -/*! - \fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor, - int lineWidth, const QBrush *fill) - \relates <qdrawutil.h> - - Draws the plain rectangle beginning at (\a x, \a y) with the given - \a width and \a height, using the specified \a painter, \a lineColor - and \a lineWidth. The rectangle's interior is filled with the \a - fill brush unless \a fill is 0. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a plain rectangle: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 4 - - \sa qDrawShadeRect(), QStyle -*/ - -void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c, - int lineWidth, const QBrush *fill) -{ - if (w == 0 || h == 0) - return; - if (!(w > 0 && h > 0 && lineWidth >= 0)) { - qWarning("qDrawPlainRect: Invalid parameters"); - } - QPen oldPen = p->pen(); - QBrush oldBrush = p->brush(); - p->setPen(c); - p->setBrush(Qt::NoBrush); - for (int i=0; i<lineWidth; i++) - p->drawRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1); - if (fill) { // fill with fill color - p->setPen(Qt::NoPen); - p->setBrush(*fill); - p->drawRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2); - } - p->setPen(oldPen); - p->setBrush(oldBrush); -} - -/***************************************************************************** - Overloaded functions. - *****************************************************************************/ - -/*! - \fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2, - const QPalette &palette, bool sunken, int lineWidth, int midLineWidth) - \relates <qdrawutil.h> - \overload - - Draws a horizontal or vertical shaded line between \a p1 and \a p2 - using the given \a painter. Note that nothing is drawn if the line - between the points would be neither horizontal nor vertical. - - The provided \a palette specifies the shading colors (\l - {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l - {QPalette::mid()}{middle} colors). The given \a lineWidth - specifies the line width for each of the lines; it is not the - total line width. The given \a midLineWidth specifies the width of - a middle line drawn in the QPalette::mid() color. - - The line appears sunken if \a sunken is true, otherwise raised. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to - make widgets that follow the current GUI style. - - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a shaded line: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 5 - - \sa qDrawShadeRect(), qDrawShadePanel(), QStyle -*/ - -void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2, - const QPalette &pal, bool sunken, - int lineWidth, int midLineWidth) -{ - qDrawShadeLine(p, p1.x(), p1.y(), p2.x(), p2.y(), pal, sunken, - lineWidth, midLineWidth); -} - -/*! - \fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette, - bool sunken, int lineWidth, int midLineWidth, const QBrush *fill) - \relates <qdrawutil.h> - \overload - - Draws the shaded rectangle specified by \a rect using the given \a painter. - - The provide \a palette specifies the shading colors (\l - {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l - {QPalette::mid()}{middle} colors. The given \a lineWidth - specifies the line width for each of the lines; it is not the - total line width. The \a midLineWidth specifies the width of a - middle line drawn in the QPalette::mid() color. The rectangle's - interior is filled with the \a fill brush unless \a fill is 0. - - The rectangle appears sunken if \a sunken is true, otherwise - raised. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a shaded rectangle: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 6 - - \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle -*/ - -void qDrawShadeRect(QPainter *p, const QRect &r, - const QPalette &pal, bool sunken, - int lineWidth, int midLineWidth, - const QBrush *fill) -{ - qDrawShadeRect(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, - lineWidth, midLineWidth, fill); -} - -/*! - \fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette, - bool sunken, int lineWidth, const QBrush *fill) - \relates <qdrawutil.h> - \overload - - Draws the shaded panel at the rectangle specified by \a rect using the - given \a painter and the given \a lineWidth. - - The given \a palette specifies the shading colors (\l - {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l - {QPalette::mid()}{middle} colors). The panel's interior is filled - with the \a fill brush unless \a fill is 0. - - The panel appears sunken if \a sunken is true, otherwise raised. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a shaded panel: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 7 - - \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle -*/ - -void qDrawShadePanel(QPainter *p, const QRect &r, - const QPalette &pal, bool sunken, - int lineWidth, const QBrush *fill) -{ - qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, - lineWidth, fill); -} - -/*! - \fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette, - bool sunken, const QBrush *fill) - \relates <qdrawutil.h> - \overload - - Draws the Windows-style button at the rectangle specified by \a rect using - the given \a painter with a line width of 2 pixels. The button's interior - is filled with the \a{fill} brush unless \a fill is 0. - - The given \a palette specifies the shading colors (\l - {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l - {QPalette::mid()}{middle} colors). - - The button appears sunken if \a sunken is true, otherwise raised. - - \warning This function does not look at QWidget::style() or - QApplication::style()-> Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - \sa qDrawWinPanel(), QStyle -*/ - -void qDrawWinButton(QPainter *p, const QRect &r, - const QPalette &pal, bool sunken, const QBrush *fill) -{ - qDrawWinButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill); -} - -/*! - \fn void qDrawWinPanel(QPainter *painter, const QRect &rect, const QPalette &palette, - bool sunken, const QBrush *fill) - \overload - - Draws the Windows-style panel at the rectangle specified by \a rect using - the given \a painter with a line width of 2 pixels. The button's interior - is filled with the \a fill brush unless \a fill is 0. - - The given \a palette specifies the shading colors. The panel - appears sunken if \a sunken is true, otherwise raised. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a shaded panel: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 8 - - \sa qDrawShadePanel(), qDrawWinButton(), QStyle -*/ - -void qDrawWinPanel(QPainter *p, const QRect &r, - const QPalette &pal, bool sunken, const QBrush *fill) -{ - qDrawWinPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill); -} - -/*! - \fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill) - \relates <qdrawutil.h> - \overload - - Draws the plain rectangle specified by \a rect using the given \a painter, - \a lineColor and \a lineWidth. The rectangle's interior is filled with the - \a fill brush unless \a fill is 0. - - \warning This function does not look at QWidget::style() or - QApplication::style(). Use the drawing functions in QStyle to make - widgets that follow the current GUI style. - - Alternatively you can use a QFrame widget and apply the - QFrame::setFrameStyle() function to display a plain rectangle: - - \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 9 - - \sa qDrawShadeRect(), QStyle -*/ - -void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c, - int lineWidth, const QBrush *fill) -{ - qDrawPlainRect(p, r.x(), r.y(), r.width(), r.height(), c, - lineWidth, fill); -} - -#ifdef QT3_SUPPORT -static void qDrawWinArrow(QPainter *p, Qt::ArrowType type, bool down, - int x, int y, int w, int h, - const QPalette &pal, bool enabled) -{ - QPolygon a; // arrow polygon - switch (type) { - case Qt::UpArrow: - a.setPoints(7, -3,1, 3,1, -2,0, 2,0, -1,-1, 1,-1, 0,-2); - break; - case Qt::DownArrow: - a.setPoints(7, -3,-1, 3,-1, -2,0, 2,0, -1,1, 1,1, 0,2); - break; - case Qt::LeftArrow: - a.setPoints(7, 1,-3, 1,3, 0,-2, 0,2, -1,-1, -1,1, -2,0); - break; - case Qt::RightArrow: - a.setPoints(7, -1,-3, -1,3, 0,-2, 0,2, 1,-1, 1,1, 2,0); - break; - default: - break; - } - if (a.isEmpty()) - return; - - if (down) { - x++; - y++; - } - - QPen savePen = p->pen(); // save current pen - if (down) - p->setBrushOrigin(p->brushOrigin() + QPoint(1,1)); - p->fillRect(x, y, w, h, pal.brush(QPalette::Button)); - if (down) - p->setBrushOrigin(p->brushOrigin() - QPoint(1,1)); - if (enabled) { - a.translate(x+w/2, y+h/2); - p->setPen(pal.foreground().color()); - p->drawLine(a.at(0), a.at(1)); - p->drawLine(a.at(2), a.at(2)); - p->drawPoint(a[6]); - } else { - a.translate(x+w/2+1, y+h/2+1); - p->setPen(pal.light().color()); - p->drawLine(a.at(0), a.at(1)); - p->drawLine(a.at(2), a.at(2)); - p->drawPoint(a[6]); - a.translate(-1, -1); - p->setPen(pal.mid().color()); - p->drawLine(a.at(0), a.at(1)); - p->drawLine(a.at(2), a.at(2)); - p->drawPoint(a[6]); - } - p->setPen(savePen); // restore pen -} -#endif // QT3_SUPPORT - -#if defined(Q_CC_MSVC) -#pragma warning(disable: 4244) -#endif - -#ifdef QT3_SUPPORT -#ifndef QT_NO_STYLE_MOTIF -// motif arrows look the same whether they are used or not -// is this correct? -static void qDrawMotifArrow(QPainter *p, Qt::ArrowType type, bool down, - int x, int y, int w, int h, - const QPalette &pal, bool) -{ - QPolygon bFill; // fill polygon - QPolygon bTop; // top shadow. - QPolygon bBot; // bottom shadow. - QPolygon bLeft; // left shadow. - QTransform matrix; // xform matrix - bool vertical = type == Qt::UpArrow || type == Qt::DownArrow; - bool horizontal = !vertical; - int dim = w < h ? w : h; - int colspec = 0x0000; // color specification array - - if (dim < 2) // too small arrow - return; - - if (dim > 3) { - if (dim > 6) - bFill.resize(dim & 1 ? 3 : 4); - bTop.resize((dim/2)*2); - bBot.resize(dim & 1 ? dim + 1 : dim); - bLeft.resize(dim > 4 ? 4 : 2); - bLeft.putPoints(0, 2, 0,0, 0,dim-1); - if (dim > 4) - bLeft.putPoints(2, 2, 1,2, 1,dim-3); - bTop.putPoints(0, 4, 1,0, 1,1, 2,1, 3,1); - bBot.putPoints(0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2); - - for(int i=0; i<dim/2-2 ; i++) { - bTop.putPoints(i*2+4, 2, 2+i*2,2+i, 5+i*2, 2+i); - bBot.putPoints(i*2+4, 2, 2+i*2,dim-3-i, 5+i*2,dim-3-i); - } - if (dim & 1) // odd number size: extra line - bBot.putPoints(dim-1, 2, dim-3,dim/2, dim-1,dim/2); - if (dim > 6) { // dim>6: must fill interior - bFill.putPoints(0, 2, 1,dim-3, 1,2); - if (dim & 1) // if size is an odd number - bFill.setPoint(2, dim - 3, dim / 2); - else - bFill.putPoints(2, 2, dim-4,dim/2-1, dim-4,dim/2); - } - } - else { - if (dim == 3) { // 3x3 arrow pattern - bLeft.setPoints(4, 0,0, 0,2, 1,1, 1,1); - bTop .setPoints(2, 1,0, 1,0); - bBot .setPoints(2, 1,2, 2,1); - } - else { // 2x2 arrow pattern - bLeft.setPoints(2, 0,0, 0,1); - bTop .setPoints(2, 1,0, 1,0); - bBot .setPoints(2, 1,1, 1,1); - } - } - - if (type == Qt::UpArrow || type == Qt::LeftArrow) { - matrix.translate(x, y); - if (vertical) { - matrix.translate(0, h - 1); - matrix.rotate(-90); - } else { - matrix.translate(w - 1, h - 1); - matrix.rotate(180); - } - if (down) - colspec = horizontal ? 0x2334 : 0x2343; - else - colspec = horizontal ? 0x1443 : 0x1434; - } - else if (type == Qt::DownArrow || type == Qt::RightArrow) { - matrix.translate(x, y); - if (vertical) { - matrix.translate(w-1, 0); - matrix.rotate(90); - } - if (down) - colspec = horizontal ? 0x2443 : 0x2434; - else - colspec = horizontal ? 0x1334 : 0x1343; - } - - const QColor *cols[5]; - cols[0] = 0; - cols[1] = &pal.button().color(); - cols[2] = &pal.mid().color(); - cols[3] = &pal.light().color(); - cols[4] = &pal.dark().color(); -#define CMID *cols[(colspec>>12) & 0xf] -#define CLEFT *cols[(colspec>>8) & 0xf] -#define CTOP *cols[(colspec>>4) & 0xf] -#define CBOT *cols[colspec & 0xf] - - QPen savePen = p->pen(); // save current pen - QBrush saveBrush = p->brush(); // save current brush - QTransform wxm = p->transform(); - QPen pen(Qt::NoPen); - const QBrush &brush = pal.brush(QPalette::Button); - - p->setPen(pen); - p->setBrush(brush); - p->setTransform(matrix, true); // set transformation matrix - p->drawPolygon(bFill); // fill arrow - p->setBrush(Qt::NoBrush); // don't fill - - p->setPen(CLEFT); - p->drawLines(bLeft); - p->setPen(CTOP); - p->drawLines(bTop); - p->setPen(CBOT); - p->drawLines(bBot); - - p->setTransform(wxm); - p->setBrush(saveBrush); // restore brush - p->setPen(savePen); // restore pen - -#undef CMID -#undef CLEFT -#undef CTOP -#undef CBOT -} -#endif // QT_NO_STYLE_MOTIF - -QRect qItemRect(QPainter *p, Qt::GUIStyle gs, - int x, int y, int w, int h, - int flags, - bool enabled, - const QPixmap *pixmap, - const QString& text, int len) -{ - QRect result; - - if (pixmap) { - if ((flags & Qt::AlignVCenter) == Qt::AlignVCenter) - y += h/2 - pixmap->height()/2; - else if ((flags & Qt::AlignBottom) == Qt::AlignBottom) - y += h - pixmap->height(); - if ((flags & Qt::AlignRight) == Qt::AlignRight) - x += w - pixmap->width(); - else if ((flags & Qt::AlignHCenter) == Qt::AlignHCenter) - x += w/2 - pixmap->width()/2; - else if ((flags & Qt::AlignLeft) != Qt::AlignLeft && QApplication::isRightToLeft()) - x += w - pixmap->width(); - result = QRect(x, y, pixmap->width(), pixmap->height()); - } else if (!text.isNull() && p) { - result = p->boundingRect(QRect(x, y, w, h), flags, text.left(len)); - if (gs == Qt::WindowsStyle && !enabled) { - result.setWidth(result.width()+1); - result.setHeight(result.height()+1); - } - } else { - result = QRect(x, y, w, h); - } - - return result; -} - -void qDrawArrow(QPainter *p, Qt::ArrowType type, Qt::GUIStyle style, bool down, - int x, int y, int w, int h, - const QPalette &pal, bool enabled) -{ - switch (style) { - case Qt::WindowsStyle: - qDrawWinArrow(p, type, down, x, y, w, h, pal, enabled); - break; -#ifndef QT_NO_STYLE_MOTIF - case Qt::MotifStyle: - qDrawMotifArrow(p, type, down, x, y, w, h, pal, enabled); - break; -#endif - default: - qWarning("qDrawArrow: Requested unsupported GUI style"); - } -} - -void qDrawItem(QPainter *p, Qt::GUIStyle gs, - int x, int y, int w, int h, - int flags, - const QPalette &pal, bool enabled, - const QPixmap *pixmap, - const QString& text, int len , const QColor* penColor) -{ - p->setPen(penColor?*penColor:pal.foreground().color()); - if (pixmap) { - QPixmap pm(*pixmap); - bool clip = (flags & Qt::TextDontClip) == 0; - if (clip) { - if (pm.width() < w && pm.height() < h) - clip = false; - else - p->setClipRect(x, y, w, h); - } - if ((flags & Qt::AlignVCenter) == Qt::AlignVCenter) - y += h/2 - pm.height()/2; - else if ((flags & Qt::AlignBottom) == Qt::AlignBottom) - y += h - pm.height(); - if ((flags & Qt::AlignRight) == Qt::AlignRight) - x += w - pm.width(); - else if ((flags & Qt::AlignHCenter) == Qt::AlignHCenter) - x += w/2 - pm.width()/2; - else if (((flags & Qt::AlignLeft) != Qt::AlignLeft) && QApplication::isRightToLeft()) // Qt::AlignAuto && rightToLeft - x += w - pm.width(); - - if (!enabled) { - if (pm.hasAlphaChannel()) { // pixmap with a mask - pm = pm.mask(); - } else if (pm.depth() == 1) { // monochrome pixmap, no mask - ; -#ifndef QT_NO_IMAGE_HEURISTIC_MASK - } else { // color pixmap, no mask - QString k = QLatin1Literal("$qt-drawitem") - % HexString<qint64>(pm.cacheKey()); - - if (!QPixmapCache::find(k, pm)) { - pm = pm.createHeuristicMask(); - pm.setMask((QBitmap&)pm); - QPixmapCache::insert(k, pm); - } -#endif - } - if (gs == Qt::WindowsStyle) { - p->setPen(pal.light().color()); - p->drawPixmap(x+1, y+1, pm); - p->setPen(pal.text().color()); - } - } - p->drawPixmap(x, y, pm); - if (clip) - p->setClipping(false); - } else if (!text.isNull()) { - if (gs == Qt::WindowsStyle && !enabled) { - p->setPen(pal.light().color()); - p->drawText(x+1, y+1, w, h, flags, text.left(len)); - p->setPen(pal.text().color()); - } - p->drawText(x, y, w, h, flags, text.left(len)); - } -} - -#endif - -/*! - \class QTileRules - \since 4.6 - - Holds the rules used to draw a pixmap or image split into nine segments, - similar to \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}. - - \sa Qt::TileRule, QMargins -*/ - -/*! \fn QTileRules::QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule) - Constructs a QTileRules with the given \a horizontalRule and - \a verticalRule. - */ - -/*! \fn QTileRules::QTileRules(Qt::TileRule rule) - Constructs a QTileRules with the given \a rule used for both - the horizontal rule and the vertical rule. - */ - -/*! - \fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap) - \relates <qdrawutil.h> - \since 4.6 - \overload - - \brief The qDrawBorderPixmap function is for drawing a pixmap into - the margins of a rectangle. - - Draws the given \a pixmap into the given \a target rectangle, using the - given \a painter. The pixmap will be split into nine segments and drawn - according to the \a margins structure. -*/ - -typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray; - -/*! - \since 4.6 - - Draws the indicated \a sourceRect rectangle from the given \a pixmap into - the given \a targetRect rectangle, using the given \a painter. The pixmap - will be split into nine segments according to the given \a targetMargins - and \a sourceMargins structures. Finally, the pixmap will be drawn - according to the given \a rules. - - This function is used to draw a scaled pixmap, similar to - \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images} - - \sa Qt::TileRule, QTileRules, QMargins -*/ - -void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, - const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins, - const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints) -{ - QPainter::PixmapFragment d; - d.opacity = 1.0; - d.rotation = 0.0; - - QPixmapFragmentsArray opaqueData; - QPixmapFragmentsArray translucentData; - - // source center - const int sourceCenterTop = sourceRect.top() + sourceMargins.top(); - const int sourceCenterLeft = sourceRect.left() + sourceMargins.left(); - const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1; - const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1; - const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft; - const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop; - // target center - const int targetCenterTop = targetRect.top() + targetMargins.top(); - const int targetCenterLeft = targetRect.left() + targetMargins.left(); - const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1; - const int targetCenterRight = targetRect.right() - targetMargins.right() + 1; - const int targetCenterWidth = targetCenterRight - targetCenterLeft; - const int targetCenterHeight = targetCenterBottom - targetCenterTop; - - QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles - QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles - - int columns = 3; - int rows = 3; - if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0) - columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth))); - if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0) - rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight))); - - xTarget.resize(columns + 1); - yTarget.resize(rows + 1); - - bool oldAA = painter->testRenderHint(QPainter::Antialiasing); - if (painter->paintEngine()->type() != QPaintEngine::OpenGL - && painter->paintEngine()->type() != QPaintEngine::OpenGL2 - && oldAA && painter->combinedTransform().type() != QTransform::TxNone) { - painter->setRenderHint(QPainter::Antialiasing, false); - } - - xTarget[0] = targetRect.left(); - xTarget[1] = targetCenterLeft; - xTarget[columns - 1] = targetCenterRight; - xTarget[columns] = targetRect.left() + targetRect.width(); - - yTarget[0] = targetRect.top(); - yTarget[1] = targetCenterTop; - yTarget[rows - 1] = targetCenterBottom; - yTarget[rows] = targetRect.top() + targetRect.height(); - - qreal dx = targetCenterWidth; - qreal dy = targetCenterHeight; - - switch (rules.horizontal) { - case Qt::StretchTile: - dx = targetCenterWidth; - break; - case Qt::RepeatTile: - dx = sourceCenterWidth; - break; - case Qt::RoundTile: - dx = targetCenterWidth / qreal(columns - 2); - break; - } - - for (int i = 2; i < columns - 1; ++i) - xTarget[i] = xTarget[i - 1] + dx; - - switch (rules.vertical) { - case Qt::StretchTile: - dy = targetCenterHeight; - break; - case Qt::RepeatTile: - dy = sourceCenterHeight; - break; - case Qt::RoundTile: - dy = targetCenterHeight / qreal(rows - 2); - break; - } - - for (int i = 2; i < rows - 1; ++i) - yTarget[i] = yTarget[i - 1] + dy; - - // corners - if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left - d.x = (0.5 * (xTarget[1] + xTarget[0])); - d.y = (0.5 * (yTarget[1] + yTarget[0])); - d.sourceLeft = sourceRect.left(); - d.sourceTop = sourceRect.top(); - d.width = sourceMargins.left(); - d.height = sourceMargins.top(); - d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; - d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; - if (hints & QDrawBorderPixmap::OpaqueTopLeft) - opaqueData.append(d); - else - translucentData.append(d); - } - if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right - d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); - d.y = (0.5 * (yTarget[1] + yTarget[0])); - d.sourceLeft = sourceCenterRight; - d.sourceTop = sourceRect.top(); - d.width = sourceMargins.right(); - d.height = sourceMargins.top(); - d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; - d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; - if (hints & QDrawBorderPixmap::OpaqueTopRight) - opaqueData.append(d); - else - translucentData.append(d); - } - if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left - d.x = (0.5 * (xTarget[1] + xTarget[0])); - d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1])); - d.sourceLeft = sourceRect.left(); - d.sourceTop = sourceCenterBottom; - d.width = sourceMargins.left(); - d.height = sourceMargins.bottom(); - d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; - d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; - if (hints & QDrawBorderPixmap::OpaqueBottomLeft) - opaqueData.append(d); - else - translucentData.append(d); - } - if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right - d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); - d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); - d.sourceLeft = sourceCenterRight; - d.sourceTop = sourceCenterBottom; - d.width = sourceMargins.right(); - d.height = sourceMargins.bottom(); - d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; - d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; - if (hints & QDrawBorderPixmap::OpaqueBottomRight) - opaqueData.append(d); - else - translucentData.append(d); - } - - // horizontal edges - if (targetCenterWidth > 0 && sourceCenterWidth > 0) { - if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData; - d.sourceLeft = sourceCenterLeft; - d.sourceTop = sourceRect.top(); - d.width = sourceCenterWidth; - d.height = sourceMargins.top(); - d.y = (0.5 * (yTarget[1] + yTarget[0])); - d.scaleX = dx / d.width; - d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; - for (int i = 1; i < columns - 1; ++i) { - d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); - data.append(d); - } - if (rules.horizontal == Qt::RepeatTile) - data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); - } - if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData; - d.sourceLeft = sourceCenterLeft; - d.sourceTop = sourceCenterBottom; - d.width = sourceCenterWidth; - d.height = sourceMargins.bottom(); - d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); - d.scaleX = dx / d.width; - d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; - for (int i = 1; i < columns - 1; ++i) { - d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); - data.append(d); - } - if (rules.horizontal == Qt::RepeatTile) - data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); - } - } - - // vertical edges - if (targetCenterHeight > 0 && sourceCenterHeight > 0) { - if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData; - d.sourceLeft = sourceRect.left(); - d.sourceTop = sourceCenterTop; - d.width = sourceMargins.left(); - d.height = sourceCenterHeight; - d.x = (0.5 * (xTarget[1] + xTarget[0])); - d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; - d.scaleY = dy / d.height; - for (int i = 1; i < rows - 1; ++i) { - d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); - data.append(d); - } - if (rules.vertical == Qt::RepeatTile) - data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); - } - if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData; - d.sourceLeft = sourceCenterRight; - d.sourceTop = sourceCenterTop; - d.width = sourceMargins.right(); - d.height = sourceCenterHeight; - d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); - d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; - d.scaleY = dy / d.height; - for (int i = 1; i < rows - 1; ++i) { - d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); - data.append(d); - } - if (rules.vertical == Qt::RepeatTile) - data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); - } - } - - // center - if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) { - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData; - d.sourceLeft = sourceCenterLeft; - d.sourceTop = sourceCenterTop; - d.width = sourceCenterWidth; - d.height = sourceCenterHeight; - d.scaleX = dx / d.width; - d.scaleY = dy / d.height; - - qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX; - qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY; - - for (int j = 1; j < rows - 1; ++j) { - d.y = (0.5 * (yTarget[j + 1] + yTarget[j])); - for (int i = 1; i < columns - 1; ++i) { - d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); - data.append(d); - } - if (rules.horizontal == Qt::RepeatTile) - data[data.size() - 1].width = repeatWidth; - } - if (rules.vertical == Qt::RepeatTile) { - for (int i = 1; i < columns - 1; ++i) - data[data.size() - i].height = repeatHeight; - } - } - - if (opaqueData.size()) - painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint); - if (translucentData.size()) - painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap); - - if (oldAA) - painter->setRenderHint(QPainter::Antialiasing, true); -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qdrawutil.h b/src/gui/painting/qdrawutil.h deleted file mode 100644 index 0f38357841..0000000000 --- a/src/gui/painting/qdrawutil.h +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDRAWUTIL_H -#define QDRAWUTIL_H - -#include <QtCore/qnamespace.h> -#include <QtCore/qstring.h> // char*->QString conversion -#include <QtCore/qmargins.h> -#include <QtGui/qpixmap.h> -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QPainter; -#ifndef QT3_SUPPORT -class QColorGroup; -#endif -class QPalette; -class QPoint; -class QColor; -class QBrush; -class QRect; - -// -// Standard shade drawing -// - -Q_GUI_EXPORT void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, - const QPalette &pal, bool sunken = true, - int lineWidth = 1, int midLineWidth = 0); - -Q_GUI_EXPORT void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2, - const QPalette &pal, bool sunken = true, - int lineWidth = 1, int midLineWidth = 0); - -Q_GUI_EXPORT void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, - const QPalette &pal, bool sunken = false, - int lineWidth = 1, int midLineWidth = 0, - const QBrush *fill = 0); - -Q_GUI_EXPORT void qDrawShadeRect(QPainter *p, const QRect &r, - const QPalette &pal, bool sunken = false, - int lineWidth = 1, int midLineWidth = 0, - const QBrush *fill = 0); - -Q_GUI_EXPORT void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, - const QPalette &pal, bool sunken = false, - int lineWidth = 1, const QBrush *fill = 0); - -Q_GUI_EXPORT void qDrawShadePanel(QPainter *p, const QRect &r, - const QPalette &pal, bool sunken = false, - int lineWidth = 1, const QBrush *fill = 0); - -Q_GUI_EXPORT void qDrawWinButton(QPainter *p, int x, int y, int w, int h, - const QPalette &pal, bool sunken = false, - const QBrush *fill = 0); - -Q_GUI_EXPORT void qDrawWinButton(QPainter *p, const QRect &r, - const QPalette &pal, bool sunken = false, - const QBrush *fill = 0); - -Q_GUI_EXPORT void qDrawWinPanel(QPainter *p, int x, int y, int w, int h, - const QPalette &pal, bool sunken = false, - const QBrush *fill = 0); - -Q_GUI_EXPORT void qDrawWinPanel(QPainter *p, const QRect &r, - const QPalette &pal, bool sunken = false, - const QBrush *fill = 0); - -Q_GUI_EXPORT void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &, - int lineWidth = 1, const QBrush *fill = 0); - -Q_GUI_EXPORT void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &, - int lineWidth = 1, const QBrush *fill = 0); - - -#ifdef QT3_SUPPORT -// -// Use QStyle::itemRect(), QStyle::drawItem() and QStyle::drawArrow() instead. -// -Q_GUI_EXPORT QT3_SUPPORT QRect qItemRect(QPainter *p, Qt::GUIStyle gs, int x, int y, int w, int h, - int flags, bool enabled, - const QPixmap *pixmap, const QString& text, int len=-1); - -Q_GUI_EXPORT QT3_SUPPORT void qDrawItem(QPainter *p, Qt::GUIStyle gs, int x, int y, int w, int h, - int flags, const QPalette &pal, bool enabled, - const QPixmap *pixmap, const QString& text, - int len=-1, const QColor* penColor = 0); - -Q_GUI_EXPORT QT3_SUPPORT void qDrawArrow(QPainter *p, Qt::ArrowType type, Qt::GUIStyle style, bool down, - int x, int y, int w, int h, - const QPalette &pal, bool enabled); -#endif - -struct QTileRules -{ - inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule) - : horizontal(horizontalRule), vertical(verticalRule) {} - inline QTileRules(Qt::TileRule rule = Qt::StretchTile) - : horizontal(rule), vertical(rule) {} - Qt::TileRule horizontal; - Qt::TileRule vertical; -}; - -#ifndef Q_QDOC -// For internal use only. -namespace QDrawBorderPixmap -{ - enum DrawingHint - { - OpaqueTopLeft = 0x0001, - OpaqueTop = 0x0002, - OpaqueTopRight = 0x0004, - OpaqueLeft = 0x0008, - OpaqueCenter = 0x0010, - OpaqueRight = 0x0020, - OpaqueBottomLeft = 0x0040, - OpaqueBottom = 0x0080, - OpaqueBottomRight = 0x0100, - OpaqueCorners = OpaqueTopLeft | OpaqueTopRight | OpaqueBottomLeft | OpaqueBottomRight, - OpaqueEdges = OpaqueTop | OpaqueLeft | OpaqueRight | OpaqueBottom, - OpaqueFrame = OpaqueCorners | OpaqueEdges, - OpaqueAll = OpaqueCenter | OpaqueFrame - }; - - Q_DECLARE_FLAGS(DrawingHints, DrawingHint) -} -#endif - -Q_GUI_EXPORT void qDrawBorderPixmap(QPainter *painter, - const QRect &targetRect, - const QMargins &targetMargins, - const QPixmap &pixmap, - const QRect &sourceRect, - const QMargins &sourceMargins, - const QTileRules &rules = QTileRules() -#ifndef Q_QDOC - , QDrawBorderPixmap::DrawingHints hints = 0 -#endif - ); - -inline void qDrawBorderPixmap(QPainter *painter, - const QRect &target, - const QMargins &margins, - const QPixmap &pixmap) -{ - qDrawBorderPixmap(painter, target, margins, pixmap, pixmap.rect(), margins); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QDRAWUTIL_H diff --git a/src/gui/painting/qgraphicssystem.cpp b/src/gui/painting/qgraphicssystem.cpp deleted file mode 100644 index de0b516e79..0000000000 --- a/src/gui/painting/qgraphicssystem.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgraphicssystem_p.h" - -#ifdef Q_WS_X11 -# include <private/qpixmap_x11_p.h> -#endif -#if defined(Q_WS_WIN) -# include <private/qpixmap_raster_p.h> -#endif -#ifdef Q_WS_MAC -# include <private/qpixmap_mac_p.h> -#endif -#ifdef Q_WS_QPA -# include <QtGui/private/qapplication_p.h> -#endif -#ifdef Q_OS_SYMBIAN -# include <private/qpixmap_s60_p.h> -#endif - -QT_BEGIN_NAMESPACE - -QGraphicsSystem::~QGraphicsSystem() -{ -} - -QPixmapData *QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixelType type) -{ -#ifdef Q_WS_QWS - Q_UNUSED(type); -#endif -#if defined(Q_WS_X11) - return new QX11PixmapData(type); -#elif defined(Q_WS_WIN) - return new QRasterPixmapData(type); -#elif defined(Q_WS_MAC) - return new QMacPixmapData(type); -#elif defined(Q_WS_QPA) - return QApplicationPrivate::platformIntegration()->createPixmapData(type); -#elif defined(Q_OS_SYMBIAN) - return new QS60PixmapData(type); -#elif !defined(Q_WS_QWS) -#error QGraphicsSystem::createDefaultPixmapData() not implemented -#endif - return 0; -} - -QPixmapData *QGraphicsSystem::createPixmapData(QPixmapData *origin) -{ - return createPixmapData(origin->pixelType()); -} - -void QGraphicsSystem::releaseCachedResources() -{ - // Do nothing here -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystem_mac.cpp b/src/gui/painting/qgraphicssystem_mac.cpp deleted file mode 100644 index bbff88b6b5..0000000000 --- a/src/gui/painting/qgraphicssystem_mac.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgraphicssystem_mac_p.h" - -#include <private/qpixmap_mac_p.h> -#include <private/qwindowsurface_mac_p.h> - -QT_BEGIN_NAMESPACE - -QPixmapData *QCoreGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const -{ - return new QMacPixmapData(type); -} - -QWindowSurface *QCoreGraphicsSystem::createWindowSurface(QWidget *widget) const -{ - return new QMacWindowSurface(widget); -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystem_mac_p.h b/src/gui/painting/qgraphicssystem_mac_p.h deleted file mode 100644 index 8e15d8b236..0000000000 --- a/src/gui/painting/qgraphicssystem_mac_p.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSYSTEM_MAC_P_H -#define QGRAPHICSSYSTEM_MAC_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "private/qgraphicssystem_p.h" - -QT_BEGIN_NAMESPACE - -class Q_GUI_EXPORT QCoreGraphicsSystem : public QGraphicsSystem -{ -public: - QPixmapData *createPixmapData(QPixmapData::PixelType type) const; - QWindowSurface *createWindowSurface(QWidget *widget) const; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/gui/painting/qgraphicssystem_p.h b/src/gui/painting/qgraphicssystem_p.h deleted file mode 100644 index 53c05515fa..0000000000 --- a/src/gui/painting/qgraphicssystem_p.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSYSTEM_P_H -#define QGRAPHICSSYSTEM_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "private/qpixmapdata_p.h" -#include "private/qwindowsurface_p.h" -#include "private/qpaintengine_blitter_p.h" - -#include <qdebug.h> - -QT_BEGIN_NAMESPACE - -class QPixmapFilter; -class QBlittable; - -class Q_GUI_EXPORT QGraphicsSystem -{ -public: - virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const = 0; - virtual QPixmapData *createPixmapData(QPixmapData *origin); - virtual QWindowSurface *createWindowSurface(QWidget *widget) const = 0; - - virtual ~QGraphicsSystem(); - - //### Remove this & change qpixmap.cpp & qbitmap.cpp once every platform is gaurenteed - // to have a graphics system. - static QPixmapData *createDefaultPixmapData(QPixmapData::PixelType type); - - virtual void releaseCachedResources(); -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/gui/painting/qgraphicssystem_qws.cpp b/src/gui/painting/qgraphicssystem_qws.cpp deleted file mode 100644 index 2c2b776f5d..0000000000 --- a/src/gui/painting/qgraphicssystem_qws.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qscreen_qws.h> -#include "qgraphicssystem_qws_p.h" -#include <private/qpixmap_raster_p.h> -#include <private/qwindowsurface_qws_p.h> - -QT_BEGIN_NAMESPACE - -QPixmapData *QWSGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const -{ - if (screen->pixmapDataFactory()) - return screen->pixmapDataFactory()->create(type); //### For 4.4 compatibility - else - return new QRasterPixmapData(type); -} - -QWindowSurface *QWSGraphicsSystem::createWindowSurface(QWidget *widget) const -{ - return screen->createSurface(widget); -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystem_qws_p.h b/src/gui/painting/qgraphicssystem_qws_p.h deleted file mode 100644 index b54aad90f9..0000000000 --- a/src/gui/painting/qgraphicssystem_qws_p.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSYSTEM_QWS_P_H -#define QGRAPHICSSYSTEM_QWS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qgraphicssystem_p.h" - -QT_BEGIN_NAMESPACE - -class Q_GUI_EXPORT QWSGraphicsSystem : public QGraphicsSystem -{ -public: - - QWSGraphicsSystem() - : screen(QScreen::instance()) {} - - QWSGraphicsSystem(QScreen* s) - : screen(s) {} - - virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const; - QWindowSurface *createWindowSurface(QWidget *widget) const; - -private: - QScreen* screen; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/gui/painting/qgraphicssystem_raster.cpp b/src/gui/painting/qgraphicssystem_raster.cpp deleted file mode 100644 index 0edbe9f5a3..0000000000 --- a/src/gui/painting/qgraphicssystem_raster.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgraphicssystem_raster_p.h" - -#ifdef Q_OS_SYMBIAN -#include "private/qpixmap_s60_p.h" -#include "private/qwindowsurface_s60_p.h" -#else -#include "private/qpixmap_raster_p.h" -#include "private/qwindowsurface_raster_p.h" -#endif - -QT_BEGIN_NAMESPACE - -QPixmapData *QRasterGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const -{ -#ifdef Q_OS_SYMBIAN - return new QS60PixmapData(type); -#else - return new QRasterPixmapData(type); -#endif -} - -QWindowSurface *QRasterGraphicsSystem::createWindowSurface(QWidget *widget) const -{ -#ifdef Q_OS_SYMBIAN - return new QS60WindowSurface(widget); -#else - return new QRasterWindowSurface(widget); -#endif -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystem_raster_p.h b/src/gui/painting/qgraphicssystem_raster_p.h deleted file mode 100644 index e9737ce78f..0000000000 --- a/src/gui/painting/qgraphicssystem_raster_p.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSYSTEM_RASTER_P_H -#define QGRAPHICSSYSTEM_RASTER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qgraphicssystem_p.h" - -QT_BEGIN_NAMESPACE - -class QRasterGraphicsSystem : public QGraphicsSystem -{ -public: - QPixmapData *createPixmapData(QPixmapData::PixelType type) const; - QWindowSurface *createWindowSurface(QWidget *widget) const; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp deleted file mode 100644 index 19b29a13b3..0000000000 --- a/src/gui/painting/qgraphicssystem_runtime.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qgraphicssystem_runtime_p.h> -#include <private/qgraphicssystem_raster_p.h> -#include <private/qgraphicssystemfactory_p.h> -#include <private/qapplication_p.h> -#include <private/qwidget_p.h> -#include <QtCore/QDebug> -#include <QtCore/QTimer> -#include <QtGui/QBitmap> - -QT_BEGIN_NAMESPACE - -static int qt_pixmap_serial = 0; - -#define READBACK(f) \ - f \ - readBackInfo(); - - -class QDeferredGraphicsSystemChange : public QObject -{ - Q_OBJECT - -public: - QDeferredGraphicsSystemChange(QRuntimeGraphicsSystem *gs, const QString& graphicsSystemName) - : m_graphicsSystem(gs), m_graphicsSystemName(graphicsSystemName) - { - } - - void launch() - { - QTimer::singleShot(0, this, SLOT(doChange())); - } - -private slots: - - void doChange() - { - m_graphicsSystem->setGraphicsSystem(m_graphicsSystemName); - deleteLater(); - } - -private: - - QRuntimeGraphicsSystem *m_graphicsSystem; - QString m_graphicsSystemName; -}; - -QRuntimePixmapData::QRuntimePixmapData(const QRuntimeGraphicsSystem *gs, PixelType type) - : QPixmapData(type, RuntimeClass), m_graphicsSystem(gs) -{ - setSerialNumber(++qt_pixmap_serial); -} - -QRuntimePixmapData::~QRuntimePixmapData() -{ - if (QApplicationPrivate::graphics_system) - m_graphicsSystem->removePixmapData(this); - delete m_data; -} - -void QRuntimePixmapData::readBackInfo() -{ - w = m_data->width(); - h = m_data->height(); - d = m_data->depth(); - is_null = m_data->isNull(); -} - - -QPixmapData *QRuntimePixmapData::createCompatiblePixmapData() const -{ - QRuntimePixmapData *rtData = new QRuntimePixmapData(m_graphicsSystem, pixelType()); - rtData->m_data = m_data->createCompatiblePixmapData(); - return rtData; -} - - -void QRuntimePixmapData::resize(int width, int height) -{ - READBACK( - m_data->resize(width, height); - ) -} - - -void QRuntimePixmapData::fromImage(const QImage &image, - Qt::ImageConversionFlags flags) -{ - READBACK( - m_data->fromImage(image, flags); - ) -} - - -bool QRuntimePixmapData::fromFile(const QString &filename, const char *format, - Qt::ImageConversionFlags flags) -{ - bool success(false); - READBACK( - success = m_data->fromFile(filename, format, flags); - ) - return success; -} - -bool QRuntimePixmapData::fromData(const uchar *buffer, uint len, const char *format, - Qt::ImageConversionFlags flags) -{ - bool success(false); - READBACK( - success = m_data->fromData(buffer, len, format, flags); - ) - return success; -} - - -void QRuntimePixmapData::copy(const QPixmapData *data, const QRect &rect) -{ - if (data->runtimeData()) { - READBACK( - m_data->copy(data->runtimeData(), rect); - ) - } else { - READBACK( - m_data->copy(data, rect); - ) - } -} - -bool QRuntimePixmapData::scroll(int dx, int dy, const QRect &rect) -{ - return m_data->scroll(dx, dy, rect); -} - - -int QRuntimePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const -{ - return m_data->metric(metric); -} - -void QRuntimePixmapData::fill(const QColor &color) -{ - return m_data->fill(color); -} - -QBitmap QRuntimePixmapData::mask() const -{ - return m_data->mask(); -} - -void QRuntimePixmapData::setMask(const QBitmap &mask) -{ - READBACK( - m_data->setMask(mask); - ) -} - -bool QRuntimePixmapData::hasAlphaChannel() const -{ - return m_data->hasAlphaChannel(); -} - -QPixmap QRuntimePixmapData::transformed(const QTransform &matrix, - Qt::TransformationMode mode) const -{ - return m_data->transformed(matrix, mode); -} - -void QRuntimePixmapData::setAlphaChannel(const QPixmap &alphaChannel) -{ - READBACK( - m_data->setAlphaChannel(alphaChannel); - ) -} - -QPixmap QRuntimePixmapData::alphaChannel() const -{ - return m_data->alphaChannel(); -} - -QImage QRuntimePixmapData::toImage() const -{ - return m_data->toImage(); -} - -QPaintEngine* QRuntimePixmapData::paintEngine() const -{ - return m_data->paintEngine(); -} - -QImage* QRuntimePixmapData::buffer() -{ - return m_data->buffer(); -} - -#if defined(Q_OS_SYMBIAN) -void* QRuntimePixmapData::toNativeType(NativeType type) -{ - return m_data->toNativeType(type); -} - -void QRuntimePixmapData::fromNativeType(void *pixmap, NativeType type) -{ - m_data->fromNativeType(pixmap, type); - readBackInfo(); -} -#endif - -QPixmapData* QRuntimePixmapData::runtimeData() const -{ - return m_data; -} - -QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window) - : QWindowSurface(window), m_graphicsSystem(gs) -{ - -} - -QRuntimeWindowSurface::~QRuntimeWindowSurface() -{ - if (QApplicationPrivate::graphics_system) - m_graphicsSystem->removeWindowSurface(this); -} - -QPaintDevice *QRuntimeWindowSurface::paintDevice() -{ - return m_windowSurface->paintDevice(); -} - -void QRuntimeWindowSurface::flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset) -{ - m_windowSurface->flush(widget, region, offset); - - int destroyPolicy = m_graphicsSystem->windowSurfaceDestroyPolicy(); - if(m_pendingWindowSurface && - destroyPolicy == QRuntimeGraphicsSystem::DestroyAfterFirstFlush) { -#ifdef QT_DEBUG - qDebug() << "QRuntimeWindowSurface::flush() - destroy pending window surface"; -#endif - m_pendingWindowSurface.reset(); - } -} - -void QRuntimeWindowSurface::setGeometry(const QRect &rect) -{ - QWindowSurface::setGeometry(rect); - m_windowSurface->setGeometry(rect); -} - -bool QRuntimeWindowSurface::scroll(const QRegion &area, int dx, int dy) -{ - return m_windowSurface->scroll(area, dx, dy); -} - -void QRuntimeWindowSurface::beginPaint(const QRegion &rgn) -{ - m_windowSurface->beginPaint(rgn); -} - -void QRuntimeWindowSurface::endPaint(const QRegion &rgn) -{ - m_windowSurface->endPaint(rgn); -} - -QImage* QRuntimeWindowSurface::buffer(const QWidget *widget) -{ - return m_windowSurface->buffer(widget); -} - -QPixmap QRuntimeWindowSurface::grabWidget(const QWidget *widget, const QRect& rectangle) const -{ - return m_windowSurface->grabWidget(widget, rectangle); -} - -QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const -{ - return m_windowSurface->offset(widget); -} - -QWindowSurface::WindowSurfaceFeatures QRuntimeWindowSurface::features() const -{ - return m_windowSurface->features(); -} - -QRuntimeGraphicsSystem::QRuntimeGraphicsSystem() - : m_windowSurfaceDestroyPolicy(DestroyImmediately), - m_graphicsSystem(0) -{ - QApplicationPrivate::runtime_graphics_system = true; - -#ifdef QT_DEFAULT_RUNTIME_SYSTEM - m_graphicsSystemName = QLatin1String(QT_DEFAULT_RUNTIME_SYSTEM); - if (m_graphicsSystemName.isNull()) -#endif - m_graphicsSystemName = QLatin1String("raster"); - -#ifdef Q_OS_SYMBIAN - m_windowSurfaceDestroyPolicy = DestroyAfterFirstFlush; -#endif - - m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName); - - QApplicationPrivate::graphics_system_name = QLatin1String("runtime"); -} - - -QPixmapData *QRuntimeGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const -{ - Q_ASSERT(m_graphicsSystem); - QPixmapData *data = m_graphicsSystem->createPixmapData(type); - - QRuntimePixmapData *rtData = new QRuntimePixmapData(this, type); - rtData->m_data = data; - m_pixmapDatas << rtData; - - return rtData; -} - -QWindowSurface *QRuntimeGraphicsSystem::createWindowSurface(QWidget *widget) const -{ - Q_ASSERT(m_graphicsSystem); - QRuntimeWindowSurface *rtSurface = new QRuntimeWindowSurface(this, widget); - rtSurface->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget)); - widget->setWindowSurface(rtSurface); - m_windowSurfaces << rtSurface; - return rtSurface; -} - -void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name) -{ - if (m_graphicsSystemName == name) - return; -#ifdef QT_DEBUG - qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )"; -#endif - QGraphicsSystem *oldSystem = m_graphicsSystem; - m_graphicsSystem = QGraphicsSystemFactory::create(name); - m_graphicsSystemName = name; - - Q_ASSERT(m_graphicsSystem); - - m_pendingGraphicsSystemName = QString(); - - for (int i = 0; i < m_pixmapDatas.size(); ++i) { - QRuntimePixmapData *proxy = m_pixmapDatas.at(i); - QPixmapData *newData = m_graphicsSystem->createPixmapData(proxy->m_data); - newData->fromImage(proxy->m_data->toImage(), Qt::NoOpaqueDetection); - delete proxy->m_data; - proxy->m_data = newData; - proxy->readBackInfo(); - } - - for (int i = 0; i < m_windowSurfaces.size(); ++i) { - QRuntimeWindowSurface *proxy = m_windowSurfaces.at(i); - QWidget *widget = proxy->m_windowSurface->window(); - - if(m_windowSurfaceDestroyPolicy == DestroyAfterFirstFlush) - proxy->m_pendingWindowSurface.reset(proxy->m_windowSurface.take()); - - QWindowSurface *newWindowSurface = m_graphicsSystem->createWindowSurface(widget); - newWindowSurface->setGeometry(proxy->geometry()); - - proxy->m_windowSurface.reset(newWindowSurface); - qt_widget_private(widget)->invalidateBuffer(widget->rect()); - } - - delete oldSystem; -} - -void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const -{ - int index = m_pixmapDatas.lastIndexOf(pixmapData); - m_pixmapDatas.removeAt(index); -} - -void QRuntimeGraphicsSystem::removeWindowSurface(QRuntimeWindowSurface *windowSurface) const -{ - int index = m_windowSurfaces.lastIndexOf(windowSurface); - m_windowSurfaces.removeAt(index); -} - -#include "qgraphicssystem_runtime.moc" - -QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystem_runtime_p.h b/src/gui/painting/qgraphicssystem_runtime_p.h deleted file mode 100644 index a3828d44c0..0000000000 --- a/src/gui/painting/qgraphicssystem_runtime_p.h +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSYSTEM_RUNTIME_P_H -#define QGRAPHICSSYSTEM_RUNTIME_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qgraphicssystem_p.h" - -#include <private/qpixmapdata_p.h> - -QT_BEGIN_NAMESPACE - -class QRuntimeGraphicsSystem; - -class Q_GUI_EXPORT QRuntimePixmapData : public QPixmapData { -public: - QRuntimePixmapData(const QRuntimeGraphicsSystem *gs, PixelType type); - ~QRuntimePixmapData(); - - virtual QPixmapData *createCompatiblePixmapData() const; - virtual void resize(int width, int height); - virtual void fromImage(const QImage &image, - Qt::ImageConversionFlags flags); - - virtual bool fromFile(const QString &filename, const char *format, - Qt::ImageConversionFlags flags); - virtual bool fromData(const uchar *buffer, uint len, const char *format, - Qt::ImageConversionFlags flags); - - virtual void copy(const QPixmapData *data, const QRect &rect); - virtual bool scroll(int dx, int dy, const QRect &rect); - - virtual int metric(QPaintDevice::PaintDeviceMetric metric) const; - virtual void fill(const QColor &color); - virtual QBitmap mask() const; - virtual void setMask(const QBitmap &mask); - virtual bool hasAlphaChannel() const; - virtual QPixmap transformed(const QTransform &matrix, - Qt::TransformationMode mode) const; - virtual void setAlphaChannel(const QPixmap &alphaChannel); - virtual QPixmap alphaChannel() const; - virtual QImage toImage() const; - virtual QPaintEngine *paintEngine() const; - - virtual QImage *buffer(); - - void readBackInfo(); - - QPixmapData *m_data; - -#if defined(Q_OS_SYMBIAN) - void* toNativeType(NativeType type); - void fromNativeType(void* pixmap, NativeType type); -#endif - - virtual QPixmapData *runtimeData() const; - -private: - const QRuntimeGraphicsSystem *m_graphicsSystem; - -}; - -class QRuntimeWindowSurface : public QWindowSurface { -public: - QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window); - ~QRuntimeWindowSurface(); - - virtual QPaintDevice *paintDevice(); - virtual void flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset); - virtual void setGeometry(const QRect &rect); - - virtual bool scroll(const QRegion &area, int dx, int dy); - - virtual void beginPaint(const QRegion &); - virtual void endPaint(const QRegion &); - - virtual QImage* buffer(const QWidget *widget); - virtual QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const; - - virtual QPoint offset(const QWidget *widget) const; - - virtual WindowSurfaceFeatures features() const; - - QScopedPointer<QWindowSurface> m_windowSurface; - QScopedPointer<QWindowSurface> m_pendingWindowSurface; - -private: - const QRuntimeGraphicsSystem *m_graphicsSystem; -}; - -class QRuntimeGraphicsSystem : public QGraphicsSystem -{ -public: - - enum WindowSurfaceDestroyPolicy - { - DestroyImmediately, - DestroyAfterFirstFlush - }; - -public: - QRuntimeGraphicsSystem(); - - QPixmapData *createPixmapData(QPixmapData::PixelType type) const; - QWindowSurface *createWindowSurface(QWidget *widget) const; - - void removePixmapData(QRuntimePixmapData *pixmapData) const; - void removeWindowSurface(QRuntimeWindowSurface *windowSurface) const; - - void setGraphicsSystem(const QString &name); - QString graphicsSystemName() const { return m_graphicsSystemName; } - - void setWindowSurfaceDestroyPolicy(WindowSurfaceDestroyPolicy policy) - { - m_windowSurfaceDestroyPolicy = policy; - } - - int windowSurfaceDestroyPolicy() const { return m_windowSurfaceDestroyPolicy; } - - -private: - int m_windowSurfaceDestroyPolicy; - QGraphicsSystem *m_graphicsSystem; - mutable QList<QRuntimePixmapData *> m_pixmapDatas; - mutable QList<QRuntimeWindowSurface *> m_windowSurfaces; - QString m_graphicsSystemName; - - QString m_pendingGraphicsSystemName; - - friend class QRuntimePixmapData; - friend class QRuntimeWindowSurface; - friend class QMeeGoGraphicsSystem; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp deleted file mode 100644 index 4309140cc4..0000000000 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgraphicssystemfactory_p.h" -#include "qgraphicssystemplugin_p.h" -#include "private/qfactoryloader_p.h" -#include "qmutex.h" - -#include "qapplication.h" -#include <private/qapplication_p.h> -#include "qgraphicssystem_raster_p.h" -#include "qgraphicssystem_runtime_p.h" -#include "qdebug.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_LIBRARY -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QGraphicsSystemFactoryInterface_iid, QLatin1String("/graphicssystems"), Qt::CaseInsensitive)) -#endif - -QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) -{ - QGraphicsSystem *ret = 0; - QString system = key.toLower(); - -#if defined (QT_GRAPHICSSYSTEM_OPENGL) - if (system.isEmpty()) { - system = QLatin1String("opengl"); - } -#elif defined (QT_GRAPHICSSYSTEM_OPENVG) - if (system.isEmpty()) { - system = QLatin1String("openvg"); - } -#elif defined (QT_GRAPHICSSYSTEM_RUNTIME) - if (system.isEmpty()) { - system = QLatin1String("runtime"); - } -#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) || (defined (Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) - if (system.isEmpty()) { - system = QLatin1String("raster"); - } -#endif - - QApplicationPrivate::graphics_system_name = system; - if (system == QLatin1String("raster")) - return new QRasterGraphicsSystem; - else if (system == QLatin1String("runtime")) - return new QRuntimeGraphicsSystem; - else if (system.isEmpty() || system == QLatin1String("native")) - return 0; - -#ifndef QT_NO_LIBRARY - if (!ret) { - if (QGraphicsSystemFactoryInterface *factory = qobject_cast<QGraphicsSystemFactoryInterface*>(loader()->instance(system))) - ret = factory->create(system); - } -#endif - - if (!ret) - qWarning() << "Unable to load graphicssystem" << system; - - return ret; -} - -/*! - Returns the list of valid keys, i.e. the keys this factory can - create styles for. - - \sa create() -*/ -QStringList QGraphicsSystemFactory::keys() -{ -#ifndef QT_NO_LIBRARY - QStringList list = loader()->keys(); -#else - QStringList list; -#endif - if (!list.contains(QLatin1String("Raster"))) - list << QLatin1String("raster"); - return list; -} - -QT_END_NAMESPACE - diff --git a/src/gui/painting/qgraphicssystemplugin.cpp b/src/gui/painting/qgraphicssystemplugin.cpp deleted file mode 100644 index 8153b8aa05..0000000000 --- a/src/gui/painting/qgraphicssystemplugin.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgraphicssystemplugin_p.h" -#include "qgraphicssystem_p.h" - -QT_BEGIN_NAMESPACE - -QGraphicsSystemPlugin::QGraphicsSystemPlugin(QObject *parent) - : QObject(parent) -{ -} - -QGraphicsSystemPlugin::~QGraphicsSystemPlugin() -{ -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystemplugin_p.h b/src/gui/painting/qgraphicssystemplugin_p.h deleted file mode 100644 index 3d353abe79..0000000000 --- a/src/gui/painting/qgraphicssystemplugin_p.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSYSTEMPLUGIN_H -#define QGRAPHICSSYSTEMPLUGIN_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qplugin.h> -#include <QtCore/qfactoryinterface.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QGraphicsSystem; - -struct QGraphicsSystemFactoryInterface : public QFactoryInterface -{ - virtual QGraphicsSystem *create(const QString &key) = 0; -}; - -#define QGraphicsSystemFactoryInterface_iid "com.trolltech.Qt.QGraphicsSystemFactoryInterface" - -Q_DECLARE_INTERFACE(QGraphicsSystemFactoryInterface, QGraphicsSystemFactoryInterface_iid) - -class Q_GUI_EXPORT QGraphicsSystemPlugin : public QObject, public QGraphicsSystemFactoryInterface -{ - Q_OBJECT - Q_INTERFACES(QGraphicsSystemFactoryInterface:QFactoryInterface) -public: - explicit QGraphicsSystemPlugin(QObject *parent = 0); - ~QGraphicsSystemPlugin(); - - virtual QStringList keys() const = 0; - virtual QGraphicsSystem *create(const QString &key) = 0; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGRAPHICSSYSTEMEPLUGIN_H diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp index 7bb2324a2f..767706a5bc 100644 --- a/src/gui/painting/qmatrix.cpp +++ b/src/gui/painting/qmatrix.cpp @@ -731,42 +731,6 @@ QPainterPath QMatrix::map(const QPainterPath &path) const } /*! - \fn QRegion QMatrix::mapToRegion(const QRect &rectangle) const - - Returns the transformed rectangle \a rectangle as a QRegion - object. A rectangle which has been rotated or sheared may result - in a non-rectangular region being returned. - - Use the mapToPolygon() or map() function instead. -*/ -#ifdef QT3_SUPPORT -QRegion QMatrix::mapToRegion(const QRect &rect) const -{ - QRegion result; - if (isIdentity()) { - result = rect; - } else if (m12() == 0.0F && m21() == 0.0F) { - int x = qRound(m11()*rect.x() + dx()); - int y = qRound(m22()*rect.y() + dy()); - int w = qRound(m11()*rect.width()); - int h = qRound(m22()*rect.height()); - if (w < 0) { - w = -w; - x -= w - 1; - } - if (h < 0) { - h = -h; - y -= h - 1; - } - result = QRect(x, y, w, h); - } else { - result = QRegion(mapToPolygon(rect)); - } - return result; - -} -#endif -/*! \fn QPolygon QMatrix::mapToPolygon(const QRect &rectangle) const Creates and returns a QPolygon representation of the given \a diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h index ff80704387..830a0a734f 100644 --- a/src/gui/painting/qmatrix.h +++ b/src/gui/painting/qmatrix.h @@ -118,12 +118,6 @@ public: operator QVariant() const; -#ifdef QT3_SUPPORT - inline QT3_SUPPORT QMatrix invert(bool *invertible=0) const { return inverted(invertible); } - inline QT3_SUPPORT QRect map(const QRect &r) const { return mapRect(r); } - QT3_SUPPORT QRegion mapToRegion(const QRect &r) const; -#endif - private: inline QMatrix(bool) : _m11(1.) @@ -193,12 +187,6 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix &); Q_GUI_EXPORT QDebug operator<<(QDebug, const QMatrix &); #endif -#ifdef QT3_SUPPORT -QT_BEGIN_INCLUDE_NAMESPACE -#include <QtGui/qwmatrix.h> -QT_END_INCLUDE_NAMESPACE -#endif - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp index 0ab6674913..857621df6e 100644 --- a/src/gui/painting/qmemrotate.cpp +++ b/src/gui/painting/qmemrotate.cpp @@ -512,34 +512,34 @@ inline void qt_memrotate90_template<quint18, quint32>(const quint32 *src, } #define QT_IMPL_MEMROTATE(srctype, desttype) \ -void qt_memrotate90(const srctype *src, int w, int h, int sstride, \ +Q_GUI_EXPORT void qt_memrotate90(const srctype *src, int w, int h, int sstride, \ desttype *dest, int dstride) \ { \ qt_memrotate90_template(src, w, h, sstride, dest, dstride); \ } \ -void qt_memrotate180(const srctype *src, int w, int h, int sstride, \ +Q_GUI_EXPORT void qt_memrotate180(const srctype *src, int w, int h, int sstride, \ desttype *dest, int dstride) \ { \ qt_memrotate180_template(src, w, h, sstride, dest, dstride); \ } \ -void qt_memrotate270(const srctype *src, int w, int h, int sstride, \ +Q_GUI_EXPORT void qt_memrotate270(const srctype *src, int w, int h, int sstride, \ desttype *dest, int dstride) \ { \ qt_memrotate270_template(src, w, h, sstride, dest, dstride); \ } #define QT_IMPL_SIMPLE_MEMROTATE(srctype, desttype) \ -void qt_memrotate90(const srctype *src, int w, int h, int sstride, \ +Q_GUI_EXPORT void qt_memrotate90(const srctype *src, int w, int h, int sstride, \ desttype *dest, int dstride) \ { \ qt_memrotate90_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \ } \ -void qt_memrotate180(const srctype *src, int w, int h, int sstride, \ +Q_GUI_EXPORT void qt_memrotate180(const srctype *src, int w, int h, int sstride, \ desttype *dest, int dstride) \ { \ qt_memrotate180_template(src, w, h, sstride, dest, dstride); \ } \ -void qt_memrotate270(const srctype *src, int w, int h, int sstride, \ +Q_GUI_EXPORT void qt_memrotate270(const srctype *src, int w, int h, int sstride, \ desttype *dest, int dstride) \ { \ qt_memrotate270_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \ diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h index 019576a446..84b0b01846 100644 --- a/src/gui/painting/qmemrotate_p.h +++ b/src/gui/painting/qmemrotate_p.h @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE #endif #endif -#ifdef Q_WS_QWS +#if defined(Q_WS_QWS) || defined(Q_WS_QPA) && defined(Q_OS_WIN) #define Q_GUI_QWS_EXPORT Q_GUI_EXPORT #else #define Q_GUI_QWS_EXPORT diff --git a/src/gui/painting/qpaintdevice.cpp b/src/gui/painting/qpaintdevice.cpp index 7b3d4add49..fc5cdcdaa5 100644 --- a/src/gui/painting/qpaintdevice.cpp +++ b/src/gui/painting/qpaintdevice.cpp @@ -43,8 +43,6 @@ QT_BEGIN_NAMESPACE -extern void qt_painter_removePaintDevice(QPaintDevice *); //qpainter.cpp - QPaintDevice::QPaintDevice() { painters = 0; @@ -55,7 +53,6 @@ QPaintDevice::~QPaintDevice() if (paintingActive()) qWarning("QPaintDevice: Cannot destroy paint device that is being " "painted"); - qt_painter_removePaintDevice(this); } @@ -67,6 +64,20 @@ int QPaintDevice::metric(PaintDeviceMetric) const } #endif +void QPaintDevice::init(QPainter *) const +{ +} + +QPaintDevice *QPaintDevice::redirected(QPoint *) const +{ + return 0; +} + +QPainter *QPaintDevice::sharedPainter() const +{ + return 0; +} + Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice::PaintDeviceMetric metric) { return device->metric(metric); diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h index 3ebc24ee14..0b44990c69 100644 --- a/src/gui/painting/qpaintdevice.h +++ b/src/gui/painting/qpaintdevice.h @@ -105,61 +105,22 @@ public: protected: QPaintDevice(); virtual int metric(PaintDeviceMetric metric) const; + virtual void init(QPainter *painter) const; + virtual QPaintDevice *redirected(QPoint *offset) const; + virtual QPainter *sharedPainter() const; ushort painters; // refcount private: Q_DISABLE_COPY(QPaintDevice) -#if defined(Q_WS_X11) && defined(QT3_SUPPORT) -public: - QT3_SUPPORT Display *x11Display() const; - QT3_SUPPORT int x11Screen() const; - QT3_SUPPORT int x11Depth() const; - QT3_SUPPORT int x11Cells() const; - QT3_SUPPORT Qt::HANDLE x11Colormap() const; - QT3_SUPPORT bool x11DefaultColormap() const; - QT3_SUPPORT void *x11Visual() const; - QT3_SUPPORT bool x11DefaultVisual() const; - - static QT3_SUPPORT Display *x11AppDisplay(); - static QT3_SUPPORT int x11AppScreen(); - static QT3_SUPPORT int x11AppDepth(int screen = -1); - static QT3_SUPPORT int x11AppCells(int screen = -1); - static QT3_SUPPORT Qt::HANDLE x11AppRootWindow(int screen = -1); - static QT3_SUPPORT Qt::HANDLE x11AppColormap(int screen = -1); - static QT3_SUPPORT void *x11AppVisual(int screen = -1); - static QT3_SUPPORT bool x11AppDefaultColormap(int screen =-1); - static QT3_SUPPORT bool x11AppDefaultVisual(int screen =-1); - static QT3_SUPPORT int x11AppDpiX(int screen = -1); - static QT3_SUPPORT int x11AppDpiY(int screen = -1); - static QT3_SUPPORT void x11SetAppDpiX(int, int); - static QT3_SUPPORT void x11SetAppDpiY(int, int); -#endif - friend class QPainter; + friend class QPainterPrivate; friend class QFontEngineMac; friend class QX11PaintEngine; friend Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, PaintDeviceMetric metric); }; -#ifdef QT3_SUPPORT -QT3_SUPPORT Q_GUI_EXPORT -void bitBlt(QPaintDevice *dst, int dx, int dy, - const QPaintDevice *src, int sx=0, int sy=0, int sw=-1, int sh=-1, - bool ignoreMask=false); - -QT3_SUPPORT Q_GUI_EXPORT -void bitBlt(QPaintDevice *dst, int dx, int dy, - const QImage *src, int sx=0, int sy=0, int sw=-1, int sh=-1, - int conversion_flags=0); - -QT3_SUPPORT Q_GUI_EXPORT -void bitBlt(QPaintDevice *dst, const QPoint &dp, - const QPaintDevice *src, const QRect &sr=QRect(0,0,-1,-1), - bool ignoreMask=false); -#endif - /***************************************************************************** Inline functions *****************************************************************************/ diff --git a/src/gui/painting/qpaintdevice_mac.cpp b/src/gui/painting/qpaintdevice_mac.cpp deleted file mode 100644 index 56cf8dc5a8..0000000000 --- a/src/gui/painting/qpaintdevice_mac.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpaintdevice.h" -#include "qpainter.h" -#include "qwidget.h" -#include "qbitmap.h" -#include "qapplication.h" -#include "qprinter.h" -#include <qdebug.h> -#include <private/qt_mac_p.h> -#include <private/qprintengine_mac_p.h> -#include <private/qpixmap_mac_p.h> -#include <private/qpixmap_raster_p.h> - -QT_BEGIN_NAMESPACE - -/***************************************************************************** - Internal variables and functions - *****************************************************************************/ - -/*! \internal */ -float qt_mac_defaultDpi_x() -{ - // Mac OS X currently assumes things to be 72 dpi. - // (see http://developer.apple.com/releasenotes/GraphicsImaging/RN-ResolutionIndependentUI/) - // This may need to be re-worked as we go further in the resolution-independence stuff. - return 72; -} - -/*! \internal */ -float qt_mac_defaultDpi_y() -{ - // Mac OS X currently assumes things to be 72 dpi. - // (see http://developer.apple.com/releasenotes/GraphicsImaging/RN-ResolutionIndependentUI/) - // This may need to be re-worked as we go further in the resolution-independence stuff. - return 72; -} - - -/*! \internal - - Returns the QuickDraw CGrafPtr of the paint device. 0 is returned - if it can't be obtained. Do not hold the pointer around for long - as it can be relocated. - - \warning This function is only available on Mac OS X. -*/ - -Q_GUI_EXPORT GrafPtr qt_mac_qd_context(const QPaintDevice *device) -{ - if (device->devType() == QInternal::Pixmap) { - return static_cast<GrafPtr>(static_cast<const QPixmap *>(device)->macQDHandle()); - } else if(device->devType() == QInternal::Widget) { - return static_cast<GrafPtr>(static_cast<const QWidget *>(device)->macQDHandle()); - } else if(device->devType() == QInternal::Printer) { - QPaintEngine *engine = static_cast<const QPrinter *>(device)->paintEngine(); - return static_cast<GrafPtr>(static_cast<const QMacPrintEngine *>(engine)->handle()); - } - return 0; -} - -extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *pdev); - -/*! \internal - - Returns the CoreGraphics CGContextRef of the paint device. 0 is - returned if it can't be obtained. It is the caller's responsiblity to - CGContextRelease the context when finished using it. - - \warning This function is only available on Mac OS X. -*/ - -Q_GUI_EXPORT CGContextRef qt_mac_cg_context(const QPaintDevice *pdev) -{ - if (pdev->devType() == QInternal::Pixmap) { - const QPixmap *pm = static_cast<const QPixmap*>(pdev); - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev); - uint flags = kCGImageAlphaPremultipliedFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - flags |= kCGBitmapByteOrder32Host; -#endif - CGContextRef ret = 0; - - // It would make sense to put this into a mac #ifdef'ed - // virtual function in the QPixmapData at some point - if (pm->data->classId() == QPixmapData::MacClass) { - const QMacPixmapData *pmData = static_cast<const QMacPixmapData*>(pm->data.data()); - ret = CGBitmapContextCreate(pmData->pixels, pmData->w, pmData->h, - 8, pmData->bytesPerRow, colorspace, - flags); - if(!ret) - qWarning("QPaintDevice: Unable to create context for pixmap (%d/%d/%d)", - pmData->w, pmData->h, (pmData->bytesPerRow * pmData->h)); - } else if (pm->data->classId() == QPixmapData::RasterClass) { - QImage *image = pm->data->buffer(); - ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - } - - CGContextTranslateCTM(ret, 0, pm->height()); - CGContextScaleCTM(ret, 1, -1); - return ret; - } else if (pdev->devType() == QInternal::Widget) { - CGContextRef ret = static_cast<CGContextRef>(static_cast<const QWidget *>(pdev)->macCGHandle()); - CGContextRetain(ret); - return ret; - } else if (pdev->devType() == QInternal::MacQuartz) { - return static_cast<const QMacQuartzPaintDevice *>(pdev)->cgContext(); - } - return 0; -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintdevice_qpa.cpp b/src/gui/painting/qpaintdevice_qpa.cpp index 813965feb1..65eeaaa7e8 100644 --- a/src/gui/painting/qpaintdevice_qpa.cpp +++ b/src/gui/painting/qpaintdevice_qpa.cpp @@ -41,14 +41,11 @@ #include "qpaintdevice.h" #include "qpainter.h" -#include "qwidget.h" #include "qbitmap.h" -#include "qapplication.h" +#include "qguiapplication.h" QT_BEGIN_NAMESPACE -extern void qt_painter_removePaintDevice(QPaintDevice *); //qpainter.cpp - int QPaintDevice::metric(PaintDeviceMetric m) const { qWarning("QPaintDevice::metrics: Device has no metric information"); diff --git a/src/gui/painting/qpaintdevice_qws.cpp b/src/gui/painting/qpaintdevice_qws.cpp deleted file mode 100644 index 9d5ba6e850..0000000000 --- a/src/gui/painting/qpaintdevice_qws.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpaintdevice.h" -#include "qpainter.h" -#include "qwidget.h" -#include "qbitmap.h" -#include "qapplication.h" -#include "qwsdisplay_qws.h" - -QT_BEGIN_NAMESPACE - -QWSDisplay *QPaintDevice::qwsDisplay() -{ - return qt_fbdpy; -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintdevice_win.cpp b/src/gui/painting/qpaintdevice_win.cpp deleted file mode 100644 index a6d79d8341..0000000000 --- a/src/gui/painting/qpaintdevice_win.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpaintdevice.h" -#include "qpainter.h" -#include "qwidget.h" -#include "qbitmap.h" -#include "qapplication.h" -#include <private/qapplication_p.h> -#include "qt_windows.h" -#include "qprinter.h" - -QT_BEGIN_NAMESPACE - -HDC QPaintDevice::getDC() const -{ - return 0; -} - -void QPaintDevice::releaseDC(HDC) const -{ -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintdevice_x11.cpp b/src/gui/painting/qpaintdevice_x11.cpp deleted file mode 100644 index 42e61e855b..0000000000 --- a/src/gui/painting/qpaintdevice_x11.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpaintdevice.h" -#include "qpainter.h" -#include "qwidget.h" -#include "qbitmap.h" -#include "qapplication.h" -#include <private/qt_x11_p.h> -#include "qx11info_x11.h" - -QT_BEGIN_NAMESPACE - -/*! \internal - - Returns the X11 Drawable of the paint device. 0 is returned if it - can't be obtained. -*/ - -Drawable Q_GUI_EXPORT qt_x11Handle(const QPaintDevice *pd) -{ - if (!pd) return 0; - if (pd->devType() == QInternal::Widget) - return static_cast<const QWidget *>(pd)->handle(); - else if (pd->devType() == QInternal::Pixmap) - return static_cast<const QPixmap *>(pd)->handle(); - return 0; -} - -/*! - \relates QPaintDevice - - Returns the QX11Info structure for the \a pd paint device. 0 is - returned if it can't be obtained. -*/ -const Q_GUI_EXPORT QX11Info *qt_x11Info(const QPaintDevice *pd) -{ - if (!pd) return 0; - if (pd->devType() == QInternal::Widget) - return &static_cast<const QWidget *>(pd)->x11Info(); - else if (pd->devType() == QInternal::Pixmap) - return &static_cast<const QPixmap *>(pd)->x11Info(); - return 0; -} - - - -#ifdef QT3_SUPPORT - -Display *QPaintDevice::x11Display() const -{ - return X11->display; -} - -int QPaintDevice::x11Screen() const -{ - const QX11Info *info = qt_x11Info(this); - if (info) - return info->screen(); - return QX11Info::appScreen(); -} - -void *QPaintDevice::x11Visual() const -{ - const QX11Info *info = qt_x11Info(this); - if (info) - return info->visual(); - return QX11Info::appVisual(); -} - -int QPaintDevice::x11Depth() const -{ - const QX11Info *info = qt_x11Info(this); - if (info) - return info->depth(); - return QX11Info::appDepth(); -} - -int QPaintDevice::x11Cells() const -{ - const QX11Info *info = qt_x11Info(this); - if (info) - return info->cells(); - return QX11Info::appCells(); -} - -Qt::HANDLE QPaintDevice::x11Colormap() const -{ - const QX11Info *info = qt_x11Info(this); - if (info) - return info->colormap(); - return QX11Info::appColormap(); -} - -bool QPaintDevice::x11DefaultColormap() const -{ - const QX11Info *info = qt_x11Info(this); - if (info) - return info->defaultColormap(); - return QX11Info::appDefaultColormap(); -} - -bool QPaintDevice::x11DefaultVisual() const -{ - const QX11Info *info = qt_x11Info(this); - if (info) - return info->defaultVisual(); - return QX11Info::appDefaultVisual(); -} - -void *QPaintDevice::x11AppVisual(int screen) -{ return QX11Info::appVisual(screen); } - -Qt::HANDLE QPaintDevice::x11AppColormap(int screen) -{ return QX11Info::appColormap(screen); } - -Display *QPaintDevice::x11AppDisplay() -{ return QX11Info::display(); } - -int QPaintDevice::x11AppScreen() -{ return QX11Info::appScreen(); } - -int QPaintDevice::x11AppDepth(int screen) -{ return QX11Info::appDepth(screen); } - -int QPaintDevice::x11AppCells(int screen) -{ return QX11Info::appCells(screen); } - -Qt::HANDLE QPaintDevice::x11AppRootWindow(int screen) -{ return QX11Info::appRootWindow(screen); } - -bool QPaintDevice::x11AppDefaultColormap(int screen) -{ return QX11Info::appDefaultColormap(screen); } - -bool QPaintDevice::x11AppDefaultVisual(int screen) -{ return QX11Info::appDefaultVisual(screen); } - -void QPaintDevice::x11SetAppDpiX(int dpi, int screen) -{ - QX11Info::setAppDpiX(dpi, screen); -} - -void QPaintDevice::x11SetAppDpiY(int dpi, int screen) -{ - QX11Info::setAppDpiY(dpi, screen); -} - -int QPaintDevice::x11AppDpiX(int screen) -{ - return QX11Info::appDpiX(screen); -} - -int QPaintDevice::x11AppDpiY(int screen) -{ - return QX11Info::appDpiY(screen); -} -#endif - - -QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index c46513a07c..c8870cd5d3 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -43,9 +43,9 @@ #include "qpainter_p.h" #include "qpolygon.h" #include "qbitmap.h" -#include "qapplication.h" #include <qdebug.h> #include <qmath.h> +#include <qguiapplication.h> #include <private/qtextengine_p.h> #include <qvarlengtharray.h> #include <private/qfontengine_p.h> @@ -139,7 +139,7 @@ QString QTextItem::text() const QFont QTextItem::font() const { const QTextItemInt *ti = static_cast<const QTextItemInt *>(this); - return ti->f ? *ti->f : QApplication::font(); + return ti->f ? *ti->f : QGuiApplication::font(); } diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp index 75efa20804..f8bc3f1c9e 100644 --- a/src/gui/painting/qpaintengine_blitter.cpp +++ b/src/gui/painting/qpaintengine_blitter.cpp @@ -44,7 +44,6 @@ #include "private/qblittable_p.h" #include "private/qpaintengine_raster_p.h" #include "private/qpainter_p.h" -#include "private/qapplication_p.h" #include "private/qpixmap_blitter_p.h" #ifndef QT_NO_BLITTABLE diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp deleted file mode 100644 index 0d459a5d89..0000000000 --- a/src/gui/painting/qpaintengine_mac.cpp +++ /dev/null @@ -1,1747 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qbitmap.h> -#include <qpaintdevice.h> -#include <private/qpaintengine_mac_p.h> -#include <qpainterpath.h> -#include <qpixmapcache.h> -#include <private/qpaintengine_raster_p.h> -#include <private/qprintengine_mac_p.h> -#include <qprinter.h> -#include <qstack.h> -#include <qtextcodec.h> -#include <qwidget.h> -#include <qvarlengtharray.h> -#include <qdebug.h> -#include <qcoreapplication.h> -#include <qmath.h> - -#include <private/qfont_p.h> -#include <private/qfontengine_p.h> -#include <private/qfontengine_coretext_p.h> -#include <private/qfontengine_mac_p.h> -#include <private/qnumeric_p.h> -#include <private/qpainter_p.h> -#include <private/qpainterpath_p.h> -#include <private/qpixmap_mac_p.h> -#include <private/qt_mac_p.h> -#include <private/qtextengine_p.h> -#include <private/qwidget_p.h> -#include <private/qt_cocoa_helpers_mac_p.h> - -#include <string.h> - -QT_BEGIN_NAMESPACE - -extern int qt_antialiasing_threshold; // QApplication.cpp - -/***************************************************************************** - External functions - *****************************************************************************/ -extern CGImageRef qt_mac_create_imagemask(const QPixmap &px, const QRectF &sr); //qpixmap_mac.cpp -extern QPoint qt_mac_posInWindow(const QWidget *w); //qwidget_mac.cpp -extern OSWindowRef qt_mac_window_for(const QWidget *); //qwidget_mac.cpp -extern CGContextRef qt_mac_cg_context(const QPaintDevice *); //qpaintdevice_mac.cpp -extern void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp -extern QPixmap qt_pixmapForBrush(int, bool); //qbrush.cpp - -void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform); - - -//Implemented for qt_mac_p.h -QMacCGContext::QMacCGContext(QPainter *p) -{ - QPaintEngine *pe = p->paintEngine(); - if (pe->type() == QPaintEngine::MacPrinter) - pe = static_cast<QMacPrintEngine*>(pe)->paintEngine(); - pe->syncState(); - context = 0; - if(pe->type() == QPaintEngine::CoreGraphics) - context = static_cast<QCoreGraphicsPaintEngine*>(pe)->handle(); - - int devType = p->device()->devType(); - if (pe->type() == QPaintEngine::Raster - && (devType == QInternal::Widget || - devType == QInternal::Pixmap || - devType == QInternal::Image)) { - - extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice); - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice()); - uint flags = kCGImageAlphaPremultipliedFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - flags |= kCGBitmapByteOrder32Host; -#endif - const QImage *image = (const QImage *) pe->paintDevice(); - - context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - - CGContextTranslateCTM(context, 0, image->height()); - CGContextScaleCTM(context, 1, -1); - - if (devType == QInternal::Widget) { - QRegion clip = p->paintEngine()->systemClip(); - QTransform native = p->deviceTransform(); - QTransform logical = p->combinedTransform(); - - if (p->hasClipping()) { - QRegion r = p->clipRegion(); - r.translate(native.dx(), native.dy()); - if (clip.isEmpty()) - clip = r; - else - clip &= r; - } - qt_mac_clip_cg(context, clip, 0); - - CGContextTranslateCTM(context, native.dx(), native.dy()); - } - } else { - CGContextRetain(context); - } -} - - -/***************************************************************************** - QCoreGraphicsPaintEngine utility functions - *****************************************************************************/ - -//conversion -inline static float qt_mac_convert_color_to_cg(int c) { return ((float)c * 1000 / 255) / 1000; } -inline static int qt_mac_convert_color_from_cg(float c) { return qRound(c * 255); } -CGAffineTransform qt_mac_convert_transform_to_cg(const QTransform &t) { - return CGAffineTransformMake(t.m11(), t.m12(), t.m21(), t.m22(), t.dx(), t.dy()); -} - -CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice) -{ - bool isWidget = (paintDevice->devType() == QInternal::Widget); - return QCoreGraphicsPaintEngine::macDisplayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice) - : 0); -} - -inline static QCFType<CGColorRef> cgColorForQColor(const QColor &col, QPaintDevice *pdev) -{ - CGFloat components[] = { - qt_mac_convert_color_to_cg(col.red()), - qt_mac_convert_color_to_cg(col.green()), - qt_mac_convert_color_to_cg(col.blue()), - qt_mac_convert_color_to_cg(col.alpha()) - }; - return CGColorCreate(qt_mac_colorSpaceForDeviceType(pdev), components); -} - -// There's architectural problems with using native gradients -// on the Mac at the moment, so disable them. -// #define QT_MAC_USE_NATIVE_GRADIENTS - -#ifdef QT_MAC_USE_NATIVE_GRADIENTS -static bool drawGradientNatively(const QGradient *gradient) -{ - return gradient->spread() == QGradient::PadSpread; -} - -// gradiant callback -static void qt_mac_color_gradient_function(void *info, const CGFloat *in, CGFloat *out) -{ - QBrush *brush = static_cast<QBrush *>(info); - Q_ASSERT(brush && brush->gradient()); - - const QGradientStops stops = brush->gradient()->stops(); - const int n = stops.count(); - Q_ASSERT(n >= 1); - const QGradientStop *begin = stops.constBegin(); - const QGradientStop *end = begin + n; - - qreal p = in[0]; - const QGradientStop *i = begin; - while (i != end && i->first < p) - ++i; - - QRgb c; - if (i == begin) { - c = begin->second.rgba(); - } else if (i == end) { - c = (end - 1)->second.rgba(); - } else { - const QGradientStop &s1 = *(i - 1); - const QGradientStop &s2 = *i; - qreal p1 = s1.first; - qreal p2 = s2.first; - QRgb c1 = s1.second.rgba(); - QRgb c2 = s2.second.rgba(); - int idist = 256 * (p - p1) / (p2 - p1); - int dist = 256 - idist; - c = qRgba(INTERPOLATE_PIXEL_256(qRed(c1), dist, qRed(c2), idist), - INTERPOLATE_PIXEL_256(qGreen(c1), dist, qGreen(c2), idist), - INTERPOLATE_PIXEL_256(qBlue(c1), dist, qBlue(c2), idist), - INTERPOLATE_PIXEL_256(qAlpha(c1), dist, qAlpha(c2), idist)); - } - - out[0] = qt_mac_convert_color_to_cg(qRed(c)); - out[1] = qt_mac_convert_color_to_cg(qGreen(c)); - out[2] = qt_mac_convert_color_to_cg(qBlue(c)); - out[3] = qt_mac_convert_color_to_cg(qAlpha(c)); -} -#endif - -//clipping handling -void QCoreGraphicsPaintEnginePrivate::resetClip() -{ - static bool inReset = false; - if (inReset) - return; - inReset = true; - - CGAffineTransform old_xform = CGContextGetCTM(hd); - - //setup xforms - CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform)); - while (stackCount > 0) { - restoreGraphicsState(); - } - saveGraphicsState(); - inReset = false; - //reset xforms - CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd))); - CGContextConcatCTM(hd, old_xform); -} - -static CGRect qt_mac_compose_rect(const QRectF &r, float off=0) -{ - return CGRectMake(r.x()+off, r.y()+off, r.width(), r.height()); -} - -static CGMutablePathRef qt_mac_compose_path(const QPainterPath &p, float off=0) -{ - CGMutablePathRef ret = CGPathCreateMutable(); - QPointF startPt; - for (int i=0; i<p.elementCount(); ++i) { - const QPainterPath::Element &elm = p.elementAt(i); - switch (elm.type) { - case QPainterPath::MoveToElement: - if(i > 0 - && p.elementAt(i - 1).x == startPt.x() - && p.elementAt(i - 1).y == startPt.y()) - CGPathCloseSubpath(ret); - startPt = QPointF(elm.x, elm.y); - CGPathMoveToPoint(ret, 0, elm.x+off, elm.y+off); - break; - case QPainterPath::LineToElement: - CGPathAddLineToPoint(ret, 0, elm.x+off, elm.y+off); - break; - case QPainterPath::CurveToElement: - Q_ASSERT(p.elementAt(i+1).type == QPainterPath::CurveToDataElement); - Q_ASSERT(p.elementAt(i+2).type == QPainterPath::CurveToDataElement); - CGPathAddCurveToPoint(ret, 0, - elm.x+off, elm.y+off, - p.elementAt(i+1).x+off, p.elementAt(i+1).y+off, - p.elementAt(i+2).x+off, p.elementAt(i+2).y+off); - i+=2; - break; - default: - qFatal("QCoreGraphicsPaintEngine::drawPath(), unhandled type: %d", elm.type); - break; - } - } - if(!p.isEmpty() - && p.elementAt(p.elementCount() - 1).x == startPt.x() - && p.elementAt(p.elementCount() - 1).y == startPt.y()) - CGPathCloseSubpath(ret); - return ret; -} - -CGColorSpaceRef QCoreGraphicsPaintEngine::m_genericColorSpace = 0; -QHash<CGDirectDisplayID, CGColorSpaceRef> QCoreGraphicsPaintEngine::m_displayColorSpaceHash; -bool QCoreGraphicsPaintEngine::m_postRoutineRegistered = false; - -CGColorSpaceRef QCoreGraphicsPaintEngine::macGenericColorSpace() -{ -#if 0 - if (!m_genericColorSpace) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - } else -#endif - { - m_genericColorSpace = CGColorSpaceCreateDeviceRGB(); - } - if (!m_postRoutineRegistered) { - m_postRoutineRegistered = true; - qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces); - } - } - return m_genericColorSpace; -#else - // Just return the main display colorspace for the moment. - return macDisplayColorSpace(); -#endif -} - -/* - Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc. - to support multiple displays correctly. -*/ -CGColorSpaceRef QCoreGraphicsPaintEngine::macDisplayColorSpace(const QWidget *widget) -{ - CGColorSpaceRef colorSpace; - - CGDirectDisplayID displayID; - CMProfileRef displayProfile = 0; - if (widget == 0) { - displayID = CGMainDisplayID(); - } else { - const QRect &qrect = widget->window()->geometry(); - CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height()); - CGDisplayCount throwAway; - CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway); - if (dErr != kCGErrorSuccess) - return macDisplayColorSpace(0); // fall back on main display - } - if ((colorSpace = m_displayColorSpaceHash.value(displayID))) - return colorSpace; - - CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile); - if (err == noErr) { - colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile); - } else if (widget) { - return macDisplayColorSpace(0); // fall back on main display - } - - if (colorSpace == 0) - colorSpace = CGColorSpaceCreateDeviceRGB(); - - m_displayColorSpaceHash.insert(displayID, colorSpace); - CMCloseProfile(displayProfile); - if (!m_postRoutineRegistered) { - m_postRoutineRegistered = true; - qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces); - } - return colorSpace; -} - -void QCoreGraphicsPaintEngine::cleanUpMacColorSpaces() -{ - if (m_genericColorSpace) { - CFRelease(m_genericColorSpace); - m_genericColorSpace = 0; - } - QHash<CGDirectDisplayID, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin(); - while (it != m_displayColorSpaceHash.constEnd()) { - if (it.value()) - CFRelease(it.value()); - ++it; - } - m_displayColorSpaceHash.clear(); -} - -void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform) -{ - CGAffineTransform old_xform = CGAffineTransformIdentity; - if(orig_xform) { //setup xforms - old_xform = CGContextGetCTM(hd); - CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform)); - CGContextConcatCTM(hd, *orig_xform); - } - - //do the clipping - CGContextBeginPath(hd); - if(rgn.isEmpty()) { - CGContextAddRect(hd, CGRectMake(0, 0, 0, 0)); - } else { -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { - QCFType<HIMutableShapeRef> shape = rgn.toHIMutableShape(); - Q_ASSERT(!HIShapeIsEmpty(shape)); - HIShapeReplacePathInCGContext(shape, hd); - } else -#endif - { - QVector<QRect> rects = rgn.rects(); - const int count = rects.size(); - for(int i = 0; i < count; i++) { - const QRect &r = rects[i]; - CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height()); - CGContextAddRect(hd, mac_r); - } - } - - } - CGContextClip(hd); - - if(orig_xform) {//reset xforms - CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd))); - CGContextConcatCTM(hd, old_xform); - } -} - - -//pattern handling (tiling) -#if 1 -# define QMACPATTERN_MASK_MULTIPLIER 32 -#else -# define QMACPATTERN_MASK_MULTIPLIER 1 -#endif -class QMacPattern -{ -public: - QMacPattern() : as_mask(false), pdev(0), image(0) { data.bytes = 0; } - ~QMacPattern() { CGImageRelease(image); } - int width() { - if(image) - return CGImageGetWidth(image); - if(data.bytes) - return 8*QMACPATTERN_MASK_MULTIPLIER; - return data.pixmap.width(); - } - int height() { - if(image) - return CGImageGetHeight(image); - if(data.bytes) - return 8*QMACPATTERN_MASK_MULTIPLIER; - return data.pixmap.height(); - } - - //input - QColor foreground; - bool as_mask; - struct { - QPixmap pixmap; - const uchar *bytes; - } data; - QPaintDevice *pdev; - //output - CGImageRef image; -}; -static void qt_mac_draw_pattern(void *info, CGContextRef c) -{ - QMacPattern *pat = (QMacPattern*)info; - int w = 0, h = 0; - bool isBitmap = (pat->data.pixmap.depth() == 1); - if(!pat->image) { //lazy cache - if(pat->as_mask) { - Q_ASSERT(pat->data.bytes); - w = h = 8; -#if (QMACPATTERN_MASK_MULTIPLIER == 1) - CGDataProviderRef provider = CGDataProviderCreateWithData(0, pat->data.bytes, w*h, 0); - pat->image = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false); - CGDataProviderRelease(provider); -#else - const int numBytes = (w*h)/sizeof(uchar); - uchar xor_bytes[numBytes]; - for(int i = 0; i < numBytes; ++i) - xor_bytes[i] = pat->data.bytes[i] ^ 0xFF; - CGDataProviderRef provider = CGDataProviderCreateWithData(0, xor_bytes, w*h, 0); - CGImageRef swatch = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false); - CGDataProviderRelease(provider); - - const QColor c0(0, 0, 0, 0), c1(255, 255, 255, 255); - QPixmap pm(w*QMACPATTERN_MASK_MULTIPLIER, h*QMACPATTERN_MASK_MULTIPLIER); - pm.fill(c0); - CGContextRef pm_ctx = qt_mac_cg_context(&pm); - CGContextSetFillColorWithColor(c, cgColorForQColor(c1, pat->pdev)); - CGRect rect = CGRectMake(0, 0, w, h); - for(int x = 0; x < QMACPATTERN_MASK_MULTIPLIER; ++x) { - rect.origin.x = x * w; - for(int y = 0; y < QMACPATTERN_MASK_MULTIPLIER; ++y) { - rect.origin.y = y * h; - qt_mac_drawCGImage(pm_ctx, &rect, swatch); - } - } - pat->image = qt_mac_create_imagemask(pm, pm.rect()); - CGImageRelease(swatch); - CGContextRelease(pm_ctx); - w *= QMACPATTERN_MASK_MULTIPLIER; - h *= QMACPATTERN_MASK_MULTIPLIER; -#endif - } else { - w = pat->data.pixmap.width(); - h = pat->data.pixmap.height(); - if (isBitmap) - pat->image = qt_mac_create_imagemask(pat->data.pixmap, pat->data.pixmap.rect()); - else - pat->image = (CGImageRef)pat->data.pixmap.macCGHandle(); - } - } else { - w = CGImageGetWidth(pat->image); - h = CGImageGetHeight(pat->image); - } - - //draw - bool needRestore = false; - if (CGImageIsMask(pat->image)) { - CGContextSaveGState(c); - CGContextSetFillColorWithColor(c, cgColorForQColor(pat->foreground, pat->pdev)); - } - CGRect rect = CGRectMake(0, 0, w, h); - qt_mac_drawCGImage(c, &rect, pat->image); - if(needRestore) - CGContextRestoreGState(c); -} -static void qt_mac_dispose_pattern(void *info) -{ - QMacPattern *pat = (QMacPattern*)info; - delete pat; -} - -/***************************************************************************** - QCoreGraphicsPaintEngine member functions - *****************************************************************************/ - -inline static QPaintEngine::PaintEngineFeatures qt_mac_cg_features() -{ - return QPaintEngine::PaintEngineFeatures(QPaintEngine::AllFeatures & ~QPaintEngine::PaintOutsidePaintEvent - & ~QPaintEngine::PerspectiveTransform - & ~QPaintEngine::ConicalGradientFill - & ~QPaintEngine::LinearGradientFill - & ~QPaintEngine::RadialGradientFill - & ~QPaintEngine::BrushStroke); -} - -QCoreGraphicsPaintEngine::QCoreGraphicsPaintEngine() -: QPaintEngine(*(new QCoreGraphicsPaintEnginePrivate), qt_mac_cg_features()) -{ -} - -QCoreGraphicsPaintEngine::QCoreGraphicsPaintEngine(QPaintEnginePrivate &dptr) -: QPaintEngine(dptr, qt_mac_cg_features()) -{ -} - -QCoreGraphicsPaintEngine::~QCoreGraphicsPaintEngine() -{ -} - -bool -QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev) -{ - Q_D(QCoreGraphicsPaintEngine); - if(isActive()) { // already active painting - qWarning("QCoreGraphicsPaintEngine::begin: Painter already active"); - return false; - } - - //initialization - d->pdev = pdev; - d->complexXForm = false; - d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticSetPenWidth; - d->cosmeticPenSize = 1; - d->current.clipEnabled = false; - d->pixelSize = QPoint(1,1); - d->hd = qt_mac_cg_context(pdev); - if(d->hd) { - d->saveGraphicsState(); - d->orig_xform = CGContextGetCTM(d->hd); - if (d->shading) { - CGShadingRelease(d->shading); - d->shading = 0; - } - d->setClip(0); //clear the context's clipping - } - - setActive(true); - - if(d->pdev->devType() == QInternal::Widget) { // device is a widget - QWidget *w = (QWidget*)d->pdev; - bool unclipped = w->testAttribute(Qt::WA_PaintUnclipped); - - if((w->windowType() == Qt::Desktop)) { - if(!unclipped) - qWarning("QCoreGraphicsPaintEngine::begin: Does not support clipped desktop on Mac OS X"); - // ## need to do [qt_mac_window_for(w) makeKeyAndOrderFront]; (need to rename the file) - } else if(unclipped) { - qWarning("QCoreGraphicsPaintEngine::begin: Does not support unclipped painting"); - } - } else if(d->pdev->devType() == QInternal::Pixmap) { // device is a pixmap - QPixmap *pm = (QPixmap*)d->pdev; - if(pm->isNull()) { - qWarning("QCoreGraphicsPaintEngine::begin: Cannot paint null pixmap"); - end(); - return false; - } - } - - setDirty(QPaintEngine::DirtyPen); - setDirty(QPaintEngine::DirtyBrush); - setDirty(QPaintEngine::DirtyBackground); - setDirty(QPaintEngine::DirtyHints); - return true; -} - -bool -QCoreGraphicsPaintEngine::end() -{ - Q_D(QCoreGraphicsPaintEngine); - setActive(false); - if(d->pdev->devType() == QInternal::Widget && static_cast<QWidget*>(d->pdev)->windowType() == Qt::Desktop) { -#ifndef QT_MAC_USE_COCOA - HideWindow(qt_mac_window_for(static_cast<QWidget*>(d->pdev))); -#else -// // ### need to do [qt_mac_window_for(static_cast<QWidget *>(d->pdev)) orderOut]; (need to rename) -#endif - - } - if(d->shading) { - CGShadingRelease(d->shading); - d->shading = 0; - } - d->pdev = 0; - if(d->hd) { - d->restoreGraphicsState(); - CGContextSynchronize(d->hd); - CGContextRelease(d->hd); - d->hd = 0; - } - return true; -} - -void -QCoreGraphicsPaintEngine::updateState(const QPaintEngineState &state) -{ - Q_D(QCoreGraphicsPaintEngine); - QPaintEngine::DirtyFlags flags = state.state(); - - if (flags & DirtyTransform) - updateMatrix(state.transform()); - - if (flags & DirtyClipEnabled) { - if (state.isClipEnabled()) - updateClipPath(painter()->clipPath(), Qt::ReplaceClip); - else - updateClipPath(QPainterPath(), Qt::NoClip); - } - - if (flags & DirtyClipPath) { - updateClipPath(state.clipPath(), state.clipOperation()); - } else if (flags & DirtyClipRegion) { - updateClipRegion(state.clipRegion(), state.clipOperation()); - } - - // If the clip has changed we need to update all other states - // too, since they are included in the system context on OSX, - // and changing the clip resets that context back to scratch. - if (flags & (DirtyClipPath | DirtyClipRegion | DirtyClipEnabled)) - flags |= AllDirty; - - if (flags & DirtyPen) - updatePen(state.pen()); - if (flags & (DirtyBrush|DirtyBrushOrigin)) - updateBrush(state.brush(), state.brushOrigin()); - if (flags & DirtyFont) - updateFont(state.font()); - if (flags & DirtyOpacity) - updateOpacity(state.opacity()); - if (flags & DirtyHints) - updateRenderHints(state.renderHints()); - if (flags & DirtyCompositionMode) - updateCompositionMode(state.compositionMode()); - - if (flags & (DirtyPen | DirtyTransform)) { - if (!d->current.pen.isCosmetic()) { - d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticNone; - } else if (d->current.transform.m11() < d->current.transform.m22()-1.0 || - d->current.transform.m11() > d->current.transform.m22()+1.0) { - d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticTransformPath; - d->cosmeticPenSize = d->adjustPenWidth(d->current.pen.widthF()); - if (!d->cosmeticPenSize) - d->cosmeticPenSize = 1.0; - } else { - d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticSetPenWidth; - static const float sqrt2 = sqrt(2); - qreal width = d->current.pen.widthF(); - if (!width) - width = 1; - d->cosmeticPenSize = sqrt(pow(d->pixelSize.y(), 2) + pow(d->pixelSize.x(), 2)) / sqrt2 * width; - } - } -} - -void -QCoreGraphicsPaintEngine::updatePen(const QPen &pen) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - d->current.pen = pen; - d->setStrokePen(pen); -} - -void -QCoreGraphicsPaintEngine::updateBrush(const QBrush &brush, const QPointF &brushOrigin) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - d->current.brush = brush; - -#ifdef QT_MAC_USE_NATIVE_GRADIENTS - // Quartz supports only pad spread - if (const QGradient *gradient = brush.gradient()) { - if (drawGradientNatively(gradient)) { - gccaps |= QPaintEngine::LinearGradientFill | QPaintEngine::RadialGradientFill; - } else { - gccaps &= ~(QPaintEngine::LinearGradientFill | QPaintEngine::RadialGradientFill); - } - } -#endif - - if (d->shading) { - CGShadingRelease(d->shading); - d->shading = 0; - } - d->setFillBrush(brushOrigin); -} - -void -QCoreGraphicsPaintEngine::updateOpacity(qreal opacity) -{ - Q_D(QCoreGraphicsPaintEngine); - CGContextSetAlpha(d->hd, opacity); -} - -void -QCoreGraphicsPaintEngine::updateFont(const QFont &) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - updatePen(d->current.pen); -} - -void -QCoreGraphicsPaintEngine::updateMatrix(const QTransform &transform) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - - if (qt_is_nan(transform.m11()) || qt_is_nan(transform.m12()) || qt_is_nan(transform.m13()) - || qt_is_nan(transform.m21()) || qt_is_nan(transform.m22()) || qt_is_nan(transform.m23()) - || qt_is_nan(transform.m31()) || qt_is_nan(transform.m32()) || qt_is_nan(transform.m33())) - return; - - d->current.transform = transform; - d->setTransform(transform.isIdentity() ? 0 : &transform); - d->complexXForm = (transform.m11() != 1 || transform.m22() != 1 - || transform.m12() != 0 || transform.m21() != 0); - d->pixelSize = d->devicePixelSize(d->hd); -} - -void -QCoreGraphicsPaintEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - if(op == Qt::NoClip) { - if(d->current.clipEnabled) { - d->current.clipEnabled = false; - d->current.clip = QRegion(); - d->setClip(0); - } - } else { - if(!d->current.clipEnabled) - op = Qt::ReplaceClip; - d->current.clipEnabled = true; - QRegion clipRegion(p.toFillPolygon().toPolygon(), p.fillRule()); - if(op == Qt::ReplaceClip) { - d->current.clip = clipRegion; - d->setClip(0); - if(p.isEmpty()) { - CGRect rect = CGRectMake(0, 0, 0, 0); - CGContextClipToRect(d->hd, rect); - } else { - CGMutablePathRef path = qt_mac_compose_path(p); - CGContextBeginPath(d->hd); - CGContextAddPath(d->hd, path); - if(p.fillRule() == Qt::WindingFill) - CGContextClip(d->hd); - else - CGContextEOClip(d->hd); - CGPathRelease(path); - } - } else if(op == Qt::IntersectClip) { - d->current.clip = d->current.clip.intersected(clipRegion); - d->setClip(&d->current.clip); - } - } -} - -void -QCoreGraphicsPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - if(op == Qt::NoClip) { - d->current.clipEnabled = false; - d->current.clip = QRegion(); - d->setClip(0); - } else { - if(!d->current.clipEnabled) - op = Qt::ReplaceClip; - d->current.clipEnabled = true; - if(op == Qt::IntersectClip) - d->current.clip = d->current.clip.intersected(clipRegion); - else if(op == Qt::ReplaceClip) - d->current.clip = clipRegion; - d->setClip(&d->current.clip); - } -} - -void -QCoreGraphicsPaintEngine::drawPath(const QPainterPath &p) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - - if (state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - CGMutablePathRef path = qt_mac_compose_path(p); - uchar ops = QCoreGraphicsPaintEnginePrivate::CGStroke; - if(p.fillRule() == Qt::WindingFill) - ops |= QCoreGraphicsPaintEnginePrivate::CGFill; - else - ops |= QCoreGraphicsPaintEnginePrivate::CGEOFill; - CGContextBeginPath(d->hd); - d->drawPath(ops, path); - CGPathRelease(path); -} - -void -QCoreGraphicsPaintEngine::drawRects(const QRectF *rects, int rectCount) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - - if (state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - for (int i=0; i<rectCount; ++i) { - QRectF r = rects[i]; - - CGMutablePathRef path = CGPathCreateMutable(); - CGPathAddRect(path, 0, qt_mac_compose_rect(r)); - d->drawPath(QCoreGraphicsPaintEnginePrivate::CGFill|QCoreGraphicsPaintEnginePrivate::CGStroke, - path); - CGPathRelease(path); - } -} - -void -QCoreGraphicsPaintEngine::drawPoints(const QPointF *points, int pointCount) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - - if (state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - if (d->current.pen.capStyle() == Qt::FlatCap) - CGContextSetLineCap(d->hd, kCGLineCapSquare); - - CGMutablePathRef path = CGPathCreateMutable(); - for(int i=0; i < pointCount; i++) { - float x = points[i].x(), y = points[i].y(); - CGPathMoveToPoint(path, 0, x, y); - CGPathAddLineToPoint(path, 0, x+0.001, y); - } - - bool doRestore = false; - if(d->cosmeticPen == QCoreGraphicsPaintEnginePrivate::CosmeticNone && !(state->renderHints() & QPainter::Antialiasing)) { - //we don't want adjusted pens for point rendering - doRestore = true; - d->saveGraphicsState(); - CGContextSetLineWidth(d->hd, d->current.pen.widthF()); - } - d->drawPath(QCoreGraphicsPaintEnginePrivate::CGStroke, path); - if (doRestore) - d->restoreGraphicsState(); - CGPathRelease(path); - if (d->current.pen.capStyle() == Qt::FlatCap) - CGContextSetLineCap(d->hd, kCGLineCapButt); -} - -void -QCoreGraphicsPaintEngine::drawEllipse(const QRectF &r) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - - if (state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - CGMutablePathRef path = CGPathCreateMutable(); - CGAffineTransform transform = CGAffineTransformMakeScale(r.width() / r.height(), 1); - CGPathAddArc(path, &transform,(r.x() + (r.width() / 2)) / (r.width() / r.height()), - r.y() + (r.height() / 2), r.height() / 2, 0, (2 * M_PI), false); - d->drawPath(QCoreGraphicsPaintEnginePrivate::CGFill | QCoreGraphicsPaintEnginePrivate::CGStroke, - path); - CGPathRelease(path); -} - -void -QCoreGraphicsPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - - if (state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - CGMutablePathRef path = CGPathCreateMutable(); - CGPathMoveToPoint(path, 0, points[0].x(), points[0].y()); - for(int x = 1; x < pointCount; ++x) - CGPathAddLineToPoint(path, 0, points[x].x(), points[x].y()); - if(mode != PolylineMode && points[0] != points[pointCount-1]) - CGPathAddLineToPoint(path, 0, points[0].x(), points[0].y()); - uint op = QCoreGraphicsPaintEnginePrivate::CGStroke; - if (mode != PolylineMode) - op |= mode == OddEvenMode ? QCoreGraphicsPaintEnginePrivate::CGEOFill - : QCoreGraphicsPaintEnginePrivate::CGFill; - d->drawPath(op, path); - CGPathRelease(path); -} - -void -QCoreGraphicsPaintEngine::drawLines(const QLineF *lines, int lineCount) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - - if (state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - CGMutablePathRef path = CGPathCreateMutable(); - for(int i = 0; i < lineCount; i++) { - const QPointF start = lines[i].p1(), end = lines[i].p2(); - CGPathMoveToPoint(path, 0, start.x(), start.y()); - CGPathAddLineToPoint(path, 0, end.x(), end.y()); - } - d->drawPath(QCoreGraphicsPaintEnginePrivate::CGStroke, path); - CGPathRelease(path); -} - -void QCoreGraphicsPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - - if (state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - if(pm.isNull()) - return; - - bool differentSize = (QRectF(0, 0, pm.width(), pm.height()) != sr), doRestore = false; - CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height()); - QCFType<CGImageRef> image; - bool isBitmap = (pm.depth() == 1); - if (isBitmap) { - doRestore = true; - d->saveGraphicsState(); - - const QColor &col = d->current.pen.color(); - CGContextSetFillColorWithColor(d->hd, cgColorForQColor(col, d->pdev)); - image = qt_mac_create_imagemask(pm, sr); - } else if (differentSize) { - QCFType<CGImageRef> img = pm.toMacCGImageRef(); - image = CGImageCreateWithImageInRect(img, CGRectMake(qRound(sr.x()), qRound(sr.y()), qRound(sr.width()), qRound(sr.height()))); - } else { - image = (CGImageRef)pm.macCGHandle(); - } - qt_mac_drawCGImage(d->hd, &rect, image); - if (doRestore) - d->restoreGraphicsState(); -} - -static void drawImageReleaseData (void *info, const void *, size_t) -{ - delete static_cast<QImage *>(info); -} - -CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0) -{ - QImage *image; - if (img.depth() != 32) - image = new QImage(img.convertToFormat(QImage::Format_ARGB32_Premultiplied)); - else - image = new QImage(img); - - uint cgflags = kCGImageAlphaNone; - switch (image->format()) { - case QImage::Format_ARGB32_Premultiplied: - cgflags = kCGImageAlphaPremultipliedFirst; - break; - case QImage::Format_ARGB32: - cgflags = kCGImageAlphaFirst; - break; - case QImage::Format_RGB32: - cgflags = kCGImageAlphaNoneSkipFirst; - default: - break; - } -#if defined(kCGBitmapByteOrder32Host) //only needed because CGImage.h added symbols in the minor version - cgflags |= kCGBitmapByteOrder32Host; -#endif - QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(image, - static_cast<const QImage *>(image)->bits(), - image->byteCount(), - drawImageReleaseData); - if (imagePtr) - *imagePtr = image; - return CGImageCreate(image->width(), image->height(), 8, 32, - image->bytesPerLine(), - QCoreGraphicsPaintEngine::macGenericColorSpace(), - cgflags, dataProvider, 0, false, kCGRenderingIntentDefault); - -} - -void QCoreGraphicsPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr, - Qt::ImageConversionFlags flags) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_UNUSED(flags); - Q_ASSERT(isActive()); - - if (img.isNull() || state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - const QImage *image; - QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(img, &image); - CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height()); - if (QRectF(0, 0, img.width(), img.height()) != sr) - cgimage = CGImageCreateWithImageInRect(cgimage, CGRectMake(sr.x(), sr.y(), - sr.width(), sr.height())); - qt_mac_drawCGImage(d->hd, &rect, cgimage); -} - -void QCoreGraphicsPaintEngine::initialize() -{ -} - -void QCoreGraphicsPaintEngine::cleanup() -{ -} - -CGContextRef -QCoreGraphicsPaintEngine::handle() const -{ - return d_func()->hd; -} - -void -QCoreGraphicsPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, - const QPointF &p) -{ - Q_D(QCoreGraphicsPaintEngine); - Q_ASSERT(isActive()); - - if (state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - //save the old state - d->saveGraphicsState(); - - //setup the pattern - QMacPattern *qpattern = new QMacPattern; - qpattern->data.pixmap = pixmap; - qpattern->foreground = d->current.pen.color(); - qpattern->pdev = d->pdev; - CGPatternCallbacks callbks; - callbks.version = 0; - callbks.drawPattern = qt_mac_draw_pattern; - callbks.releaseInfo = qt_mac_dispose_pattern; - const int width = qpattern->width(), height = qpattern->height(); - CGAffineTransform trans = CGContextGetCTM(d->hd); - CGPatternRef pat = CGPatternCreate(qpattern, CGRectMake(0, 0, width, height), - trans, width, height, - kCGPatternTilingNoDistortion, true, &callbks); - CGColorSpaceRef cs = CGColorSpaceCreatePattern(0); - CGContextSetFillColorSpace(d->hd, cs); - CGFloat component = 1.0; //just one - CGContextSetFillPattern(d->hd, pat, &component); - CGSize phase = CGSizeApplyAffineTransform(CGSizeMake(-(p.x()-r.x()), -(p.y()-r.y())), trans); - CGContextSetPatternPhase(d->hd, phase); - - //fill the rectangle - CGRect mac_rect = CGRectMake(r.x(), r.y(), r.width(), r.height()); - CGContextFillRect(d->hd, mac_rect); - - //restore the state - d->restoreGraphicsState(); - //cleanup - CGColorSpaceRelease(cs); - CGPatternRelease(pat); -} - -void QCoreGraphicsPaintEngine::drawTextItem(const QPointF &pos, const QTextItem &item) -{ - Q_D(QCoreGraphicsPaintEngine); - if (d->current.transform.type() == QTransform::TxProject -#ifndef QMAC_NATIVE_GRADIENTS - || painter()->pen().brush().gradient() //Just let the base engine "emulate" the gradient -#endif - ) { - QPaintEngine::drawTextItem(pos, item); - return; - } - - if (state->compositionMode() == QPainter::CompositionMode_Destination) - return; - - const QTextItemInt &ti = static_cast<const QTextItemInt &>(item); - - QPen oldPen = painter()->pen(); - QBrush oldBrush = painter()->brush(); - QPointF oldBrushOrigin = painter()->brushOrigin(); - updatePen(Qt::NoPen); - updateBrush(oldPen.brush(), QPointF(0, 0)); - - Q_ASSERT(type() == QPaintEngine::CoreGraphics); - - QFontEngine *fe = ti.fontEngine; - - const bool textAA = state->renderHints() & QPainter::TextAntialiasing && fe->fontDef.pointSize > qt_antialiasing_threshold && !(fe->fontDef.styleStrategy & QFont::NoAntialias); - const bool lineAA = state->renderHints() & QPainter::Antialiasing; - if(textAA != lineAA) - CGContextSetShouldAntialias(d->hd, textAA); - - if (ti.glyphs.numGlyphs) { - switch (fe->type()) { - case QFontEngine::Mac: -#ifdef QT_MAC_USE_COCOA - static_cast<QCoreTextFontEngine *>(fe)->draw(d->hd, pos.x(), pos.y(), ti, paintDevice()->height()); -#else - static_cast<QFontEngineMac *>(fe)->draw(d->hd, pos.x(), pos.y(), ti, paintDevice()->height()); -#endif - break; - case QFontEngine::Box: - d->drawBoxTextItem(pos, ti); - break; - default: - break; - } - } - - if(textAA != lineAA) - CGContextSetShouldAntialias(d->hd, !textAA); - - updatePen(oldPen); - updateBrush(oldBrush, oldBrushOrigin); -} - -QPainter::RenderHints -QCoreGraphicsPaintEngine::supportedRenderHints() const -{ - return QPainter::RenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); -} -enum CGCompositeMode { - kCGCompositeModeClear = 0, - kCGCompositeModeCopy = 1, - kCGCompositeModeSourceOver = 2, - kCGCompositeModeSourceIn = 3, - kCGCompositeModeSourceOut = 4, - kCGCompositeModeSourceAtop = 5, - kCGCompositeModeDestinationOver = 6, - kCGCompositeModeDestinationIn = 7, - kCGCompositeModeDestinationOut = 8, - kCGCompositeModeDestinationAtop = 9, - kCGCompositeModeXOR = 10, - kCGCompositeModePlusDarker = 11, // (max (0, (1-d) + (1-s))) - kCGCompositeModePlusLighter = 12, // (min (1, s + d)) - }; -extern "C" { - extern void CGContextSetCompositeOperation(CGContextRef, int); -} // private function, but is in all versions of OS X. -void -QCoreGraphicsPaintEngine::updateCompositionMode(QPainter::CompositionMode mode) -{ -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { - int cg_mode = kCGBlendModeNormal; - switch(mode) { - case QPainter::CompositionMode_Multiply: - cg_mode = kCGBlendModeMultiply; - break; - case QPainter::CompositionMode_Screen: - cg_mode = kCGBlendModeScreen; - break; - case QPainter::CompositionMode_Overlay: - cg_mode = kCGBlendModeOverlay; - break; - case QPainter::CompositionMode_Darken: - cg_mode = kCGBlendModeDarken; - break; - case QPainter::CompositionMode_Lighten: - cg_mode = kCGBlendModeLighten; - break; - case QPainter::CompositionMode_ColorDodge: - cg_mode = kCGBlendModeColorDodge; - break; - case QPainter::CompositionMode_ColorBurn: - cg_mode = kCGBlendModeColorBurn; - break; - case QPainter::CompositionMode_HardLight: - cg_mode = kCGBlendModeHardLight; - break; - case QPainter::CompositionMode_SoftLight: - cg_mode = kCGBlendModeSoftLight; - break; - case QPainter::CompositionMode_Difference: - cg_mode = kCGBlendModeDifference; - break; - case QPainter::CompositionMode_Exclusion: - cg_mode = kCGBlendModeExclusion; - break; - case QPainter::CompositionMode_Plus: - cg_mode = kCGBlendModePlusLighter; - break; - case QPainter::CompositionMode_SourceOver: - cg_mode = kCGBlendModeNormal; - break; - case QPainter::CompositionMode_DestinationOver: - cg_mode = kCGBlendModeDestinationOver; - break; - case QPainter::CompositionMode_Clear: - cg_mode = kCGBlendModeClear; - break; - case QPainter::CompositionMode_Source: - cg_mode = kCGBlendModeCopy; - break; - case QPainter::CompositionMode_Destination: - cg_mode = -1; - break; - case QPainter::CompositionMode_SourceIn: - cg_mode = kCGBlendModeSourceIn; - break; - case QPainter::CompositionMode_DestinationIn: - cg_mode = kCGCompositeModeDestinationIn; - break; - case QPainter::CompositionMode_SourceOut: - cg_mode = kCGBlendModeSourceOut; - break; - case QPainter::CompositionMode_DestinationOut: - cg_mode = kCGBlendModeDestinationOver; - break; - case QPainter::CompositionMode_SourceAtop: - cg_mode = kCGBlendModeSourceAtop; - break; - case QPainter::CompositionMode_DestinationAtop: - cg_mode = kCGBlendModeDestinationAtop; - break; - case QPainter::CompositionMode_Xor: - cg_mode = kCGBlendModeXOR; - break; - default: - break; - } - if (cg_mode > -1) { - CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode)); - } - } else -#endif - // The standard porter duff ops. - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_3 - && mode <= QPainter::CompositionMode_Xor) { - int cg_mode = kCGCompositeModeCopy; - switch (mode) { - case QPainter::CompositionMode_SourceOver: - cg_mode = kCGCompositeModeSourceOver; - break; - case QPainter::CompositionMode_DestinationOver: - cg_mode = kCGCompositeModeDestinationOver; - break; - case QPainter::CompositionMode_Clear: - cg_mode = kCGCompositeModeClear; - break; - default: - qWarning("QCoreGraphicsPaintEngine: Unhandled composition mode %d", (int)mode); - break; - case QPainter::CompositionMode_Source: - cg_mode = kCGCompositeModeCopy; - break; - case QPainter::CompositionMode_Destination: - cg_mode = CGCompositeMode(-1); - break; - case QPainter::CompositionMode_SourceIn: - cg_mode = kCGCompositeModeSourceIn; - break; - case QPainter::CompositionMode_DestinationIn: - cg_mode = kCGCompositeModeDestinationIn; - break; - case QPainter::CompositionMode_SourceOut: - cg_mode = kCGCompositeModeSourceOut; - break; - case QPainter::CompositionMode_DestinationOut: - cg_mode = kCGCompositeModeDestinationOut; - break; - case QPainter::CompositionMode_SourceAtop: - cg_mode = kCGCompositeModeSourceAtop; - break; - case QPainter::CompositionMode_DestinationAtop: - cg_mode = kCGCompositeModeDestinationAtop; - break; - case QPainter::CompositionMode_Xor: - cg_mode = kCGCompositeModeXOR; - break; - } - if (cg_mode > -1) - CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode)); - } else { -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) - bool needPrivateAPI = false; - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - int cg_mode = kCGBlendModeNormal; - switch (mode) { - case QPainter::CompositionMode_Multiply: - cg_mode = kCGBlendModeMultiply; - break; - case QPainter::CompositionMode_Screen: - cg_mode = kCGBlendModeScreen; - break; - case QPainter::CompositionMode_Overlay: - cg_mode = kCGBlendModeOverlay; - break; - case QPainter::CompositionMode_Darken: - cg_mode = kCGBlendModeDarken; - break; - case QPainter::CompositionMode_Lighten: - cg_mode = kCGBlendModeLighten; - break; - case QPainter::CompositionMode_ColorDodge: - cg_mode = kCGBlendModeColorDodge; - break; - case QPainter::CompositionMode_ColorBurn: - cg_mode = kCGBlendModeColorBurn; - break; - case QPainter::CompositionMode_HardLight: - cg_mode = kCGBlendModeHardLight; - break; - case QPainter::CompositionMode_SoftLight: - cg_mode = kCGBlendModeSoftLight; - break; - case QPainter::CompositionMode_Difference: - cg_mode = kCGBlendModeDifference; - break; - case QPainter::CompositionMode_Exclusion: - cg_mode = kCGBlendModeExclusion; - break; - case QPainter::CompositionMode_Plus: - needPrivateAPI = true; - cg_mode = kCGCompositeModePlusLighter; - break; - default: - break; - } - if (!needPrivateAPI) - CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode)); - else - CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode)); - } -#endif - } -} - -void -QCoreGraphicsPaintEngine::updateRenderHints(QPainter::RenderHints hints) -{ - Q_D(QCoreGraphicsPaintEngine); - CGContextSetShouldAntialias(d->hd, hints & QPainter::Antialiasing); - static const CGFloat ScaleFactor = qt_mac_get_scalefactor(); - if (ScaleFactor > 1.) { - CGContextSetInterpolationQuality(d->hd, kCGInterpolationHigh); - } else { - CGContextSetInterpolationQuality(d->hd, (hints & QPainter::SmoothPixmapTransform) ? - kCGInterpolationHigh : kCGInterpolationNone); - } - bool textAntialiasing = (hints & QPainter::TextAntialiasing) == QPainter::TextAntialiasing; - if (!textAntialiasing || d->disabledSmoothFonts) { - d->disabledSmoothFonts = !textAntialiasing; - CGContextSetShouldSmoothFonts(d->hd, textAntialiasing); - } -} - -/* - Returns the size of one device pixel in user-space coordinates. -*/ -QPointF QCoreGraphicsPaintEnginePrivate::devicePixelSize(CGContextRef) -{ - QPointF p1 = current.transform.inverted().map(QPointF(0, 0)); - QPointF p2 = current.transform.inverted().map(QPointF(1, 1)); - return QPointF(qAbs(p2.x() - p1.x()), qAbs(p2.y() - p1.y())); -} - -/* - Adjusts the pen width so we get correct line widths in the - non-transformed, aliased case. -*/ -float QCoreGraphicsPaintEnginePrivate::adjustPenWidth(float penWidth) -{ - Q_Q(QCoreGraphicsPaintEngine); - float ret = penWidth; - if (!complexXForm && !(q->state->renderHints() & QPainter::Antialiasing)) { - if (penWidth < 2) - ret = 1; - else if (penWidth < 3) - ret = 1.5; - else - ret = penWidth -1; - } - return ret; -} - -void -QCoreGraphicsPaintEnginePrivate::setStrokePen(const QPen &pen) -{ - //pencap - CGLineCap cglinecap = kCGLineCapButt; - if(pen.capStyle() == Qt::SquareCap) - cglinecap = kCGLineCapSquare; - else if(pen.capStyle() == Qt::RoundCap) - cglinecap = kCGLineCapRound; - CGContextSetLineCap(hd, cglinecap); - CGContextSetLineWidth(hd, adjustPenWidth(pen.widthF())); - - //join - CGLineJoin cglinejoin = kCGLineJoinMiter; - if(pen.joinStyle() == Qt::BevelJoin) - cglinejoin = kCGLineJoinBevel; - else if(pen.joinStyle() == Qt::RoundJoin) - cglinejoin = kCGLineJoinRound; - CGContextSetLineJoin(hd, cglinejoin); -// CGContextSetMiterLimit(hd, pen.miterLimit()); - - //pen style - QVector<CGFloat> linedashes; - if(pen.style() == Qt::CustomDashLine) { - QVector<qreal> customs = pen.dashPattern(); - for(int i = 0; i < customs.size(); ++i) - linedashes.append(customs.at(i)); - } else if(pen.style() == Qt::DashLine) { - linedashes.append(4); - linedashes.append(2); - } else if(pen.style() == Qt::DotLine) { - linedashes.append(1); - linedashes.append(2); - } else if(pen.style() == Qt::DashDotLine) { - linedashes.append(4); - linedashes.append(2); - linedashes.append(1); - linedashes.append(2); - } else if(pen.style() == Qt::DashDotDotLine) { - linedashes.append(4); - linedashes.append(2); - linedashes.append(1); - linedashes.append(2); - linedashes.append(1); - linedashes.append(2); - } - const CGFloat cglinewidth = pen.widthF() <= 0.0f ? 1.0f : float(pen.widthF()); - for(int i = 0; i < linedashes.size(); ++i) { - linedashes[i] *= cglinewidth; - if(cglinewidth < 3 && (cglinecap == kCGLineCapSquare || cglinecap == kCGLineCapRound)) { - if((i%2)) - linedashes[i] += cglinewidth/2; - else - linedashes[i] -= cglinewidth/2; - } - } - CGContextSetLineDash(hd, pen.dashOffset() * cglinewidth, linedashes.data(), linedashes.size()); - - // color - CGContextSetStrokeColorWithColor(hd, cgColorForQColor(pen.color(), pdev)); -} - -// Add our own patterns here to deal with the fact that the coordinate system -// is flipped vertically with Quartz2D. -static const uchar *qt_mac_patternForBrush(int brushStyle) -{ - Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern); - static const uchar dense1_pat[] = { 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00 }; - static const uchar dense2_pat[] = { 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88 }; - static const uchar dense3_pat[] = { 0x11, 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa }; - static const uchar dense4_pat[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }; - static const uchar dense5_pat[] = { 0xee, 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55 }; - static const uchar dense6_pat[] = { 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff, 0x77 }; - static const uchar dense7_pat[] = { 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff }; - static const uchar hor_pat[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff }; - static const uchar ver_pat[] = { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef }; - static const uchar cross_pat[] = { 0xef, 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef }; - static const uchar fdiag_pat[] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe }; - static const uchar bdiag_pat[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f }; - static const uchar dcross_pat[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e }; - static const uchar *const pat_tbl[] = { - dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat, - dense6_pat, dense7_pat, - hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat }; - return pat_tbl[brushStyle - Qt::Dense1Pattern]; -} - -void QCoreGraphicsPaintEnginePrivate::setFillBrush(const QPointF &offset) -{ - // pattern - Qt::BrushStyle bs = current.brush.style(); -#ifdef QT_MAC_USE_NATIVE_GRADIENTS - if (bs == Qt::LinearGradientPattern || bs == Qt::RadialGradientPattern) { - const QGradient *grad = static_cast<const QGradient*>(current.brush.gradient()); - if (drawGradientNatively(grad)) { - Q_ASSERT(grad->spread() == QGradient::PadSpread); - - static const CGFloat domain[] = { 0.0f, +1.0f }; - static const CGFunctionCallbacks callbacks = { 0, qt_mac_color_gradient_function, 0 }; - CGFunctionRef fill_func = CGFunctionCreate(reinterpret_cast<void *>(¤t.brush), - 1, domain, 4, 0, &callbacks); - - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev); - if (bs == Qt::LinearGradientPattern) { - const QLinearGradient *linearGrad = static_cast<const QLinearGradient *>(grad); - const QPointF start(linearGrad->start()); - const QPointF stop(linearGrad->finalStop()); - shading = CGShadingCreateAxial(colorspace, CGPointMake(start.x(), start.y()), - CGPointMake(stop.x(), stop.y()), fill_func, true, true); - } else { - Q_ASSERT(bs == Qt::RadialGradientPattern); - const QRadialGradient *radialGrad = static_cast<const QRadialGradient *>(grad); - QPointF center(radialGrad->center()); - QPointF focal(radialGrad->focalPoint()); - qreal radius = radialGrad->radius(); - qreal focalRadius = radialGrad->focalRadius(); - shading = CGShadingCreateRadial(colorspace, CGPointMake(focal.x(), focal.y()), - focalRadius, CGPointMake(center.x(), center.y()), radius, fill_func, false, true); - } - - CGFunctionRelease(fill_func); - } - } else -#endif - if(bs != Qt::SolidPattern && bs != Qt::NoBrush -#ifndef QT_MAC_USE_NATIVE_GRADIENTS - && (bs < Qt::LinearGradientPattern || bs > Qt::ConicalGradientPattern) -#endif - ) - { - QMacPattern *qpattern = new QMacPattern; - qpattern->pdev = pdev; - CGFloat components[4] = { 1.0, 1.0, 1.0, 1.0 }; - CGColorSpaceRef base_colorspace = 0; - if(bs == Qt::TexturePattern) { - qpattern->data.pixmap = current.brush.texture(); - if(qpattern->data.pixmap.isQBitmap()) { - const QColor &col = current.brush.color(); - components[0] = qt_mac_convert_color_to_cg(col.red()); - components[1] = qt_mac_convert_color_to_cg(col.green()); - components[2] = qt_mac_convert_color_to_cg(col.blue()); - base_colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace(); - } - } else { - qpattern->as_mask = true; - - qpattern->data.bytes = qt_mac_patternForBrush(bs); - const QColor &col = current.brush.color(); - components[0] = qt_mac_convert_color_to_cg(col.red()); - components[1] = qt_mac_convert_color_to_cg(col.green()); - components[2] = qt_mac_convert_color_to_cg(col.blue()); - base_colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace(); - } - int width = qpattern->width(), height = qpattern->height(); - qpattern->foreground = current.brush.color(); - - CGColorSpaceRef fill_colorspace = CGColorSpaceCreatePattern(base_colorspace); - CGContextSetFillColorSpace(hd, fill_colorspace); - - CGAffineTransform xform = CGContextGetCTM(hd); - xform = CGAffineTransformConcat(qt_mac_convert_transform_to_cg(current.brush.transform()), xform); - xform = CGAffineTransformTranslate(xform, offset.x(), offset.y()); - - CGPatternCallbacks callbks; - callbks.version = 0; - callbks.drawPattern = qt_mac_draw_pattern; - callbks.releaseInfo = qt_mac_dispose_pattern; - CGPatternRef fill_pattern = CGPatternCreate(qpattern, CGRectMake(0, 0, width, height), - xform, width, height, kCGPatternTilingNoDistortion, - !base_colorspace, &callbks); - CGContextSetFillPattern(hd, fill_pattern, components); - - CGPatternRelease(fill_pattern); - CGColorSpaceRelease(fill_colorspace); - } else if(bs != Qt::NoBrush) { - CGContextSetFillColorWithColor(hd, cgColorForQColor(current.brush.color(), pdev)); - } -} - -void -QCoreGraphicsPaintEnginePrivate::setClip(const QRegion *rgn) -{ - Q_Q(QCoreGraphicsPaintEngine); - if(hd) { - resetClip(); - QRegion sysClip = q->systemClip(); - if(!sysClip.isEmpty()) - qt_mac_clip_cg(hd, sysClip, &orig_xform); - if(rgn) - qt_mac_clip_cg(hd, *rgn, 0); - } -} - -struct qt_mac_cg_transform_path { - CGMutablePathRef path; - CGAffineTransform transform; -}; - -void qt_mac_cg_transform_path_apply(void *info, const CGPathElement *element) -{ - Q_ASSERT(info && element); - qt_mac_cg_transform_path *t = (qt_mac_cg_transform_path*)info; - switch(element->type) { - case kCGPathElementMoveToPoint: - CGPathMoveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y); - break; - case kCGPathElementAddLineToPoint: - CGPathAddLineToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y); - break; - case kCGPathElementAddQuadCurveToPoint: - CGPathAddQuadCurveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y, - element->points[1].x, element->points[1].y); - break; - case kCGPathElementAddCurveToPoint: - CGPathAddCurveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y, - element->points[1].x, element->points[1].y, - element->points[2].x, element->points[2].y); - break; - case kCGPathElementCloseSubpath: - CGPathCloseSubpath(t->path); - break; - default: - qDebug() << "Unhandled path transform type: " << element->type; - } -} - -void QCoreGraphicsPaintEnginePrivate::drawPath(uchar ops, CGMutablePathRef path) -{ - Q_Q(QCoreGraphicsPaintEngine); - Q_ASSERT((ops & (CGFill | CGEOFill)) != (CGFill | CGEOFill)); //can't really happen - if((ops & (CGFill | CGEOFill))) { - if (shading) { - Q_ASSERT(path); - CGContextBeginPath(hd); - CGContextAddPath(hd, path); - saveGraphicsState(); - if (ops & CGFill) - CGContextClip(hd); - else if (ops & CGEOFill) - CGContextEOClip(hd); - if (current.brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) { - CGRect boundingBox = CGPathGetBoundingBox(path); - CGContextConcatCTM(hd, - CGAffineTransformMake(boundingBox.size.width, 0, - 0, boundingBox.size.height, - boundingBox.origin.x, boundingBox.origin.y)); - } - CGContextDrawShading(hd, shading); - restoreGraphicsState(); - ops &= ~CGFill; - ops &= ~CGEOFill; - } else if (current.brush.style() == Qt::NoBrush) { - ops &= ~CGFill; - ops &= ~CGEOFill; - } - } - if((ops & CGStroke) && current.pen.style() == Qt::NoPen) - ops &= ~CGStroke; - - if(ops & (CGEOFill | CGFill)) { - CGContextBeginPath(hd); - CGContextAddPath(hd, path); - if (ops & CGEOFill) { - CGContextEOFillPath(hd); - } else { - CGContextFillPath(hd); - } - } - - // Avoid saving and restoring the context if we can. - const bool needContextSave = (cosmeticPen != QCoreGraphicsPaintEnginePrivate::CosmeticNone || - !(q->state->renderHints() & QPainter::Antialiasing)); - if(ops & CGStroke) { - if (needContextSave) - saveGraphicsState(); - CGContextBeginPath(hd); - - // Translate a fraction of a pixel size in the y direction - // to make sure that primitives painted at pixel borders - // fills the right pixel. This is needed since the y xais - // in the Quartz coordinate system is inverted compared to Qt. - if (!(q->state->renderHints() & QPainter::Antialiasing)) { - if (current.pen.style() == Qt::SolidLine || current.pen.width() >= 3) - CGContextTranslateCTM(hd, double(pixelSize.x()) * 0.25, double(pixelSize.y()) * 0.25); - else if (current.pen.style() == Qt::DotLine && QSysInfo::MacintoshVersion == QSysInfo::MV_10_3) - ; // Do nothing. - else - CGContextTranslateCTM(hd, 0, double(pixelSize.y()) * 0.1); - } - - if (cosmeticPen != QCoreGraphicsPaintEnginePrivate::CosmeticNone) { - // If antialiazing is enabled, use the cosmetic pen size directly. - if (q->state->renderHints() & QPainter::Antialiasing) - CGContextSetLineWidth(hd, cosmeticPenSize); - else if (current.pen.widthF() <= 1) - CGContextSetLineWidth(hd, cosmeticPenSize * 0.9f); - else - CGContextSetLineWidth(hd, cosmeticPenSize); - } - if(cosmeticPen == QCoreGraphicsPaintEnginePrivate::CosmeticTransformPath) { - qt_mac_cg_transform_path t; - t.transform = qt_mac_convert_transform_to_cg(current.transform); - t.path = CGPathCreateMutable(); - CGPathApply(path, &t, qt_mac_cg_transform_path_apply); //transform the path - setTransform(0); //unset the context transform - CGContextSetLineWidth(hd, cosmeticPenSize); - CGContextAddPath(hd, t.path); - CGPathRelease(t.path); - } else { - CGContextAddPath(hd, path); - } - - CGContextStrokePath(hd); - if (needContextSave) - restoreGraphicsState(); - } -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine_mac_p.h b/src/gui/painting/qpaintengine_mac_p.h deleted file mode 100644 index 2434011e52..0000000000 --- a/src/gui/painting/qpaintengine_mac_p.h +++ /dev/null @@ -1,256 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPAINTENGINE_MAC_P_H -#define QPAINTENGINE_MAC_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtGui/qpaintengine.h" -#include "private/qt_mac_p.h" -#include "private/qpaintengine_p.h" -#include "private/qpolygonclipper_p.h" -#include "private/qfont_p.h" -#include "QtCore/qhash.h" - -typedef struct CGColorSpace *CGColorSpaceRef; -QT_BEGIN_NAMESPACE - -class QCoreGraphicsPaintEnginePrivate; -class QCoreGraphicsPaintEngine : public QPaintEngine -{ - Q_DECLARE_PRIVATE(QCoreGraphicsPaintEngine) - -public: - QCoreGraphicsPaintEngine(); - ~QCoreGraphicsPaintEngine(); - - bool begin(QPaintDevice *pdev); - bool end(); - static CGColorSpaceRef macGenericColorSpace(); - static CGColorSpaceRef macDisplayColorSpace(const QWidget *widget = 0); - - void updateState(const QPaintEngineState &state); - - void updatePen(const QPen &pen); - void updateBrush(const QBrush &brush, const QPointF &pt); - void updateFont(const QFont &font); - void updateOpacity(qreal opacity); - void updateMatrix(const QTransform &matrix); - void updateTransform(const QTransform &matrix); - void updateClipRegion(const QRegion ®ion, Qt::ClipOperation op); - void updateClipPath(const QPainterPath &path, Qt::ClipOperation op); - void updateCompositionMode(QPainter::CompositionMode mode); - void updateRenderHints(QPainter::RenderHints hints); - - void drawLines(const QLineF *lines, int lineCount); - void drawRects(const QRectF *rects, int rectCount); - void drawPoints(const QPointF *p, int pointCount); - void drawEllipse(const QRectF &r); - void drawPath(const QPainterPath &path); - - void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); - void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); - - void drawTextItem(const QPointF &pos, const QTextItem &item); - void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, - Qt::ImageConversionFlags flags = Qt::AutoColor); - - Type type() const { return QPaintEngine::CoreGraphics; } - - CGContextRef handle() const; - - static void initialize(); - static void cleanup(); - - QPainter::RenderHints supportedRenderHints() const; - - //avoid partial shadowed overload warnings... - void drawLines(const QLine *lines, int lineCount) { QPaintEngine::drawLines(lines, lineCount); } - void drawRects(const QRect *rects, int rectCount) { QPaintEngine::drawRects(rects, rectCount); } - void drawPoints(const QPoint *p, int pointCount) { QPaintEngine::drawPoints(p, pointCount); } - void drawEllipse(const QRect &r) { QPaintEngine::drawEllipse(r); } - void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) - { QPaintEngine::drawPolygon(points, pointCount, mode); } - - bool supportsTransformations(qreal, const QTransform &) const { return true; }; - -protected: - friend class QMacPrintEngine; - friend class QMacPrintEnginePrivate; - friend void qt_mac_display_change_callbk(CGDirectDisplayID, CGDisplayChangeSummaryFlags, void *); - friend void qt_color_profile_changed(CFNotificationCenterRef center, void *, - CFStringRef , const void *, CFDictionaryRef); - QCoreGraphicsPaintEngine(QPaintEnginePrivate &dptr); - -private: - static bool m_postRoutineRegistered; - static CGColorSpaceRef m_genericColorSpace; - static QHash<CGDirectDisplayID, CGColorSpaceRef> m_displayColorSpaceHash; - static void cleanUpMacColorSpaces(); - Q_DISABLE_COPY(QCoreGraphicsPaintEngine) -}; - -/***************************************************************************** - Private data - *****************************************************************************/ -class QCoreGraphicsPaintEnginePrivate : public QPaintEnginePrivate -{ - Q_DECLARE_PUBLIC(QCoreGraphicsPaintEngine) -public: - QCoreGraphicsPaintEnginePrivate() - : hd(0), shading(0), stackCount(0), complexXForm(false), disabledSmoothFonts(false) - { - } - - struct { - QPen pen; - QBrush brush; - uint clipEnabled : 1; - QRegion clip; - QTransform transform; - } current; - - //state info (shared with QD) - CGAffineTransform orig_xform; - - //cg structures - CGContextRef hd; - CGShadingRef shading; - int stackCount; - bool complexXForm; - bool disabledSmoothFonts; - enum { CosmeticNone, CosmeticTransformPath, CosmeticSetPenWidth } cosmeticPen; - - // pixel and cosmetic pen size in user coordinates. - QPointF pixelSize; - float cosmeticPenSize; - - //internal functions - enum { CGStroke=0x01, CGEOFill=0x02, CGFill=0x04 }; - void drawPath(uchar ops, CGMutablePathRef path = 0); - void setClip(const QRegion *rgn=0); - void resetClip(); - void setFillBrush(const QPointF &origin=QPoint()); - void setStrokePen(const QPen &pen); - inline void saveGraphicsState(); - inline void restoreGraphicsState(); - float penOffset(); - QPointF devicePixelSize(CGContextRef context); - float adjustPenWidth(float penWidth); - inline void setTransform(const QTransform *matrix=0) - { - CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd))); - CGAffineTransform xform = orig_xform; - if(matrix) { - extern CGAffineTransform qt_mac_convert_transform_to_cg(const QTransform &); - xform = CGAffineTransformConcat(qt_mac_convert_transform_to_cg(*matrix), xform); - } - CGContextConcatCTM(hd, xform); - CGContextSetTextMatrix(hd, xform); - } -}; - -inline void QCoreGraphicsPaintEnginePrivate::saveGraphicsState() -{ - ++stackCount; - CGContextSaveGState(hd); -} - -inline void QCoreGraphicsPaintEnginePrivate::restoreGraphicsState() -{ - --stackCount; - Q_ASSERT(stackCount >= 0); - CGContextRestoreGState(hd); -} - -class QMacQuartzPaintDevice : public QPaintDevice -{ -public: - QMacQuartzPaintDevice(CGContextRef cg, int width, int height, int bytesPerLine) - : mCG(cg), mWidth(width), mHeight(height), mBytesPerLine(bytesPerLine) - { } - int devType() const { return QInternal::MacQuartz; } - CGContextRef cgContext() const { return mCG; } - int metric(PaintDeviceMetric metric) const { - switch (metric) { - case PdmWidth: - return mWidth; - case PdmHeight: - return mHeight; - case PdmWidthMM: - return (qt_defaultDpiX() * mWidth) / 2.54; - case PdmHeightMM: - return (qt_defaultDpiY() * mHeight) / 2.54; - case PdmNumColors: - return 0; - case PdmDepth: - return 32; - case PdmDpiX: - case PdmPhysicalDpiX: - return qt_defaultDpiX(); - case PdmDpiY: - case PdmPhysicalDpiY: - return qt_defaultDpiY(); - } - return 0; - } - QPaintEngine *paintEngine() const { qWarning("This function should never be called."); return 0; } -private: - CGContextRef mCG; - int mWidth; - int mHeight; - int mBytesPerLine; -}; - -QT_END_NAMESPACE - -#endif // QPAINTENGINE_MAC_P_H diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h index 2b54e82c39..5d540bd11b 100644 --- a/src/gui/painting/qpaintengine_p.h +++ b/src/gui/painting/qpaintengine_p.h @@ -66,7 +66,7 @@ class QPaintEnginePrivate { Q_DECLARE_PUBLIC(QPaintEngine) public: - QPaintEnginePrivate() : pdev(0), q_ptr(0), currentClipWidget(0), hasSystemTransform(0), + QPaintEnginePrivate() : pdev(0), q_ptr(0), currentClipDevice(0), hasSystemTransform(0), hasSystemViewport(0) {} virtual ~QPaintEnginePrivate() { } QPaintDevice *pdev; @@ -75,7 +75,7 @@ public: QRect systemRect; QRegion systemViewport; QTransform systemTransform; - QWidget *currentClipWidget; + QPaintDevice *currentClipDevice; uint hasSystemTransform : 1; uint hasSystemViewport : 1; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index e1802e6552..09ffc8ec59 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -51,7 +51,6 @@ #include <qpainterpath.h> #include <qdebug.h> #include <qhash.h> -#include <qlabel.h> #include <qbitmap.h> #include <qmath.h> @@ -76,7 +75,7 @@ // #include "qbezier_p.h" #include "qoutlinemapper_p.h" -#if defined(Q_WS_WIN) +#if defined(Q_OS_WIN) # include <qt_windows.h> # include <qvarlengtharray.h> # include <private/qfontengine_p.h> @@ -87,21 +86,13 @@ # include <private/qt_mac_p.h> # include <private/qpixmap_mac_p.h> # include <private/qpaintengine_mac_p.h> -#elif defined(Q_WS_QWS) -# if !defined(QT_NO_FREETYPE) -# include <private/qfontengine_ft_p.h> -# endif -# if !defined(QT_NO_QWS_QPF2) -# include <private/qfontengine_qpf_p.h> -# endif -# include <private/qabstractfontengine_p.h> #elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) # include <private/qfontengine_s60_p.h> #elif defined(Q_WS_QPA) # include <private/qfontengine_ft_p.h> #endif -#if defined(Q_WS_WIN64) +#if defined(Q_OS_WIN64) # include <malloc.h> #endif #include <limits.h> @@ -127,12 +118,28 @@ void dumpClip(int width, int height, const QClipData *clip); // 4 pixels. #define int_dim(pos, dim) (int(pos+dim) - int(pos)) -// use the same rounding as in qrasterizer.cpp (6 bit fixed point) static const qreal aliasedCoordinateDelta = 0.5 - 0.015625; -#ifdef Q_WS_WIN -extern bool qt_cleartype_enabled; +#ifdef Q_OS_WIN + +static inline bool winClearTypeFontsEnabled() +{ + UINT result = 0; +#if !defined(SPI_GETFONTSMOOTHINGTYPE) // MinGW +# define SPI_GETFONTSMOOTHINGTYPE 0x200A +# define FE_FONTSMOOTHINGCLEARTYPE 0x002 #endif + SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0); + return result == FE_FONTSMOOTHINGCLEARTYPE; +} + +bool QRasterPaintEngine::clearTypeFontsEnabled() +{ + static const bool result = winClearTypeFontsEnabled(); + return result; +} + +#endif // Q_OS_WIN #ifdef Q_WS_MAC extern bool qt_applefontsmoothing_enabled; @@ -332,7 +339,7 @@ void QRasterPaintEngine::init() Q_D(QRasterPaintEngine); -#ifdef Q_WS_WIN +#ifdef Q_OS_WIN d->hdc = 0; #endif @@ -378,11 +385,6 @@ void QRasterPaintEngine::init() case QInternal::Image: format = d->rasterBuffer->prepare(static_cast<QImage *>(d->device)); break; -#ifdef Q_WS_QWS - case QInternal::CustomRaster: - d->rasterBuffer->prepare(static_cast<QCustomRasterPaintDevice*>(d->device)); - break; -#endif default: qWarning("QRasterPaintEngine: unsupported target device %d\n", d->device->devType()); d->device = 0; @@ -485,8 +487,8 @@ bool QRasterPaintEngine::begin(QPaintDevice *device) if (d->mono_surface) d->glyphCacheType = QFontEngineGlyphCache::Raster_Mono; -#if defined(Q_WS_WIN) - else if (qt_cleartype_enabled) +#if defined(Q_OS_WIN) + else if (clearTypeFontsEnabled()) #elif defined (Q_WS_MAC) else if (qt_applefontsmoothing_enabled) #else @@ -947,13 +949,6 @@ void QRasterPaintEngine::clipEnabledChanged() } } -#ifdef Q_WS_QWS -void QRasterPaintEnginePrivate::prepare(QCustomRasterPaintDevice *device) -{ - rasterBuffer->prepare(device); -} -#endif - void QRasterPaintEnginePrivate::drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func, @@ -3052,33 +3047,17 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte return; } -#elif defined (Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) // Q_WS_WIN || Q_WS_MAC +#elif defined (Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) // Q_OS_WIN || Q_WS_MAC if (s->matrix.type() <= QTransform::TxTranslate || (s->matrix.type() == QTransform::TxScale && (qFuzzyCompare(s->matrix.m11(), s->matrix.m22())))) { drawGlyphsS60(p, ti); return; } -#else // Q_WS_WIN || Q_WS_MAC +#else // Q_OS_WIN || Q_WS_MAC QFontEngine *fontEngine = ti.fontEngine; -#if defined(Q_WS_QWS) - if (fontEngine->type() == QFontEngine::Box) { - fontEngine->draw(this, qFloor(p.x()), qFloor(p.y()), ti); - return; - } - - if (s->matrix.type() < QTransform::TxScale - && (fontEngine->type() == QFontEngine::QPF1 || fontEngine->type() == QFontEngine::QPF2 - || (fontEngine->type() == QFontEngine::Proxy - && !(static_cast<QProxyFontEngine *>(fontEngine)->drawAsOutline())) - )) { - fontEngine->draw(this, qFloor(p.x() + aliasedCoordinateDelta), qFloor(p.y() + aliasedCoordinateDelta), ti); - return; - } -#endif // Q_WS_QWS - #ifdef Q_WS_QPA if (s->matrix.type() < QTransform::TxScale) { @@ -3109,14 +3088,6 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte #if (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE) -#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_QPF2) - if (fontEngine->type() == QFontEngine::QPF2) { - QFontEngine *renderingEngine = static_cast<QFontEngineQPF *>(fontEngine)->renderingEngine(); - if (renderingEngine) - fontEngine = renderingEngine; - } -#endif - if (fontEngine->type() != QFontEngine::Freetype) { QPaintEngineEx::drawTextItem(p, ti); return; @@ -3333,7 +3304,7 @@ CGContextRef QRasterPaintEngine::getCGContext() const } #endif -#ifdef Q_WS_WIN +#ifdef Q_OS_WIN /*! \internal */ @@ -3399,59 +3370,6 @@ QPoint QRasterPaintEngine::coordinateOffset() const return QPoint(0, 0); } -/*! - Draws the given color \a spans with the specified \a color. The \a - count parameter specifies the number of spans. - - The default implementation does nothing; reimplement this function - to draw the given color \a spans with the specified \a color. Note - that this function \e must be reimplemented if the framebuffer is - not memory-mapped. - - \sa drawBufferSpan() -*/ -#if defined(Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS) -void QRasterPaintEngine::drawColorSpans(const QSpan *spans, int count, uint color) -{ - Q_UNUSED(spans); - Q_UNUSED(count); - Q_UNUSED(color); - qFatal("QRasterPaintEngine::drawColorSpans must be reimplemented on " - "a non memory-mapped device"); -} - -/*! - \fn void QRasterPaintEngine::drawBufferSpan(const uint *buffer, int size, int x, int y, int length, uint alpha) - - Draws the given \a buffer. - - The default implementation does nothing; reimplement this function - to draw a buffer that contains more than one color. Note that this - function \e must be reimplemented if the framebuffer is not - memory-mapped. - - The \a size parameter specifies the total size of the given \a - buffer, while the \a length parameter specifies the number of - pixels to draw. The buffer's position is given by (\a x, \a - y). The provided \a alpha value is added to each pixel in the - buffer when drawing. - - \sa drawColorSpans() -*/ -void QRasterPaintEngine::drawBufferSpan(const uint *buffer, int bufsize, - int x, int y, int length, uint const_alpha) -{ - Q_UNUSED(buffer); - Q_UNUSED(bufsize); - Q_UNUSED(x); - Q_UNUSED(y); - Q_UNUSED(length); - Q_UNUSED(const_alpha); - qFatal("QRasterPaintEngine::drawBufferSpan must be reimplemented on " - "a non memory-mapped device"); -} -#endif // Q_WS_QWS - void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fg) { Q_ASSERT(fg); @@ -3733,7 +3651,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, const int rasterPoolInitialSize = MINIMUM_POOL_SIZE; int rasterPoolSize = rasterPoolInitialSize; unsigned char *rasterPoolBase; -#if defined(Q_WS_WIN64) +#if defined(Q_OS_WIN64) rasterPoolBase = // We make use of setjmp and longjmp in qgrayraster.c which requires // 16-byte alignment, hence we hardcode this requirement here.. @@ -3786,7 +3704,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, rendered_spans += q_gray_rendered_spans(*grayRaster.data()); -#if defined(Q_WS_WIN64) +#if defined(Q_OS_WIN64) _aligned_free(rasterPoolBase); #else if (rasterPoolBase != rasterPoolOnStack) // initially on the stack @@ -3795,7 +3713,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, rasterPoolSize = new_size; rasterPoolBase = -#if defined(Q_WS_WIN64) +#if defined(Q_OS_WIN64) // We make use of setjmp and longjmp in qgrayraster.c which requires // 16-byte alignment, hence we hardcode this requirement here.. (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2); @@ -3812,7 +3730,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, } } -#if defined(Q_WS_WIN64) +#if defined(Q_OS_WIN64) _aligned_free(rasterPoolBase); #else if (rasterPoolBase != rasterPoolOnStack) // initially on the stack @@ -3899,127 +3817,6 @@ void QRasterBuffer::resetBuffer(int val) memset(m_buffer, val, m_height*bytes_per_line); } - -#if defined(Q_WS_QWS) -void QRasterBuffer::prepare(QCustomRasterPaintDevice *device) -{ - m_buffer = reinterpret_cast<uchar*>(device->memory()); - m_width = qMin(QT_RASTER_COORD_LIMIT, device->width()); - m_height = qMin(QT_RASTER_COORD_LIMIT, device->height()); - bytes_per_pixel = device->depth() / 8; - bytes_per_line = device->bytesPerLine(); - format = device->format(); -#ifndef QT_NO_RASTERCALLBACKS - if (!m_buffer) - drawHelper = qDrawHelperCallback + format; - else -#endif - drawHelper = qDrawHelper + format; -} - -int QCustomRasterPaintDevice::metric(PaintDeviceMetric m) const -{ - switch (m) { - case PdmWidth: - return widget->frameGeometry().width(); - case PdmHeight: - return widget->frameGeometry().height(); - default: - break; - } - - return qt_paint_device_metric(widget, m); -} - -int QCustomRasterPaintDevice::bytesPerLine() const -{ - return (width() * depth() + 7) / 8; -} - -#elif defined(Q_OS_SYMBIAN) - -void QRasterBuffer::prepareBuffer(int /* width */, int /* height */) -{ -} - -#endif // Q_OS_SYMBIAN - -/*! - \class QCustomRasterPaintDevice - \preliminary - \ingroup qws - \since 4.2 - - \brief The QCustomRasterPaintDevice class is provided to activate - hardware accelerated paint engines in Qt for Embedded Linux. - - Note that this class is only available in \l{Qt for Embedded Linux}. - - In \l{Qt for Embedded Linux}, painting is a pure software - implementation. But starting with Qt 4.2, it is - possible to add an accelerated graphics driver to take advantage - of available hardware resources. - - Hardware acceleration is accomplished by creating a custom screen - driver, accelerating the copying from memory to the screen, and - implementing a custom paint engine accelerating the various - painting operations. Then a custom paint device (derived from the - QCustomRasterPaintDevice class) and a custom window surface - (derived from QWSWindowSurface) must be implemented to make - \l{Qt for Embedded Linux} aware of the accelerated driver. - - See the \l {Adding an Accelerated Graphics Driver to Qt for Embedded Linux} - documentation for details. - - \sa QRasterPaintEngine, QPaintDevice -*/ - -/*! - \fn QCustomRasterPaintDevice::QCustomRasterPaintDevice(QWidget *widget) - - Constructs a custom raster based paint device for the given - top-level \a widget. -*/ - -/*! - \fn int QCustomRasterPaintDevice::bytesPerLine() const - - Returns the number of bytes per line in the framebuffer. Note that - this number might be larger than the framebuffer width. -*/ - -/*! - \fn int QCustomRasterPaintDevice::devType() const - \internal -*/ - -/*! - \fn QImage::Format QCustomRasterPaintDevice::format() const - - Returns the format of the device's memory buffet. - - The default format is QImage::Format_ARGB32_Premultiplied. The - only other valid format is QImage::Format_RGB16. -*/ - -/*! - \fn void * QCustomRasterPaintDevice::memory () const - - Returns a pointer to the paint device's memory buffer, or 0 if no - such buffer exists. -*/ - -/*! - \fn int QCustomRasterPaintDevice::metric ( PaintDeviceMetric m ) const - \reimp -*/ - -/*! - \fn QSize QCustomRasterPaintDevice::size () const - \internal -*/ - - QClipData::QClipData(int height) { clipSpanHeight = height; @@ -4743,9 +4540,6 @@ Q_GLOBAL_STATIC(QGradientCache, qt_gradient_cache) void QSpanData::init(QRasterBuffer *rb, const QRasterPaintEngine *pe) { rasterBuffer = rb; -#ifdef Q_WS_QWS - rasterEngine = const_cast<QRasterPaintEngine *>(pe); -#endif type = None; txop = 0; bilinear = false; @@ -4891,16 +4685,7 @@ void QSpanData::adjustSpanMethods() unclipped_blend = rasterBuffer->drawHelper->blendGradient; break; case Texture: -#ifdef Q_WS_QWS -#ifndef QT_NO_RASTERCALLBACKS - if (!rasterBuffer->buffer()) - unclipped_blend = qBlendTextureCallback; - else -#endif - unclipped_blend = qBlendTexture; -#else unclipped_blend = qBlendTexture; -#endif if (!texture.imageData) unclipped_blend = 0; diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index f9d388d14e..d387e1312a 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -72,7 +72,6 @@ class QOutlineMapper; class QRasterPaintEnginePrivate; class QRasterBuffer; class QClipData; -class QCustomRasterPaintDevice; class QRasterPaintEngineState : public QPainterState { @@ -129,11 +128,7 @@ public: /******************************************************************************* * QRasterPaintEngine */ -class -#ifdef Q_WS_QWS -Q_GUI_EXPORT -#endif -QRasterPaintEngine : public QPaintEngineEx +class Q_GUI_EXPORT QRasterPaintEngine : public QPaintEngineEx { Q_DECLARE_PRIVATE(QRasterPaintEngine) public: @@ -229,10 +224,11 @@ public: CGContextRef getCGContext() const; #endif -#ifdef Q_WS_WIN +#ifdef Q_OS_WIN void setDC(HDC hdc); HDC getDC() const; void releaseDC(HDC hdc) const; + static bool clearTypeFontsEnabled(); #endif void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h); @@ -241,11 +237,6 @@ public: QPoint coordinateOffset() const; -#if defined(Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS) - virtual void drawColorSpans(const QSpan *spans, int count, uint color); - virtual void drawBufferSpan(const uint *buffer, int bufsize, - int x, int y, int length, uint const_alpha); -#endif bool supportsTransformations(const QFontEngine *fontEngine) const; bool supportsTransformations(qreal pixelSize, const QTransform &m) const; @@ -295,11 +286,7 @@ private: /******************************************************************************* * QRasterPaintEnginePrivate */ -class -#ifdef Q_WS_QWS -Q_GUI_EXPORT -#endif -QRasterPaintEnginePrivate : public QPaintEngineExPrivate +class QRasterPaintEnginePrivate : public QPaintEngineExPrivate { Q_DECLARE_PUBLIC(QRasterPaintEngine) public: @@ -331,10 +318,6 @@ public: ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const; ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const; -#ifdef Q_WS_QWS - void prepare(QCustomRasterPaintDevice *); -#endif - inline const QClipData *clip() const; void initializeRasterizer(QSpanData *data); @@ -346,7 +329,7 @@ public: QScopedPointer<QOutlineMapper> outlineMapper; QScopedPointer<QRasterBuffer> rasterBuffer; -#if defined (Q_WS_WIN) +#if defined (Q_OS_WIN) HDC hdc; #elif defined(Q_WS_MAC) CGContextRef cgContext; @@ -378,11 +361,7 @@ public: }; -class -#ifdef Q_WS_QWS -Q_GUI_EXPORT -#endif -QClipData { +class QClipData { public: QClipData(int height); ~QClipData(); @@ -459,41 +438,10 @@ inline void QClipData::appendSpans(const QSpan *s, int num) count += num; } -#ifdef Q_WS_QWS -class Q_GUI_EXPORT QCustomRasterPaintDevice : public QPaintDevice -{ -public: - QCustomRasterPaintDevice(QWidget *w) : widget(w) {} - - int devType() const { return QInternal::CustomRaster; } - - virtual int metric(PaintDeviceMetric m) const; - - virtual void* memory() const { return 0; } - - virtual QImage::Format format() const { - return QImage::Format_ARGB32_Premultiplied; - } - - virtual int bytesPerLine() const; - - virtual QSize size() const { - return static_cast<QRasterPaintEngine*>(paintEngine())->size(); - } - -private: - QWidget *widget; -}; -#endif // Q_WS_QWS - /******************************************************************************* * QRasterBuffer */ -class -#ifdef Q_WS_QWS -Q_GUI_EXPORT -#endif -QRasterBuffer +class QRasterBuffer { public: QRasterBuffer() : m_width(0), m_height(0), m_buffer(0) { init(); } @@ -504,9 +452,6 @@ public: QImage::Format prepare(QImage *image); QImage::Format prepare(QPixmap *pix); -#ifdef Q_WS_QWS - void prepare(QCustomRasterPaintDevice *device); -#endif void prepare(int w, int h); void prepareBuffer(int w, int h); diff --git a/src/gui/painting/qpaintengine_s60.cpp b/src/gui/painting/qpaintengine_s60.cpp deleted file mode 100644 index 091e2e65a4..0000000000 --- a/src/gui/painting/qpaintengine_s60.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <private/qpaintengine_s60_p.h> -#include <private/qpixmap_s60_p.h> -#include <private/qt_s60_p.h> -#include <private/qvolatileimage_p.h> - -QT_BEGIN_NAMESPACE - -class QS60PaintEnginePrivate : public QRasterPaintEnginePrivate -{ -public: - QS60PaintEnginePrivate() {} -}; - -QS60PaintEngine::QS60PaintEngine(QPaintDevice *device, QS60PixmapData *data) - : QRasterPaintEngine(*(new QS60PaintEnginePrivate), device), pixmapData(data) -{ -} - -bool QS60PaintEngine::begin(QPaintDevice *device) -{ - Q_D(QS60PaintEngine); - - if (pixmapData->classId() == QPixmapData::RasterClass) { - pixmapData->beginDataAccess(); - bool ret = QRasterPaintEngine::begin(device); - // Make sure QPaintEngine::paintDevice() returns the proper device. - // QRasterPaintEngine changes pdev to QImage in case of RasterClass QPixmapData - // which is incorrect in Symbian. - d->pdev = device; - return ret; - } - - return QRasterPaintEngine::begin(device); -} - -bool QS60PaintEngine::end() -{ - if (pixmapData->classId() == QPixmapData::RasterClass) { - bool ret = QRasterPaintEngine::end(); - pixmapData->endDataAccess(); - return ret; - } - return QRasterPaintEngine::end(); -} - -void QS60PaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm) -{ - if (pm.pixmapData()->classId() == QPixmapData::RasterClass) { - QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); - srcData->beginDataAccess(); - QRasterPaintEngine::drawPixmap(p, pm); - srcData->endDataAccess(); - } else { - void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage); - if (nativeData) { - QVolatileImage *img = static_cast<QVolatileImage *>(nativeData); - img->beginDataAccess(); - QRasterPaintEngine::drawImage(p, img->imageRef()); - img->endDataAccess(true); - } else { - QRasterPaintEngine::drawPixmap(p, pm); - } - } -} - -void QS60PaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) -{ - if (pm.pixmapData()->classId() == QPixmapData::RasterClass) { - QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); - srcData->beginDataAccess(); - QRasterPaintEngine::drawPixmap(r, pm, sr); - srcData->endDataAccess(); - } else { - void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage); - if (nativeData) { - QVolatileImage *img = static_cast<QVolatileImage *>(nativeData); - img->beginDataAccess(); - QRasterPaintEngine::drawImage(r, img->imageRef(), sr); - img->endDataAccess(true); - } else { - QRasterPaintEngine::drawPixmap(r, pm, sr); - } - } -} - -void QS60PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr) -{ - if (pm.pixmapData()->classId() == QPixmapData::RasterClass) { - QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); - srcData->beginDataAccess(); - QRasterPaintEngine::drawTiledPixmap(r, pm, sr); - srcData->endDataAccess(); - } else { - QRasterPaintEngine::drawTiledPixmap(r, pm, sr); - } -} - -void QS60PaintEngine::prepare(QImage *image) -{ - QRasterBuffer *buffer = d_func()->rasterBuffer.data(); - if (buffer) - buffer->prepare(image); -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine_s60_p.h b/src/gui/painting/qpaintengine_s60_p.h deleted file mode 100644 index 2a3b443db3..0000000000 --- a/src/gui/painting/qpaintengine_s60_p.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPAINTENGINE_S60_P_H -#define QPAINTENGINE_S60_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "private/qpaintengine_raster_p.h" - -QT_BEGIN_NAMESPACE - -class QS60PaintEnginePrivate; -class QS60PixmapData; - -class QS60PaintEngine : public QRasterPaintEngine -{ - Q_DECLARE_PRIVATE(QS60PaintEngine) - -public: - QS60PaintEngine(QPaintDevice *device, QS60PixmapData* data); - bool begin(QPaintDevice *device); - bool end(); - - void drawPixmap(const QPointF &p, const QPixmap &pm); - void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr); - - void prepare(QImage* image); - -private: - QS60PixmapData *pixmapData; -}; - -QT_END_NAMESPACE - -#endif // QPAINTENGINE_S60_P_H diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp deleted file mode 100644 index 5f613ee001..0000000000 --- a/src/gui/painting/qpaintengine_x11.cpp +++ /dev/null @@ -1,2499 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qplatformdefs.h" - -#include "private/qpixmap_x11_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 <qmath.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 <private/qwidget_p.h> -#include <private/qpainterpath_p.h> - -#include "qpen.h" -#include "qcolor.h" -#include "qcolormap.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> -#endif - -#include <private/qstylehelper_p.h> - -QT_BEGIN_NAMESPACE - -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 -extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); - -// use the same rounding as in qrasterizer.cpp (6 bit fixed point) -static const qreal aliasedCoordinateDelta = 0.5 - 0.015625; - -#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_XRENDER -static 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.h -Q_GUI_EXPORT void *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 16 -static 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 = QLatin1Literal("$qt-alpha-brush$") - % HexString<uchar>(alpha) - % HexString<int>(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 = q_check_ptr((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_XRENDER -static 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 = qrand() % 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); -} -#endif - -void 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()); - 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])); -} - -void QX11PaintEnginePrivate::systemStateChanged() -{ - Q_Q(QX11PaintEngine); - QPainter *painter = q->state ? static_cast<QPainterState *>(q->state)->painter : 0; - if (painter && painter->hasClipping()) { - if (q->testDirty(QPaintEngine::DirtyTransform)) - q->updateMatrix(q->state->transform()); - QPolygonF clip_poly_dev(matrix.map(painter->clipPath().toFillPolygon())); - QPolygonF clipped_poly_dev; - clipPolygon_dev(clip_poly_dev, &clipped_poly_dev); - q->updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip); - } else { - q->updateClipRegion_dev(QRegion(), Qt::NoClip); - } -} - -static QPaintEngine::PaintEngineFeatures qt_decide_features() -{ - QPaintEngine::PaintEngineFeatures features = - QPaintEngine::PrimitiveTransform - | QPaintEngine::PatternBrush - | QPaintEngine::AlphaBlend - | QPaintEngine::PainterPaths - | QPaintEngine::RasterOpModes; - - if (X11->use_xrender) { - features |= QPaintEngine::Antialiasing; - features |= QPaintEngine::PorterDuff; - features |= QPaintEngine::MaskedBrush; -#if 0 - if (X11->xrender_version > 10) { - features |= QPaintEngine::LinearGradientFill; - // ### - } -#endif - } - - 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() -{ -#ifndef QT_NO_XRENDER - Q_D(QX11PaintEngine); - delete d->tessellator; -#endif -} - -bool QX11PaintEngine::begin(QPaintDevice *pdev) -{ - Q_D(QX11PaintEngine); - d->xinfo = qt_x11Info(pdev); - QWidget *w = d->pdev->devType() == QInternal::Widget ? static_cast<QWidget *>(d->pdev) : 0; - const bool isAlienWidget = w && !w->internalWinId() && w->testAttribute(Qt::WA_WState_Created); -#ifndef QT_NO_XRENDER - if (w) { - if (isAlienWidget) - d->picture = (::Picture)w->nativeParentWidget()->x11PictureHandle(); - else - d->picture = (::Picture)w->x11PictureHandle(); - } else if (pdev->devType() == QInternal::Pixmap) { - const QPixmap *pm = static_cast<const QPixmap *>(pdev); - QX11PixmapData *data = static_cast<QX11PixmapData*>(pm->data.data()); - if (X11->use_xrender && data->depth() != 32 && data->x11_mask) - data->convertToARGB32(); - d->picture = (::Picture)static_cast<const QPixmap *>(pdev)->x11PictureHandle(); - } -#else - d->picture = 0; -#endif - d->hd = !isAlienWidget ? qt_x11Handle(pdev) : qt_x11Handle(w->nativeParentWidget()); - - Q_ASSERT(d->xinfo != 0); - d->dpy = d->xinfo->display(); // get display variable - d->scrn = d->xinfo->screen(); // get screen variable - - 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_scaling_xform = false; - d->has_non_scaling_xform = true; - d->xform_scale = 1; - d->has_custom_pen = false; - d->matrix = QTransform(); - d->pdev_depth = d->pdev->depth(); - d->render_hints = 0; - d->txop = QTransform::TxNone; - d->use_path_fallback = false; -#if !defined(QT_NO_XRENDER) - d->composition_mode = PictOpOver; -#endif - d->xlibMaxLinePoints = 32762; // a safe number used to avoid, call to XMaxRequestSize(d->dpy) - 3; - d->opacity = 1; - - // 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 = 1000; - QRect devClipRect(-BUFFERZONE, -BUFFERZONE, - pdev->width() + 2*BUFFERZONE, pdev->height() + 2*BUFFERZONE); - d->polygonClipper.setBoundingRect(devClipRect); - - if (isAlienWidget) { - // Set system clip for alien widgets painting outside the paint event. - // This is not a problem with native windows since the windowing system - // will handle the clip. - QWidgetPrivate *wd = w->d_func(); - QRegion widgetClip(wd->clipRect()); - wd->clipToEffectiveMask(widgetClip); - wd->subtractOpaqueSiblings(widgetClip); - widgetClip.translate(w->mapTo(w->nativeParentWidget(), QPoint())); - setSystemClip(widgetClip); - } - - QPixmap::x11SetDefaultScreen(d->xinfo->screen()); - - 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; - } - - // Restore system clip for alien widgets painting outside the paint event. - if (d->pdev->devType() == QInternal::Widget && !static_cast<QWidget *>(d->pdev)->internalWinId()) - setSystemClip(QRegion()); - - 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->has_non_scaling_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 == QTransform::TxNone) { - linef = lines[i]; - } else { - linef = d->matrix.map(QLineF(lines[i])); - } - if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - - XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); - } - } - } -} - -void QX11PaintEngine::drawLines(const QLineF *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->has_non_scaling_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 = d->matrix.map(lines[i]); - if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - - XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); - } - } - } -} - -static inline QLine clipStraightLine(const QRect &clip, const QLine &l) -{ - if (l.p1().x() == l.p2().x()) { - int x = qBound(clip.left(), l.p1().x(), clip.right()); - int y1 = qBound(clip.top(), l.p1().y(), clip.bottom()); - int y2 = qBound(clip.top(), l.p2().y(), clip.bottom()); - - return QLine(x, y1, x, y2); - } else { - Q_ASSERT(l.p1().y() == l.p2().y()); - - int x1 = qBound(clip.left(), l.p1().x(), clip.right()); - int x2 = qBound(clip.left(), l.p2().x(), clip.right()); - int y = qBound(clip.top(), l.p1().y(), clip.bottom()); - - return QLine(x1, y, x2, y); - } -} - -void QX11PaintEngine::drawRects(const QRectF *rects, int rectCount) -{ - Q_D(QX11PaintEngine); - Q_ASSERT(rects); - Q_ASSERT(rectCount); - - if (rectCount != 1 - || d->has_pen - || d->has_alpha_brush - || d->has_complex_xform - || d->has_custom_pen - || d->cbrush.style() != Qt::SolidPattern) - { - QPaintEngine::drawRects(rects, rectCount); - return; - } - - QPoint alignedOffset; - if (d->txop == QTransform::TxTranslate) { - QPointF offset(d->matrix.dx(), d->matrix.dy()); - alignedOffset = offset.toPoint(); - if (offset != QPointF(alignedOffset)) { - QPaintEngine::drawRects(rects, rectCount); - return; - } - } - - const QRectF& r = rects[0]; - QRect alignedRect = r.toAlignedRect(); - if (r != QRectF(alignedRect)) { - QPaintEngine::drawRects(rects, rectCount); - return; - } - alignedRect.translate(alignedOffset); - - QRect clip(d->polygonClipper.boundingRect()); - alignedRect = alignedRect.intersected(clip); - if (alignedRect.isEmpty()) - return; - - // simple-case: - // the rectangle is pixel-aligned - // the fill brush is just a solid non-alpha color - // the painter transform is only integer translation - // ignore: antialiasing and just XFillRectangles directly - XRectangle xrect; - xrect.x = short(alignedRect.x()); - xrect.y = short(alignedRect.y()); - xrect.width = ushort(alignedRect.width()); - xrect.height = ushort(alignedRect.height()); - XFillRectangles(d->dpy, d->hd, d->gc_brush, &xrect, 1); -} - -void QX11PaintEngine::drawRects(const QRect *rects, int rectCount) -{ - Q_D(QX11PaintEngine); - Q_ASSERT(rects); - Q_ASSERT(rectCount); - - if (d->has_alpha_pen - || d->has_complex_xform - || d->has_custom_pen - || (d->render_hints & QPainter::Antialiasing)) - { - 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 == QTransform::TxTranslate) - r.translate(offset); - - if (r.width() == 0 || r.height() == 0) { - if (d->has_pen) { - const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height())); - XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y()); - } - continue; - } - - r = r.intersected(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 == QTransform::TxTranslate) - r.translate(offset); - - if (r.width() == 0 || r.height() == 0) { - const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height())); - XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y()); - continue; - } - - r = r.intersected(clip); - if (r.isEmpty()) - continue; - d->setupAdaptedOrigin(r.topLeft()); - XFillRectangle(d->dpy, d->hd, d->gc_brush, r.x(), r.y(), r.width(), r.height()); - 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 == QTransform::TxTranslate) - r.translate(offset); - - if (r.width() == 0 || r.height() == 0) { - --numClipped; - if (d->has_pen) { - const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height())); - XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y()); - } - continue; - } - - r = r.intersected(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) - XFillRectangles(d->dpy, d->hd, d->gc_brush, xrects.data(), numClipped); - else if (d->has_pen) - XDrawRectangles(d->dpy, d->hd, d->gc, xrects.data(), numClipped); - d->resetAdaptedOrigin(); - } - } - } -} - -static inline void setCapStyle(int cap_style, GC gc) -{ - ulong mask = GCCapStyle; - XGCValues vals; - vals.cap_style = cap_style; - XChangeGC(X11->display, gc, mask, &vals); -} - -void QX11PaintEngine::drawPoints(const QPoint *points, int pointCount) -{ - Q_ASSERT(points); - Q_ASSERT(pointCount); - Q_D(QX11PaintEngine); - - if (!d->has_pen) - return; - - // use the same test here as in drawPath to ensure that we don't use the path fallback - // and end up in XDrawLines for pens with width <= 1 - if (d->cpen.widthF() > 1.0f - || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing))) - || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate)) - { - Qt::PenCapStyle capStyle = d->cpen.capStyle(); - if (capStyle == Qt::FlatCap) { - setCapStyle(CapProjecting, d->gc); - d->cpen.setCapStyle(Qt::SquareCap); - } - const QPoint *end = points + pointCount; - while (points < end) { - QPainterPath path; - path.moveTo(*points); - path.lineTo(points->x()+.005, points->y()); - drawPath(path); - ++points; - } - - if (capStyle == Qt::FlatCap) { - setCapStyle(CapButt, d->gc); - d->cpen.setCapStyle(capStyle); - } - 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; - - // use the same test here as in drawPath to ensure that we don't use the path fallback - // and end up in XDrawLines for pens with width <= 1 - if (d->cpen.widthF() > 1.0f - || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing))) - || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate)) - { - Qt::PenCapStyle capStyle = d->cpen.capStyle(); - if (capStyle == Qt::FlatCap) { - setCapStyle(CapProjecting, d->gc); - d->cpen.setCapStyle(Qt::SquareCap); - } - - const QPointF *end = points + pointCount; - while (points < end) { - QPainterPath path; - path.moveTo(*points); - path.lineTo(points->x() + 0.005, points->y()); - drawPath(path); - ++points; - } - if (capStyle == Qt::FlatCap) { - setCapStyle(CapButt, d->gc); - d->cpen.setCapStyle(capStyle); - } - 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 & DirtyOpacity) { - d->opacity = state.opacity(); - // Force update pen/brush as to get proper alpha colors propagated - flags |= DirtyPen; - flags |= DirtyBrush; - } - - if (flags & DirtyTransform) updateMatrix(state.transform()); - 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) { - if (state.isClipEnabled()) { - QPolygonF clip_poly_dev(d->matrix.map(painter()->clipPath().toFillPolygon())); - QPolygonF clipped_poly_dev; - d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev); - updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip); - } else { - updateClipRegion_dev(QRegion(), Qt::NoClip); - } - } - - if (flags & DirtyClipPath) { - QPolygonF clip_poly_dev(d->matrix.map(state.clipPath().toFillPolygon())); - QPolygonF clipped_poly_dev; - d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev); - updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon(), state.clipPath().fillRule()), - state.clipOperation()); - } else if (flags & DirtyClipRegion) { - extern QPainterPath qt_regionToPath(const QRegion ®ion); - QPainterPath clip_path = qt_regionToPath(state.clipRegion()); - QPolygonF clip_poly_dev(d->matrix.map(clip_path.toFillPolygon())); - QPolygonF clipped_poly_dev; - d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev); - updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), state.clipOperation()); - } - if (flags & DirtyHints) updateRenderHints(state.renderHints()); - if (flags & DirtyCompositionMode) { - int function = GXcopy; - if (state.compositionMode() >= QPainter::RasterOp_SourceOrDestination) { - switch (state.compositionMode()) { - case QPainter::RasterOp_SourceOrDestination: - function = GXor; - break; - case QPainter::RasterOp_SourceAndDestination: - function = GXand; - break; - case QPainter::RasterOp_SourceXorDestination: - function = GXxor; - break; - case QPainter::RasterOp_NotSourceAndNotDestination: - function = GXnor; - break; - case QPainter::RasterOp_NotSourceOrNotDestination: - function = GXnand; - break; - case QPainter::RasterOp_NotSourceXorDestination: - function = GXequiv; - break; - case QPainter::RasterOp_NotSource: - function = GXcopyInverted; - break; - case QPainter::RasterOp_SourceAndNotDestination: - function = GXandReverse; - break; - case QPainter::RasterOp_NotSourceAndDestination: - function = GXandInverted; - break; - default: - function = GXcopy; - } - } -#if !defined(QT_NO_XRENDER) - else { - d->composition_mode = - qpainterOpToXrender(state.compositionMode()); - } -#endif - XSetFunction(X11->display, d->gc, function); - XSetFunction(X11->display, d->gc_brush, function); - } - d->decidePathFallback(); - d->decideCoordAdjust(); -} - -void QX11PaintEngine::updateRenderHints(QPainter::RenderHints hints) -{ - Q_D(QX11PaintEngine); - d->render_hints = hints; - -#if !defined(QT_NO_XRENDER) - if (X11->use_xrender && d->picture) { - XRenderPictureAttributes attrs; - attrs.poly_edge = (hints & QPainter::Antialiasing) ? PolyEdgeSmooth : PolyEdgeSharp; - XRenderChangePicture(d->dpy, d->picture, CPPolyEdge, &attrs); - } -#endif -} - -void QX11PaintEngine::updatePen(const QPen &pen) -{ - Q_D(QX11PaintEngine); - d->cpen = pen; - int cp = CapButt; - int jn = JoinMiter; - int ps = pen.style(); - - if (d->opacity < 1.0) { - QColor c = d->cpen.color(); - c.setAlpha(qRound(c.alpha()*d->opacity)); - d->cpen.setColor(c); - } - - d->has_pen = (ps != Qt::NoPen); - d->has_alpha_pen = (pen.color().alpha() != 255); - - switch (pen.capStyle()) { - case Qt::SquareCap: - cp = CapProjecting; - break; - case Qt::RoundCap: - cp = CapRound; - break; - case Qt::FlatCap: - default: - cp = CapButt; - break; - } - switch (pen.joinStyle()) { - case Qt::BevelJoin: - jn = JoinBevel; - break; - case Qt::RoundJoin: - jn = JoinRound; - break; - case Qt::MiterJoin: - default: - jn = JoinMiter; - break; - } - - d->adapted_pen_origin = false; - - char dashes[10]; // custom pen dashes - int dash_len = 0; // length of dash list - int xStyle = LineSolid; - - /* - We are emulating Windows here. Windows treats cpen.width() == 1 - (or 0) as a very special case. The fudge variable unifies this - case with the general case. - */ - qreal pen_width = pen.widthF(); - int scale = qRound(pen_width < 1 ? 1 : pen_width); - int space = (pen_width < 1 && pen_width > 0 ? 1 : (2 * scale)); - int dot = 1 * scale; - int dash = 4 * scale; - - d->has_custom_pen = false; - - switch (ps) { - case Qt::NoPen: - case Qt::SolidLine: - xStyle = LineSolid; - break; - case Qt::DashLine: - dashes[0] = dash; - dashes[1] = space; - dash_len = 2; - xStyle = LineOnOffDash; - break; - case Qt::DotLine: - dashes[0] = dot; - dashes[1] = space; - dash_len = 2; - xStyle = LineOnOffDash; - break; - case Qt::DashDotLine: - dashes[0] = dash; - dashes[1] = space; - dashes[2] = dot; - dashes[3] = space; - dash_len = 4; - xStyle = LineOnOffDash; - break; - case Qt::DashDotDotLine: - dashes[0] = dash; - dashes[1] = space; - dashes[2] = dot; - dashes[3] = space; - dashes[4] = dot; - dashes[5] = space; - dash_len = 6; - xStyle = LineOnOffDash; - break; - case Qt::CustomDashLine: - d->has_custom_pen = true; - break; - } - - ulong mask = GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth - | GCCapStyle | GCJoinStyle | GCLineStyle; - XGCValues vals; - vals.graphics_exposures = false; - if (d->pdev_depth == 1) { - vals.foreground = qGray(pen.color().rgb()) > 127 ? 0 : 1; - vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1; - } else if (d->pdev->devType() == QInternal::Pixmap && d->pdev_depth == 32 - && X11->use_xrender) { - vals.foreground = pen.color().rgba(); - vals.background = QColor(Qt::transparent).rgba(); - } else { - QColormap cmap = QColormap::instance(d->scrn); - vals.foreground = cmap.pixel(pen.color()); - vals.background = cmap.pixel(QColor(Qt::transparent)); - } - - - vals.line_width = qRound(pen.widthF()); - vals.cap_style = cp; - vals.join_style = jn; - vals.line_style = xStyle; - - XChangeGC(d->dpy, d->gc, mask, &vals); - - if (dash_len) { // make dash list - XSetDashes(d->dpy, d->gc, 0, dashes, dash_len); - } - - if (!d->has_clipping) { // if clipping is set the paintevent clip region is merged with the clip region - QRegion sysClip = systemClip(); - if (!sysClip.isEmpty()) - x11SetClipRegion(d->dpy, d->gc, 0, d->picture, sysClip); - else - x11ClearClipRegion(d->dpy, d->gc, 0, d->picture); - } -} - -void QX11PaintEngine::updateBrush(const QBrush &brush, const QPointF &origin) -{ - Q_D(QX11PaintEngine); - d->cbrush = brush; - d->bg_origin = origin; - d->adapted_brush_origin = false; -#if !defined(QT_NO_XRENDER) - d->current_brush = 0; -#endif - if (d->opacity < 1.0) { - QColor c = d->cbrush.color(); - c.setAlpha(qRound(c.alpha()*d->opacity)); - d->cbrush.setColor(c); - } - - int s = FillSolid; - int bs = d->cbrush.style(); - d->has_brush = (bs != Qt::NoBrush); - d->has_pattern = bs >= Qt::Dense1Pattern && bs <= Qt::DiagCrossPattern; - d->has_texture = bs == Qt::TexturePattern; - d->has_alpha_brush = brush.color().alpha() != 255; - d->has_alpha_texture = d->has_texture && d->cbrush.texture().hasAlphaChannel(); - - ulong mask = GCForeground | GCBackground | GCGraphicsExposures - | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle; - XGCValues vals; - vals.graphics_exposures = false; - if (d->pdev_depth == 1) { - vals.foreground = qGray(d->cbrush.color().rgb()) > 127 ? 0 : 1; - vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1; - } else if (X11->use_xrender && d->pdev->devType() == QInternal::Pixmap - && d->pdev_depth == 32) { - vals.foreground = d->cbrush.color().rgba(); - vals.background = QColor(Qt::transparent).rgba(); - } else { - QColormap cmap = QColormap::instance(d->scrn); - vals.foreground = cmap.pixel(d->cbrush.color()); - vals.background = cmap.pixel(QColor(Qt::transparent)); - - if (!X11->use_xrender && d->has_brush && !d->has_pattern && !brush.isOpaque()) { - QPixmap pattern = qt_patternForAlpha(brush.color().alpha(), d->scrn); - mask |= GCStipple; - vals.stipple = pattern.handle(); - s = FillStippled; - d->adapted_brush_origin = true; - } - } - vals.cap_style = CapButt; - vals.join_style = JoinMiter; - vals.line_style = LineSolid; - - if (d->has_pattern || d->has_texture) { - if (bs == Qt::TexturePattern) { - d->brush_pm = qt_toX11Pixmap(d->cbrush.texture()); -#if !defined(QT_NO_XRENDER) - if (X11->use_xrender) { - XRenderPictureAttributes attrs; - attrs.repeat = true; - XRenderChangePicture(d->dpy, d->brush_pm.x11PictureHandle(), CPRepeat, &attrs); - QX11PixmapData *data = static_cast<QX11PixmapData*>(d->brush_pm.data.data()); - if (data->mask_picture) - XRenderChangePicture(d->dpy, data->mask_picture, CPRepeat, &attrs); - } -#endif - } else { - d->brush_pm = qt_toX11Pixmap(qt_pixmapForBrush(bs, true)); - } - d->brush_pm.x11SetScreen(d->scrn); - if (d->brush_pm.depth() == 1) { - mask |= GCStipple; - vals.stipple = d->brush_pm.handle(); - s = FillStippled; -#if !defined(QT_NO_XRENDER) - if (X11->use_xrender) { - d->bitmap_texture = QPixmap(d->brush_pm.size()); - d->bitmap_texture.fill(Qt::transparent); - d->bitmap_texture = qt_toX11Pixmap(d->bitmap_texture); - d->bitmap_texture.x11SetScreen(d->scrn); - - ::Picture src = X11->getSolidFill(d->scrn, d->cbrush.color()); - XRenderComposite(d->dpy, PictOpSrc, src, d->brush_pm.x11PictureHandle(), - d->bitmap_texture.x11PictureHandle(), - 0, 0, d->brush_pm.width(), d->brush_pm.height(), - 0, 0, d->brush_pm.width(), d->brush_pm.height()); - - XRenderPictureAttributes attrs; - attrs.repeat = true; - XRenderChangePicture(d->dpy, d->bitmap_texture.x11PictureHandle(), CPRepeat, &attrs); - - d->current_brush = d->bitmap_texture.x11PictureHandle(); - } -#endif - } else { - mask |= GCTile; -#ifndef QT_NO_XRENDER - if (d->pdev_depth == 32 && d->brush_pm.depth() != 32) { - d->brush_pm.detach(); - QX11PixmapData *brushData = static_cast<QX11PixmapData*>(d->brush_pm.data.data()); - brushData->convertToARGB32(); - } -#endif - vals.tile = (d->brush_pm.depth() == d->pdev_depth - ? d->brush_pm.handle() - : static_cast<QX11PixmapData*>(d->brush_pm.data.data())->x11ConvertToDefaultDepth()); - s = FillTiled; -#if !defined(QT_NO_XRENDER) - d->current_brush = d->cbrush.texture().x11PictureHandle(); -#endif - } - - mask |= GCTileStipXOrigin | GCTileStipYOrigin; - vals.ts_x_origin = qRound(origin.x()); - vals.ts_y_origin = qRound(origin.y()); - } -#if !defined(QT_NO_XRENDER) - else if (d->has_alpha_brush) { - d->current_brush = X11->getSolidFill(d->scrn, d->cbrush.color()); - } -#endif - - vals.fill_style = s; - XChangeGC(d->dpy, d->gc_brush, mask, &vals); - if (!d->has_clipping) { - QRegion sysClip = systemClip(); - if (!sysClip.isEmpty()) - x11SetClipRegion(d->dpy, d->gc_brush, 0, d->picture, sysClip); - else - x11ClearClipRegion(d->dpy, d->gc_brush, 0, d->picture); - } -} - -void QX11PaintEngine::drawEllipse(const QRectF &rect) -{ - QRect aligned = rect.toAlignedRect(); - if (aligned == rect) - drawEllipse(aligned); - else - QPaintEngine::drawEllipse(rect); -} - -void QX11PaintEngine::drawEllipse(const QRect &rect) -{ - if (rect.isEmpty()) { - drawRects(&rect, 1); - return; - } - - Q_D(QX11PaintEngine); - QRect devclip(SHRT_MIN, SHRT_MIN, SHRT_MAX*2 - 1, SHRT_MAX*2 - 1); - QRect r(rect); - if (d->txop < QTransform::TxRotate) { - r = d->matrix.mapRect(rect); - } else if (d->txop == QTransform::TxRotate && rect.width() == rect.height()) { - QPainterPath path; - path.addEllipse(rect); - r = d->matrix.map(path).boundingRect().toRect(); - } - - if (d->has_alpha_brush || d->has_alpha_pen || d->has_custom_pen || (d->render_hints & QPainter::Antialiasing) - || d->has_alpha_texture || devclip.intersected(r) != r - || (d->has_complex_xform - && !(d->has_non_scaling_xform && rect.width() == rect.height()))) - { - QPainterPath path; - path.addEllipse(rect); - drawPath(path); - return; - } - - int x = r.x(); - int y = r.y(); - int w = r.width(); - int h = r.height(); - if (w < 1 || h < 1) - return; - if (w == 1 && h == 1) { - XDrawPoint(d->dpy, d->hd, d->has_pen ? d->gc : d->gc_brush, x, y); - return; - } - d->setupAdaptedOrigin(rect.topLeft()); - if (d->has_brush) { // draw filled ellipse - XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64); - if (!d->has_pen) // make smoother outline - XDrawArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64); - } - if (d->has_pen) // draw outline - XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64); - d->resetAdaptedOrigin(); -} - - - -void QX11PaintEnginePrivate::fillPolygon_translated(const QPointF *polygonPoints, int pointCount, - QX11PaintEnginePrivate::GCMode gcMode, - QPaintEngine::PolygonDrawMode mode) -{ - - QVarLengthArray<QPointF> translated_points(pointCount); - QPointF offset(matrix.dx(), matrix.dy()); - - qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0; - if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing)) - offset += QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta); - - for (int i = 0; i < pointCount; ++i) { - translated_points[i] = polygonPoints[i] + offset; - - translated_points[i].rx() = qRound(translated_points[i].x()) + offs; - translated_points[i].ry() = qRound(translated_points[i].y()) + offs; - } - - fillPolygon_dev(translated_points.data(), pointCount, gcMode, mode); -} - -#ifndef QT_NO_XRENDER -static void qt_XRenderCompositeTrapezoids(Display *dpy, - int op, - Picture src, - Picture dst, - _Xconst XRenderPictFormat *maskFormat, - int xSrc, - int ySrc, - const XTrapezoid *traps, int size) -{ - const int MAX_TRAPS = 50000; - while (size) { - int to_draw = size; - if (to_draw > MAX_TRAPS) - to_draw = MAX_TRAPS; - XRenderCompositeTrapezoids(dpy, op, src, dst, - maskFormat, - xSrc, ySrc, - traps, to_draw); - size -= to_draw; - traps += to_draw; - } -} -#endif - -void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount, - QX11PaintEnginePrivate::GCMode gcMode, - QPaintEngine::PolygonDrawMode mode) -{ - Q_Q(QX11PaintEngine); - - int clippedCount = 0; - qt_float_point *clippedPoints = 0; - -#ifndef QT_NO_XRENDER - //can change if we switch to pen if gcMode != BrushGC - bool has_fill_texture = has_texture; - bool has_fill_pattern = has_pattern; - ::Picture src; -#endif - QBrush fill; - GC fill_gc; - if (gcMode == BrushGC) { - fill = cbrush; - fill_gc = gc_brush; -#ifndef QT_NO_XRENDER - if (current_brush) - src = current_brush; - else - src = X11->getSolidFill(scrn, fill.color()); -#endif - } else { - fill = QBrush(cpen.brush()); - fill_gc = gc; -#ifndef QT_NO_XRENDER - //we use the pens brush - has_fill_texture = (fill.style() == Qt::TexturePattern); - has_fill_pattern = (fill.style() >= Qt::Dense1Pattern && fill.style() <= Qt::DiagCrossPattern); - if (has_fill_texture) - src = fill.texture().x11PictureHandle(); - else if (has_fill_pattern) - src = getPatternFill(scrn, fill); - else - src = X11->getSolidFill(scrn, fill.color()); -#endif - } - - polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount, - &clippedPoints, &clippedCount); - -#ifndef QT_NO_XRENDER - bool solid_fill = fill.color().alpha() == 255; - if (has_fill_texture && fill.texture().depth() == 1 && solid_fill) { - has_fill_texture = false; - has_fill_pattern = true; - } - - bool antialias = render_hints & QPainter::Antialiasing; - - if (X11->use_xrender - && picture - && !has_fill_pattern - && (clippedCount > 0) - && (fill.style() != Qt::NoBrush) - && ((has_fill_texture && fill.texture().hasAlpha()) || antialias || !solid_fill || has_alpha_pen != has_alpha_brush)) - { - if (tessellator->size > 0) { - XRenderPictureAttributes attrs; - attrs.poly_edge = antialias ? PolyEdgeSmooth : PolyEdgeSharp; - XRenderChangePicture(dpy, picture, CPPolyEdge, &attrs); - int x_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.x) - bg_origin.x()); - int y_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.y) - bg_origin.y()); - qt_XRenderCompositeTrapezoids(dpy, composition_mode, src, picture, - antialias - ? XRenderFindStandardFormat(dpy, PictStandardA8) - : XRenderFindStandardFormat(dpy, PictStandardA1), - x_offset, y_offset, - tessellator->traps, tessellator->size); - tessellator->done(); - } - } else -#endif - if (fill.style() != Qt::NoBrush) { - if (clippedCount > 200000) { - QPolygon poly; - for (int i = 0; i < clippedCount; ++i) - poly << QPoint(qFloor(clippedPoints[i].x), qFloor(clippedPoints[i].y)); - - const QRect bounds = poly.boundingRect(); - const QRect aligned = bounds - & QRect(QPoint(), QSize(pdev->width(), pdev->height())); - - QImage img(aligned.size(), QImage::Format_ARGB32_Premultiplied); - img.fill(0); - - QPainter painter(&img); - painter.translate(-aligned.x(), -aligned.y()); - painter.setPen(Qt::NoPen); - painter.setBrush(fill); - if (gcMode == BrushGC) - painter.setBrushOrigin(q->painter()->brushOrigin()); - painter.drawPolygon(poly); - painter.end(); - - q->drawImage(aligned, img, img.rect(), Qt::AutoColor); - } else if (clippedCount > 0) { - QVarLengthArray<XPoint> xpoints(clippedCount); - for (int i = 0; i < clippedCount; ++i) { - xpoints[i].x = qFloor(clippedPoints[i].x); - xpoints[i].y = qFloor(clippedPoints[i].y); - } - if (mode == QPaintEngine::WindingMode) - XSetFillRule(dpy, fill_gc, WindingRule); - setupAdaptedOrigin(QPoint(xpoints[0].x, xpoints[0].y)); - XFillPolygon(dpy, hd, fill_gc, - xpoints.data(), clippedCount, - mode == QPaintEngine::ConvexMode ? Convex : Complex, CoordModeOrigin); - resetAdaptedOrigin(); - if (mode == QPaintEngine::WindingMode) - XSetFillRule(dpy, fill_gc, EvenOddRule); - } - } -} - -void QX11PaintEnginePrivate::strokePolygon_translated(const QPointF *polygonPoints, int pointCount, bool close) -{ - QVarLengthArray<QPointF> translated_points(pointCount); - QPointF offset(matrix.dx(), matrix.dy()); - for (int i = 0; i < pointCount; ++i) - translated_points[i] = polygonPoints[i] + offset; - strokePolygon_dev(translated_points.data(), pointCount, close); -} - -void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int pointCount, bool close) -{ - int clippedCount = 0; - qt_float_point *clippedPoints = 0; - polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount, - &clippedPoints, &clippedCount, close); - - if (clippedCount > 0) { - QVarLengthArray<XPoint> xpoints(clippedCount); - for (int i = 0; i < clippedCount; ++i) { - xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta); - xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta); - } - uint numberPoints = qMin(clippedCount, xlibMaxLinePoints); - XPoint *pts = xpoints.data(); - XDrawLines(dpy, hd, gc, pts, numberPoints, CoordModeOrigin); - pts += numberPoints; - clippedCount -= numberPoints; - numberPoints = qMin(clippedCount, xlibMaxLinePoints-1); - while (clippedCount) { - XDrawLines(dpy, hd, gc, pts-1, numberPoints+1, CoordModeOrigin); - pts += numberPoints; - clippedCount -= numberPoints; - numberPoints = qMin(clippedCount, xlibMaxLinePoints-1); - } - } -} - -void QX11PaintEngine::drawPolygon(const QPointF *polygonPoints, int pointCount, PolygonDrawMode mode) -{ - Q_D(QX11PaintEngine); - if (d->use_path_fallback) { - QPainterPath path(polygonPoints[0]); - for (int i = 1; i < pointCount; ++i) - path.lineTo(polygonPoints[i]); - if (mode == PolylineMode) { - QBrush oldBrush = d->cbrush; - d->cbrush = QBrush(Qt::NoBrush); - path.setFillRule(Qt::WindingFill); - drawPath(path); - d->cbrush = oldBrush; - } else { - path.setFillRule(mode == OddEvenMode ? Qt::OddEvenFill : Qt::WindingFill); - path.closeSubpath(); - drawPath(path); - } - return; - } - if (mode != PolylineMode && d->has_brush) - d->fillPolygon_translated(polygonPoints, pointCount, QX11PaintEnginePrivate::BrushGC, mode); - - if (d->has_pen) - d->strokePolygon_translated(polygonPoints, pointCount, mode != PolylineMode); -} - - -void QX11PaintEnginePrivate::fillPath(const QPainterPath &path, QX11PaintEnginePrivate::GCMode gc_mode, bool transform) -{ - qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0; - - QPainterPath clippedPath; - QPainterPath clipPath; - clipPath.addRect(polygonClipper.boundingRect()); - - if (transform) - clippedPath = (path*matrix).intersected(clipPath); - else - clippedPath = path.intersected(clipPath); - - QList<QPolygonF> polys = clippedPath.toFillPolygons(); - for (int i = 0; i < polys.size(); ++i) { - QVarLengthArray<QPointF> translated_points(polys.at(i).size()); - - for (int j = 0; j < polys.at(i).size(); ++j) { - translated_points[j] = polys.at(i).at(j); - if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing)) { - translated_points[j].rx() = qRound(translated_points[j].rx() + aliasedCoordinateDelta) + offs; - translated_points[j].ry() = qRound(translated_points[j].ry() + aliasedCoordinateDelta) + offs; - } - } - - fillPolygon_dev(translated_points.data(), polys.at(i).size(), gc_mode, - path.fillRule() == Qt::OddEvenFill ? QPaintEngine::OddEvenMode : QPaintEngine::WindingMode); - } -} - -void QX11PaintEngine::drawPath(const QPainterPath &path) -{ - Q_D(QX11PaintEngine); - if (path.isEmpty()) - return; - - if (d->has_brush) - d->fillPath(path, QX11PaintEnginePrivate::BrushGC, true); - if (d->has_pen - && ((X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing))) - || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate - && !d->has_non_scaling_xform) - || (d->cpen.style() == Qt::CustomDashLine))) { - QPainterPathStroker stroker; - if (d->cpen.style() == Qt::CustomDashLine) { - stroker.setDashPattern(d->cpen.dashPattern()); - stroker.setDashOffset(d->cpen.dashOffset()); - } else { - stroker.setDashPattern(d->cpen.style()); - } - stroker.setCapStyle(d->cpen.capStyle()); - stroker.setJoinStyle(d->cpen.joinStyle()); - QPainterPath stroke; - qreal width = d->cpen.widthF(); - QPolygonF poly; - QRectF deviceRect(0, 0, d->pdev->width(), d->pdev->height()); - // necessary to get aliased alphablended primitives to be drawn correctly - if (d->cpen.isCosmetic() || d->has_scaling_xform) { - if (d->cpen.isCosmetic()) - stroker.setWidth(width == 0 ? 1 : width); - else - stroker.setWidth(width * d->xform_scale); - stroker.d_ptr->stroker.setClipRect(deviceRect); - stroke = stroker.createStroke(path * d->matrix); - if (stroke.isEmpty()) - return; - stroke.setFillRule(Qt::WindingFill); - d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, false); - } else { - stroker.setWidth(width); - stroker.d_ptr->stroker.setClipRect(d->matrix.inverted().mapRect(deviceRect)); - stroke = stroker.createStroke(path); - if (stroke.isEmpty()) - return; - stroke.setFillRule(Qt::WindingFill); - d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, true); - } - } else if (d->has_pen) { - // if we have a cosmetic pen - use XDrawLine() for speed - QList<QPolygonF> polys = path.toSubpathPolygons(d->matrix); - for (int i = 0; i < polys.size(); ++i) - d->strokePolygon_dev(polys.at(i).data(), polys.at(i).size(), false); - } -} - -Q_GUI_EXPORT void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image, - Drawable hd, GC gc, Display *dpy, Visual *visual, int depth) -{ - Q_ASSERT(image.format() == QImage::Format_RGB32); - Q_ASSERT(image.depth() == 32); - - XImage *xi; - // Note: this code assumes either RGB or BGR, 8 bpc server layouts - const uint red_mask = (uint) visual->red_mask; - bool bgr_layout = (red_mask == 0xff); - - const int w = rect.width(); - const int h = rect.height(); - - QImage im; - int image_byte_order = ImageByteOrder(X11->display); - if ((QSysInfo::ByteOrder == QSysInfo::BigEndian && ((image_byte_order == LSBFirst) || bgr_layout)) - || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian) - || (image_byte_order == LSBFirst && bgr_layout)) - { - im = image.copy(rect); - const int iw = im.bytesPerLine() / 4; - uint *data = (uint *)im.bits(); - for (int i=0; i < h; i++) { - uint *p = data; - uint *end = p + w; - if (bgr_layout && image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian) { - while (p < end) { - *p = ((*p << 8) & 0xffffff00) | ((*p >> 24) & 0x000000ff); - p++; - } - } else if ((image_byte_order == LSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian) - || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) { - while (p < end) { - *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000) - | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff); - p++; - } - } else if ((image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian) - || (image_byte_order == LSBFirst && bgr_layout)) - { - while (p < end) { - *p = ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff) - | ((*p ) & 0xff00ff00); - p++; - } - } - data += iw; - } - xi = XCreateImage(dpy, visual, depth, ZPixmap, - 0, (char *) im.bits(), w, h, 32, im.bytesPerLine()); - } else { - xi = XCreateImage(dpy, visual, depth, ZPixmap, - 0, (char *) image.scanLine(rect.y())+rect.x()*sizeof(uint), w, h, 32, image.bytesPerLine()); - } - XPutImage(dpy, hd, gc, xi, 0, 0, pos.x(), pos.y(), w, h); - xi->data = 0; // QImage owns these bits - XDestroyImage(xi); -} - -void QX11PaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags) -{ - Q_D(QX11PaintEngine); - - if (image.format() == QImage::Format_RGB32 - && d->pdev_depth >= 24 && image.depth() == 32 - && r.size() == sr.size()) - { - int sx = qRound(sr.x()); - int sy = qRound(sr.y()); - int x = qRound(r.x()); - int y = qRound(r.y()); - int w = qRound(r.width()); - int h = qRound(r.height()); - - qt_x11_drawImage(QRect(sx, sy, w, h), QPoint(x, y), image, d->hd, d->gc, d->dpy, - (Visual *)d->xinfo->visual(), d->pdev_depth); - } else { - QPaintEngine::drawImage(r, image, sr, flags); - } -} - -void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRectF &_sr) -{ - Q_D(QX11PaintEngine); - QRectF sr = _sr; - int x = qRound(r.x()); - int y = qRound(r.y()); - int sx = qRound(sr.x()); - int sy = qRound(sr.y()); - int sw = qRound(sr.width()); - int sh = qRound(sr.height()); - - QPixmap pixmap = qt_toX11Pixmap(px); - if(pixmap.isNull()) - return; - - if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen()) - || (pixmap.x11Info().screen() != DefaultScreen(X11->display))) { - QPixmap* p = const_cast<QPixmap *>(&pixmap); - p->x11SetScreen(d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display)); - } - - QPixmap::x11SetDefaultScreen(pixmap.x11Info().screen()); - -#ifndef QT_NO_XRENDER - ::Picture src_pict = static_cast<QX11PixmapData*>(pixmap.data.data())->picture; - if (src_pict && d->picture) { - const int pDepth = pixmap.depth(); - if (pDepth == 1 && (d->has_alpha_pen)) { - qt_render_bitmap(d->dpy, d->scrn, src_pict, d->picture, - sx, sy, x, y, sw, sh, d->cpen); - return; - } else if (pDepth != 1 && (pDepth == 32 || pDepth != d->pdev_depth)) { - XRenderComposite(d->dpy, d->composition_mode, - src_pict, 0, d->picture, sx, sy, 0, 0, x, y, sw, sh); - return; - } - } -#endif - - bool mono_src = pixmap.depth() == 1; - bool mono_dst = d->pdev_depth == 1; - bool restore_clip = false; - - if (static_cast<QX11PixmapData*>(pixmap.data.data())->x11_mask) { // pixmap has a mask - QBitmap comb(sw, sh); - GC cgc = XCreateGC(d->dpy, comb.handle(), 0, 0); - XSetForeground(d->dpy, cgc, 0); - XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh); - XSetBackground(d->dpy, cgc, 0); - XSetForeground(d->dpy, cgc, 1); - if (!d->crgn.isEmpty()) { - int num; - XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num); - XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted); - } else if (d->has_clipping) { - XSetClipRectangles(d->dpy, cgc, 0, 0, 0, 0, Unsorted); - } - XSetFillStyle(d->dpy, cgc, FillOpaqueStippled); - XSetTSOrigin(d->dpy, cgc, -sx, -sy); - XSetStipple(d->dpy, cgc, - static_cast<QX11PixmapData*>(pixmap.data.data())->x11_mask); - XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh); - XFreeGC(d->dpy, cgc); - - XSetClipOrigin(d->dpy, d->gc, x, y); - XSetClipMask(d->dpy, d->gc, comb.handle()); - restore_clip = true; - } - - if (mono_src) { - if (!d->crgn.isEmpty()) { - Pixmap comb = XCreatePixmap(d->dpy, d->hd, sw, sh, 1); - GC cgc = XCreateGC(d->dpy, comb, 0, 0); - XSetForeground(d->dpy, cgc, 0); - XFillRectangle(d->dpy, comb, cgc, 0, 0, sw, sh); - int num; - XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num); - XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted); - XCopyArea(d->dpy, pixmap.handle(), comb, cgc, sx, sy, sw, sh, 0, 0); - XFreeGC(d->dpy, cgc); - - XSetClipMask(d->dpy, d->gc, comb); - XSetClipOrigin(d->dpy, d->gc, x, y); - XFreePixmap(d->dpy, comb); - } else { - XSetClipMask(d->dpy, d->gc, pixmap.handle()); - XSetClipOrigin(d->dpy, d->gc, x - sx, y - sy); - } - - if (mono_dst) { - XSetForeground(d->dpy, d->gc, qGray(d->cpen.color().rgb()) > 127 ? 0 : 1); - } else { - QColormap cmap = QColormap::instance(d->scrn); - XSetForeground(d->dpy, d->gc, cmap.pixel(d->cpen.color())); - } - XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh); - restore_clip = true; - } else if (mono_dst && !mono_src) { - QBitmap bitmap(pixmap); - XCopyArea(d->dpy, bitmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y); - } else { - XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y); - } - - if (d->pdev->devType() == QInternal::Pixmap) { - const QPixmap *px = static_cast<const QPixmap*>(d->pdev); - Pixmap src_mask = static_cast<QX11PixmapData*>(pixmap.data.data())->x11_mask; - Pixmap dst_mask = static_cast<QX11PixmapData*>(px->data.data())->x11_mask; - if (dst_mask) { - GC cgc = XCreateGC(d->dpy, dst_mask, 0, 0); - if (src_mask) { // copy src mask into dst mask - XCopyArea(d->dpy, src_mask, dst_mask, cgc, sx, sy, sw, sh, x, y); - } else { // no src mask, but make sure the area copied is opaque in dest - XSetBackground(d->dpy, cgc, 0); - XSetForeground(d->dpy, cgc, 1); - XFillRectangle(d->dpy, dst_mask, cgc, x, y, sw, sh); - } - XFreeGC(d->dpy, cgc); - } - } - - if (restore_clip) { - XSetClipOrigin(d->dpy, d->gc, 0, 0); - int num; - XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num); - if (num == 0) - XSetClipMask(d->dpy, d->gc, XNone); - else - XSetClipRectangles(d->dpy, d->gc, 0, 0, rects, num, Unsorted); - } -} - -void QX11PaintEngine::updateMatrix(const QTransform &mtx) -{ - Q_D(QX11PaintEngine); - d->txop = mtx.type(); - d->matrix = mtx; - - d->has_complex_xform = (d->txop > QTransform::TxTranslate); - - extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); - bool scaling = qt_scaleForTransform(d->matrix, &d->xform_scale); - d->has_scaling_xform = scaling && d->xform_scale != 1.0; - d->has_non_scaling_xform = scaling && d->xform_scale == 1.0; -} - -/* - NB! the clip region is expected to be in dev coordinates -*/ -void QX11PaintEngine::updateClipRegion_dev(const QRegion &clipRegion, Qt::ClipOperation op) -{ - Q_D(QX11PaintEngine); - QRegion sysClip = systemClip(); - if (op == Qt::NoClip) { - d->has_clipping = false; - d->crgn = sysClip; - if (!sysClip.isEmpty()) { - x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, sysClip); - } else { - x11ClearClipRegion(d->dpy, d->gc, d->gc_brush, d->picture); - } - return; - } - - switch (op) { - case Qt::IntersectClip: - if (d->has_clipping) { - d->crgn &= clipRegion; - break; - } - // fall through - case Qt::ReplaceClip: - if (!sysClip.isEmpty()) - d->crgn = clipRegion.intersected(sysClip); - else - d->crgn = clipRegion; - break; - default: - break; - } - d->has_clipping = true; - x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, d->crgn); -} - -void QX11PaintEngine::updateFont(const QFont &) -{ -} - -Qt::HANDLE QX11PaintEngine::handle() const -{ - Q_D(const QX11PaintEngine); - Q_ASSERT(isActive()); - Q_ASSERT(d->hd); - return d->hd; -} - -extern void qt_draw_tile(QPaintEngine *, qreal, qreal, qreal, qreal, const QPixmap &, - qreal, qreal); - -void QX11PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &p) -{ - int x = qRound(r.x()); - int y = qRound(r.y()); - int w = qRound(r.width()); - int h = qRound(r.height()); - int sx = qRound(p.x()); - int sy = qRound(p.y()); - - bool mono_src = pixmap.depth() == 1; - Q_D(QX11PaintEngine); - - if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen()) - || (pixmap.x11Info().screen() != DefaultScreen(X11->display))) { - QPixmap* p = const_cast<QPixmap *>(&pixmap); - p->x11SetScreen(d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display)); - } - - QPixmap::x11SetDefaultScreen(pixmap.x11Info().screen()); - -#ifndef QT_NO_XRENDER - if (X11->use_xrender && d->picture && pixmap.x11PictureHandle()) { -#if 0 - // ### Qt 5: enable this - XRenderPictureAttributes attrs; - attrs.repeat = true; - XRenderChangePicture(d->dpy, pixmap.x11PictureHandle(), CPRepeat, &attrs); - - if (mono_src) { - qt_render_bitmap(d->dpy, d->scrn, pixmap.x11PictureHandle(), d->picture, - sx, sy, x, y, w, h, d->cpen); - } else { - XRenderComposite(d->dpy, d->composition_mode, - pixmap.x11PictureHandle(), XNone, d->picture, - sx, sy, 0, 0, x, y, w, h); - } -#else - const int numTiles = (w / pixmap.width()) * (h / pixmap.height()); - if (numTiles < 100) { - // this is essentially qt_draw_tile(), inlined for - // the XRenderComposite call - int yPos, xPos, drawH, drawW, yOff, xOff; - yPos = y; - yOff = sy; - while(yPos < y + h) { - drawH = pixmap.height() - yOff; // Cropping first row - if (yPos + drawH > y + h) // Cropping last row - drawH = y + h - yPos; - xPos = x; - xOff = sx; - while(xPos < x + w) { - drawW = pixmap.width() - xOff; // Cropping first column - if (xPos + drawW > x + w) // Cropping last column - drawW = x + w - xPos; - if (mono_src) { - qt_render_bitmap(d->dpy, d->scrn, pixmap.x11PictureHandle(), d->picture, - xOff, yOff, xPos, yPos, drawW, drawH, d->cpen); - } else { - XRenderComposite(d->dpy, d->composition_mode, - pixmap.x11PictureHandle(), XNone, d->picture, - xOff, yOff, 0, 0, xPos, yPos, drawW, drawH); - } - xPos += drawW; - xOff = 0; - } - yPos += drawH; - yOff = 0; - } - } else { - w = qMin(w, d->pdev->width() - x); - h = qMin(h, d->pdev->height() - y); - if (w <= 0 || h <= 0) - return; - - const int pw = w + sx; - const int ph = h + sy; - QPixmap pm(pw, ph); - if (pixmap.hasAlpha() || mono_src) - pm.fill(Qt::transparent); - - const int mode = pixmap.hasAlpha() ? PictOpOver : PictOpSrc; - const ::Picture pmPicture = pm.x11PictureHandle(); - - // first tile - XRenderComposite(d->dpy, mode, - pixmap.x11PictureHandle(), XNone, pmPicture, - 0, 0, 0, 0, 0, 0, qMin(pw, pixmap.width()), qMin(ph, pixmap.height())); - - // first row of tiles - int xPos = pixmap.width(); - const int sh = qMin(ph, pixmap.height()); - while (xPos < pw) { - const int sw = qMin(xPos, pw - xPos); - XRenderComposite(d->dpy, mode, - pmPicture, XNone, pmPicture, - 0, 0, 0, 0, xPos, 0, sw, sh); - xPos *= 2; - } - - // remaining rows - int yPos = pixmap.height(); - const int sw = pw; - while (yPos < ph) { - const int sh = qMin(yPos, ph - yPos); - XRenderComposite(d->dpy, mode, - pmPicture, XNone, pmPicture, - 0, 0, 0, 0, 0, yPos, sw, sh); - yPos *= 2; - } - - // composite - if (mono_src) - qt_render_bitmap(d->dpy, d->scrn, pmPicture, d->picture, - sx, sy, x, y, w, h, d->cpen); - else - XRenderComposite(d->dpy, d->composition_mode, - pmPicture, XNone, d->picture, - sx, sy, 0, 0, x, y, w, h); - } -#endif - } else -#endif // !QT_NO_XRENDER - if (pixmap.depth() > 1 && !static_cast<QX11PixmapData*>(pixmap.data.data())->x11_mask) { - XSetTile(d->dpy, d->gc, pixmap.handle()); - XSetFillStyle(d->dpy, d->gc, FillTiled); - XSetTSOrigin(d->dpy, d->gc, x-sx, y-sy); - XFillRectangle(d->dpy, d->hd, d->gc, x, y, w, h); - XSetTSOrigin(d->dpy, d->gc, 0, 0); - XSetFillStyle(d->dpy, d->gc, FillSolid); - } else { - qt_draw_tile(this, x, y, w, h, pixmap, sx, sy); - } -} - -void QX11PaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) -{ - const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); - - switch(ti.fontEngine->type()) { - case QFontEngine::TestFontEngine: - case QFontEngine::Box: - d_func()->drawBoxTextItem(p, ti); - break; - case QFontEngine::XLFD: - drawXLFD(p, ti); - break; -#ifndef QT_NO_FONTCONFIG - case QFontEngine::Freetype: - drawFreetype(p, ti); - break; -#endif - default: - Q_ASSERT(false); - } -} - -void QX11PaintEngine::drawXLFD(const QPointF &p, const QTextItemInt &ti) -{ - Q_D(QX11PaintEngine); - - if (d->txop > QTransform::TxTranslate) { - // XServer or font don't support server side transformations, need to do it by hand - QPaintEngine::drawTextItem(p, ti); - return; - } - - if (!ti.glyphs.numGlyphs) - return; - - QVarLengthArray<QFixedPoint> positions; - QVarLengthArray<glyph_t> glyphs; - QTransform matrix = d->matrix; - matrix.translate(p.x(), p.y()); - ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); - if (glyphs.size() == 0) - return; - - QFontEngineXLFD *xlfd = static_cast<QFontEngineXLFD *>(ti.fontEngine); - Qt::HANDLE font_id = xlfd->fontStruct()->fid; - - XSetFont(d->dpy, d->gc, font_id); - - const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta); - for (int i = 0; i < glyphs.size(); i++) { - int xp = qRound(positions[i].x + offs); - int yp = qRound(positions[i].y + offs); - if (xp < SHRT_MAX && xp > SHRT_MIN && yp > SHRT_MIN && yp < SHRT_MAX) { - XChar2b ch; - ch.byte1 = glyphs[i] >> 8; - ch.byte2 = glyphs[i] & 0xff; - XDrawString16(d->dpy, d->hd, d->gc, xp, yp, &ch, 1); - } - } -} - -#ifndef QT_NO_FONTCONFIG -static QPainterPath path_for_glyphs(const QVarLengthArray<glyph_t> &glyphs, - const QVarLengthArray<QFixedPoint> &positions, - const QFontEngineFT *ft) -{ - QPainterPath path; - path.setFillRule(Qt::WindingFill); - ft->lockFace(); - int i = 0; - while (i < glyphs.size()) { - QFontEngineFT::Glyph *glyph = ft->loadGlyph(glyphs[i], QFontEngineFT::Format_Mono); - // #### fix case where we don't get a glyph - if (!glyph) - break; - - Q_ASSERT(glyph->format == QFontEngineFT::Format_Mono); - int n = 0; - int h = glyph->height; - int xp = qRound(positions[i].x); - int yp = qRound(positions[i].y); - - xp += glyph->x; - yp += -glyph->y + glyph->height; - int pitch = ((glyph->width + 31) & ~31) >> 3; - - uchar *src = glyph->data; - while (h--) { - for (int x = 0; x < glyph->width; ++x) { - bool set = src[x >> 3] & (0x80 >> (x & 7)); - if (set) { - QRect r(xp + x, yp - h, 1, 1); - while (x < glyph->width-1 && src[(x+1) >> 3] & (0x80 >> ((x+1) & 7))) { - ++x; - r.setRight(r.right()+1); - } - - path.addRect(r); - ++n; - } - } - src += pitch; - } - ++i; - } - ft->unlockFace(); - return path; -} - -void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti) -{ - Q_D(QX11PaintEngine); - if (!ti.glyphs.numGlyphs) - return; - - QFontEngineX11FT *ft = static_cast<QFontEngineX11FT *>(ti.fontEngine); - - if (!d->cpen.isSolid()) { - QPaintEngine::drawTextItem(p, ti); - return; - } - - const bool xrenderPath = (X11->use_xrender - && !(d->pdev->devType() == QInternal::Pixmap - && static_cast<const QPixmap *>(d->pdev)->data->pixelType() == QPixmapData::BitmapType)); - - QVarLengthArray<QFixedPoint> positions; - QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - - if (xrenderPath) - matrix = d->matrix; - matrix.translate(p.x(), p.y()); - ft->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); - if (glyphs.count() == 0) - return; - -#ifndef QT_NO_XRENDER - QFontEngineFT::QGlyphSet *set = ft->defaultGlyphs(); - if (d->txop >= QTransform::TxScale && xrenderPath) - set = ft->loadTransformedGlyphSet(d->matrix); - - if (!set || set->outline_drawing - || !ft->loadGlyphs(set, glyphs.constData(), glyphs.size(), positions.constData(), QFontEngineFT::Format_Render)) - { - QPaintEngine::drawTextItem(p, ti); - return; - } - - if (xrenderPath) { - GlyphSet glyphSet = set->id; - const QColor &pen = d->cpen.color(); - ::Picture src = X11->getSolidFill(d->scrn, pen); - XRenderPictFormat *maskFormat = 0; - if (ft->xglyph_format != PictStandardA1) - maskFormat = XRenderFindStandardFormat(X11->display, ft->xglyph_format); - - enum { t_min = SHRT_MIN, t_max = SHRT_MAX }; - - int i = 0; - for (; i < glyphs.size() - && (positions[i].x < t_min || positions[i].x > t_max - || positions[i].y < t_min || positions[i].y > t_max); - ++i) - ; - - if (i >= glyphs.size()) - return; - ++i; - - QFixed xp = positions[i - 1].x; - QFixed yp = positions[i - 1].y; - QFixed offs = QFixed::fromReal(aliasedCoordinateDelta); - - XGlyphElt32 elt; - elt.glyphset = glyphSet; - elt.chars = &glyphs[i - 1]; - elt.nchars = 1; - elt.xOff = qRound(xp + offs); - elt.yOff = qRound(yp + offs); - for (; i < glyphs.size(); ++i) { - if (positions[i].x < t_min || positions[i].x > t_max - || positions[i].y < t_min || positions[i].y > t_max) { - break; - } - QFontEngineFT::Glyph *g = ft->cachedGlyph(glyphs[i - 1]); - if (g - && positions[i].x == xp + g->advance - && positions[i].y == yp - && elt.nchars < 253 // don't draw more than 253 characters as some X servers - // hang with it - ) { - elt.nchars++; - xp += g->advance; - } else { - xp = positions[i].x; - yp = positions[i].y; - - XRenderCompositeText32(X11->display, PictOpOver, src, d->picture, - maskFormat, 0, 0, 0, 0, - &elt, 1); - elt.chars = &glyphs[i]; - elt.nchars = 1; - elt.xOff = qRound(xp + offs); - elt.yOff = qRound(yp + offs); - } - } - XRenderCompositeText32(X11->display, PictOpOver, src, d->picture, - maskFormat, 0, 0, 0, 0, - &elt, 1); - - return; - - } -#endif - - QPainterPath path = path_for_glyphs(glyphs, positions, ft); - if (path.elementCount() <= 1) - return; - Q_ASSERT((path.elementCount() % 5) == 0); - if (d->txop >= QTransform::TxScale) { - painter()->save(); - painter()->setBrush(d->cpen.brush()); - painter()->setPen(Qt::NoPen); - painter()->drawPath(path); - painter()->restore(); - return; - } - - const int rectcount = 256; - XRectangle rects[rectcount]; - int num_rects = 0; - - QPoint delta(qRound(d->matrix.dx()), qRound(d->matrix.dy())); - QRect clip(d->polygonClipper.boundingRect()); - for (int i=0; i < path.elementCount(); i+=5) { - int x = qRound(path.elementAt(i).x); - int y = qRound(path.elementAt(i).y); - int w = qRound(path.elementAt(i+1).x) - x; - int h = qRound(path.elementAt(i+2).y) - y; - - QRect rect = QRect(x + delta.x(), y + delta.y(), w, h); - rect = rect.intersected(clip); - if (rect.isEmpty()) - continue; - - rects[num_rects].x = short(rect.x()); - rects[num_rects].y = short(rect.y()); - rects[num_rects].width = ushort(rect.width()); - rects[num_rects].height = ushort(rect.height()); - ++num_rects; - if (num_rects == rectcount) { - XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects); - num_rects = 0; - } - } - if (num_rects > 0) - XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects); - -} -#endif // !QT_NO_XRENDER - -QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine_x11_p.h b/src/gui/painting/qpaintengine_x11_p.h deleted file mode 100644 index d8d8817993..0000000000 --- a/src/gui/painting/qpaintengine_x11_p.h +++ /dev/null @@ -1,246 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPAINTENGINE_X11_P_H -#define QPAINTENGINE_X11_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtGui/qpaintengine.h" -#include "QtGui/qregion.h" -#include "QtGui/qpen.h" -#include "QtCore/qpoint.h" -#include "private/qpaintengine_p.h" -#include "private/qpainter_p.h" -#include "private/qpolygonclipper_p.h" - -typedef unsigned long Picture; - -QT_BEGIN_NAMESPACE - -class QX11PaintEnginePrivate; -class QFontEngineFT; -class QXRenderTessellator; - -struct qt_float_point -{ - qreal x, y; -}; - -class QX11PaintEngine : public QPaintEngine -{ - Q_DECLARE_PRIVATE(QX11PaintEngine) -public: - QX11PaintEngine(); - ~QX11PaintEngine(); - - bool begin(QPaintDevice *pdev); - bool end(); - - void updateState(const QPaintEngineState &state); - - void updatePen(const QPen &pen); - void updateBrush(const QBrush &brush, const QPointF &pt); - void updateRenderHints(QPainter::RenderHints hints); - void updateFont(const QFont &font); - void updateMatrix(const QTransform &matrix); - void updateClipRegion_dev(const QRegion ®ion, Qt::ClipOperation op); - - void drawLines(const QLine *lines, int lineCount); - void drawLines(const QLineF *lines, int lineCount); - - void drawRects(const QRect *rects, int rectCount); - void drawRects(const QRectF *rects, int rectCount); - - void drawPoints(const QPoint *points, int pointCount); - void drawPoints(const QPointF *points, int pointCount); - - void drawEllipse(const QRect &r); - void drawEllipse(const QRectF &r); - - virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); - inline void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) - { QPaintEngine::drawPolygon(points, pointCount, mode); } - - void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); - void drawPath(const QPainterPath &path); - void drawTextItem(const QPointF &p, const QTextItem &textItem); - void drawImage(const QRectF &r, const QImage &img, const QRectF &sr, - Qt::ImageConversionFlags flags = Qt::AutoColor); - - virtual Qt::HANDLE handle() const; - inline Type type() const { return QPaintEngine::X11; } - - QPainter::RenderHints supportedRenderHints() const; - -protected: - QX11PaintEngine(QX11PaintEnginePrivate &dptr); - - void drawXLFD(const QPointF &p, const QTextItemInt &si); -#ifndef QT_NO_FONTCONFIG - void drawFreetype(const QPointF &p, const QTextItemInt &si); -#endif - - friend class QPixmap; - friend class QFontEngineBox; - friend Q_GUI_EXPORT GC qt_x11_get_pen_gc(QPainter *); - friend Q_GUI_EXPORT GC qt_x11_get_brush_gc(QPainter *); - -private: - Q_DISABLE_COPY(QX11PaintEngine) -}; - -class QX11PaintEnginePrivate : public QPaintEnginePrivate -{ - Q_DECLARE_PUBLIC(QX11PaintEngine) -public: - QX11PaintEnginePrivate() - { - scrn = -1; - hd = 0; - picture = 0; - gc = gc_brush = 0; - dpy = 0; - xinfo = 0; - txop = QTransform::TxNone; - has_clipping = false; - render_hints = 0; - xform_scale = 1; -#ifndef QT_NO_XRENDER - tessellator = 0; -#endif - } - enum GCMode { - PenGC, - BrushGC - }; - - void init(); - void fillPolygon_translated(const QPointF *points, int pointCount, GCMode gcMode, - QPaintEngine::PolygonDrawMode mode); - void fillPolygon_dev(const QPointF *points, int pointCount, GCMode gcMode, - QPaintEngine::PolygonDrawMode mode); - void fillPath(const QPainterPath &path, GCMode gcmode, bool transform); - void strokePolygon_dev(const QPointF *points, int pointCount, bool close); - void strokePolygon_translated(const QPointF *points, int pointCount, bool close); - void setupAdaptedOrigin(const QPoint &p); - void resetAdaptedOrigin(); - void decidePathFallback() { - use_path_fallback = has_alpha_brush - || has_alpha_pen - || has_custom_pen - || has_complex_xform - || (render_hints & QPainter::Antialiasing); - } - void decideCoordAdjust() { - adjust_coords = !(render_hints & QPainter::Antialiasing) - && (has_alpha_pen - || (has_alpha_brush && has_pen && !has_alpha_pen) - || (cpen.style() > Qt::SolidLine)); - } - void clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly); - void systemStateChanged(); - - Display *dpy; - int scrn; - int pdev_depth; - Qt::HANDLE hd; - QPixmap brush_pm; -#if !defined (QT_NO_XRENDER) - Qt::HANDLE picture; - Qt::HANDLE current_brush; - QPixmap bitmap_texture; - int composition_mode; -#else - Qt::HANDLE picture; -#endif - GC gc; - GC gc_brush; - - QPen cpen; - QBrush cbrush; - QRegion crgn; - QTransform matrix; - qreal opacity; - - uint has_complex_xform : 1; - uint has_scaling_xform : 1; - uint has_non_scaling_xform : 1; - uint has_custom_pen : 1; - uint use_path_fallback : 1; - uint adjust_coords : 1; - uint has_clipping : 1; - uint adapted_brush_origin : 1; - uint adapted_pen_origin : 1; - uint has_pen : 1; - uint has_brush : 1; - uint has_texture : 1; - uint has_alpha_texture : 1; - uint has_pattern : 1; - uint has_alpha_pen : 1; - uint has_alpha_brush : 1; - uint render_hints; - - const QX11Info *xinfo; - QPointF bg_origin; - QTransform::TransformationType txop; - qreal xform_scale; - QPolygonClipper<qt_float_point, qt_float_point, float> polygonClipper; - - int xlibMaxLinePoints; -#ifndef QT_NO_XRENDER - QXRenderTessellator *tessellator; -#endif -}; - -QT_END_NAMESPACE - -#endif // QPAINTENGINE_X11_P_H diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index c6056855f0..604a43133f 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -54,7 +54,6 @@ // #include <QtGui/qpaintengine.h> -#include <QtGui/qdrawutil.h> #include <private/qpaintengine_p.h> #include <private/qstroker_p.h> @@ -213,6 +212,7 @@ public: virtual void beginNativePainting() {} virtual void endNativePainting() {} + // ### Qt5: remove, once QtOpenGL is merged into QtGui and QtWidgets // Return a pixmap filter of "type" that can render the parameters // in "prototype". The returned filter is owned by the engine and // will be destroyed when the engine is destroyed. The "prototype" diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 686f2f023a..d5b9f97378 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -56,9 +56,6 @@ #include "qpixmapcache.h" #include "qpolygon.h" #include "qtextlayout.h" -#include "qwidget.h" -#include "qapplication.h" -#include "qstyle.h" #include "qthread.h" #include "qvarlengtharray.h" #include "qstatictext.h" @@ -69,12 +66,12 @@ #include <private/qemulationpaintengine_p.h> #include <private/qpainterpath_p.h> #include <private/qtextengine_p.h> -#include <private/qwidget_p.h> #include <private/qpaintengine_raster_p.h> #include <private/qmath_p.h> #include <private/qstatictext_p.h> #include <private/qglyphrun_p.h> -#include <private/qstylehelper_p.h> +#include <private/qhexstring_p.h> +#include <private/qguiapplication_p.h> #include <private/qrawfont_p.h> QT_BEGIN_NAMESPACE @@ -242,34 +239,10 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev) Q_ASSERT(q); Q_ASSERT(pdev); - if (pdev->devType() != QInternal::Widget) + QPainter *sp = pdev->sharedPainter(); + if (!sp) return false; - QWidget *widget = static_cast<QWidget *>(pdev); - Q_ASSERT(widget); - - // Someone either called QPainter::setRedirected in the widget's paint event - // right before this painter was created (or begin was called) or - // sent a paint event directly to the widget. - if (!widget->d_func()->redirectDev) - return false; - - QPainter *sp = widget->d_func()->sharedPainter(); - if (!sp || !sp->isActive()) - return false; - - if (sp->paintEngine()->paintDevice() != widget->d_func()->redirectDev) - return false; - - // Check if we're attempting to paint outside a paint event. - if (!sp->d_ptr->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent) - && !widget->testAttribute(Qt::WA_PaintOutsidePaintEvent) - && !widget->testAttribute(Qt::WA_WState_InPaintEvent)) { - - qWarning("QPainter::begin: Widget painting can only begin as a result of a paintEvent"); - return false; - } - // Save the current state of the shared painter and assign // the current d_ptr to the shared painter's d_ptr. sp->save(); @@ -293,14 +266,14 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev) Q_ASSERT(q->d_ptr->state); // Now initialize the painter with correct widget properties. - q->initFrom(widget); + q->initFrom(pdev); QPoint offset; - widget->d_func()->redirected(&offset); + pdev->redirected(&offset); offset += q->d_ptr->engine->coordinateOffset(); // Update system rect. - q->d_ptr->state->ww = q->d_ptr->state->vw = widget->width(); - q->d_ptr->state->wh = q->d_ptr->state->vh = widget->height(); + q->d_ptr->state->ww = q->d_ptr->state->vw = pdev->width(); + q->d_ptr->state->wh = q->d_ptr->state->vh = pdev->height(); // Update matrix. if (q->d_ptr->state->WxF) { @@ -314,13 +287,13 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev) q->d_ptr->updateMatrix(); QPaintEnginePrivate *enginePrivate = q->d_ptr->engine->d_func(); - if (enginePrivate->currentClipWidget == widget) { + if (enginePrivate->currentClipDevice == pdev) { enginePrivate->systemStateChanged(); return true; } // Update system transform and clip. - enginePrivate->currentClipWidget = widget; + enginePrivate->currentClipDevice = pdev; enginePrivate->setSystemTransform(q->d_ptr->state->matrix); return true; } @@ -1371,10 +1344,7 @@ void QPainterPrivate::updateState(QPainterState *newState) only use the format types QImage::Format_ARGB32_Premultiplied, QImage::Format_RGB32 or QImage::Format_RGB16. Any other format, including QImage::Format_ARGB32, has significantly worse - performance. This engine is also used by default on Windows and on - QWS. It can be used as default graphics system on any - OS/hardware/software combination by passing \c {-graphicssystem - raster} on the command line + performance. This engine is used by default for QWidget and QPixmap. \o OpenGL 2.0 (ES) - This backend is the primary backend for hardware accelerated graphics. It can be run on desktop machines @@ -1542,8 +1512,8 @@ QPainter::~QPainter() QPaintDevice *QPainter::device() const { Q_D(const QPainter); - if (isActive() && d->engine->d_func()->currentClipWidget) - return d->engine->d_func()->currentClipWidget; + if (isActive() && d->engine->d_func()->currentClipDevice) + return d->engine->d_func()->currentClipDevice; return d->original_device; } @@ -1562,25 +1532,23 @@ bool QPainter::isActive() const /*! Initializes the painters pen, background and font to the same as - the given \a widget. This function is called automatically when the - painter is opened on a QWidget. + the given \a paint device. + + \obsolete \sa begin(), {QPainter#Settings}{Settings} */ -void QPainter::initFrom(const QWidget *widget) +void QPainter::initFrom(const QPaintDevice *device) { - Q_ASSERT_X(widget, "QPainter::initFrom(const QWidget *widget)", "Widget cannot be 0"); + Q_ASSERT_X(device, "QPainter::initFrom(const QPaintDevice *device)", "QPaintDevice cannot be 0"); Q_D(QPainter); if (!d->engine) { qWarning("QPainter::initFrom: Painter not active, aborted"); return; } - const QPalette &pal = widget->palette(); - d->state->pen = QPen(pal.brush(widget->foregroundRole()), 0); - d->state->bgBrush = pal.brush(widget->backgroundRole()); - d->state->deviceFont = QFont(widget->font(), const_cast<QWidget*> (widget)); - d->state->font = d->state->deviceFont; + device->init(this); + if (d->extended) { d->extended->penChanged(); } else if (d->engine) { @@ -1753,22 +1721,9 @@ bool QPainter::begin(QPaintDevice *pd) d->helper_device = pd; d->original_device = pd; - QPaintDevice *rpd = 0; QPoint redirectionOffset; - // We know for sure that redirection is broken when the widget is inside - // its paint event, so it's safe to use our hard-coded redirection. However, - // there IS one particular case we still need to support, and that's - // when people call QPainter::setRedirected in the widget's paint event right - // before any painter is created (or QPainter::begin is called). In that - // particular case our hard-coded redirection is restored and the redirection - // is retrieved from QPainter::redirected (as before). - if (pd->devType() == QInternal::Widget) - rpd = static_cast<QWidget *>(pd)->d_func()->redirected(&redirectionOffset); - - if (!rpd) - rpd = redirected(pd, &redirectionOffset); - + QPaintDevice *rpd = pd->redirected(&redirectionOffset); if (rpd) pd = rpd; @@ -1811,6 +1766,8 @@ bool QPainter::begin(QPaintDevice *pd) d->engine->state = d->state; switch (pd->devType()) { +#if 0 + // is this needed any more?? case QInternal::Widget: { const QWidget *widget = static_cast<const QWidget *>(pd); @@ -1818,13 +1775,6 @@ bool QPainter::begin(QPaintDevice *pd) const bool paintOutsidePaintEvent = widget->testAttribute(Qt::WA_PaintOutsidePaintEvent); const bool inPaintEvent = widget->testAttribute(Qt::WA_WState_InPaintEvent); - if(!d->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent) - && !paintOutsidePaintEvent && !inPaintEvent) { - qWarning("QPainter::begin: Widget painting can only begin as a " - "result of a paintEvent"); - qt_cleanup_painter_state(d); - return false; - } // Adjust offset for alien widgets painting outside the paint event. if (!inPaintEvent && paintOutsidePaintEvent && !widget->internalWinId() @@ -1834,6 +1784,7 @@ bool QPainter::begin(QPaintDevice *pd) } break; } +#endif case QInternal::Pixmap: { QPixmap *pm = static_cast<QPixmap *>(pd); @@ -1894,8 +1845,7 @@ bool QPainter::begin(QPaintDevice *pd) // Copy painter properties from original paint device, // required for QPixmap::grabWidget() if (d->original_device->devType() == QInternal::Widget) { - QWidget *widget = static_cast<QWidget *>(d->original_device); - initFrom(widget); + initFrom(d->original_device); } else { d->state->layoutDirection = Qt::LayoutDirectionAuto; // make sure we have a font compatible with the paintdevice @@ -4597,82 +4547,6 @@ void QPainter::drawChord(const QRectF &r, int a, int alen) startAngle and \a spanAngle. */ -#ifdef QT3_SUPPORT -/*! - \fn void QPainter::drawLineSegments(const QPolygon &polygon, int - index, int count) - - Draws \a count separate lines from points defined by the \a - polygon, starting at \a{polygon}\e{[index]} (\a index defaults to - 0). If \a count is -1 (the default) all points until the end of - the array are used. - - Use drawLines() combined with QPolygon::constData() instead. - - \oldcode - QPainter painter(this); - painter.drawLineSegments(polygon, index, count); - \newcode - int lineCount = (count == -1) ? (polygon.size() - index) / 2 : count; - - QPainter painter(this); - painter.drawLines(polygon.constData() + index * 2, lineCount); - \endcode -*/ - -void QPainter::drawLineSegments(const QPolygon &a, int index, int nlines) -{ -#ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) - printf("QPainter::drawLineSegments(), count=%d\n", a.size()/2); -#endif - Q_D(QPainter); - - if (!d->engine) - return; - - if (nlines < 0) - nlines = a.size()/2 - index/2; - if (index + nlines*2 > (int)a.size()) - nlines = (a.size() - index)/2; - if (nlines < 1 || index < 0) - return; - - if (d->extended) { - // FALCON: Use QVectorPath - QVector<QLineF> lines; - for (int i=index; i<index + nlines*2; i+=2) - lines << QLineF(a.at(i), a.at(i+1)); - d->extended->drawLines(lines.data(), lines.size()); - return; - } - - d->updateState(d->state); - - QVector<QLineF> lines; - if (d->state->emulationSpecifier) { - if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform - && d->state->matrix.type() == QTransform::TxTranslate) { - QPointF offset(d->state->matrix.dx(), d->state->matrix.dy()); - for (int i=index; i<index + nlines*2; i+=2) - lines << QLineF(a.at(i) + offset, a.at(i+1) + offset); - } else { - QPainterPath linesPath; - for (int i=index; i<index + nlines*2; i+=2) { - linesPath.moveTo(a.at(i)); - linesPath.lineTo(a.at(i+1)); - } - d->draw_helper(linesPath, QPainterPrivate::StrokeDraw); - return; - } - } else { - for (int i=index; i<index + nlines*2; i+=2) - lines << QLineF(a.at(i), a.at(i+1)); - } - - d->engine->drawLines(lines.data(), lines.size()); -} -#endif // QT3_SUPPORT /*! Draws the first \a lineCount lines in the array \a lines @@ -6458,7 +6332,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const const qreal underlinePos = pos.y() + qCeil(underlineOffset) - aliasedCoordinateDelta; if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { - underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); + underlineStyle = QTextCharFormat::SpellCheckUnderline; // ### Qt5 QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); } if (underlineStyle == QTextCharFormat::WaveUnderline) { @@ -7509,328 +7383,6 @@ void QPainter::setViewTransformEnabled(bool enable) d->updateMatrix(); } -#ifdef QT3_SUPPORT - -/*! - \obsolete - - Use the worldTransform() combined with QTransform::dx() instead. - - \oldcode - QPainter painter(this); - qreal x = painter.translationX(); - \newcode - QPainter painter(this); - qreal x = painter.worldTransform().dx(); - \endcode -*/ -qreal QPainter::translationX() const -{ - Q_D(const QPainter); - if (!d->engine) { - qWarning("QPainter::translationX: Painter not active"); - return 0.0; - } - return d->state->worldMatrix.dx(); -} - -/*! - \obsolete - - Use the worldTransform() combined with QTransform::dy() instead. - - \oldcode - QPainter painter(this); - qreal y = painter.translationY(); - \newcode - QPainter painter(this); - qreal y = painter.worldTransform().dy(); - \endcode -*/ -qreal QPainter::translationY() const -{ - Q_D(const QPainter); - if (!d->engine) { - qWarning("QPainter::translationY: Painter not active"); - return 0.0; - } - return d->state->worldMatrix.dy(); -} - -/*! - \fn void QPainter::map(int x, int y, int *rx, int *ry) const - - \internal - - Sets (\a{rx}, \a{ry}) to the point that results from applying the - painter's current transformation on the point (\a{x}, \a{y}). -*/ -void QPainter::map(int x, int y, int *rx, int *ry) const -{ - QPoint p(x, y); - p = p * combinedMatrix(); - *rx = p.x(); - *ry = p.y(); -} - -/*! - \fn QPoint QPainter::xForm(const QPoint &point) const - - Use combinedTransform() instead. -*/ - -QPoint QPainter::xForm(const QPoint &p) const -{ - Q_D(const QPainter); - if (!d->engine) { - qWarning("QPainter::xForm: Painter not active"); - return QPoint(); - } - if (d->state->matrix.type() == QTransform::TxNone) - return p; - return p * combinedMatrix(); -} - - -/*! - \fn QRect QPainter::xForm(const QRect &rectangle) const - \overload - - Use combinedTransform() instead of this function and call - mapRect() on the result to obtain a QRect. -*/ - -QRect QPainter::xForm(const QRect &r) const -{ - Q_D(const QPainter); - if (!d->engine) { - qWarning("QPainter::xForm: Painter not active"); - return QRect(); - } - if (d->state->matrix.type() == QTransform::TxNone) - return r; - return combinedMatrix().mapRect(r); -} - -/*! - \fn QPolygon QPainter::xForm(const QPolygon &polygon) const - \overload - - Use combinedTransform() instead. -*/ - -QPolygon QPainter::xForm(const QPolygon &a) const -{ - Q_D(const QPainter); - if (!d->engine) { - qWarning("QPainter::xForm: Painter not active"); - return QPolygon(); - } - if (d->state->matrix.type() == QTransform::TxNone) - return a; - return a * combinedMatrix(); -} - -/*! - \fn QPolygon QPainter::xForm(const QPolygon &polygon, int index, int count) const - \overload - - Use combinedTransform() combined with QPolygon::mid() instead. - - \oldcode - QPainter painter(this); - QPolygon transformed = painter.xForm(polygon, index, count) - \newcode - QPainter painter(this); - QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform(); - \endcode -*/ - -QPolygon QPainter::xForm(const QPolygon &av, int index, int npoints) const -{ - int lastPoint = npoints < 0 ? av.size() : index+npoints; - QPolygon a(lastPoint-index); - memcpy(a.data(), av.data()+index, (lastPoint-index)*sizeof(QPoint)); - return a * combinedMatrix(); -} - -/*! - \fn QPoint QPainter::xFormDev(const QPoint &point) const - \overload - \obsolete - - Use combinedTransform() combined with QTransform::inverted() instead. - - \oldcode - QPainter painter(this); - QPoint transformed = painter.xFormDev(point); - \newcode - QPainter painter(this); - QPoint transformed = point * painter.combinedTransform().inverted(); - \endcode -*/ - -QPoint QPainter::xFormDev(const QPoint &p) const -{ - Q_D(const QPainter); - if (!d->engine) { - qWarning("QPainter::xFormDev: Painter not active"); - return QPoint(); - } - if(d->state->matrix.type() == QTransform::TxNone) - return p; - return p * combinedMatrix().inverted(); -} - -/*! - \fn QRect QPainter::xFormDev(const QRect &rectangle) const - \overload - \obsolete - - Use combinedTransform() combined with QTransform::inverted() instead. - - \oldcode - QPainter painter(this); - QRect transformed = painter.xFormDev(rectangle); - \newcode - QPainter painter(this); - QRegion region = QRegion(rectangle) * painter.combinedTransform().inverted(); - QRect transformed = region.boundingRect(); - \endcode -*/ - -QRect QPainter::xFormDev(const QRect &r) const -{ - Q_D(const QPainter); - if (!d->engine) { - qWarning("QPainter::xFormDev: Painter not active"); - return QRect(); - } - if (d->state->matrix.type() == QTransform::TxNone) - return r; - return combinedMatrix().inverted().mapRect(r); -} - -/*! - \overload - - \fn QPoint QPainter::xFormDev(const QPolygon &polygon) const - \obsolete - - Use combinedTransform() combined with QTransform::inverted() instead. - - \oldcode - QPainter painter(this); - QPolygon transformed = painter.xFormDev(rectangle); - \newcode - QPainter painter(this); - QPolygon transformed = polygon * painter.combinedTransform().inverted(); - \endcode -*/ - -QPolygon QPainter::xFormDev(const QPolygon &a) const -{ - Q_D(const QPainter); - if (!d->engine) { - qWarning("QPainter::xFormDev: Painter not active"); - return QPolygon(); - } - if (d->state->matrix.type() == QTransform::TxNone) - return a; - return a * combinedMatrix().inverted(); -} - -/*! - \fn QPolygon QPainter::xFormDev(const QPolygon &polygon, int index, int count) const - \overload - \obsolete - - Use combinedTransform() combined with QPolygon::mid() and QTransform::inverted() instead. - - \oldcode - QPainter painter(this); - QPolygon transformed = painter.xFormDev(polygon, index, count); - \newcode - QPainter painter(this); - QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform().inverted(); - \endcode -*/ - -QPolygon QPainter::xFormDev(const QPolygon &ad, int index, int npoints) const -{ - Q_D(const QPainter); - int lastPoint = npoints < 0 ? ad.size() : index+npoints; - QPolygon a(lastPoint-index); - memcpy(a.data(), ad.data()+index, (lastPoint-index)*sizeof(QPoint)); - if (d->state->matrix.type() == QTransform::TxNone) - return a; - return a * combinedMatrix().inverted(); -} - -/*! - \fn void QPainter::drawCubicBezier(const QPolygon &controlPoints, int index) - - Draws a cubic Bezier curve defined by the \a controlPoints, - starting at \a{controlPoints}\e{[index]} (\a index defaults to 0). - Points after \a{controlPoints}\e{[index + 3]} are ignored. Nothing - happens if there aren't enough control points. - - Use strokePath() instead. - - \oldcode - QPainter painter(this); - painter.drawCubicBezier(controlPoints, index) - \newcode - QPainterPath path; - path.moveTo(controlPoints.at(index)); - path.cubicTo(controlPoints.at(index+1), - controlPoints.at(index+2), - controlPoints.at(index+3)); - - QPainter painter(this); - painter.strokePath(path, painter.pen()); - \endcode -*/ -void QPainter::drawCubicBezier(const QPolygon &a, int index) -{ - Q_D(QPainter); - - if (!d->engine) - return; - - if ((int)a.size() - index < 4) { - qWarning("QPainter::drawCubicBezier: Cubic Bezier needs 4 control " - "points"); - return; - } - - QPainterPath path; - path.moveTo(a.at(index)); - path.cubicTo(a.at(index+1), a.at(index+2), a.at(index+3)); - strokePath(path, d->state->pen); -} -#endif - -struct QPaintDeviceRedirection -{ - QPaintDeviceRedirection() : device(0), replacement(0), internalWidgetRedirectionIndex(-1) {} - QPaintDeviceRedirection(const QPaintDevice *device, QPaintDevice *replacement, - const QPoint& offset, int internalWidgetRedirectionIndex) - : device(device), replacement(replacement), offset(offset), - internalWidgetRedirectionIndex(internalWidgetRedirectionIndex) { } - const QPaintDevice *device; - QPaintDevice *replacement; - QPoint offset; - int internalWidgetRedirectionIndex; - bool operator==(const QPaintDevice *pdev) const { return device == pdev; } - Q_DUMMY_COMPARISON_OPERATOR(QPaintDeviceRedirection) -}; - -typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList; -Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections) -Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex) -Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic) - /*! \threadsafe @@ -7860,29 +7412,7 @@ void QPainter::setRedirected(const QPaintDevice *device, { Q_ASSERT(device != 0); - bool hadInternalWidgetRedirection = false; - if (device->devType() == QInternal::Widget) { - const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func(); - // This is the case when the widget is in a paint event. - if (widgetPrivate->redirectDev) { - // Remove internal redirection and put it back into the global redirection list. - QPoint oldOffset; - QPaintDevice *oldReplacement = widgetPrivate->redirected(&oldOffset); - const_cast<QWidgetPrivate *>(widgetPrivate)->restoreRedirected(); - setRedirected(device, oldReplacement, oldOffset); - hadInternalWidgetRedirection = true; - } - } - - QPoint roffset; - QPaintDevice *rdev = redirected(replacement, &roffset); - - QMutexLocker locker(globalRedirectionsMutex()); - QPaintDeviceRedirectionList *redirections = globalRedirections(); - Q_ASSERT(redirections != 0); - *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset, - hadInternalWidgetRedirection ? redirections->size() - 1 : -1); - globalRedirectionAtomic()->ref(); + qWarning() << "QPainter::setRedirected(): ignoring call to deprecated function, use QWidget::render() instead"; } /*! @@ -7904,29 +7434,7 @@ void QPainter::setRedirected(const QPaintDevice *device, */ void QPainter::restoreRedirected(const QPaintDevice *device) { - Q_ASSERT(device != 0); - QMutexLocker locker(globalRedirectionsMutex()); - QPaintDeviceRedirectionList *redirections = globalRedirections(); - Q_ASSERT(redirections != 0); - for (int i = redirections->size()-1; i >= 0; --i) { - if (redirections->at(i) == device) { - globalRedirectionAtomic()->deref(); - const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex; - redirections->removeAt(i); - // Restore the internal widget redirection, i.e. remove it from the global - // redirection list and put it back into QWidgetPrivate. The index is only set when - // someone call QPainter::setRedirected in a widget's paint event and we internally - // have a redirection set (typically set in QWidgetPrivate::drawWidget). - if (internalWidgetRedirectionIndex >= 0) { - Q_ASSERT(internalWidgetRedirectionIndex < redirections->size()); - const QPaintDeviceRedirection &redirectionDevice = redirections->at(internalWidgetRedirectionIndex); - QWidget *widget = static_cast<QWidget *>(const_cast<QPaintDevice *>(device)); - widget->d_func()->setRedirected(redirectionDevice.replacement, redirectionDevice.offset); - redirections->removeAt(internalWidgetRedirectionIndex); - } - return; - } - } + qWarning() << "QPainter::restoreRedirected(): ignoring call to deprecated function, use QWidget::render() instead"; } /*! @@ -7948,61 +7456,9 @@ void QPainter::restoreRedirected(const QPaintDevice *device) */ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) { - Q_ASSERT(device != 0); - - if (device->devType() == QInternal::Widget) { - const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func(); - if (widgetPrivate->redirectDev) - return widgetPrivate->redirected(offset); - } - - if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0) - return 0; - - QMutexLocker locker(globalRedirectionsMutex()); - QPaintDeviceRedirectionList *redirections = globalRedirections(); - Q_ASSERT(redirections != 0); - for (int i = redirections->size()-1; i >= 0; --i) - if (redirections->at(i) == device) { - if (offset) - *offset = redirections->at(i).offset; - return redirections->at(i).replacement; - } - if (offset) - *offset = QPoint(0, 0); return 0; } - -void qt_painter_removePaintDevice(QPaintDevice *dev) -{ - if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0) - return; - - QMutex *mutex = 0; - QT_TRY { - mutex = globalRedirectionsMutex(); - } QT_CATCH(...) { - // ignore the missing mutex, since we could be called from - // a destructor, and destructors shall not throw - } - QMutexLocker locker(mutex); - QPaintDeviceRedirectionList *redirections = 0; - QT_TRY { - redirections = globalRedirections(); - } QT_CATCH(...) { - // do nothing - code below is safe with redirections being 0. - } - if (redirections) { - for (int i = 0; i < redirections->size(); ) { - if(redirections->at(i) == dev || redirections->at(i).replacement == dev) - redirections->removeAt(i); - else - ++i; - } - } -} - void qt_format_text(const QFont &fnt, const QRectF &_r, int tf, const QString& str, QRectF *brect, int tabstops, int *ta, int tabarraylen, @@ -8054,7 +7510,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, else layout_direction = Qt::LeftToRight; - tf = QStyle::visualAlignment(layout_direction, QFlag(tf)); + tf = QGuiApplicationPrivate::visualAlignment(layout_direction, QFlag(tf)); bool isRightToLeft = layout_direction == Qt::RightToLeft; bool expandtabs = ((tf & Qt::TextExpandTabs) && @@ -8314,7 +7770,7 @@ QPainterState::QPainterState() wx(0), wy(0), ww(0), wh(0), vx(0), vy(0), vw(0), vh(0), opacity(1), WxF(false), VxF(false), clipEnabled(true), bgMode(Qt::TransparentMode), painter(0), - layoutDirection(QApplication::layoutDirection()), + layoutDirection(QGuiApplication::layoutDirection()), composition_mode(QPainter::CompositionMode_SourceOver), emulationSpecifier(0), changeFlags(0) { @@ -8344,7 +7800,7 @@ void QPainterState::init(QPainter *p) { clipInfo.clear(); worldMatrix.reset(); matrix.reset(); - layoutDirection = QApplication::layoutDirection(); + layoutDirection = QGuiApplication::layoutDirection(); composition_mode = QPainter::CompositionMode_SourceOver; emulationSpecifier = 0; dirtyFlags = 0; @@ -8353,45 +7809,6 @@ void QPainterState::init(QPainter *p) { opacity = 1; } -#ifdef QT3_SUPPORT -static void bitBlt_helper(QPaintDevice *dst, const QPoint &dp, - const QPaintDevice *src, const QRect &sr, bool) -{ - Q_ASSERT(dst); - Q_ASSERT(src); - - if (src->devType() == QInternal::Pixmap) { - const QPixmap *pixmap = static_cast<const QPixmap *>(src); - QPainter pt(dst); - pt.drawPixmap(dp, *pixmap, sr); - - } else { - qWarning("QPainter: bitBlt only works when source is of type pixmap"); - } -} - -void bitBlt(QPaintDevice *dst, int dx, int dy, - const QPaintDevice *src, int sx, int sy, int sw, int sh, - bool ignoreMask ) -{ - bitBlt_helper(dst, QPoint(dx, dy), src, QRect(sx, sy, sw, sh), ignoreMask); -} - -void bitBlt(QPaintDevice *dst, const QPoint &dp, const QPaintDevice *src, const QRect &sr, bool ignoreMask) -{ - bitBlt_helper(dst, dp, src, sr, ignoreMask); -} - -void bitBlt(QPaintDevice *dst, int dx, int dy, - const QImage *src, int sx, int sy, int sw, int sh, int fl) -{ - Qt::ImageConversionFlags flags(fl); - QPixmap srcPixmap = QPixmap::fromImage(*src, flags); - bitBlt_helper(dst, QPoint(dx, dy), &srcPixmap, QRect(sx, sy, sw, sh), false); -} - -#endif // QT3_SUPPORT - /*! \fn void QPainter::setBackgroundColor(const QColor &color) diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 30f8da0928..fd40111368 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -49,7 +49,6 @@ #include <QtGui/qpixmap.h> #include <QtGui/qimage.h> #include <QtGui/qtextoption.h> -#include <QtGui/qdrawutil.h> #ifndef QT_INCLUDE_COMPAT #include <QtGui/qpolygon.h> @@ -133,7 +132,7 @@ public: bool end(); bool isActive() const; - void initFrom(const QWidget *widget); + void initFrom(const QPaintDevice *device); enum CompositionMode { CompositionMode_SourceOver, @@ -464,85 +463,13 @@ public: void beginNativePainting(); void endNativePainting(); -#ifdef QT3_SUPPORT - - inline QT3_SUPPORT void setBackgroundColor(const QColor &color) { setBackground(color); } - inline QT3_SUPPORT const QColor &backgroundColor() const { return background().color(); } - - inline QT3_SUPPORT void drawText(int x, int y, const QString &s, int pos, int len) - { drawText(x, y, s.mid(pos, len)); } - inline QT3_SUPPORT void drawText(const QPoint &p, const QString &s, int pos, int len) - { drawText(p, s.mid(pos, len)); } - inline QT3_SUPPORT void drawText(int x, int y, const QString &s, int len) - { drawText(x, y, s.left(len)); } - inline QT3_SUPPORT void drawText(const QPoint &p, const QString &s, int len) - { drawText(p, s.left(len)); } - inline QT3_SUPPORT void drawText(const QRect &r, int flags, const QString &str, int len, QRect *br=0) - { drawText(r, flags, str.left(len), br); } - inline QT3_SUPPORT void drawText(int x, int y, int w, int h, int flags, const QString &text, int len, QRect *br=0) - { drawText(QRect(x, y, w, h), flags, text.left(len), br); } - inline QT3_SUPPORT QRect boundingRect(const QRect &rect, int flags, const QString &text, int len) - { return boundingRect(rect, flags, text.left(len)); } - inline QT3_SUPPORT QRect boundingRect(int x, int y, int w, int h, int flags, const QString &text, int len) - { return boundingRect(QRect(x, y, w, h), flags, text.left(len)); } - - inline QT3_SUPPORT bool begin(QPaintDevice *pdev, const QWidget *init) - { bool ret = begin(pdev); initFrom(init); return ret; } - QT3_SUPPORT void drawPoints(const QPolygon &pa, int index, int npoints = -1) - { drawPoints(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); } - - QT3_SUPPORT void drawCubicBezier(const QPolygon &pa, int index = 0); - - QT3_SUPPORT void drawLineSegments(const QPolygon &points, int index = 0, int nlines = -1); - - inline QT3_SUPPORT void drawPolyline(const QPolygon &pa, int index, int npoints = -1) - { drawPolyline(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); } - - inline QT3_SUPPORT void drawPolygon(const QPolygon &pa, bool winding, int index = 0, int npoints = -1) - { drawPolygon(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints, - winding ? Qt::WindingFill : Qt::OddEvenFill); } - - inline QT3_SUPPORT void drawPolygon(const QPolygonF &polygon, bool winding, int index = 0, - int npoints = -1) - { drawPolygon(polygon.constData() + index, npoints == -1 ? polygon.size() - index : npoints, - winding ? Qt::WindingFill : Qt::OddEvenFill); } - - inline QT3_SUPPORT void drawConvexPolygon(const QPolygonF &polygon, int index, int npoints = -1) - { drawConvexPolygon(polygon.constData() + index, npoints == -1 ? polygon.size() - index : npoints); } - inline QT3_SUPPORT void drawConvexPolygon(const QPolygon &pa, int index, int npoints = -1) - { drawConvexPolygon(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); } - - static inline QT3_SUPPORT void redirect(QPaintDevice *pdev, QPaintDevice *replacement) - { setRedirected(pdev, replacement); } - static inline QT3_SUPPORT QPaintDevice *redirect(QPaintDevice *pdev) - { return const_cast<QPaintDevice*>(redirected(pdev)); } - - inline QT3_SUPPORT void setWorldXForm(bool enabled) { setMatrixEnabled(enabled); } - inline QT3_SUPPORT bool hasWorldXForm() const { return matrixEnabled(); } - inline QT3_SUPPORT void resetXForm() { resetTransform(); } - - inline QT3_SUPPORT void setViewXForm(bool enabled) { setViewTransformEnabled(enabled); } - inline QT3_SUPPORT bool hasViewXForm() const { return viewTransformEnabled(); } - - QT3_SUPPORT void map(int x, int y, int *rx, int *ry) const; - QT3_SUPPORT QPoint xForm(const QPoint &) const; // map virtual -> deviceb - QT3_SUPPORT QRect xForm(const QRect &) const; - QT3_SUPPORT QPolygon xForm(const QPolygon &) const; - QT3_SUPPORT QPolygon xForm(const QPolygon &, int index, int npoints) const; - QT3_SUPPORT QPoint xFormDev(const QPoint &) const; // map device -> virtual - QT3_SUPPORT QRect xFormDev(const QRect &) const; - QT3_SUPPORT QPolygon xFormDev(const QPolygon &) const; - QT3_SUPPORT QPolygon xFormDev(const QPolygon &, int index, int npoints) const; - QT3_SUPPORT qreal translationX() const; - QT3_SUPPORT qreal translationY() const; -#endif - private: Q_DISABLE_COPY(QPainter) friend class Q3Painter; QScopedPointer<QPainterPrivate> d_ptr; + friend class QWidget; friend class QFontEngine; friend class QFontEngineBox; friend class QFontEngineFT; diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index 8cc56befe1..c9e14b6b7b 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -153,8 +153,8 @@ namespace QPdf { struct PaperSize { int width, height; // in postscript points }; - PaperSize paperSize(QPrinter::PaperSize paperSize); - const char *paperSizeToString(QPrinter::PaperSize paperSize); + Q_GUI_EXPORT PaperSize paperSize(QPrinter::PaperSize paperSize); + Q_GUI_EXPORT const char *paperSizeToString(QPrinter::PaperSize paperSize); } diff --git a/src/gui/painting/qplatformbackingstore_qpa.cpp b/src/gui/painting/qplatformbackingstore_qpa.cpp new file mode 100644 index 0000000000..fa85661f31 --- /dev/null +++ b/src/gui/painting/qplatformbackingstore_qpa.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.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 the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qplatformbackingstore_qpa.h> +#include <qwindow.h> +#include <qpixmap.h> +#include <private/qwindow_p.h> + +QT_BEGIN_NAMESPACE + +class QPlatformBackingStorePrivate +{ +public: + QPlatformBackingStorePrivate(QWindow *w) + : window(w) + { + } + + QWindow *window; + QSize size; +}; + +/*! + \class QPlatformBackingStore + \since 5.0 + \internal + \preliminary + \ingroup qpa + + \brief The QPlatformBackingStore class provides the drawing area for top-level + windows. +*/ + + +/*! + \fn void QPlatformBackingStore::beginPaint(const QRegion ®ion) + + This function is called before painting onto the surface begins, + with the \a region in which the painting will occur. + + \sa endPaint(), paintDevice() +*/ + +/*! + \fn void QPlatformBackingStore::endPaint(const QRegion ®ion) + + This function is called after painting onto the surface has ended, + with the \a region in which the painting was performed. + + \sa beginPaint(), paintDevice() +*/ + +/*! + \fn void QPlatformBackingStore::flush(QWindow *window, const QRegion ®ion, + const QPoint &offset) + + Flushes the given \a region from the specified \a window onto the + screen. + + Note that the \a offset parameter is currently unused. +*/ + +/*! + \fn QPaintDevice* QPlatformBackingStore::paintDevice() + + Implement this function to return the appropriate paint device. +*/ + +/*! + Constructs an empty surface for the given top-level \a window. +*/ +QPlatformBackingStore::QPlatformBackingStore(QWindow *window) + : d_ptr(new QPlatformBackingStorePrivate(window)) +{ +} + +/*! + Destroys this surface. +*/ +QPlatformBackingStore::~QPlatformBackingStore() +{ + delete d_ptr; +} + +/*! + Returns a pointer to the top-level window associated with this + surface. +*/ +QWindow* QPlatformBackingStore::window() const +{ + return d_ptr->window; +} + +void QPlatformBackingStore::beginPaint(const QRegion &) +{ +} + +void QPlatformBackingStore::endPaint() +{ +} + +/*! + Scrolls the given \a area \a dx pixels to the right and \a dy + downward; both \a dx and \a dy may be negative. + + Returns true if the area was scrolled successfully; false otherwise. +*/ +bool QPlatformBackingStore::scroll(const QRegion &area, int dx, int dy) +{ + Q_UNUSED(area); + Q_UNUSED(dx); + Q_UNUSED(dy); + + return false; +} + +QT_END_NAMESPACE diff --git a/src/gui/painting/qwindowsurface_mac_p.h b/src/gui/painting/qplatformbackingstore_qpa.h index 05571646eb..29730167b4 100644 --- a/src/gui/painting/qwindowsurface_mac_p.h +++ b/src/gui/painting/qplatformbackingstore_qpa.h @@ -39,46 +39,48 @@ ** ****************************************************************************/ -#ifndef QWINDOWSURFACE_MAC_P_H -#define QWINDOWSURFACE_MAC_P_H +#ifndef QPLATFORMBACKINGSTORE_QPA_H +#define QPLATFORMBACKINGSTORE_QPA_H -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// +#include <QtCore/qrect.h> -#include <qglobal.h> -#include "private/qwindowsurface_p.h" +#include <QtGui/qwindow.h> +#include <QtGui/qregion.h> QT_BEGIN_NAMESPACE -class QPaintDevice; -class QPoint; class QRegion; -class QWidget; -struct QMacWindowSurfacePrivate; +class QRect; +class QPoint; +class QImage; +class QPlatformBackingStorePrivate; +class QPlatformWindow; -class QMacWindowSurface : public QWindowSurface +class Q_GUI_EXPORT QPlatformBackingStore { public: - QMacWindowSurface(QWidget *widget); - ~QMacWindowSurface(); + QPlatformBackingStore(QWindow *window); + virtual ~QPlatformBackingStore(); + + QWindow *window() const; + + virtual QPaintDevice *paintDevice() = 0; + + // 'window' can be a child window, in which case 'region' is in child window coordinates and + // offset is the (child) window's offset in relation to the window surface. + virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) = 0; + + virtual void resize(const QSize &size, const QRegion &staticContents) = 0; + + virtual bool scroll(const QRegion &area, int dx, int dy); - QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - void setGeometry(const QRect &rect); - bool scroll(const QRegion &area, int dx, int dy); + virtual void beginPaint(const QRegion &); + virtual void endPaint(); private: - QMacWindowSurfacePrivate *d_ptr; + QPlatformBackingStorePrivate *d_ptr; }; QT_END_NAMESPACE -#endif // QWINDOWSURFACE_MAC_P_H +#endif // QPLATFORMBACKINGSTORE_QPA_H diff --git a/src/gui/painting/qplatformprintersupport_qpa.cpp b/src/gui/painting/qplatformprintersupport_qpa.cpp new file mode 100644 index 0000000000..9fb25c953f --- /dev/null +++ b/src/gui/painting/qplatformprintersupport_qpa.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.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 the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformprintersupport_qpa.h" + +#include <QtGui/qprinterinfo.h> + +#include <private/qprinterinfo_p.h> + +#ifndef QT_NO_PRINTER + +QT_BEGIN_NAMESPACE + +QPlatformPrinterSupport::QPlatformPrinterSupport() +{ +} + +QPlatformPrinterSupport::~QPlatformPrinterSupport() +{ +} + +QPrintEngine *QPlatformPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode) +{ + return 0; +} + +QPaintEngine *QPlatformPrinterSupport::createPaintEngine(QPrintEngine *, QPrinter::PrinterMode) +{ + return 0; +} + +QList<QPrinter::PaperSize> QPlatformPrinterSupport::supportedPaperSizes(const QPrinterInfo &) const +{ + return QList<QPrinter::PaperSize>(); +} + +QList<QPrinterInfo> QPlatformPrinterSupport::availablePrinters() +{ + return QList<QPrinterInfo>(); +} + +QPrinterInfo QPlatformPrinterSupport::defaultPrinter() +{ + const QList<QPrinterInfo> printers = availablePrinters(); + foreach (const QPrinterInfo &printerInfo, printers) { + if (printerInfo.isDefault()) + return printerInfo; + } + return printers.isEmpty() ? QPrinterInfo() : printers.front(); +} + +QPrinterInfo QPlatformPrinterSupport::printerInfo(const QString &printerName, bool isDefault) +{ + QPrinterInfo pi = QPrinterInfo(printerName); + pi.d_func()->isDefault = isDefault; + return pi; +} + +void QPlatformPrinterSupport::setPrinterInfoDefault(QPrinterInfo *p, bool isDefault) +{ + p->d_func()->isDefault = isDefault; +} + +bool QPlatformPrinterSupport::printerInfoIsDefault(const QPrinterInfo &p) +{ + return p.d_func()->isDefault; +} + +int QPlatformPrinterSupport::printerInfoCupsPrinterIndex(const QPrinterInfo &p) +{ + int i = -1; +#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA) +#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) + if (!p.isNull()) + return i = p.d_func()->cupsPrinterIndex; +#endif +#endif + Q_UNUSED(p) + return i; +} + +void QPlatformPrinterSupport::setPrinterInfoCupsPrinterIndex(QPrinterInfo *p, int index) +{ +#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA) +#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) + p->d_func()->cupsPrinterIndex = index; +#endif +#endif + Q_UNUSED(p) + Q_UNUSED(index) +} + +QT_END_NAMESPACE + +#endif // QT_NO_PRINTER diff --git a/src/gui/painting/qgraphicssystemfactory_p.h b/src/gui/painting/qplatformprintersupport_qpa.h index c8e55e049d..90dd260925 100644 --- a/src/gui/painting/qgraphicssystemfactory_p.h +++ b/src/gui/painting/qplatformprintersupport_qpa.h @@ -39,21 +39,10 @@ ** ****************************************************************************/ -#ifndef QGRAPHICSSYSTEMFACTORY_H -#define QGRAPHICSSYSTEMFACTORY_H +#ifndef QPLATFORMPRINTINGSUPPORT_H +#define QPLATFORMPRINTINGSUPPORT_H -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qstringlist.h> +#include <QtGui/qprinter.h> QT_BEGIN_HEADER @@ -61,18 +50,35 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -class QGraphicsSystem; +#ifndef QT_NO_PRINTER + +class QPrintEngine; -class QGraphicsSystemFactory +class Q_GUI_EXPORT QPlatformPrinterSupport { public: - static QStringList keys(); - static QGraphicsSystem *create(const QString&); + QPlatformPrinterSupport(); + virtual ~QPlatformPrinterSupport(); + + virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode); + virtual QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode); + virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const; + + virtual QList<QPrinterInfo> availablePrinters(); + virtual QPrinterInfo defaultPrinter(); + +protected: + static QPrinterInfo printerInfo(const QString &printerName, bool isDefault = false); + static void setPrinterInfoDefault(QPrinterInfo *p, bool isDefault); + static bool printerInfoIsDefault(const QPrinterInfo &p); + static int printerInfoCupsPrinterIndex(const QPrinterInfo &p); + static void setPrinterInfoCupsPrinterIndex(QPrinterInfo *p, int index); }; +#endif // QT_NO_PRINTER + QT_END_NAMESPACE QT_END_HEADER -#endif // QGRAPHICSSYSTEMFACTORY_H - +#endif // QPLATFORMPRINTINGSUPPORT_H diff --git a/src/gui/painting/qprintengine_mac.mm b/src/gui/painting/qprintengine_mac.mm deleted file mode 100644 index fb40677e2d..0000000000 --- a/src/gui/painting/qprintengine_mac.mm +++ /dev/null @@ -1,911 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qprintengine_mac_p.h> -#include <qdebug.h> -#include <qthread.h> -#include <QtCore/qcoreapplication.h> - -#ifndef QT_NO_PRINTER - -QT_BEGIN_NAMESPACE - -extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size); - -QMacPrintEngine::QMacPrintEngine(QPrinter::PrinterMode mode) : QPaintEngine(*(new QMacPrintEnginePrivate)) -{ - Q_D(QMacPrintEngine); - d->mode = mode; - d->initialize(); -} - -bool QMacPrintEngine::begin(QPaintDevice *dev) -{ - Q_D(QMacPrintEngine); - - Q_ASSERT(dev && dev->devType() == QInternal::Printer); - if (!static_cast<QPrinter *>(dev)->isValid()) - return false; - - if (d->state == QPrinter::Idle && !d->isPrintSessionInitialized()) // Need to reinitialize - d->initialize(); - - d->paintEngine->state = state; - d->paintEngine->begin(dev); - Q_ASSERT_X(d->state == QPrinter::Idle, "QMacPrintEngine", "printer already active"); - - if (PMSessionValidatePrintSettings(d->session, d->settings, kPMDontWantBoolean) != noErr - || PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean) != noErr) { - d->state = QPrinter::Error; - return false; - } - - if (!d->outputFilename.isEmpty()) { - QCFType<CFURLRef> outFile = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, - QCFString(d->outputFilename), - kCFURLPOSIXPathStyle, - false); - if (PMSessionSetDestination(d->session, d->settings, kPMDestinationFile, - kPMDocumentFormatPDF, outFile) != noErr) { - qWarning("QMacPrintEngine::begin: Problem setting file [%s]", d->outputFilename.toUtf8().constData()); - return false; - } - } - OSStatus status = noErr; -#ifndef QT_MAC_USE_COCOA - status = d->shouldSuppressStatus() ? PMSessionBeginCGDocumentNoDialog(d->session, d->settings, d->format) - : PMSessionBeginCGDocument(d->session, d->settings, d->format); -#else - status = PMSessionBeginCGDocumentNoDialog(d->session, d->settings, d->format); -#endif - - if (status != noErr) { - d->state = QPrinter::Error; - return false; - } - - d->state = QPrinter::Active; - setActive(true); - d->newPage_helper(); - return true; -} - -bool QMacPrintEngine::end() -{ - Q_D(QMacPrintEngine); - if (d->state == QPrinter::Aborted) - return true; // I was just here a function call ago :) - if(d->paintEngine->type() == QPaintEngine::CoreGraphics) { - // We dont need the paint engine to call restoreGraphicsState() - static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->stackCount = 0; - static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = 0; - } - d->paintEngine->end(); - if (d->state != QPrinter::Idle) - d->releaseSession(); - d->state = QPrinter::Idle; - return true; -} - -QPaintEngine * -QMacPrintEngine::paintEngine() const -{ - return d_func()->paintEngine; -} - -Qt::HANDLE QMacPrintEngine::handle() const -{ - QCoreGraphicsPaintEngine *cgEngine = static_cast<QCoreGraphicsPaintEngine*>(paintEngine()); - return cgEngine->d_func()->hd; -} - -QMacPrintEnginePrivate::~QMacPrintEnginePrivate() -{ -#ifdef QT_MAC_USE_COCOA - [printInfo release]; -#endif - delete paintEngine; -} - -void QMacPrintEnginePrivate::setPaperSize(QPrinter::PaperSize ps) -{ - Q_Q(QMacPrintEngine); - QSizeF newSize = qt_paperSizeToQSizeF(ps); - QCFType<CFArrayRef> formats; - PMPrinter printer; - - if (PMSessionGetCurrentPrinter(session, &printer) == noErr - && PMSessionCreatePageFormatList(session, printer, &formats) == noErr) { - CFIndex total = CFArrayGetCount(formats); - PMPageFormat tmp; - PMRect paper; - for (CFIndex idx = 0; idx < total; ++idx) { - tmp = static_cast<PMPageFormat>( - const_cast<void *>(CFArrayGetValueAtIndex(formats, idx))); - PMGetUnadjustedPaperRect(tmp, &paper); - int wMM = int((paper.right - paper.left) / 72 * 25.4 + 0.5); - int hMM = int((paper.bottom - paper.top) / 72 * 25.4 + 0.5); - if (newSize.width() == wMM && newSize.height() == hMM) { - PMCopyPageFormat(tmp, format); - // reset the orientation and resolution as they are lost in the copy. - q->setProperty(QPrintEngine::PPK_Orientation, orient); - if (PMSessionValidatePageFormat(session, format, kPMDontWantBoolean) != noErr) { - // Don't know, warn for the moment. - qWarning("QMacPrintEngine, problem setting format and resolution for this page size"); - } - break; - } - } - } -} - -QPrinter::PaperSize QMacPrintEnginePrivate::paperSize() const -{ - PMRect paper; - PMGetUnadjustedPaperRect(format, &paper); - int wMM = int((paper.right - paper.left) / 72 * 25.4 + 0.5); - int hMM = int((paper.bottom - paper.top) / 72 * 25.4 + 0.5); - for (int i = QPrinter::A4; i < QPrinter::NPaperSize; ++i) { - QSizeF s = qt_paperSizeToQSizeF(QPrinter::PaperSize(i)); - if (s.width() == wMM && s.height() == hMM) - return (QPrinter::PaperSize)i; - } - return QPrinter::Custom; -} - -QList<QVariant> QMacPrintEnginePrivate::supportedResolutions() const -{ - Q_ASSERT_X(session, "QMacPrinterEngine::supportedResolutions", - "must have a valid printer session"); - UInt32 resCount; - QList<QVariant> resolutions; - PMPrinter printer; - if (PMSessionGetCurrentPrinter(session, &printer) == noErr) { - PMResolution res; - OSStatus status = PMPrinterGetPrinterResolutionCount(printer, &resCount); - if (status == kPMNotImplemented) { -#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5) - // *Sigh* we have to use the non-indexed version. - if (PMPrinterGetPrinterResolution(printer, kPMMinSquareResolution, &res) == noErr) - resolutions.append(int(res.hRes)); - if (PMPrinterGetPrinterResolution(printer, kPMMaxSquareResolution, &res) == noErr) { - QVariant var(int(res.hRes)); - if (!resolutions.contains(var)) - resolutions.append(var); - } - if (PMPrinterGetPrinterResolution(printer, kPMDefaultResolution, &res) == noErr) { - QVariant var(int(res.hRes)); - if (!resolutions.contains(var)) - resolutions.append(var); - } -#endif - } else if (status == noErr) { - // According to the docs, index start at 1. - for (UInt32 i = 1; i <= resCount; ++i) { - if (PMPrinterGetIndexedPrinterResolution(printer, i, &res) == noErr) - resolutions.append(QVariant(int(res.hRes))); - } - } else { - qWarning("QMacPrintEngine::supportedResolutions: Unexpected error: %ld", long(status)); - } - } - return resolutions; -} - -bool QMacPrintEnginePrivate::shouldSuppressStatus() const -{ - if (suppressStatus == true) - return true; - - // Supress displaying the automatic progress dialog if we are printing - // from a non-gui thread. - return (qApp->thread() != QThread::currentThread()); -} - -QPrinter::PrinterState QMacPrintEngine::printerState() const -{ - return d_func()->state; -} - -bool QMacPrintEngine::newPage() -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - OSStatus err = -#ifndef QT_MAC_USE_COCOA - d->shouldSuppressStatus() ? PMSessionEndPageNoDialog(d->session) - : PMSessionEndPage(d->session); -#else - PMSessionEndPageNoDialog(d->session); -#endif - if (err != noErr) { - if (err == kPMCancel) { - // User canceled, we need to abort! - abort(); - } else { - // Not sure what the problem is... - qWarning("QMacPrintEngine::newPage: Cannot end current page. %ld", long(err)); - d->state = QPrinter::Error; - } - return false; - } - return d->newPage_helper(); -} - -bool QMacPrintEngine::abort() -{ - Q_D(QMacPrintEngine); - if (d->state != QPrinter::Active) - return false; - bool ret = end(); - d->state = QPrinter::Aborted; - return ret; -} - -static inline int qt_get_PDMWidth(PMPageFormat pformat, bool fullPage, - const PMResolution &resolution) -{ - int val = 0; - PMRect r; - qreal hRatio = resolution.hRes / 72; - if (fullPage) { - if (PMGetAdjustedPaperRect(pformat, &r) == noErr) - val = qRound((r.right - r.left) * hRatio); - } else { - if (PMGetAdjustedPageRect(pformat, &r) == noErr) - val = qRound((r.right - r.left) * hRatio); - } - return val; -} - -static inline int qt_get_PDMHeight(PMPageFormat pformat, bool fullPage, - const PMResolution &resolution) -{ - int val = 0; - PMRect r; - qreal vRatio = resolution.vRes / 72; - if (fullPage) { - if (PMGetAdjustedPaperRect(pformat, &r) == noErr) - val = qRound((r.bottom - r.top) * vRatio); - } else { - if (PMGetAdjustedPageRect(pformat, &r) == noErr) - val = qRound((r.bottom - r.top) * vRatio); - } - return val; -} - - -int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const -{ - Q_D(const QMacPrintEngine); - int val = 1; - switch (m) { - case QPaintDevice::PdmWidth: - if (d->hasCustomPaperSize) { - val = qRound(d->customSize.width()); - if (d->hasCustomPageMargins) { - val -= qRound(d->leftMargin + d->rightMargin); - } else { - QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList(); - val -= qRound(margins.at(0).toDouble() + margins.at(2).toDouble()); - } - } else { - val = qt_get_PDMWidth(d->format, property(PPK_FullPage).toBool(), d->resolution); - } - break; - case QPaintDevice::PdmHeight: - if (d->hasCustomPaperSize) { - val = qRound(d->customSize.height()); - if (d->hasCustomPageMargins) { - val -= qRound(d->topMargin + d->bottomMargin); - } else { - QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList(); - val -= qRound(margins.at(1).toDouble() + margins.at(3).toDouble()); - } - } else { - val = qt_get_PDMHeight(d->format, property(PPK_FullPage).toBool(), d->resolution); - } - break; - case QPaintDevice::PdmWidthMM: - val = metric(QPaintDevice::PdmWidth); - val = int((val * 254 + 5 * d->resolution.hRes) / (10 * d->resolution.hRes)); - break; - case QPaintDevice::PdmHeightMM: - val = metric(QPaintDevice::PdmHeight); - val = int((val * 254 + 5 * d->resolution.vRes) / (10 * d->resolution.vRes)); - break; - case QPaintDevice::PdmPhysicalDpiX: - case QPaintDevice::PdmPhysicalDpiY: { - PMPrinter printer; - if(PMSessionGetCurrentPrinter(d->session, &printer) == noErr) { - PMResolution resolution; -#ifndef QT_MAC_USE_COCOA -# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { - PMPrinterGetOutputResolution(printer, d->settings, &resolution); - } else -# endif - { - PMPrinterGetPrinterResolution(printer, kPMCurrentValue, &resolution); - } -#else - PMPrinterGetOutputResolution(printer, d->settings, &resolution); -#endif - val = (int)resolution.vRes; - break; - } - //otherwise fall through - } - case QPaintDevice::PdmDpiY: - val = (int)d->resolution.vRes; - break; - case QPaintDevice::PdmDpiX: - val = (int)d->resolution.hRes; - break; - case QPaintDevice::PdmNumColors: - val = (1 << metric(QPaintDevice::PdmDepth)); - break; - case QPaintDevice::PdmDepth: - val = 24; - break; - default: - val = 0; - qWarning("QPrinter::metric: Invalid metric command"); - } - return val; -} - -void QMacPrintEnginePrivate::initialize() -{ - Q_Q(QMacPrintEngine); - -#ifndef QT_MAC_USE_COCOA - Q_ASSERT(!session); -#else - Q_ASSERT(!printInfo); -#endif - - if (!paintEngine) - paintEngine = new QCoreGraphicsPaintEngine(); - - q->gccaps = paintEngine->gccaps; - - fullPage = false; - -#ifndef QT_MAC_USE_COCOA - if (PMCreateSession(&session) != 0) - session = 0; -#else - QMacCocoaAutoReleasePool pool; - printInfo = [[NSPrintInfo alloc] initWithDictionary:[NSDictionary dictionary]]; - session = static_cast<PMPrintSession>([printInfo PMPrintSession]); -#endif - - PMPrinter printer; - if (session && PMSessionGetCurrentPrinter(session, &printer) == noErr) { - QList<QVariant> resolutions = supportedResolutions(); - if (!resolutions.isEmpty() && mode != QPrinter::ScreenResolution) { - if (resolutions.count() > 1 && mode == QPrinter::HighResolution) { - int max = 0; - for (int i = 0; i < resolutions.count(); ++i) { - int value = resolutions.at(i).toInt(); - if (value > max) - max = value; - } - resolution.hRes = resolution.vRes = max; - } else { - resolution.hRes = resolution.vRes = resolutions.at(0).toInt(); - } - if(resolution.hRes == 0) - resolution.hRes = resolution.vRes = 600; - } else { - resolution.hRes = resolution.vRes = qt_defaultDpi(); - } - } - -#ifndef QT_MAC_USE_COCOA - bool settingsInitialized = (settings != 0); - bool settingsOK = !settingsInitialized ? PMCreatePrintSettings(&settings) == noErr : true; - if (settingsOK && !settingsInitialized) - settingsOK = PMSessionDefaultPrintSettings(session, settings) == noErr; - - - bool formatInitialized = (format != 0); - bool formatOK = !formatInitialized ? PMCreatePageFormat(&format) == noErr : true; - if (formatOK) { - if (!formatInitialized) { - formatOK = PMSessionDefaultPageFormat(session, format) == noErr; - } - formatOK = PMSessionValidatePageFormat(session, format, kPMDontWantBoolean) == noErr; - } -#else - settings = static_cast<PMPrintSettings>([printInfo PMPrintSettings]); - format = static_cast<PMPageFormat>([printInfo PMPageFormat]); -#endif - -#ifndef QT_MAC_USE_COCOA - if (!settingsOK || !formatOK) { - qWarning("QMacPrintEngine::initialize: Unable to initialize QPainter"); - state = QPrinter::Error; - } -#endif - - QHash<QMacPrintEngine::PrintEnginePropertyKey, QVariant>::const_iterator propC; - for (propC = valueCache.constBegin(); propC != valueCache.constEnd(); propC++) { - q->setProperty(propC.key(), propC.value()); - } -} - -void QMacPrintEnginePrivate::releaseSession() -{ -#ifndef QT_MAC_USE_COCOA - if (shouldSuppressStatus()) { - PMSessionEndPageNoDialog(session); - PMSessionEndDocumentNoDialog(session); - } else { - PMSessionEndPage(session); - PMSessionEndDocument(session); - } - PMRelease(session); -#else - PMSessionEndPageNoDialog(session); - PMSessionEndDocumentNoDialog(session); - [printInfo release]; -#endif - printInfo = 0; - session = 0; -} - -bool QMacPrintEnginePrivate::newPage_helper() -{ - Q_Q(QMacPrintEngine); - Q_ASSERT(state == QPrinter::Active); - - if (PMSessionError(session) != noErr) { - q->abort(); - return false; - } - - // pop the stack of saved graphic states, in case we get the same - // context back - either way, the stack count should be 0 when we - // get the new one - QCoreGraphicsPaintEngine *cgEngine = static_cast<QCoreGraphicsPaintEngine*>(paintEngine); - while (cgEngine->d_func()->stackCount > 0) - cgEngine->d_func()->restoreGraphicsState(); - - OSStatus status = -#ifndef QT_MAC_USE_COCOA - shouldSuppressStatus() ? PMSessionBeginPageNoDialog(session, format, 0) - : PMSessionBeginPage(session, format, 0); -#else - PMSessionBeginPageNoDialog(session, format, 0); -#endif - if(status != noErr) { - state = QPrinter::Error; - return false; - } - - QRect page = q->property(QPrintEngine::PPK_PageRect).toRect(); - QRect paper = q->property(QPrintEngine::PPK_PaperRect).toRect(); - - CGContextRef cgContext; - OSStatus err = noErr; - err = PMSessionGetCGGraphicsContext(session, &cgContext); - if(err != noErr) { - qWarning("QMacPrintEngine::newPage: Cannot retrieve CoreGraphics context: %ld", long(err)); - state = QPrinter::Error; - return false; - } - cgEngine->d_func()->hd = cgContext; - - // Set the resolution as a scaling ration of 72 (the default). - CGContextScaleCTM(cgContext, 72 / resolution.hRes, 72 / resolution.vRes); - - CGContextScaleCTM(cgContext, 1, -1); - CGContextTranslateCTM(cgContext, 0, -paper.height()); - if (!fullPage) - CGContextTranslateCTM(cgContext, page.x() - paper.x(), page.y() - paper.y()); - cgEngine->d_func()->orig_xform = CGContextGetCTM(cgContext); - cgEngine->d_func()->setClip(0); - cgEngine->state->dirtyFlags = QPaintEngine::DirtyFlag(QPaintEngine::AllDirty - & ~(QPaintEngine::DirtyClipEnabled - | QPaintEngine::DirtyClipRegion - | QPaintEngine::DirtyClipPath)); - if (cgEngine->painter()->hasClipping()) - cgEngine->state->dirtyFlags |= QPaintEngine::DirtyClipEnabled; - cgEngine->syncState(); - return true; -} - - -void QMacPrintEngine::updateState(const QPaintEngineState &state) -{ - d_func()->paintEngine->updateState(state); -} - -void QMacPrintEngine::drawRects(const QRectF *r, int num) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawRects(r, num); -} - -void QMacPrintEngine::drawPoints(const QPointF *points, int pointCount) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawPoints(points, pointCount); -} - -void QMacPrintEngine::drawEllipse(const QRectF &r) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawEllipse(r); -} - -void QMacPrintEngine::drawLines(const QLineF *lines, int lineCount) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawLines(lines, lineCount); -} - -void QMacPrintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawPolygon(points, pointCount, mode); -} - -void QMacPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawPixmap(r, pm, sr); -} - -void QMacPrintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawImage(r, pm, sr, flags); -} - -void QMacPrintEngine::drawTextItem(const QPointF &p, const QTextItem &ti) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawTextItem(p, ti); -} - -void QMacPrintEngine::drawTiledPixmap(const QRectF &dr, const QPixmap &pixmap, const QPointF &sr) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawTiledPixmap(dr, pixmap, sr); -} - -void QMacPrintEngine::drawPath(const QPainterPath &path) -{ - Q_D(QMacPrintEngine); - Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawPath(path); -} - - -void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) -{ - Q_D(QMacPrintEngine); - - d->valueCache.insert(key, value); - if (!d->session) - return; - - switch (key) { - case PPK_CollateCopies: - break; - case PPK_ColorMode: - break; - case PPK_Creator: - break; - case PPK_DocumentName: - break; - case PPK_PageOrder: - break; - case PPK_PaperSource: - break; - case PPK_SelectionOption: - break; - case PPK_Resolution: { - PMPrinter printer; - UInt32 count; - if (PMSessionGetCurrentPrinter(d->session, &printer) != noErr) - break; - if (PMPrinterGetPrinterResolutionCount(printer, &count) != noErr) - break; - PMResolution resolution = { 0.0, 0.0 }; - PMResolution bestResolution = { 0.0, 0.0 }; - int dpi = value.toInt(); - int bestDistance = INT_MAX; - for (UInt32 i = 1; i <= count; ++i) { // Yes, it starts at 1 - if (PMPrinterGetIndexedPrinterResolution(printer, i, &resolution) == noErr) { - if (dpi == int(resolution.hRes)) { - bestResolution = resolution; - break; - } else { - int distance = qAbs(dpi - int(resolution.hRes)); - if (distance < bestDistance) { - bestDistance = distance; - bestResolution = resolution; - } - } - } - } - PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean); - break; - } - - case PPK_FullPage: - d->fullPage = value.toBool(); - break; - case PPK_CopyCount: // fallthrough - case PPK_NumberOfCopies: - PMSetCopies(d->settings, value.toInt(), false); - break; - case PPK_Orientation: { - if (d->state == QPrinter::Active) { - qWarning("QMacPrintEngine::setOrientation: Orientation cannot be changed during a print job, ignoring change"); - } else { - QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt()); - if (d->hasCustomPaperSize && (d->orient != newOrientation)) - d->customSize = QSizeF(d->customSize.height(), d->customSize.width()); - d->orient = newOrientation; - PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape; - PMSetOrientation(d->format, o, false); - PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean); - } - break; } - case PPK_OutputFileName: - d->outputFilename = value.toString(); - break; - case PPK_PaperSize: - d->setPaperSize(QPrinter::PaperSize(value.toInt())); - break; - case PPK_PrinterName: { - bool printerNameSet = false; - OSStatus status = noErr; - QCFType<CFArrayRef> printerList; - status = PMServerCreatePrinterList(kPMServerLocal, &printerList); - if (status == noErr) { - CFIndex count = CFArrayGetCount(printerList); - for (CFIndex i=0; i<count; ++i) { - PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(printerList, i))); - QString name = QCFString::toQString(PMPrinterGetName(printer)); - if (name == value.toString()) { - status = PMSessionSetCurrentPMPrinter(d->session, printer); - printerNameSet = true; - break; - } - } - } - if (status != noErr) - qWarning("QMacPrintEngine::setPrinterName: Error setting printer: %ld", long(status)); - if (!printerNameSet) { - qWarning("QMacPrintEngine::setPrinterName: Failed to set printer named '%s'.", qPrintable(value.toString())); - d->releaseSession(); - d->state = QPrinter::Idle; - } - break; } - case PPK_SuppressSystemPrintStatus: - d->suppressStatus = value.toBool(); - break; - case PPK_CustomPaperSize: - { - PMOrientation orientation; - PMGetOrientation(d->format, &orientation); - d->hasCustomPaperSize = true; - d->customSize = value.toSizeF(); - if (orientation != kPMPortrait) - d->customSize = QSizeF(d->customSize.height(), d->customSize.width()); - break; - } - case PPK_PageMargins: - { - QList<QVariant> margins(value.toList()); - Q_ASSERT(margins.size() == 4); - d->leftMargin = margins.at(0).toDouble(); - d->topMargin = margins.at(1).toDouble(); - d->rightMargin = margins.at(2).toDouble(); - d->bottomMargin = margins.at(3).toDouble(); - d->hasCustomPageMargins = true; - break; - } - - default: - break; - } -} - -QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const -{ - Q_D(const QMacPrintEngine); - QVariant ret; - - if (!d->session && d->valueCache.contains(key)) - return *d->valueCache.find(key); - - switch (key) { - case PPK_CollateCopies: - ret = false; - break; - case PPK_ColorMode: - ret = QPrinter::Color; - break; - case PPK_Creator: - break; - case PPK_DocumentName: - break; - case PPK_FullPage: - ret = d->fullPage; - break; - case PPK_NumberOfCopies: - ret = 1; - break; - case PPK_CopyCount: { - UInt32 copies = 1; - PMGetCopies(d->settings, &copies); - ret = (uint) copies; - break; - } - case PPK_SupportsMultipleCopies: - ret = true; - break; - case PPK_Orientation: - PMOrientation orientation; - PMGetOrientation(d->format, &orientation); - ret = orientation == kPMPortrait ? QPrinter::Portrait : QPrinter::Landscape; - break; - case PPK_OutputFileName: - ret = d->outputFilename; - break; - case PPK_PageOrder: - break; - case PPK_PaperSource: - break; - case PPK_PageRect: { - // PageRect is returned in device pixels - QRect r; - PMRect macrect, macpaper; - qreal hRatio = d->resolution.hRes / 72; - qreal vRatio = d->resolution.vRes / 72; - if (d->hasCustomPaperSize) { - r = QRect(0, 0, qRound(d->customSize.width() * hRatio), qRound(d->customSize.height() * vRatio)); - if (d->hasCustomPageMargins) { - r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio), - -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio)); - } else { - QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList(); - r.adjust(qRound(margins.at(0).toDouble() * hRatio), - qRound(margins.at(1).toDouble() * vRatio), - -qRound(margins.at(2).toDouble() * hRatio), - -qRound(margins.at(3).toDouble()) * vRatio); - } - } else if (PMGetAdjustedPageRect(d->format, ¯ect) == noErr - && PMGetAdjustedPaperRect(d->format, &macpaper) == noErr) - { - if (d->fullPage || d->hasCustomPageMargins) { - r.setCoords(int(macpaper.left * hRatio), int(macpaper.top * vRatio), - int(macpaper.right * hRatio), int(macpaper.bottom * vRatio)); - r.translate(-r.x(), -r.y()); - if (d->hasCustomPageMargins) { - r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio), - -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio)); - } - } else { - r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio), - int(macrect.right * hRatio), int(macrect.bottom * vRatio)); - r.translate(int(-macpaper.left * hRatio), int(-macpaper.top * vRatio)); - } - } - ret = r; - break; } - case PPK_PaperSize: - ret = d->paperSize(); - break; - case PPK_PaperRect: { - QRect r; - PMRect macrect; - if (d->hasCustomPaperSize) { - r = QRect(0, 0, qRound(d->customSize.width()), qRound(d->customSize.height())); - } else if (PMGetAdjustedPaperRect(d->format, ¯ect) == noErr) { - qreal hRatio = d->resolution.hRes / 72; - qreal vRatio = d->resolution.vRes / 72; - r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio), - int(macrect.right * hRatio), int(macrect.bottom * vRatio)); - r.translate(-r.x(), -r.y()); - } - ret = r; - break; } - case PPK_PrinterName: { - PMPrinter printer; - OSStatus status = PMSessionGetCurrentPrinter(d->session, &printer); - if (status != noErr) - qWarning("QMacPrintEngine::printerName: Failed getting current PMPrinter: %ld", long(status)); - if (printer) - ret = QCFString::toQString(PMPrinterGetName(printer)); - break; } - case PPK_Resolution: { - ret = d->resolution.hRes; - break; - } - case PPK_SupportedResolutions: - ret = d->supportedResolutions(); - break; - case PPK_CustomPaperSize: - ret = d->customSize; - break; - case PPK_PageMargins: - { - QList<QVariant> margins; - if (d->hasCustomPageMargins) { - margins << d->leftMargin << d->topMargin - << d->rightMargin << d->bottomMargin; - } else { - PMPaperMargins paperMargins; - PMPaper paper; - PMGetPageFormatPaper(d->format, &paper); - PMPaperGetMargins(paper, &paperMargins); - margins << paperMargins.left << paperMargins.top - << paperMargins.right << paperMargins.bottom; - } - ret = margins; - break; - } - default: - break; - } - return ret; -} - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER diff --git a/src/gui/painting/qprintengine_mac_p.h b/src/gui/painting/qprintengine_mac_p.h deleted file mode 100644 index 5c4fe944e0..0000000000 --- a/src/gui/painting/qprintengine_mac_p.h +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPRINTENGINE_MAC_P_H -#define QPRINTENGINE_MAC_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QT_NO_PRINTER - -#include "QtGui/qprinter.h" -#include "QtGui/qprintengine.h" -#include "private/qpaintengine_mac_p.h" -#include "private/qpainter_p.h" - -#ifdef __OBJC__ -@class NSPrintInfo; -#else -typedef void NSPrintInfo; -#endif - -QT_BEGIN_NAMESPACE - -class QPrinterPrivate; -class QMacPrintEnginePrivate; -class QMacPrintEngine : public QPaintEngine, public QPrintEngine -{ - Q_DECLARE_PRIVATE(QMacPrintEngine) -public: - QMacPrintEngine(QPrinter::PrinterMode mode); - - Qt::HANDLE handle() const; - - bool begin(QPaintDevice *dev); - bool end(); - virtual QPaintEngine::Type type() const { return QPaintEngine::MacPrinter; } - - QPaintEngine *paintEngine() const; - - void setProperty(PrintEnginePropertyKey key, const QVariant &value); - QVariant property(PrintEnginePropertyKey key) const; - - QPrinter::PrinterState printerState() const; - - bool newPage(); - bool abort(); - int metric(QPaintDevice::PaintDeviceMetric) const; - - //forwarded functions - - void updateState(const QPaintEngineState &state); - - virtual void drawLines(const QLineF *lines, int lineCount); - virtual void drawRects(const QRectF *r, int num); - virtual void drawPoints(const QPointF *p, int pointCount); - virtual void drawEllipse(const QRectF &r); - virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); - virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags); - virtual void drawTextItem(const QPointF &p, const QTextItem &ti); - virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); - virtual void drawPath(const QPainterPath &); - -private: - friend class QPrintDialog; - friend class QPageSetupDialog; -}; - -class QMacPrintEnginePrivate : public QPaintEnginePrivate -{ - Q_DECLARE_PUBLIC(QMacPrintEngine) -public: - QPrinter::PrinterMode mode; - QPrinter::PrinterState state; - QPrinter::Orientation orient; - NSPrintInfo *printInfo; - PMPageFormat format; - PMPrintSettings settings; - PMPrintSession session; - PMResolution resolution; - QString outputFilename; - bool fullPage; - QPaintEngine *paintEngine; - bool suppressStatus; - bool hasCustomPaperSize; - QSizeF customSize; - bool hasCustomPageMargins; - qreal leftMargin; - qreal topMargin; - qreal rightMargin; - qreal bottomMargin; - QHash<QMacPrintEngine::PrintEnginePropertyKey, QVariant> valueCache; - QMacPrintEnginePrivate() : mode(QPrinter::ScreenResolution), state(QPrinter::Idle), - orient(QPrinter::Portrait), printInfo(0), format(0), settings(0), - session(0), paintEngine(0), suppressStatus(false), - hasCustomPaperSize(false), hasCustomPageMargins(false) {} - ~QMacPrintEnginePrivate(); - void initialize(); - void releaseSession(); - bool newPage_helper(); - void setPaperSize(QPrinter::PaperSize ps); - QPrinter::PaperSize paperSize() const; - QList<QVariant> supportedResolutions() const; - inline bool isPrintSessionInitialized() const - { -#ifndef QT_MAC_USE_COCOA - return session != 0; -#else - return printInfo != 0; -#endif - } - bool shouldSuppressStatus() const; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER - -#endif // QPRINTENGINE_WIN_P_H diff --git a/src/gui/painting/qprintengine_ps.cpp b/src/gui/painting/qprintengine_ps.cpp deleted file mode 100644 index 89bec21f38..0000000000 --- a/src/gui/painting/qprintengine_ps.cpp +++ /dev/null @@ -1,972 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qplatformdefs.h" - -#include <private/qprintengine_ps_p.h> -#include <private/qpainter_p.h> -#include <private/qfontengine_p.h> -#include <private/qpaintengine_p.h> -#include <private/qpdf_p.h> - -#ifndef QT_NO_PRINTER - -#include "qprinter.h" -#include "qpainter.h" -#include "qapplication.h" -#include "qpixmap.h" -#include "qimage.h" -#include "qdatetime.h" -#include "qstring.h" -#include "qbytearray.h" -#include "qhash.h" -#include "qbuffer.h" -#include "qsettings.h" -#include "qmap.h" -#include "qbitmap.h" -#include "qregion.h" -#include "qimagewriter.h" -#include <private/qpainterpath_p.h> -#include <qdebug.h> -#include <private/qdrawhelper_p.h> -#include <private/qmutexpool_p.h> - -#ifndef Q_OS_WIN -#include <unistd.h> -#endif -#include <stdlib.h> -#include <limits.h> - -QT_BEGIN_NAMESPACE - -static bool qt_gen_epsf = false; - -void qt_generate_epsf(bool b) -{ - qt_gen_epsf = b; -} - -static const char *const ps_header = -"/BD{bind def}bind def/d2{dup dup}BD/ED{exch def}BD/D0{0 ED}BD/F{setfont}BD\n" -"/RL{rlineto}BD/CM{currentmatrix}BD/SM{setmatrix}BD/TR{translate}BD/SD\n" -"{setdash}BD/SC{aload pop setrgbcolor}BD/CR{currentfile read pop}BD/i{index}\n" -"BD/scs{setcolorspace}BD/DB{dict dup begin}BD/DE{end def}BD/ie{ifelse}BD/gs\n" -"{gsave}BD/gr{grestore}BD/w{setlinewidth}BD/d{setdash}BD/J{setlinecap}BD/j\n" -"{setlinejoin}BD/scn{3 array astore/BCol exch def}BD/SCN{3 array astore/PCol\n" -"exch def}BD/cm{6 array astore concat}BD/m{moveto}BD/l{lineto}BD/c{curveto}BD\n" -"/h{closepath}BD/W{clip}BD/W*{eoclip}BD/n{newpath}BD/q{gsave 10 dict begin}BD\n" -"/Q{end grestore}BD/re{4 2 roll m dup 0 exch RL exch 0 RL 0 exch neg RL h}BD\n" -"/S{gs PCol SC stroke gr n}BD/BT{gsave 10 dict begin/_m matrix CM def BCol\n" -"SC}BD/ET{end grestore}BD/Tf{/_fs ED findfont[_fs 0 0 _fs 0 0]makefont F}BD\n" -"/Tm{6 array astore concat}BD/Td{translate}BD/Tj{0 0 m show}BD/BDC{pop pop}BD\n" -"/EMC{}BD/BSt 0 def/WFi false def/BCol[1 1 1]def/PCol[0 0 0]def/BDArr[0.94\n" -"0.88 0.63 0.50 0.37 0.12 0.06]def/level3{/languagelevel where{pop\n" -"languagelevel 3 ge}{false}ie}BD/QCIgray D0/QCIcolor D0/QCIindex D0/QCI{\n" -"/colorimage where{pop false 3 colorimage}{exec/QCIcolor ED/QCIgray QCIcolor\n" -"length 3 idiv string def 0 1 QCIcolor length 3 idiv 1 sub{/QCIindex ED/_x\n" -"QCIindex 3 mul def QCIgray QCIindex QCIcolor _x get 0.30 mul QCIcolor _x 1\n" -"add get 0.59 mul QCIcolor _x 2 add get 0.11 mul add add cvi put}for QCIgray\n" -"image}ie}BD/di{gs TR 1 i 1 eq{pop pop false 3 1 roll BCol SC imagemask}{dup\n" -"false ne{level3}{false}ie{/_ma ED 8 eq{/_dc[0 1]def/DeviceGray}{/_dc[0 1 0 1\n" -"0 1]def/DeviceRGB}ie scs/_im ED/_mt ED/_h ED/_w ED <</ImageType 3/DataDict\n" -"<</ImageType 1/Width _w/Height _h/ImageMatrix _mt/DataSource _im\n" -"/BitsPerComponent 8/Decode _dc >>/MaskDict <</ImageType 1/Width _w/Height _h\n" -"/ImageMatrix _mt/DataSource _ma/BitsPerComponent 1/Decode[0 1]>>\n" -"/InterleaveType 3 >> image}{pop 8 4 1 roll 8 eq{image}{QCI}ie}ie}ie gr}BD/BF\n" -"{gs BSt 1 eq{BCol SC WFi{fill}{eofill}ie}if BSt 2 ge BSt 8 le and{BDArr BSt\n" -"2 sub get/_sc ED BCol{1. exch sub _sc mul 1. exch sub}forall 3 array astore\n" -"SC WFi{fill}{eofill}ie}if BSt 9 ge BSt 14 le and{WFi{W}{W*}ie pathbbox 3 i 3\n" -"i TR 4 2 roll 3 2 roll exch sub/_h ED sub/_w ED BCol SC 0.3 w n BSt 9 eq BSt\n" -"11 eq or{0 4 _h{dup 0 exch m _w exch l}for}if BSt 10 eq BSt 11 eq or{0 4 _w{\n" -"dup 0 m _h l}for}if BSt 12 eq BSt 14 eq or{_w _h gt{0 6 _w _h add{dup 0 m _h\n" -"sub _h l}for}{0 6 _w _h add{dup 0 exch m _w sub _w exch l}for}ie}if BSt 13\n" -"eq BSt 14 eq or{_w _h gt{0 6 _w _h add{dup _h m _h sub 0 l}for}{0 6 _w _h\n" -"add{dup _w exch m _w sub 0 exch l}for}ie}if stroke}if BSt 15 eq{}if BSt 24\n" -"eq{}if gr}BD/f{/WFi true def BF n}BD/f*{/WFi false def BF n}BD/B{/WFi true\n" -"def BF S n}BD/B*{/WFi false def BF S n}BD/QI{/C save def pageinit q n}BD/QP{\n" -"Q C restore showpage}BD/SPD{/setpagedevice where{<< 3 1 roll >>\n" -"setpagedevice}{pop pop}ie}BD/T1AddMapping{10 dict begin/glyphs ED/fnt ED\n" -"/current fnt/NumGlyphs get def/CMap fnt/CMap get def 0 1 glyphs length 1 sub\n" -"{glyphs exch get/gn ED current dup 256 mod/min ED 256 idiv/maj ED CMap dup\n" -"maj get dup null eq{pop 256 array 0 1 255{1 i exch/.notdef put}for}if dup\n" -"min gn put maj exch put/current current 1 add def}for fnt/CMap CMap put fnt\n" -"/NumGlyphs current put end}def/T1AddGlyphs{10 dict begin/glyphs ED/fnt ED\n" -"/current fnt/NumGlyphs get def/CMap fnt/CMap get def/CharStrings fnt\n" -"/CharStrings get def 0 1 glyphs length 2 idiv 1 sub{2 mul dup glyphs exch\n" -"get/gn ED 1 add glyphs exch get/cs ED current dup 256 mod/min ED 256 idiv\n" -"/maj ED CMap dup maj get dup null eq{pop 256 array 0 1 255{1 i exch/.notdef\n" -"put}for}if dup min gn put maj exch put CharStrings gn cs put/current current\n" -"1 add def}for fnt/CharStrings CharStrings put fnt/CMap CMap put fnt\n" -"/NumGlyphs current put end}def/StringAdd{1 i length 1 i length add string 3\n" -"1 roll 2 i 0 3 i putinterval 2 i 2 i length 2 i putinterval pop pop}def\n" -"/T1Setup{10 dict begin dup/FontName ED (-Base) StringAdd cvx cvn/Font ED\n" -"/MaxPage Font/NumGlyphs get 1 sub 256 idiv def/FDepVector MaxPage 1 add\n" -"array def/Encoding MaxPage 1 add array def 0 1 MaxPage{dup Encoding exch dup\n" -"put dup/Page ED FontName (-) StringAdd exch 20 string cvs StringAdd cvn Font\n" -"0 dict copy d2/CMap get Page get/Encoding exch put definefont FDepVector\n" -"exch Page exch put}for FontName cvn <</FontType 0/FMapType 2/FontMatrix[1 0\n" -"0 1 0 0]/Encoding Encoding/FDepVector FDepVector >> definefont pop end}def\n"; - - - -// ------------------------------End of static data ---------------------------------- - -// make sure DSC comments are not longer than 255 chars per line. -static QByteArray wrapDSC(const QByteArray &str) -{ - QByteArray dsc = str.simplified(); - const int wrapAt = 254; - QByteArray wrapped; - if (dsc.length() < wrapAt) - wrapped = dsc; - else { - wrapped = dsc.left(wrapAt); - QByteArray tmp = dsc.mid(wrapAt); - while (tmp.length() > wrapAt-3) { - wrapped += "\n%%+" + tmp.left(wrapAt-3); - tmp = tmp.mid(wrapAt-3); - } - wrapped += "\n%%+" + tmp; - } - return wrapped + '\n'; -} - -// ----------------------------- Internal class declarations ----------------------------- - -QPSPrintEnginePrivate::QPSPrintEnginePrivate(QPrinter::PrinterMode m) - : QPdfBaseEnginePrivate(m), - printerState(QPrinter::Idle), hugeDocument(false), headerDone(false) -{ - useAlphaEngine = true; - postscript = true; - - firstPage = true; - -#ifndef QT_NO_SETTINGS - QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); - settings.beginGroup(QLatin1String("Qt")); - embedFonts = settings.value(QLatin1String("embedFonts"), true).toBool(); -#else - embedFonts = true; -#endif -} - -QPSPrintEnginePrivate::~QPSPrintEnginePrivate() -{ -} - -QT_BEGIN_INCLUDE_NAMESPACE -#include <qdebug.h> -QT_END_INCLUDE_NAMESPACE - -static void ps_r7(QPdf::ByteStream& stream, const char * s, int l) -{ - int i = 0; - uchar line[84]; - int col = 0; - - while(i < l) { - line[col++] = s[i++]; - if (i < l - 1 && col >= 76) { - line[col++] = '\n'; - line[col++] = '\0'; - stream << (const char *)line; - col = 0; - } - } - if (col > 0) { - while((col&3) != 0) - line[col++] = '%'; // use a comment as padding - line[col++] = '\n'; - line[col++] = '\0'; - stream << (const char *)line; - } -} - -static QByteArray runlengthEncode(const QByteArray &input) -{ - if (!input.length()) - return input; - - const char *data = input.constData(); - - QByteArray out; - int start = 0; - char last = *data; - - enum State { - Undef, - Equal, - Diff - }; - State state = Undef; - - int i = 1; - int written = 0; - while (1) { - bool flush = (i == input.size()); - if (!flush) { - switch(state) { - case Undef: - state = (last == data[i]) ? Equal : Diff; - break; - case Equal: - if (data[i] != last) - flush = true; - break; - case Diff: - if (data[i] == last) { - --i; - flush = true; - } - } - } - if (flush || i - start == 128) { - int size = i - start; - if (state == Equal) { - out.append((char)(uchar)(257-size)); - out.append(last); - written += size; - } else { - out.append((char)(uchar)size-1); - while (start < i) - out.append(data[start++]); - written += size; - } - state = Undef; - start = i; - if (i == input.size()) - break; - } - last = data[i]; - ++i; - }; - out.append((char)(uchar)128); - return out; -} - -enum format { - Raw, - Runlength, - DCT -}; -static const char *const filters[3] = { - " ", - "/RunLengthDecode filter ", - "/DCTDecode filter " -}; - -static QByteArray compressHelper(const QImage &image, bool gray, int *format) -{ - // we can't use premultiplied here - QByteArray pixelData; - int depth = image.depth(); - - Q_ASSERT(image.format() != QImage::Format_ARGB32_Premultiplied); - - if (depth != 1 && !gray && QImageWriter::supportedImageFormats().contains("jpeg")) { - QBuffer buffer(&pixelData); - QImageWriter writer(&buffer, "jpeg"); - writer.setQuality(94); - writer.write(image); - *format = DCT; - } else { - int width = image.width(); - int height = image.height(); - int size = width*height; - - if (depth == 1) - size = (width+7)/8*height; - else if (!gray) - size = size*3; - - pixelData.resize(size); - uchar *pixel = (uchar *)pixelData.data(); - int i = 0; - if (depth == 1) { - QImage::Format format = image.format(); - memset(pixel, 0xff, size); - for(int y=0; y < height; y++) { - const uchar * s = image.scanLine(y); - for(int x=0; x < width; x++) { - // need to copy bit for bit... - bool b = (format == QImage::Format_MonoLSB) ? - (*(s + (x >> 3)) >> (x & 7)) & 1 : - (*(s + (x >> 3)) << (x & 7)) & 0x80 ; - if (b) - pixel[i >> 3] ^= (0x80 >> (i & 7)); - i++; - } - // we need to align to 8 bit here - i = (i+7) & 0xffffff8; - } - } else if (depth == 8) { - for(int y=0; y < height; y++) { - const uchar * s = image.scanLine(y); - for(int x=0; x < width; x++) { - QRgb rgb = image.color(s[x]); - if (gray) { - pixel[i] = (unsigned char) qGray(rgb); - i++; - } else { - pixel[i] = (unsigned char) qRed(rgb); - pixel[i+1] = (unsigned char) qGreen(rgb); - pixel[i+2] = (unsigned char) qBlue(rgb); - i += 3; - } - } - } - } else { - for(int y=0; y < height; y++) { - QRgb * s = (QRgb*)(image.scanLine(y)); - for(int x=0; x < width; x++) { - QRgb rgb = (*s++); - if (gray) { - pixel[i] = (unsigned char) qGray(rgb); - i++; - } else { - pixel[i] = (unsigned char) qRed(rgb); - pixel[i+1] = (unsigned char) qGreen(rgb); - pixel[i+2] = (unsigned char) qBlue(rgb); - i += 3; - } - } - } - } - *format = Raw; - if (depth == 1) { - pixelData = runlengthEncode(pixelData); - *format = Runlength; - } - } - QByteArray outarr = QPdf::ascii85Encode(pixelData); - return outarr; -} - -void QPSPrintEnginePrivate::drawImageHelper(qreal x, qreal y, qreal w, qreal h, const QImage &img, - const QImage &mask, bool gray, qreal scaleX, qreal scaleY) -{ - Q_UNUSED(h); - Q_UNUSED(w); - int width = img.width(); - int height = img.height(); - - QByteArray out; - int size = 0; - const char *bits; - - if (!mask.isNull()) { - int format; - out = compressHelper(mask, true, &format); - size = (width+7)/8*height; - *currentPage << "/mask currentfile/ASCII85Decode filter" - << filters[format] - << size << " string readstring\n"; - ps_r7(*currentPage, out, out.size()); - *currentPage << " pop def\n"; - } - if (img.depth() == 1) { - size = (width+7)/8*height; - bits = "1 "; - } else if (gray) { - size = width*height; - bits = "8 "; - } else { - size = width*height*3; - bits = "24 "; - } - - int format; - out = compressHelper(img, gray, &format); - *currentPage << "/sl currentfile/ASCII85Decode filter" - << filters[format] - << size << " string readstring\n"; - ps_r7(*currentPage, out, out.size()); - *currentPage << " pop def\n"; - *currentPage << width << ' ' << height << '[' << scaleX << " 0 0 " << scaleY << " 0 0]sl " - << bits << (!mask.isNull() ? "mask " : "false ") - << x << ' ' << y << " di\n"; -} - - -void QPSPrintEnginePrivate::drawImage(qreal x, qreal y, qreal w, qreal h, - const QImage &image, const QImage &msk) -{ - if (!w || !h || image.isNull()) return; - - QImage img(image); - QImage mask(msk); - - if (image.format() == QImage::Format_ARGB32_Premultiplied) - img = image.convertToFormat(QImage::Format_ARGB32); - - if (!msk.isNull() && msk.format() == QImage::Format_ARGB32_Premultiplied) - mask = msk.convertToFormat(QImage::Format_ARGB32); - - int width = img.width(); - int height = img.height(); - qreal scaleX = width/w; - qreal scaleY = height/h; - - bool gray = (colorMode == QPrinter::GrayScale) || img.allGray(); - int splitSize = 21830 * (gray ? 3 : 1); - if (width * height > splitSize) { // 65535/3, tolerance for broken printers - int images, subheight; - images = (width * height + splitSize - 1) / splitSize; - subheight = (height + images-1) / images; - while (subheight * width > splitSize) { - images++; - subheight = (height + images-1) / images; - } - int suby = 0; - const QImage constImg(img); - const QImage constMask(mask); - while(suby < height) { - qreal subImageHeight = qMin(subheight, height-suby); - const QImage subImage(constImg.scanLine(suby), width, subImageHeight, - constImg.bytesPerLine(), constImg.format()); - const QImage subMask = mask.isNull() ? mask : QImage(constMask.scanLine(suby), width, subImageHeight, - constMask.bytesPerLine(), constMask.format()); - drawImageHelper(x, y + suby/scaleY, w, subImageHeight/scaleY, - subImage, subMask, gray, scaleX, scaleY); - suby += subheight; - } - } else { - drawImageHelper(x, y, width, height, img, mask, gray, scaleX, scaleY); - } -} - -void QPSPrintEnginePrivate::emitHeader(bool finished) -{ - QPSPrintEngine *q = static_cast<QPSPrintEngine *>(q_ptr); - QPrinter *printer = static_cast<QPrinter*>(pdev); - - if (creator.isEmpty()) - creator = QLatin1String("Qt " QT_VERSION_STR); - - QByteArray header; - QPdf::ByteStream s(&header); - - qreal scale = 72. / ((qreal) q->metric(QPaintDevice::PdmDpiY)); - QRect pageRect = this->pageRect(); - QRect paperRect = this->paperRect(); - int mtop = pageRect.top() - paperRect.top(); - int mleft = pageRect.left() - paperRect.left(); - int mbottom = paperRect.bottom() - pageRect.bottom(); - int mright = paperRect.right() - pageRect.right(); - int width = pageRect.width(); - int height = pageRect.height(); - if (finished && pageCount == 1 && copies == 1 && - ((fullPage && qt_gen_epsf) || (outputFileName.endsWith(QLatin1String(".eps"))))) - { - // According to the EPSF 3.0 spec it is required that the PS - // version is PS-Adobe-3.0 - s << "%!PS-Adobe-3.0"; - if (!boundingBox.isValid()) - boundingBox.setRect(0, 0, width, height); - if (orientation == QPrinter::Landscape) { - if (!fullPage) - boundingBox.translate(-mleft, -mtop); - s << " EPSF-3.0\n%%BoundingBox: " - << int((printer->height() - boundingBox.bottom())*scale) // llx - << int((printer->width() - boundingBox.right())*scale - 1) // lly - << int((printer->height() - boundingBox.top())*scale + 1) // urx - << int((printer->width() - boundingBox.left())*scale); // ury - } else { - if (!fullPage) - boundingBox.translate(mleft, -mtop); - s << " EPSF-3.0\n%%BoundingBox: " - << int((boundingBox.left())*scale) - << int((printer->height() - boundingBox.bottom())*scale - 1) - << int((boundingBox.right())*scale + 1) - << int((printer->height() - boundingBox.top())*scale); - } - } else { - s << "%!PS-Adobe-1.0"; - int w = width + (fullPage ? 0 : mleft + mright); - int h = height + (fullPage ? 0 : mtop + mbottom); - w = (int)(w*scale); - h = (int)(h*scale); - // set a bounding box according to the DSC - if (orientation == QPrinter::Landscape) - s << "\n%%BoundingBox: 0 0 " << h << w; - else - s << "\n%%BoundingBox: 0 0 " << w << h; - } - s << '\n' << wrapDSC("%%Creator: " + creator.toUtf8()); - if (!title.isEmpty()) - s << wrapDSC("%%Title: " + title.toUtf8()); -#ifndef QT_NO_DATESTRING - s << "%%CreationDate: " << QDateTime::currentDateTime().toString().toUtf8(); -#endif - s << "\n%%Orientation: "; - if (orientation == QPrinter::Landscape) - s << "Landscape"; - else - s << "Portrait"; - - s << "\n%%Pages: (atend)" - "\n%%DocumentFonts: (atend)" - "\n%%EndComments\n" - - "%%BeginProlog\n" - "% Prolog copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).\n" - "% You may copy this prolog in any way that is directly related to this document.\n" - "% For other use of this prolog, see your licensing agreement for Qt.\n" - << ps_header << '\n'; - - - s << "/pageinit {\n"; - if (!fullPage) { - if (orientation == QPrinter::Portrait) - s << mleft*scale << mbottom*scale << "translate\n"; - else - s << mtop*scale << mleft*scale << "translate\n"; - } - if (orientation == QPrinter::Portrait) { - s << "% " << printer->widthMM() << '*' << printer->heightMM() - << "mm (portrait)\n0 " << height*scale - << "translate " << scale << '-' << scale << "scale } def\n"; - } else { - s << "% " << printer->heightMM() << '*' << printer->widthMM() - << " mm (landscape)\n 90 rotate " << scale << '-' << scale << "scale } def\n"; - } - s << "%%EndProlog\n"; - - outDevice->write(header); - headerDone = true; -} - - -void QPSPrintEnginePrivate::emitPages() -{ - if (!hugeDocument) { - for (QHash<QFontEngine::FaceId, QFontSubset *>::const_iterator it = fonts.constBegin(); - it != fonts.constEnd(); ++it) - outDevice->write((*it)->toType1()); - } - - QIODevice *content = buffer.stream(); - // Write the page contents in chunks. - while (!content->atEnd()) { - QByteArray buf = content->read(currentPage->chunkSize()); - if (!buf.isEmpty()) - outDevice->write(buf); - } - content = currentPage->stream(); - // Write the page contents in chunks. - while (!content->atEnd()) { - QByteArray buf = content->read(currentPage->chunkSize()); - if (!buf.isEmpty()) - outDevice->write(buf); - } - outDevice->write(trailer); - - buffer.clear(); - currentPage->clear(); - trailer = QByteArray(); - hugeDocument = true; -} - - -#ifdef Q_WS_QWS -static const int max_in_memory_size = 2000000; -#else -static const int max_in_memory_size = 32000000; -#endif - -void QPSPrintEnginePrivate::flushPage(bool last) -{ - if (!last && currentPage->stream()->size() == 0) - return; - - QPdf::ByteStream e(&trailer); - buffer << "%%Page: " - << pageCount << pageCount << "\n" - "%%BeginPageSetup\n" - "QI\n"; - if (hugeDocument) { - for (QHash<QFontEngine::FaceId, QFontSubset *>::const_iterator it = fonts.constBegin(); - it != fonts.constEnd(); ++it) { - if (currentPage->fonts.contains((*it)->object_id)) { - if ((*it)->downloaded_glyphs == 0) { - buffer << (*it)->toType1(); - (*it)->downloaded_glyphs = 0; - } else { - buffer << (*it)->type1AddedGlyphs(); - } - } - } - } - for (int i = 0; i < currentPage->fonts.size(); ++i) - buffer << "(F" << QByteArray::number(currentPage->fonts.at(i)) << ") T1Setup\n"; - - buffer << "%%EndPageSetup\nq\n"; - e << "\nQ QP\n"; - if (last || hugeDocument - || buffer.stream()->size() + currentPage->stream()->size() > max_in_memory_size) { -// qDebug("emiting header at page %d", pageCount); - if (!headerDone) - emitHeader(last); - emitPages(); - } else { - buffer << *currentPage << e; - currentPage->clear(); - trailer.clear(); - } - pageCount++; -} - -// ================ PSPrinter class ======================== - -QPSPrintEngine::QPSPrintEngine(QPrinter::PrinterMode m) - : QPdfBaseEngine(*(new QPSPrintEnginePrivate(m)), - PrimitiveTransform - | PatternTransform - | PixmapTransform - | PainterPaths - | PatternBrush - ) -{ -} - -static void ignoreSigPipe(bool b) -{ -#ifndef QT_NO_LPR - static struct sigaction *users_sigpipe_handler = 0; - static int lockCount = 0; - -#ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(&users_sigpipe_handler)); -#endif - - if (b) { - if (lockCount++ > 0) - return; - - if (users_sigpipe_handler != 0) - return; // already ignoring sigpipe - - users_sigpipe_handler = new struct sigaction; - struct sigaction tmp_sigpipe_handler; - tmp_sigpipe_handler.sa_handler = SIG_IGN; - sigemptyset(&tmp_sigpipe_handler.sa_mask); - tmp_sigpipe_handler.sa_flags = 0; - - if (sigaction(SIGPIPE, &tmp_sigpipe_handler, users_sigpipe_handler) == -1) { - delete users_sigpipe_handler; - users_sigpipe_handler = 0; - } - } - else { - if (--lockCount > 0) - return; - - if (users_sigpipe_handler == 0) - return; // not ignoring sigpipe - - if (sigaction(SIGPIPE, users_sigpipe_handler, 0) == -1) - qWarning("QPSPrintEngine: Could not restore SIGPIPE handler"); - - delete users_sigpipe_handler; - users_sigpipe_handler = 0; - } -#else - Q_UNUSED(b); -#endif -} -QPSPrintEngine::~QPSPrintEngine() -{ - Q_D(QPSPrintEngine); - if (d->fd >= 0) -#if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400 - ::_close(d->fd); -#else - ::close(d->fd); -#endif -} - -bool QPSPrintEngine::begin(QPaintDevice *pdev) -{ - Q_D(QPSPrintEngine); - - if (d->fd >= 0) - return true; - - if (d->useAlphaEngine) { - QAlphaPaintEngine::begin(pdev); - if (!continueCall()) - return true; - } - - if(!QPdfBaseEngine::begin(pdev)) { - d->printerState = QPrinter::Error; - return false; - } - - d->pageCount = 1; // initialize state - - d->pen = QPen(Qt::black); - d->brush = Qt::NoBrush; - d->hasPen = true; - d->hasBrush = false; - d->clipEnabled = false; - d->allClipped = false; - d->boundingBox = QRect(); - d->fontsUsed = ""; - d->hugeDocument = false; - d->simplePen = false; - - setActive(true); - d->printerState = QPrinter::Active; - - newPage(); - - return true; -} - -bool QPSPrintEngine::end() -{ - Q_D(QPSPrintEngine); - - if (d->useAlphaEngine) { - QAlphaPaintEngine::end(); - if (!continueCall()) - return true; - } - - // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE - // if lp/lpr dies - ignoreSigPipe(true); - d->flushPage(true); - QByteArray trailer; - QPdf::ByteStream s(&trailer); - s << "%%Trailer\n" - "%%Pages: " << d->pageCount - 1 << '\n' << - wrapDSC("%%DocumentFonts: " + d->fontsUsed); - s << "%%EOF\n"; - d->outDevice->write(trailer); - - QPdfBaseEngine::end(); - ignoreSigPipe(false); - - d->firstPage = true; - d->headerDone = false; - - setActive(false); - d->printerState = QPrinter::Idle; - d->pdev = 0; - - return true; -} - -void QPSPrintEngine::setBrush() -{ - Q_D(QPSPrintEngine); -#if 0 - bool specifyColor; - int gStateObject = 0; - int patternObject = d->addBrushPattern(brush, d->stroker.matrix, brushOrigin, &specifyColor, &gStateObject); - - *d->currentPage << (patternObject ? "/PCSp cs " : "/CSp cs "); - if (specifyColor) { - QColor rgba = brush.color(); - *d->currentPage << rgba.redF() - << rgba.greenF() - << rgba.blueF(); - } - if (patternObject) - *d->currentPage << "/Pat" << patternObject; - *d->currentPage << "scn\n"; -#endif - QColor rgba = d->brush.color(); - if (d->colorMode == QPrinter::GrayScale) { - qreal gray = qGray(rgba.rgba())/255.; - *d->currentPage << gray << gray << gray; - } else { - *d->currentPage << rgba.redF() - << rgba.greenF() - << rgba.blueF(); - } - *d->currentPage << "scn\n" - << "/BSt " << d->brush.style() << "def\n"; -} - -void QPSPrintEngine::drawImageInternal(const QRectF &r, QImage image, bool bitmap) -{ - Q_D(QPSPrintEngine); - if (d->clipEnabled && d->allClipped) - return; - if (bitmap && image.depth() != 1) - bitmap = false; - QImage mask; - // the below is not necessary since it's handled by the alpha - // engine - if (!d->useAlphaEngine && !bitmap) { - if (image.format() == QImage::Format_Mono || image.format() == QImage::Format_MonoLSB) - image = image.convertToFormat(QImage::Format_Indexed8); - if (image.hasAlphaChannel()) { - // get better alpha dithering - int xscale = image.width(); - xscale *= xscale <= 800 ? 4 : (xscale <= 1600 ? 2 : 1); - int yscale = image.height(); - yscale *= yscale <= 800 ? 4 : (yscale <= 1600 ? 2 : 1); - image = image.scaled(xscale, yscale); - mask = image.createAlphaMask(Qt::OrderedAlphaDither); - } - } - *d->currentPage << "q\n"; - if(!d->simplePen) - *d->currentPage << QPdf::generateMatrix(d->stroker.matrix); - QBrush b = d->brush; - if (image.depth() == 1) { - // set current pen as brush - d->brush = d->pen.brush(); - setBrush(); - } - d->drawImage(r.x(), r.y(), r.width(), r.height(), image, mask); - *d->currentPage << "Q\n"; - d->brush = b; -} - - -void QPSPrintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr, - Qt::ImageConversionFlags) -{ - Q_D(QPSPrintEngine); - - if (d->useAlphaEngine) { - QAlphaPaintEngine::drawImage(r, img, sr); - if (!continueCall()) - return; - } - QImage image = img.copy(sr.toRect()); - drawImageInternal(r, image, false); -} - -void QPSPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) -{ - Q_D(QPSPrintEngine); - - if (d->useAlphaEngine) { - QAlphaPaintEngine::drawPixmap(r, pm, sr); - if (!continueCall()) - return; - } - - QImage img = pm.copy(sr.toRect()).toImage(); - drawImageInternal(r, img, true); -} - -void QPSPrintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &p) -{ - Q_D(QPSPrintEngine); - - if (d->useAlphaEngine) { - QAlphaPaintEngine::drawTiledPixmap(r, pixmap, p); - if (!continueCall()) - return; - } - - if (d->clipEnabled && d->allClipped) - return; - // ### Optimize implementation! - qreal yPos = r.y(); - qreal yOff = p.y(); - while(yPos < r.y() + r.height()) { - qreal drawH = pixmap.height() - yOff; // Cropping first row - if (yPos + drawH > r.y() + r.height()) // Cropping last row - drawH = r.y() + r.height() - yPos; - qreal xPos = r.x(); - qreal xOff = p.x(); - while(xPos < r.x() + r.width()) { - qreal drawW = pixmap.width() - xOff; // Cropping first column - if (xPos + drawW > r.x() + r.width()) // Cropping last column - drawW = r.x() + r.width() - xPos; - // ######## - painter()->drawPixmap(QPointF(xPos, yPos).toPoint(), pixmap, - QRectF(xOff, yOff, drawW, drawH).toRect()); - xPos += drawW; - xOff = 0; - } - yPos += drawH; - yOff = 0; - } - -} - -bool QPSPrintEngine::newPage() -{ - Q_D(QPSPrintEngine); - - if (!d->firstPage && d->useAlphaEngine) - flushAndInit(); - - // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE - // if lp/lpr dies - ignoreSigPipe(true); - if (!d->firstPage) - d->flushPage(); - d->firstPage = false; - ignoreSigPipe(false); - - delete d->currentPage; - d->currentPage = new QPdfPage; - d->stroker.stream = d->currentPage; - - return QPdfBaseEngine::newPage(); -} - -bool QPSPrintEngine::abort() -{ - // ### abort!?! - return false; -} - -QPrinter::PrinterState QPSPrintEngine::printerState() const -{ - Q_D(const QPSPrintEngine); - return d->printerState; -} - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER diff --git a/src/gui/painting/qprintengine_ps_p.h b/src/gui/painting/qprintengine_ps_p.h deleted file mode 100644 index e5203c1041..0000000000 --- a/src/gui/painting/qprintengine_ps_p.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPRINTENGINE_PS_P_H -#define QPRINTENGINE_PS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qpsprinter.cpp and qprinter_x11.cpp. -// This header file may change from version to version without notice, -// or even be removed. -// -// We mean it. -// - -#ifndef QT_NO_PRINTER - -#include "private/qpdf_p.h" -#include "qplatformdefs.h" -#include "QtCore/qlibrary.h" -#include "QtCore/qstringlist.h" -#include "QtCore/qhash.h" -#include "QtCore/qabstractitemmodel.h" - -QT_BEGIN_NAMESPACE - -class QPrinter; -class QPSPrintEnginePrivate; - -class QPSPrintEngine : public QPdfBaseEngine -{ - Q_DECLARE_PRIVATE(QPSPrintEngine) -public: - // QPrinter uses these - explicit QPSPrintEngine(QPrinter::PrinterMode m); - ~QPSPrintEngine(); - - - virtual bool begin(QPaintDevice *pdev); - virtual bool end(); - - void setBrush(); - - virtual void drawImage(const QRectF &r, const QImage &img, const QRectF &sr, Qt::ImageConversionFlags); - virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); - - virtual void drawImageInternal(const QRectF &r, QImage img, bool bitmap); - - virtual QPaintEngine::Type type() const { return QPaintEngine::PostScript; } - - virtual bool newPage(); - virtual bool abort(); - - virtual QPrinter::PrinterState printerState() const; - - virtual Qt::HANDLE handle() const { return 0; } - -private: - Q_DISABLE_COPY(QPSPrintEngine) -}; - -class QPSPrintEnginePrivate : public QPdfBaseEnginePrivate { -public: - QPSPrintEnginePrivate(QPrinter::PrinterMode m); - ~QPSPrintEnginePrivate(); - - void emitHeader(bool finished); - void emitPages(); - void drawImage(qreal x, qreal y, qreal w, qreal h, const QImage &img, const QImage &mask); - void flushPage(bool last = false); - void drawImageHelper(qreal x, qreal y, qreal w, qreal h, const QImage &img, const QImage &mask, - bool gray, qreal scaleX, qreal scaleY); - - int pageCount; - bool epsf; - QByteArray fontsUsed; - - // stores the descriptions of the n first pages. - QPdf::ByteStream buffer; - QByteArray trailer; - - bool firstPage; - - QRect boundingBox; - - QPrinter::PrinterState printerState; - bool hugeDocument; - bool headerDone; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER - -#endif // QPRINTENGINE_PS_P_H diff --git a/src/gui/painting/qprintengine_qws.cpp b/src/gui/painting/qprintengine_qws.cpp deleted file mode 100644 index 7b759c83c2..0000000000 --- a/src/gui/painting/qprintengine_qws.cpp +++ /dev/null @@ -1,886 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qprintengine_qws_p.h> - -#ifndef QT_NO_PRINTER - -#include <private/qpaintengine_raster_p.h> -#include <qimage.h> -#include <qfile.h> -#include <qdebug.h> -#include <QCopChannel> - -QT_BEGIN_NAMESPACE - -#define MM(n) int((n * 720 + 127) / 254) -#define IN(n) int(n * 72) - -extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size); - -QtopiaPrintEngine::QtopiaPrintEngine(QPrinter::PrinterMode mode) - : QPaintEngine(*(new QtopiaPrintEnginePrivate( mode ))) -{ - d_func()->initialize(); -} - -bool QtopiaPrintEngine::begin(QPaintDevice *) -{ - Q_D(QtopiaPrintEngine); - Q_ASSERT_X(d->printerState == QPrinter::Idle, "QtopiaPrintEngine", "printer already active"); - - // Create a new off-screen monochrome image to handle the drawing process. - QSize size = paperRect().size(); - if ( d->pageImage ) - delete d->pageImage; - d->pageImage = new QImage( size, QImage::Format_RGB32 ); - if ( !(d->pageImage) ) - return false; - - // Recreate the paint engine on the new image. - delete d->_paintEngine; - d->_paintEngine = 0; - d->paintEngine()->state = state; - - // Begin the paint process on the image. - if (!d->paintEngine()->begin(d->pageImage)) - return false; - - // Clear the first page to all-white. - clearPage(); - - // Clear the print buffer and output the image header. - d->buffer.clear(); - d->writeG3FaxHeader(); - - // The print engine is currently active. - d->printerState = QPrinter::Active; - return true; -} - -bool QtopiaPrintEngine::end() -{ - Q_D(QtopiaPrintEngine); - - d->paintEngine()->end(); - - // Flush the last page. - flushPage(); - - // Output the fax data to a file (TODO: send to the print queuing daemon). - QString filename; - if ( !d->outputFileName.isEmpty() ) - filename = QString::fromLocal8Bit(qgetenv("HOME").constData()) + QLatin1String("/Documents/") + d->outputFileName; - else - filename = QString::fromLocal8Bit(qgetenv("HOME").constData()) + QLatin1String("/tmp/qwsfax.tiff"); - - setProperty(QPrintEngine::PPK_OutputFileName, filename); - QFile file( filename ); - if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) { - qDebug( "Failed to open %s for printer output", - filename.toLatin1().constData() ); - } else { - file.write( d->buffer.data() ); - file.close(); - } - - // Free up the memory for the image buffer. - d->buffer.clear(); - - // Finalize the print job. - d->printerState = QPrinter::Idle; - - // call qcop service - QMap<QString, QVariant> map; - for ( int x = 0; x <= QPrintEngine::PPK_Duplex; x++ ) - map.insert( QString::number(x), property((QPrintEngine::PrintEnginePropertyKey)(x))); - QVariant variant(map); - - QByteArray data; - QDataStream out(&data, QIODevice::WriteOnly); - out << variant; - QCopChannel::send(QLatin1String("QPE/Service/Print"), QLatin1String("print(QVariant)"), data); - - return true; -} - -QPaintEngine *QtopiaPrintEngine::paintEngine() const -{ - return const_cast<QtopiaPrintEnginePrivate *>(d_func())->paintEngine(); -} - -void QtopiaPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) -{ - Q_D(QtopiaPrintEngine); - Q_ASSERT(d->printerState == QPrinter::Active); - d->paintEngine()->drawPixmap(r, pm, sr); -} - -void QtopiaPrintEngine::drawTextItem(const QPointF &p, const QTextItem &ti) -{ - Q_D(QtopiaPrintEngine); - Q_ASSERT(d->printerState == QPrinter::Active); - d->paintEngine()->drawTextItem(p, ti); -} - -void QtopiaPrintEngine::updateState(const QPaintEngineState &state) -{ - Q_D(QtopiaPrintEngine); - d->paintEngine()->updateState(state); -} - -QRect QtopiaPrintEngine::paperRect() const -{ - QSizeF s = qt_paperSizeToQSizeF(d_func()->paperSize); - s.rwidth() = MM(s.width()); - s.rheight() = MM(s.height()); - int w = qRound(s.width()*d_func()->resolution/72.); - int h = qRound(s.height()*d_func()->resolution/72.); - if (d_func()->orientation == QPrinter::Portrait) - return QRect(0, 0, w, h); - else - return QRect(0, 0, h, w); -} - -QRect QtopiaPrintEngine::pageRect() const -{ - QRect r = paperRect(); - if (d_func()->fullPage) - return r; - // would be nice to get better margins than this. - return QRect(d_func()->resolution/3, d_func()->resolution/3, r.width()-2*d_func()->resolution/3, r.height()-2*d_func()->resolution/3); -} - -bool QtopiaPrintEngine::newPage() -{ - flushPage(); - clearPage(); - ++(d_func()->pageNumber); - return true; -} - -bool QtopiaPrintEngine::abort() -{ - return false; -} - -QPrinter::PrinterState QtopiaPrintEngine::printerState() const -{ - return d_func()->printerState; -} - -int QtopiaPrintEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const -{ - int val; - QRect r = d_func()->fullPage ? paperRect() : pageRect(); - switch (metricType) { - case QPaintDevice::PdmWidth: - val = r.width(); - break; - case QPaintDevice::PdmHeight: - val = r.height(); - break; - case QPaintDevice::PdmDpiX: - val = d_func()->resolution; - break; - case QPaintDevice::PdmDpiY: - val = d_func()->resolution; - break; - case QPaintDevice::PdmPhysicalDpiX: - case QPaintDevice::PdmPhysicalDpiY: - val = QT_QWS_PRINTER_DEFAULT_DPI; - break; - case QPaintDevice::PdmWidthMM: - val = qRound(r.width()*25.4/d_func()->resolution); - break; - case QPaintDevice::PdmHeightMM: - val = qRound(r.height()*25.4/d_func()->resolution); - break; - case QPaintDevice::PdmNumColors: - val = 2; - break; - case QPaintDevice::PdmDepth: - val = 1; - break; - default: - qWarning("QtopiaPrintEngine::metric: Invalid metric command"); - return 0; - } - return val; -} - -QVariant QtopiaPrintEngine::property(PrintEnginePropertyKey key) const -{ - Q_D(const QtopiaPrintEngine); - QVariant ret; - - switch (key) { - case PPK_CollateCopies: - ret = d->collateCopies; - break; - case PPK_ColorMode: - ret = d->colorMode; - break; - case PPK_Creator: - ret = d->creator; - break; - case PPK_DocumentName: - ret = d->docName; - break; - case PPK_FullPage: - ret = d->fullPage; - break; - case PPK_CopyCount: // fallthrough - case PPK_NumberOfCopies: - ret = d->numCopies; - break; - case PPK_SupportsMultipleCopies: - ret = false; - break; - case PPK_Orientation: - ret = d->orientation; - break; - case PPK_OutputFileName: - ret = d->outputFileName; - break; - case PPK_PageOrder: - ret = d->pageOrder; - break; - case PPK_PageRect: - ret = pageRect(); - break; - case PPK_PaperSize: - ret = d->paperSize; - break; - case PPK_PaperRect: - ret = paperRect(); - break; - case PPK_PaperSource: - ret = d->paperSource; - break; - case PPK_PrinterName: - ret = d->printerName; - break; - case PPK_PrinterProgram: - ret = d->printProgram; - break; - case PPK_Resolution: - ret = d->resolution; - break; - case PPK_SupportedResolutions: - ret = QList<QVariant>() << QT_QWS_PRINTER_DEFAULT_DPI; - break; - default: - break; - } - return ret; -} - -void QtopiaPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) -{ - Q_D(QtopiaPrintEngine); - switch (key) { - case PPK_CollateCopies: - d->collateCopies = value.toBool(); - break; - case PPK_ColorMode: - d->colorMode = QPrinter::ColorMode(value.toInt()); - break; - case PPK_Creator: - d->creator = value.toString(); - break; - case PPK_DocumentName: - d->docName = value.toString(); - break; - case PPK_FullPage: - d->fullPage = value.toBool(); - break; - case PPK_CopyCount: // fallthrough - case PPK_NumberOfCopies: - d->numCopies = value.toInt(); - break; - case PPK_Orientation: - d->orientation = QPrinter::Orientation(value.toInt()); - break; - case PPK_OutputFileName: - d->outputFileName = value.toString(); - break; - case PPK_PageOrder: - d->pageOrder = QPrinter::PageOrder(value.toInt()); - break; - case PPK_PaperSize: - d->paperSize = QPrinter::PaperSize(value.toInt()); - break; - case PPK_PaperSource: - d->paperSource = QPrinter::PaperSource(value.toInt()); - case PPK_PrinterName: - d->printerName = value.toString(); - break; - case PPK_PrinterProgram: - d->printProgram = value.toString(); - break; - case PPK_Resolution: - d->resolution = value.toInt(); - break; - default: - break; - } -} - -void QtopiaPrintEngine::clearPage() -{ - d_func()->pageImage->fill(QColor(255, 255, 255).rgb()); -} - -void QtopiaPrintEngine::flushPage() -{ - d_func()->writeG3FaxPage(); -} - -QtopiaPrintEnginePrivate::~QtopiaPrintEnginePrivate() -{ - if ( pageImage ) - delete pageImage; -} - -void QtopiaPrintEnginePrivate::initialize() -{ - _paintEngine = 0; -} - -QPaintEngine *QtopiaPrintEnginePrivate::paintEngine() -{ - if (!_paintEngine) - _paintEngine = new QRasterPaintEngine(pageImage); - return _paintEngine; -} - -void QtopiaPrintEnginePrivate::writeG3FaxHeader() -{ - // Write the TIFF file magic number (little-endian TIFF). - buffer.append( (char)'I' ); - buffer.append( (char)'I' ); - buffer.append( (char)42 ); - buffer.append( (char)0 ); - - // Leave a place-holder for the IFD offset of the first page. - ifdPatch = buffer.size(); - buffer.append( (int)0 ); -} - -// Tag values, from RFC 2301. -#define TIFF_IFD_NEW_SUB_FILE_TYPE 254 -#define TIFF_IFD_IMAGE_WIDTH 256 -#define TIFF_IFD_IMAGE_LENGTH 257 -#define TIFF_IFD_BITS_PER_SAMPLE 258 -#define TIFF_IFD_COMPRESSION 259 -#define TIFF_IFD_PHOTOMETRIC_INTERP 262 -#define TIFF_IFD_FILL_ORDER 266 -#define TIFF_IFD_STRIP_OFFSETS 273 -#define TIFF_IFD_ORIENTATION 274 -#define TIFF_IFD_SAMPLES_PER_PIXEL 277 -#define TIFF_IFD_ROWS_PER_STRIP 278 -#define TIFF_IFD_STRIP_BYTE_COUNTS 279 -#define TIFF_IFD_X_RESOLUTION 282 -#define TIFF_IFD_Y_RESOLUTION 283 -#define TIFF_IFD_PLANAR_CONFIG 284 -#define TIFF_IFD_T4_OPTIONS 292 -#define TIFF_IFD_RESOLUTION_UNIT 296 -#define TIFF_IFD_PAGE_NUMBER 297 -#define TIFF_IFD_CLEAN_FAX_DATA 327 - -// IFD type values. -#define TIFF_TYPE_SHORT 3 -#define TIFF_TYPE_LONG 4 -#define TIFF_TYPE_RATIONAL 5 - -// Construct a SHORT pair from two values. -#define TIFF_SHORT_PAIR(a,b) (((a) & 0xFFFF) | ((b) << 16)) - -// Width of a FAX page in pixels, in the baseline specification from RFC 2301. -// This must be hard-wired, as per the RFC. We truncate any pixels that -// are beyond this limit, or pad lines to reach this limit. -#define TIFF_FAX_WIDTH 1728 - -void QtopiaPrintEnginePrivate::writeG3FaxPage() -{ - // Pad the image file to a word boundary, just in case. - buffer.pad(); - - // Back-patch the IFD link for the previous page. - buffer.patch( ifdPatch, buffer.size() ); - - // Output the contents of the IFD for this page (these must be - // in ascending order of tag value). - buffer.append( (short)19 ); // Number of IFD entries. - writeG3IFDEntry( TIFF_IFD_NEW_SUB_FILE_TYPE, TIFF_TYPE_LONG, 1, 2 ); - writeG3IFDEntry( TIFF_IFD_IMAGE_WIDTH, TIFF_TYPE_LONG, 1, TIFF_FAX_WIDTH ); - writeG3IFDEntry - ( TIFF_IFD_IMAGE_LENGTH, TIFF_TYPE_LONG, 1, pageImage->height() ); - writeG3IFDEntry( TIFF_IFD_BITS_PER_SAMPLE, TIFF_TYPE_SHORT, 1, 1 ); - writeG3IFDEntry( TIFF_IFD_COMPRESSION, TIFF_TYPE_SHORT, 1, 3 ); - writeG3IFDEntry( TIFF_IFD_PHOTOMETRIC_INTERP, TIFF_TYPE_SHORT, 1, 0 ); - writeG3IFDEntry( TIFF_IFD_FILL_ORDER, TIFF_TYPE_SHORT, 1, 1 ); - int stripOffsets = - writeG3IFDEntry( TIFF_IFD_STRIP_OFFSETS, TIFF_TYPE_LONG, 1, 0 ); - writeG3IFDEntry( TIFF_IFD_ORIENTATION, TIFF_TYPE_SHORT, 1, 1 ); - writeG3IFDEntry( TIFF_IFD_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, 1 ); - writeG3IFDEntry - ( TIFF_IFD_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, pageImage->height() ); - int stripBytes = writeG3IFDEntry - ( TIFF_IFD_STRIP_BYTE_COUNTS, TIFF_TYPE_LONG, 1, 0 ); - int xres = - writeG3IFDEntry( TIFF_IFD_X_RESOLUTION, TIFF_TYPE_RATIONAL, 1, 0 ); - int yres = - writeG3IFDEntry( TIFF_IFD_Y_RESOLUTION, TIFF_TYPE_RATIONAL, 1, 0 ); - writeG3IFDEntry( TIFF_IFD_PLANAR_CONFIG, TIFF_TYPE_SHORT, 1, 1 ); - writeG3IFDEntry( TIFF_IFD_T4_OPTIONS, TIFF_TYPE_LONG, 1, 2 ); - writeG3IFDEntry( TIFF_IFD_RESOLUTION_UNIT, TIFF_TYPE_SHORT, 1, 2 ); - writeG3IFDEntry( TIFF_IFD_PAGE_NUMBER, TIFF_TYPE_SHORT, 2, - TIFF_SHORT_PAIR( pageNumber, 0 ) ); - writeG3IFDEntry( TIFF_IFD_CLEAN_FAX_DATA, TIFF_TYPE_SHORT, 1, 0 ); - - // Leave a place-holder for the IFD offset of the next page. - ifdPatch = buffer.size(); - buffer.append( (int)0 ); - - // Output the X and Y resolutions, as rational values (usually 200/1). - buffer.patch( xres, buffer.size() ); - buffer.append( (int)resolution ); - buffer.append( (int)1 ); - buffer.patch( yres, buffer.size() ); - buffer.append( (int)resolution ); - buffer.append( (int)1 ); - - // We are now at the start of the image data - set the strip offset. - int start = buffer.size(); - buffer.patch( stripOffsets, start ); - - // Output the image data. - int width = pageImage->width(); - QImage::Format imageFormat = pageImage->format(); - for ( int y = 0; y < pageImage->height(); ++y ) { - unsigned char *scan = pageImage->scanLine(y); - int prev, pixel, len; - writeG3EOL(); - prev = 0; - len = 0; - - uint currentColor = qRgb(255, 255, 255); // start with white - - for ( int x = 0; x < width && x < TIFF_FAX_WIDTH; ++x ) { - if ( imageFormat == QImage::Format_RGB32 ) { - // read color of the current pixel - uint *p = (uint *)scan + x; - - if ( *p == currentColor ) { // if it is the same color - len++; // imcrement length - } else { // otherwise write color into the buffer - if ( len > 0 ) { - if ( currentColor == qRgb(0, 0, 0) ) - writeG3BlackRun( len ); - else - writeG3WhiteRun( len ); - } - // initialise length and color; - len = 1; - currentColor = *p; - } - } else if ( imageFormat == QImage::Format_Mono ) { - pixel = ((scan[x >> 3] & (1 << (x & 7))) != 0); - if ( pixel != prev ) { - if ( prev ) { - writeG3BlackRun( len ); - } else { - writeG3WhiteRun( len ); - } - prev = pixel; - len = 1; - } else { - ++len; - } - } - } - - if ( imageFormat == QImage::Format_RGB32 ) { - // Output the last run on the line, and pad to TIFF_FAX_WIDTH. - if ( len != 0 ) { - if ( currentColor == qRgb(0, 0, 0) ) - writeG3BlackRun( len ); - else - writeG3WhiteRun( len ); - } - if ( width < TIFF_FAX_WIDTH ) - writeG3WhiteRun( TIFF_FAX_WIDTH - width ); - } else if ( imageFormat == QImage::Format_Mono ) { - if ( len != 0 ) { - if ( prev ) { - writeG3BlackRun( len ); - if ( width < TIFF_FAX_WIDTH ) { - writeG3WhiteRun( TIFF_FAX_WIDTH - width ); - } - } else { - if ( width < TIFF_FAX_WIDTH ) { - writeG3WhiteRun( len + ( TIFF_FAX_WIDTH - width ) ); - } else { - writeG3WhiteRun( len ); - } - } - } - } - } - - // Flush the last partial byte, which is padded with zero fill bits. - if ( partialBits > 0 ) { - buffer.append( (char)( partialByte << ( 8 - partialBits ) ) ); - partialByte = 0; - partialBits = 0; - } - - // end of page add six EOLs - for ( int i = 0; i < 6; i++ ) - writeG3EOL(); - - // Update the byte count for the image data strip. - buffer.patch( stripBytes, buffer.size() - start ); -} - -int QtopiaPrintEnginePrivate::writeG3IFDEntry - ( int tag, int type, int count, int value ) -{ - buffer.append( (short)tag ); - buffer.append( (short)type ); - buffer.append( count ); - buffer.append( value ); - return buffer.size() - 4; // Offset of the value for back-patching. -} - -void QtopiaPrintEnginePrivate::writeG3Code( int code, int bits ) -{ - partialByte = ( ( partialByte << bits ) | code ); - partialBits += bits; - while ( partialBits >= 8 ) { - partialBits -= 8; - buffer.append( (char)( partialByte >> partialBits ) ); - } -} - -void QtopiaPrintEnginePrivate::writeG3WhiteRun( int len ) -{ - static struct { - unsigned short code; - unsigned short bits; - } whiteCodes[64 + 27] = { - {0x0035, 8}, // 0 - {0x0007, 6}, - {0x0007, 4}, - {0x0008, 4}, - {0x000B, 4}, - {0x000C, 4}, - {0x000E, 4}, - {0x000F, 4}, - {0x0013, 5}, // 8 - {0x0014, 5}, - {0x0007, 5}, - {0x0008, 5}, - {0x0008, 6}, - {0x0003, 6}, - {0x0034, 6}, - {0x0035, 6}, - {0x002A, 6}, // 16 - {0x002B, 6}, - {0x0027, 7}, - {0x000C, 7}, - {0x0008, 7}, - {0x0017, 7}, - {0x0003, 7}, - {0x0004, 7}, - {0x0028, 7}, // 24 - {0x002B, 7}, - {0x0013, 7}, - {0x0024, 7}, - {0x0018, 7}, - {0x0002, 8}, - {0x0003, 8}, - {0x001A, 8}, - {0x001B, 8}, // 32 - {0x0012, 8}, - {0x0013, 8}, - {0x0014, 8}, - {0x0015, 8}, - {0x0016, 8}, - {0x0017, 8}, - {0x0028, 8}, - {0x0029, 8}, // 40 - {0x002A, 8}, - {0x002B, 8}, - {0x002C, 8}, - {0x002D, 8}, - {0x0004, 8}, - {0x0005, 8}, - {0x000A, 8}, - {0x000B, 8}, // 48 - {0x0052, 8}, - {0x0053, 8}, - {0x0054, 8}, - {0x0055, 8}, - {0x0024, 8}, - {0x0025, 8}, - {0x0058, 8}, - {0x0059, 8}, // 56 - {0x005A, 8}, - {0x005B, 8}, - {0x004A, 8}, - {0x004B, 8}, - {0x0032, 8}, - {0x0033, 8}, - {0x0034, 8}, - {0x001B, 5}, // Make up codes: 64 - {0x0012, 5}, // 128 - {0x0017, 6}, // 192 - {0x0037, 7}, // 256 - {0x0036, 8}, // 320 - {0x0037, 8}, // 384 - {0x0064, 8}, // 448 - {0x0065, 8}, // 512 - {0x0068, 8}, // 576 - {0x0067, 8}, // 640 - {0x00CC, 9}, // 704 - {0x00CD, 9}, // 768 - {0x00D2, 9}, // 832 - {0x00D3, 9}, // 896 - {0x00D4, 9}, // 960 - {0x00D5, 9}, // 1024 - {0x00D6, 9}, // 1088 - {0x00D7, 9}, // 1152 - {0x00D8, 9}, // 1216 - {0x00D9, 9}, // 1280 - {0x00DA, 9}, // 1344 - {0x00DB, 9}, // 1408 - {0x0098, 9}, // 1472 - {0x0099, 9}, // 1536 - {0x009A, 9}, // 1600 - {0x0018, 6}, // 1664 - {0x009B, 9}, // 1728 - }; - if ( len >= 64 ) { - int index = 63 + (len >> 6); - writeG3Code( whiteCodes[index].code, whiteCodes[index].bits ); - len &= 63; - } - writeG3Code( whiteCodes[len].code, whiteCodes[len].bits ); -} - -void QtopiaPrintEnginePrivate::writeG3BlackRun( int len ) -{ - static struct { - unsigned short code; - unsigned short bits; - } blackCodes[64 + 27] = { - {0x0037, 10}, // 0 - {0x0002, 3}, - {0x0003, 2}, - {0x0002, 2}, - {0x0003, 3}, - {0x0003, 4}, - {0x0002, 4}, - {0x0003, 5}, - {0x0005, 6}, // 8 - {0x0004, 6}, - {0x0004, 7}, - {0x0005, 7}, - {0x0007, 7}, - {0x0004, 8}, - {0x0007, 8}, - {0x0018, 9}, - {0x0017, 10}, // 16 - {0x0018, 10}, - {0x0008, 10}, - {0x0067, 11}, - {0x0068, 11}, - {0x006C, 11}, - {0x0037, 11}, - {0x0028, 11}, - {0x0017, 11}, // 24 - {0x0018, 11}, - {0x00CA, 12}, - {0x00CB, 12}, - {0x00CC, 12}, - {0x00CD, 12}, - {0x0068, 12}, - {0x0069, 12}, - {0x006A, 12}, // 32 - {0x006B, 12}, - {0x00D2, 12}, - {0x00D3, 12}, - {0x00D4, 12}, - {0x00D5, 12}, - {0x00D6, 12}, - {0x00D7, 12}, - {0x006C, 12}, // 40 - {0x006D, 12}, - {0x00DA, 12}, - {0x00DB, 12}, - {0x0054, 12}, - {0x0055, 12}, - {0x0056, 12}, - {0x0057, 12}, - {0x0064, 12}, // 48 - {0x0065, 12}, - {0x0052, 12}, - {0x0053, 12}, - {0x0024, 12}, - {0x0037, 12}, - {0x0038, 12}, - {0x0027, 12}, - {0x0028, 12}, // 56 - {0x0058, 12}, - {0x0059, 12}, - {0x002B, 12}, - {0x002C, 12}, - {0x005A, 12}, - {0x0066, 12}, - {0x0067, 12}, - {0x000F, 10}, // Make up codes: 64 - {0x00C8, 12}, // 128 - {0x00C9, 12}, // 192 - {0x005B, 12}, // 256 - {0x0033, 12}, // 320 - {0x0034, 12}, // 384 - {0x0035, 12}, // 448 - {0x006C, 13}, // 512 - {0x006D, 13}, // 576 - {0x004A, 13}, // 640 - {0x004B, 13}, // 704 - {0x004C, 13}, // 768 - {0x004D, 13}, // 832 - {0x0072, 13}, // 896 - {0x0073, 13}, // 960 - {0x0074, 13}, // 1024 - {0x0075, 13}, // 1088 - {0x0076, 13}, // 1152 - {0x0077, 13}, // 1216 - {0x0052, 13}, // 1280 - {0x0053, 13}, // 1344 - {0x0054, 13}, // 1408 - {0x0055, 13}, // 1472 - {0x005A, 13}, // 1536 - {0x005B, 13}, // 1600 - {0x0064, 13}, // 1664 - {0x0065, 13}, // 1728 - }; - if ( len >= 64 ) { - int index = 63 + (len >> 6); - writeG3Code( blackCodes[index].code, blackCodes[index].bits ); - len &= 63; - } - writeG3Code( blackCodes[len].code, blackCodes[len].bits ); -} - -void QtopiaPrintEnginePrivate::writeG3EOL() -{ - int bitToPad; - if ( partialBits <= 4 ) { - bitToPad = 4 - partialBits; - } else { - bitToPad = 8 - partialBits + 4; - } - - partialByte = ((partialByte << (bitToPad + 12)) | 0x0001); - partialBits += bitToPad + 12; - - while ( partialBits >= 8 ) { - partialBits -= 8; - buffer.append( (char)(partialByte >> partialBits ) ); - } -// writeG3Code( 0x0001, 12 ); -} - -void QtopiaPrintBuffer::append( short value ) -{ - if ( _bigEndian ) { - _data.append( (char)(value >> 8) ); - _data.append( (char)value ); - } else { - _data.append( (char)value ); - _data.append( (char)(value >> 8) ); - } -} - -void QtopiaPrintBuffer::append( int value ) -{ - if ( _bigEndian ) { - _data.append( (char)(value >> 24) ); - _data.append( (char)(value >> 16) ); - _data.append( (char)(value >> 8) ); - _data.append( (char)value ); - } else { - _data.append( (char)value ); - _data.append( (char)(value >> 8) ); - _data.append( (char)(value >> 16) ); - _data.append( (char)(value >> 24) ); - } -} - -void QtopiaPrintBuffer::patch( int posn, int value ) -{ - if ( _bigEndian ) { - _data[posn] = (char)(value >> 24); - _data[posn + 1] = (char)(value >> 16); - _data[posn + 2] = (char)(value >> 8); - _data[posn + 3] = (char)value; - } else { - _data[posn] = (char)value; - _data[posn + 1] = (char)(value >> 8); - _data[posn + 2] = (char)(value >> 16); - _data[posn + 3] = (char)(value >> 24); - } -} - -void QtopiaPrintBuffer::pad() -{ - while ( ( _data.size() % 4 ) != 0 ) - _data.append( (char)0 ); -} - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER diff --git a/src/gui/painting/qprintengine_qws_p.h b/src/gui/painting/qprintengine_qws_p.h deleted file mode 100644 index e797914180..0000000000 --- a/src/gui/painting/qprintengine_qws_p.h +++ /dev/null @@ -1,213 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPRINTENGINE_QWS_P_H -#define QPRINTENGINE_QWS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtGui/qprinter.h" - -#ifndef QT_NO_PRINTER - -#include "QtGui/qprintengine.h" -#include "QtCore/qbytearray.h" -#include "private/qpaintengine_p.h" - -QT_BEGIN_NAMESPACE - -class QtopiaPrintEnginePrivate; -class QRasterPaintEngine; -class QPrinterPrivate; -class QImage; - -class QtopiaPrintEngine : public QPaintEngine, public QPrintEngine -{ - Q_DECLARE_PRIVATE(QtopiaPrintEngine) -public: - QtopiaPrintEngine(QPrinter::PrinterMode mode); - - // override QWSPaintEngine - bool begin(QPaintDevice *dev); - bool end(); - void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - void drawTextItem(const QPointF &p, const QTextItem &ti); - QPaintEngine::Type type() const { return QPaintEngine::X11; } - - QPaintEngine *paintEngine() const; - - void updateState(const QPaintEngineState &state); - - QRect paperRect() const; - QRect pageRect() const; - - bool newPage(); - bool abort(); - - QPrinter::PrinterState printerState() const; - - int metric(QPaintDevice::PaintDeviceMetric metricType) const; - - QVariant property(PrintEnginePropertyKey key) const; - void setProperty(PrintEnginePropertyKey key, const QVariant &value); - -private: - friend class QPrintDialog; - friend class QPageSetupDialog; - - void clearPage(); - void flushPage(); -}; - -class QtopiaPrintBuffer -{ -public: - QtopiaPrintBuffer( bool bigEndian=FALSE ) { _bigEndian = bigEndian; } - ~QtopiaPrintBuffer() {} - - const QByteArray& data() const { return _data; } - - int size() const { return _data.size(); } - - void clear() { _data.clear(); } - - void append( char value ) { _data.append( value ); } - void append( short value ); - void append( int value ); - void append( const QByteArray& array ) { _data.append( array ); } - - void patch( int posn, int value ); - - void pad(); - -private: - QByteArray _data; - bool _bigEndian; -}; - -#define QT_QWS_PRINTER_DEFAULT_DPI 200 - -class QtopiaPrintEnginePrivate : public QPaintEnginePrivate -{ - Q_DECLARE_PUBLIC(QtopiaPrintEngine) -public: - QtopiaPrintEnginePrivate(QPrinter::PrinterMode m) : - mode(m), - printerState(QPrinter::Idle), - orientation(QPrinter::Portrait), - paperSize(QPrinter::A4), - pageOrder(QPrinter::FirstPageFirst), - colorMode(QPrinter::GrayScale), - paperSource(QPrinter::OnlyOne), - resolution(QT_QWS_PRINTER_DEFAULT_DPI), - _paintEngine(0), - numCopies(1), - outputToFile(false), - fullPage(false), - collateCopies(false), - pageNumber(0), - pageImage(0), - partialByte(0), - partialBits(0) - { - } - ~QtopiaPrintEnginePrivate(); - - void initialize(); - QPaintEngine *paintEngine(); - - QPrinter::PrinterMode mode; - - QString printerName; - QString outputFileName; - QString printProgram; - QString docName; - QString creator; - - QPrinter::PrinterState printerState; - - QPrinter::Orientation orientation; - QPrinter::PaperSize paperSize; - QPrinter::PageOrder pageOrder; - QPrinter::ColorMode colorMode; - QPrinter::PaperSource paperSource; - - int resolution; - QPaintEngine *_paintEngine; - int numCopies; - - bool outputToFile; - bool fullPage; - bool collateCopies; - - int pageNumber; - - QImage *pageImage; - - QtopiaPrintBuffer buffer; - - // Definitions that are only relevant to G3FAX output. - int ifdPatch; - int partialByte; - int partialBits; - void writeG3FaxHeader(); - void writeG3FaxPage(); - int writeG3IFDEntry( int tag, int type, int count, int value ); - void writeG3Code( int code, int bits ); - void writeG3WhiteRun( int len ); - void writeG3BlackRun( int len ); - void writeG3EOL(); -}; - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER - -#endif // QPRINTENGINE_QWS_P_H diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp deleted file mode 100644 index 5ba33c043c..0000000000 --- a/src/gui/painting/qprintengine_win.cpp +++ /dev/null @@ -1,1775 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_NO_PRINTER - -#include "qprinter_p.h" -#include "qprintengine_win_p.h" - -#include <limits.h> - -#include <private/qfont_p.h> -#include <private/qfontengine_p.h> -#include <private/qpainter_p.h> - -#include <qbitmap.h> -#include <qdebug.h> -#include <qvector.h> -#include <qpicture.h> -#include <private/qpicture_p.h> - -QT_BEGIN_NAMESPACE - -extern QPainterPath qt_regionToPath(const QRegion ®ion); - -// #define QT_DEBUG_DRAW - -static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC hdc, - bool convertToText, const QTransform &xform, const QPointF &topLeft); - -static const struct { - int winSizeName; - QPrinter::PaperSize qtSizeName; -} dmMapping[] = { - { DMPAPER_LETTER, QPrinter::Letter }, - { DMPAPER_LETTERSMALL, QPrinter::Letter }, - { DMPAPER_TABLOID, QPrinter::Tabloid }, - { DMPAPER_LEDGER, QPrinter::Ledger }, - { DMPAPER_LEGAL, QPrinter::Legal }, - { DMPAPER_EXECUTIVE, QPrinter::Executive }, - { DMPAPER_A3, QPrinter::A3 }, - { DMPAPER_A4, QPrinter::A4 }, - { DMPAPER_A4SMALL, QPrinter::A4 }, - { DMPAPER_A5, QPrinter::A5 }, - { DMPAPER_B4, QPrinter::B4 }, - { DMPAPER_B5, QPrinter::B5 }, - { DMPAPER_FOLIO, QPrinter::Folio }, - { DMPAPER_ENV_10, QPrinter::Comm10E }, - { DMPAPER_ENV_DL, QPrinter::DLE }, - { DMPAPER_ENV_C3, QPrinter::C5E }, - { DMPAPER_LETTER_EXTRA, QPrinter::Letter }, - { DMPAPER_LEGAL_EXTRA, QPrinter::Legal }, - { DMPAPER_TABLOID_EXTRA, QPrinter::Tabloid }, - { DMPAPER_A4_EXTRA, QPrinter::A4}, - { DMPAPER_LETTER_TRANSVERSE, QPrinter::Letter}, - { DMPAPER_A4_TRANSVERSE, QPrinter::A4}, - { DMPAPER_LETTER_EXTRA_TRANSVERSE, QPrinter::Letter }, - { DMPAPER_A_PLUS, QPrinter::A4 }, - { DMPAPER_B_PLUS, QPrinter::A3 }, - { DMPAPER_LETTER_PLUS, QPrinter::Letter }, - { DMPAPER_A4_PLUS, QPrinter::A4 }, - { DMPAPER_A5_TRANSVERSE, QPrinter::A5 }, - { DMPAPER_B5_TRANSVERSE, QPrinter::B5 }, - { DMPAPER_A3_EXTRA, QPrinter::A3 }, - { DMPAPER_A5_EXTRA, QPrinter::A5 }, - { DMPAPER_B5_EXTRA, QPrinter::B5 }, - { DMPAPER_A2, QPrinter::A2 }, - { DMPAPER_A3_TRANSVERSE, QPrinter::A3 }, - { DMPAPER_A3_EXTRA_TRANSVERSE,QPrinter::A3 }, - { 0, QPrinter::Custom } -}; - -QPrinter::PaperSize mapDevmodePaperSize(int s) -{ - int i = 0; - while ((dmMapping[i].winSizeName > 0) && (dmMapping[i].winSizeName != s)) - i++; - return dmMapping[i].qtSizeName; -} - -static int mapPaperSizeDevmode(QPrinter::PaperSize s) -{ - int i = 0; - while ((dmMapping[i].winSizeName > 0) && (dmMapping[i].qtSizeName != s)) - i++; - return dmMapping[i].winSizeName; -} - -static const struct { - int winSourceName; - QPrinter::PaperSource qtSourceName; -} sources[] = { - { DMBIN_ONLYONE, QPrinter::OnlyOne }, - { DMBIN_LOWER, QPrinter::Lower }, - { DMBIN_MIDDLE, QPrinter::Middle }, - { DMBIN_MANUAL, QPrinter::Manual }, - { DMBIN_ENVELOPE, QPrinter::Envelope }, - { DMBIN_ENVMANUAL, QPrinter::EnvelopeManual }, - { DMBIN_AUTO, QPrinter::Auto }, - { DMBIN_TRACTOR, QPrinter::Tractor }, - { DMBIN_SMALLFMT, QPrinter::SmallFormat }, - { DMBIN_LARGEFMT, QPrinter::LargeFormat }, - { DMBIN_LARGECAPACITY, QPrinter::LargeCapacity }, - { DMBIN_CASSETTE, QPrinter::Cassette }, - { DMBIN_FORMSOURCE, QPrinter::FormSource }, - { 0, (QPrinter::PaperSource) -1 } -}; - -static QPrinter::PaperSource mapDevmodePaperSource(int s) -{ - int i = 0; - while ((sources[i].winSourceName > 0) && (sources[i].winSourceName != s)) - i++; - return sources[i].winSourceName ? sources[i].qtSourceName : (QPrinter::PaperSource) s; -} - -static int mapPaperSourceDevmode(QPrinter::PaperSource s) -{ - int i = 0; - while ((sources[i].qtSourceName >= 0) && (sources[i].qtSourceName != s)) - i++; - return sources[i].winSourceName ? sources[i].winSourceName : s; -} - -QWin32PrintEngine::QWin32PrintEngine(QPrinter::PrinterMode mode) - : QAlphaPaintEngine(*(new QWin32PrintEnginePrivate), - PaintEngineFeatures(PrimitiveTransform - | PixmapTransform - | PerspectiveTransform - | PainterPaths - | Antialiasing - | PaintOutsidePaintEvent)) -{ - Q_D(QWin32PrintEngine); - d->docName = QLatin1String("document1"); - d->mode = mode; - d->queryDefault(); - d->initialize(); -} - -bool QWin32PrintEngine::begin(QPaintDevice *pdev) -{ - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::begin(pdev); - if (!continueCall()) - return true; - - if (d->reinit) { - d->resetDC(); - d->reinit = false; - } - - // ### set default colors and stuff... - - bool ok = d->state == QPrinter::Idle; - - if (!d->hdc) - return false; - - // Assign the FILE: to get the query... - if (d->printToFile && d->fileName.isEmpty()) - d->fileName = d->port; - - d->devMode->dmCopies = d->num_copies; - - DOCINFO di; - memset(&di, 0, sizeof(DOCINFO)); - di.cbSize = sizeof(DOCINFO); - di.lpszDocName = reinterpret_cast<const wchar_t *>(d->docName.utf16()); - if (d->printToFile && !d->fileName.isEmpty()) - di.lpszOutput = reinterpret_cast<const wchar_t *>(d->fileName.utf16()); - if (ok && StartDoc(d->hdc, &di) == SP_ERROR) { - qErrnoWarning("QWin32PrintEngine::begin: StartDoc failed"); - ok = false; - } - - if (StartPage(d->hdc) <= 0) { - qErrnoWarning("QWin32PrintEngine::begin: StartPage failed"); - ok = false; - } - - if (!ok) { - d->state = QPrinter::Idle; - } else { - d->state = QPrinter::Active; - } - - d->matrix = QTransform(); - d->has_pen = true; - d->pen = QColor(Qt::black); - d->has_brush = false; - - d->complex_xform = false; - - updateMatrix(d->matrix); - - if (!ok) - cleanUp(); - - return ok; -} - -bool QWin32PrintEngine::end() -{ - Q_D(QWin32PrintEngine); - - if (d->hdc) { - if (d->state == QPrinter::Aborted) { - cleanUp(); - AbortDoc(d->hdc); - return true; - } - } - - QAlphaPaintEngine::end(); - if (!continueCall()) - return true; - - if (d->hdc) { - EndPage(d->hdc); // end; printing done - EndDoc(d->hdc); - } - - d->state = QPrinter::Idle; - d->reinit = true; - return true; -} - -bool QWin32PrintEngine::newPage() -{ - Q_D(QWin32PrintEngine); - Q_ASSERT(isActive()); - - Q_ASSERT(d->hdc); - - flushAndInit(); - - bool transparent = GetBkMode(d->hdc) == TRANSPARENT; - - if (!EndPage(d->hdc)) { - qErrnoWarning("QWin32PrintEngine::newPage: EndPage failed"); - return false; - } - - if (d->reinit) { - if (!d->resetDC()) { - qErrnoWarning("QWin32PrintEngine::newPage: ResetDC failed"); - return false; - } - d->reinit = false; - } - - if (!StartPage(d->hdc)) { - qErrnoWarning("Win32PrintEngine::newPage: StartPage failed"); - return false; - } - - SetTextAlign(d->hdc, TA_BASELINE); - if (transparent) - SetBkMode(d->hdc, TRANSPARENT); - - // ### - return true; - - bool success = false; - if (d->hdc && d->state == QPrinter::Active) { - if (EndPage(d->hdc) != SP_ERROR) { - // reinitialize the DC before StartPage if needed, - // because resetdc is disabled between calls to the StartPage and EndPage functions - // (see StartPage documentation in the Platform SDK:Windows GDI) -// state = PST_ACTIVEDOC; -// reinit(); -// state = PST_ACTIVE; - // start the new page now - if (d->reinit) { - if (!d->resetDC()) - qErrnoWarning("QWin32PrintEngine::newPage(), ResetDC failed (2)"); - d->reinit = false; - } - success = (StartPage(d->hdc) != SP_ERROR); - } - if (!success) { - d->state = QPrinter::Aborted; - return false; - } - } - return true; -} - -bool QWin32PrintEngine::abort() -{ - // do nothing loop. - return false; -} - -void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) -{ - Q_D(const QWin32PrintEngine); - - QAlphaPaintEngine::drawTextItem(p, textItem); - if (!continueCall()) - return; - - const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); - QRgb brushColor = state->pen().brush().color().rgb(); - bool fallBack = state->pen().brush().style() != Qt::SolidPattern - || qAlpha(brushColor) != 0xff - || d->txop >= QTransform::TxProject - || ti.fontEngine->type() != QFontEngine::Win; - - - if (!fallBack) { - QFontEngineWin *fe = static_cast<QFontEngineWin *>(ti.fontEngine); - - // Try selecting the font to see if we get a substitution font - SelectObject(d->hdc, fe->hfont); - - if (GetDeviceCaps(d->hdc, TECHNOLOGY) != DT_CHARSTREAM) { - wchar_t n[64]; - GetTextFace(d->hdc, 64, n); - fallBack = QString::fromWCharArray(n) - != QString::fromWCharArray(fe->logfont.lfFaceName); - } - } - - - if (fallBack) { - QPaintEngine::drawTextItem(p, textItem); - return ; - } - - // We only want to convert the glyphs to text if the entire string is compatible with ASCII - // and if we actually have access to the chars. - bool convertToText = ti.chars != 0; - for (int i=0; i < ti.num_chars; ++i) { - if (ti.chars[i].unicode() >= 0x80) { - convertToText = false; - break; - } - - if (ti.logClusters[i] != i) { - convertToText = false; - break; - } - } - - COLORREF cf = RGB(qRed(brushColor), qGreen(brushColor), qBlue(brushColor)); - SelectObject(d->hdc, CreateSolidBrush(cf)); - SelectObject(d->hdc, CreatePen(PS_SOLID, 1, cf)); - SetTextColor(d->hdc, cf); - - draw_text_item_win(p, ti, d->hdc, convertToText, d->matrix, d->devPaperRect.topLeft()); - DeleteObject(SelectObject(d->hdc,GetStockObject(HOLLOW_BRUSH))); - DeleteObject(SelectObject(d->hdc,GetStockObject(BLACK_PEN))); -} - -static inline qreal mmToInches(double mm) -{ - return mm*0.039370147; -} - -static inline qreal inchesToMM(double in) -{ - return in/0.039370147; -} - -int QWin32PrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const -{ - Q_D(const QWin32PrintEngine); - - if (!d->hdc) - return 0; - - int val; - int res = d->resolution; - - switch (m) { - case QPaintDevice::PdmWidth: - if (d->has_custom_paper_size) { - val = qRound(d->paper_size.width() * res / 72.0); - } else { - int logPixelsX = GetDeviceCaps(d->hdc, LOGPIXELSX); - if (logPixelsX == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - logPixelsX = 600; // Reasonable default - } - val = res - * GetDeviceCaps(d->hdc, d->fullPage ? PHYSICALWIDTH : HORZRES) - / logPixelsX; - } - if (d->pageMarginsSet) - val -= int(mmToInches((d->previousDialogMargins.left() + - d->previousDialogMargins.width()) / 100.0) * res); - break; - case QPaintDevice::PdmHeight: - if (d->has_custom_paper_size) { - val = qRound(d->paper_size.height() * res / 72.0); - } else { - int logPixelsY = GetDeviceCaps(d->hdc, LOGPIXELSY); - if (logPixelsY == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - logPixelsY = 600; // Reasonable default - } - val = res - * GetDeviceCaps(d->hdc, d->fullPage ? PHYSICALHEIGHT : VERTRES) - / logPixelsY; - } - if (d->pageMarginsSet) - val -= int(mmToInches((d->previousDialogMargins.top() + - d->previousDialogMargins.height()) / 100.0) * res); - break; - case QPaintDevice::PdmDpiX: - val = res; - break; - case QPaintDevice::PdmDpiY: - val = res; - break; - case QPaintDevice::PdmPhysicalDpiX: - val = GetDeviceCaps(d->hdc, LOGPIXELSX); - break; - case QPaintDevice::PdmPhysicalDpiY: - val = GetDeviceCaps(d->hdc, LOGPIXELSY); - break; - case QPaintDevice::PdmWidthMM: - if (d->has_custom_paper_size) { - val = qRound(d->paper_size.width()*25.4/72); - } else { - if (!d->fullPage) { - val = GetDeviceCaps(d->hdc, HORZSIZE); - } else { - float wi = 25.4 * GetDeviceCaps(d->hdc, PHYSICALWIDTH); - int logPixelsX = GetDeviceCaps(d->hdc, LOGPIXELSX); - if (logPixelsX == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - logPixelsX = 600; // Reasonable default - } - val = qRound(wi / logPixelsX); - } - } - if (d->pageMarginsSet) - val -= (d->previousDialogMargins.left() + - d->previousDialogMargins.width()) / 100.0; - break; - case QPaintDevice::PdmHeightMM: - if (d->has_custom_paper_size) { - val = qRound(d->paper_size.height()*25.4/72); - } else { - if (!d->fullPage) { - val = GetDeviceCaps(d->hdc, VERTSIZE); - } else { - float hi = 25.4 * GetDeviceCaps(d->hdc, PHYSICALHEIGHT); - int logPixelsY = GetDeviceCaps(d->hdc, LOGPIXELSY); - if (logPixelsY == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - logPixelsY = 600; // Reasonable default - } - val = qRound(hi / logPixelsY); - } - } - if (d->pageMarginsSet) - val -= (d->previousDialogMargins.top() + - d->previousDialogMargins.height()) / 100.0; - break; - case QPaintDevice::PdmNumColors: - { - int bpp = GetDeviceCaps(d->hdc, BITSPIXEL); - if(bpp==32) - val = INT_MAX; - else if(bpp<=8) - val = GetDeviceCaps(d->hdc, NUMCOLORS); - else - val = 1 << (bpp * GetDeviceCaps(d->hdc, PLANES)); - } - break; - case QPaintDevice::PdmDepth: - val = GetDeviceCaps(d->hdc, PLANES); - break; - default: - qWarning("QPrinter::metric: Invalid metric command"); - return 0; - } - return val; -} - -void QWin32PrintEngine::updateState(const QPaintEngineState &state) -{ - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::updateState(state); - if (!continueCall()) - return; - - if (state.state() & DirtyTransform) { - updateMatrix(state.transform()); - } - - if (state.state() & DirtyPen) { - d->pen = state.pen(); - d->has_pen = d->pen.style() != Qt::NoPen && d->pen.isSolid(); - } - - if (state.state() & DirtyBrush) { - QBrush brush = state.brush(); - d->has_brush = brush.style() == Qt::SolidPattern; - d->brush_color = brush.color(); - } - - if (state.state() & DirtyClipEnabled) { - if (state.isClipEnabled()) - updateClipPath(painter()->clipPath(), Qt::ReplaceClip); - else - updateClipPath(QPainterPath(), Qt::NoClip); - } - - if (state.state() & DirtyClipPath) { - updateClipPath(state.clipPath(), state.clipOperation()); - } - - if (state.state() & DirtyClipRegion) { - QRegion clipRegion = state.clipRegion(); - QPainterPath clipPath = qt_regionToPath(clipRegion); - updateClipPath(clipPath, state.clipOperation()); - } -} - -void QWin32PrintEngine::updateClipPath(const QPainterPath &clipPath, Qt::ClipOperation op) -{ - Q_D(QWin32PrintEngine); - - bool doclip = true; - if (op == Qt::NoClip) { - SelectClipRgn(d->hdc, 0); - doclip = false; - } - - if (doclip) { - QPainterPath xformed = clipPath * d->matrix; - - if (xformed.isEmpty()) { - QRegion empty(-0x1000000, -0x1000000, 1, 1); - SelectClipRgn(d->hdc, empty.handle()); - } else { - d->composeGdiPath(xformed); - const int ops[] = { - -1, // Qt::NoClip, covered above - RGN_COPY, // Qt::ReplaceClip - RGN_AND // Qt::IntersectClip - }; - Q_ASSERT(op > 0 && unsigned(op) <= sizeof(ops) / sizeof(int)); - SelectClipPath(d->hdc, ops[op]); - } - } - - QPainterPath aclip = qt_regionToPath(alphaClipping()); - if (!aclip.isEmpty()) { - QTransform tx(d->stretch_x, 0, 0, d->stretch_y, d->origin_x, d->origin_y); - d->composeGdiPath(tx.map(aclip)); - SelectClipPath(d->hdc, RGN_DIFF); - } -} - -void QWin32PrintEngine::updateMatrix(const QTransform &m) -{ - Q_D(QWin32PrintEngine); - - QTransform stretch(d->stretch_x, 0, 0, d->stretch_y, d->origin_x, d->origin_y); - d->painterMatrix = m; - d->matrix = d->painterMatrix * stretch; - d->txop = d->matrix.type(); - d->complex_xform = (d->txop > QTransform::TxScale); -} - -void QWin32PrintEngine::drawPixmap(const QRectF &targetRect, - const QPixmap &originalPixmap, - const QRectF &sourceRect) -{ - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::drawPixmap(targetRect, originalPixmap, sourceRect); - if (!continueCall()) - return; - - const int tileSize = 2048; - - QRectF r = targetRect; - QRectF sr = sourceRect; - - QPixmap pixmap = originalPixmap; - if (sr.size() != pixmap.size()) { - pixmap = pixmap.copy(sr.toRect()); - } - - qreal scaleX = 1.0f; - qreal scaleY = 1.0f; - - QTransform scaleMatrix = QTransform::fromScale(r.width() / pixmap.width(), r.height() / pixmap.height()); - QTransform adapted = QPixmap::trueMatrix(d->painterMatrix * scaleMatrix, - pixmap.width(), pixmap.height()); - - qreal xform_offset_x = adapted.dx(); - qreal xform_offset_y = adapted.dy(); - - if (d->complex_xform) { - pixmap = pixmap.transformed(adapted); - scaleX = d->stretch_x; - scaleY = d->stretch_y; - } else { - scaleX = d->stretch_x * (r.width() / pixmap.width()) * d->painterMatrix.m11(); - scaleY = d->stretch_y * (r.height() / pixmap.height()) * d->painterMatrix.m22(); - } - - QPointF topLeft = r.topLeft() * d->painterMatrix; - int tx = int(topLeft.x() * d->stretch_x + d->origin_x); - int ty = int(topLeft.y() * d->stretch_y + d->origin_y); - int tw = qAbs(int(pixmap.width() * scaleX)); - int th = qAbs(int(pixmap.height() * scaleY)); - - xform_offset_x *= d->stretch_x; - xform_offset_y *= d->stretch_y; - - int dc_state = SaveDC(d->hdc); - - int tilesw = pixmap.width() / tileSize; - int tilesh = pixmap.height() / tileSize; - ++tilesw; - ++tilesh; - - int txinc = tileSize*scaleX; - int tyinc = tileSize*scaleY; - - for (int y = 0; y < tilesh; ++y) { - int tposy = ty + (y * tyinc); - int imgh = tileSize; - int height = tyinc; - if (y == (tilesh - 1)) { - imgh = pixmap.height() - (y * tileSize); - height = (th - (y * tyinc)); - } - for (int x = 0; x < tilesw; ++x) { - int tposx = tx + (x * txinc); - int imgw = tileSize; - int width = txinc; - if (x == (tilesw - 1)) { - imgw = pixmap.width() - (x * tileSize); - width = (tw - (x * txinc)); - } - - QPixmap p = pixmap.copy(tileSize * x, tileSize * y, imgw, imgh); - HBITMAP hbitmap = p.toWinHBITMAP(QPixmap::NoAlpha); - HDC display_dc = GetDC(0); - HDC hbitmap_hdc = CreateCompatibleDC(display_dc); - HGDIOBJ null_bitmap = SelectObject(hbitmap_hdc, hbitmap); - - ReleaseDC(0, display_dc); - - if (!StretchBlt(d->hdc, qRound(tposx - xform_offset_x), qRound(tposy - xform_offset_y), width, height, - hbitmap_hdc, 0, 0, p.width(), p.height(), SRCCOPY)) - qErrnoWarning("QWin32PrintEngine::drawPixmap, StretchBlt failed"); - - SelectObject(hbitmap_hdc, null_bitmap); - DeleteObject(hbitmap); - DeleteDC(hbitmap_hdc); - } - } - - RestoreDC(d->hdc, dc_state); -} - - -void QWin32PrintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &pos) -{ - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::drawTiledPixmap(r, pm, pos); - if (!continueCall()) - return; - - if (d->complex_xform || !pos.isNull()) { - QPaintEngine::drawTiledPixmap(r, pm, pos); - } else { - int dc_state = SaveDC(d->hdc); - - HDC display_dc = GetDC(0); - HBITMAP hbitmap = pm.toWinHBITMAP(QPixmap::NoAlpha); - HDC hbitmap_hdc = CreateCompatibleDC(display_dc); - HGDIOBJ null_bitmap = SelectObject(hbitmap_hdc, hbitmap); - - ReleaseDC(0, display_dc); - - QRectF trect = d->painterMatrix.mapRect(r); - int tx = int(trect.left() * d->stretch_x + d->origin_x); - int ty = int(trect.top() * d->stretch_y + d->origin_y); - - int xtiles = int(trect.width() / pm.width()) + 1; - int ytiles = int(trect.height() / pm.height()) + 1; - int xinc = int(pm.width() * d->stretch_x); - int yinc = int(pm.height() * d->stretch_y); - - for (int y = 0; y < ytiles; ++y) { - int ity = ty + (yinc * y); - int ith = pm.height(); - if (y == (ytiles - 1)) { - ith = int(trect.height() - (pm.height() * y)); - } - - for (int x = 0; x < xtiles; ++x) { - int itx = tx + (xinc * x); - int itw = pm.width(); - if (x == (xtiles - 1)) { - itw = int(trect.width() - (pm.width() * x)); - } - - if (!StretchBlt(d->hdc, itx, ity, int(itw * d->stretch_x), int(ith * d->stretch_y), - hbitmap_hdc, 0, 0, itw, ith, SRCCOPY)) - qErrnoWarning("QWin32PrintEngine::drawPixmap, StretchBlt failed"); - - } - } - - SelectObject(hbitmap_hdc, null_bitmap); - DeleteObject(hbitmap); - DeleteDC(hbitmap_hdc); - - RestoreDC(d->hdc, dc_state); - } -} - - -void QWin32PrintEnginePrivate::composeGdiPath(const QPainterPath &path) -{ - if (!BeginPath(hdc)) - qErrnoWarning("QWin32PrintEnginePrivate::drawPath: BeginPath failed"); - - // Drawing the subpaths - int start = -1; - for (int i=0; i<path.elementCount(); ++i) { - const QPainterPath::Element &elm = path.elementAt(i); - switch (elm.type) { - case QPainterPath::MoveToElement: - if (start >= 0 - && path.elementAt(start).x == path.elementAt(i-1).x - && path.elementAt(start).y == path.elementAt(i-1).y) - CloseFigure(hdc); - start = i; - MoveToEx(hdc, qRound(elm.x), qRound(elm.y), 0); - break; - case QPainterPath::LineToElement: - LineTo(hdc, qRound(elm.x), qRound(elm.y)); - break; - case QPainterPath::CurveToElement: { - POINT pts[3] = { - { qRound(elm.x), qRound(elm.y) }, - { qRound(path.elementAt(i+1).x), qRound(path.elementAt(i+1).y) }, - { qRound(path.elementAt(i+2).x), qRound(path.elementAt(i+2).y) } - }; - i+=2; - PolyBezierTo(hdc, pts, 3); - break; - } - default: - qFatal("QWin32PaintEngine::drawPath: Unhandled type: %d", elm.type); - } - } - - if (start >= 0 - && path.elementAt(start).x == path.elementAt(path.elementCount()-1).x - && path.elementAt(start).y == path.elementAt(path.elementCount()-1).y) - CloseFigure(hdc); - - if (!EndPath(hdc)) - qErrnoWarning("QWin32PaintEngine::drawPath: EndPath failed"); - - SetPolyFillMode(hdc, path.fillRule() == Qt::WindingFill ? WINDING : ALTERNATE); -} - - -void QWin32PrintEnginePrivate::fillPath_dev(const QPainterPath &path, const QColor &color) -{ -#ifdef QT_DEBUG_DRAW - qDebug() << " --- QWin32PrintEnginePrivate::fillPath() bound:" << path.boundingRect() << color; -#endif - - composeGdiPath(path); - - HBRUSH brush = CreateSolidBrush(RGB(color.red(), color.green(), color.blue())); - HGDIOBJ old_brush = SelectObject(hdc, brush); - FillPath(hdc); - DeleteObject(SelectObject(hdc, old_brush)); -} - -void QWin32PrintEnginePrivate::strokePath_dev(const QPainterPath &path, const QColor &color, qreal penWidth) -{ - composeGdiPath(path); - LOGBRUSH brush; - brush.lbStyle = BS_SOLID; - brush.lbColor = RGB(color.red(), color.green(), color.blue()); - DWORD capStyle = PS_ENDCAP_SQUARE; - DWORD joinStyle = PS_JOIN_BEVEL; - if (pen.capStyle() == Qt::FlatCap) - capStyle = PS_ENDCAP_FLAT; - else if (pen.capStyle() == Qt::RoundCap) - capStyle = PS_ENDCAP_ROUND; - - if (pen.joinStyle() == Qt::MiterJoin) - joinStyle = PS_JOIN_MITER; - else if (pen.joinStyle() == Qt::RoundJoin) - joinStyle = PS_JOIN_ROUND; - - HPEN pen = ExtCreatePen(((penWidth == 0) ? PS_COSMETIC : PS_GEOMETRIC) - | PS_SOLID | capStyle | joinStyle, - (penWidth == 0) ? 1 : penWidth, &brush, 0, 0); - - HGDIOBJ old_pen = SelectObject(hdc, pen); - StrokePath(hdc); - DeleteObject(SelectObject(hdc, old_pen)); -} - - -void QWin32PrintEnginePrivate::fillPath(const QPainterPath &path, const QColor &color) -{ - fillPath_dev(path * matrix, color); -} - -void QWin32PrintEnginePrivate::strokePath(const QPainterPath &path, const QColor &color) -{ - QPainterPathStroker stroker; - if (pen.style() == Qt::CustomDashLine) { - stroker.setDashPattern(pen.dashPattern()); - stroker.setDashOffset(pen.dashOffset()); - } else { - stroker.setDashPattern(pen.style()); - } - stroker.setCapStyle(pen.capStyle()); - stroker.setJoinStyle(pen.joinStyle()); - stroker.setMiterLimit(pen.miterLimit()); - - QPainterPath stroke; - qreal width = pen.widthF(); - if (pen.style() == Qt::SolidLine && (pen.isCosmetic() || matrix.type() < QTransform::TxScale)) { - strokePath_dev(path * matrix, color, width); - } else { - stroker.setWidth(width); - if (pen.isCosmetic()) { - stroke = stroker.createStroke(path * matrix); - } else { - stroke = stroker.createStroke(path) * painterMatrix; - QTransform stretch(stretch_x, 0, 0, stretch_y, origin_x, origin_y); - stroke = stroke * stretch; - } - - if (stroke.isEmpty()) - return; - - fillPath_dev(stroke, color); - } -} - - -void QWin32PrintEngine::drawPath(const QPainterPath &path) -{ -#ifdef QT_DEBUG_DRAW - qDebug() << " - QWin32PrintEngine::drawPath(), bounds: " << path.boundingRect(); -#endif - - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::drawPath(path); - if (!continueCall()) - return; - - if (d->has_brush) - d->fillPath(path, d->brush_color); - - if (d->has_pen) - d->strokePath(path, d->pen.color()); -} - - -void QWin32PrintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) -{ -#ifdef QT_DEBUG_DRAW - qDebug() << " - QWin32PrintEngine::drawPolygon(), pointCount: " << pointCount; -#endif - - QAlphaPaintEngine::drawPolygon(points, pointCount, mode); - if (!continueCall()) - return; - - Q_ASSERT(pointCount > 1); - - QPainterPath path(points[0]); - - for (int i=1; i<pointCount; ++i) { - path.lineTo(points[i]); - } - - Q_D(QWin32PrintEngine); - - bool has_brush = d->has_brush; - - if (mode == PolylineMode) - d->has_brush = false; // No brush for polylines - else - path.closeSubpath(); // polygons are should always be closed. - - drawPath(path); - d->has_brush = has_brush; -} - -void QWin32PrintEnginePrivate::queryDefault() -{ - /* Read the default printer name, driver and port with the intuitive function - * Strings "windows" and "device" are specified in the MSDN under EnumPrinters() - */ - QString noPrinters(QLatin1String("qt_no_printers")); - wchar_t buffer[256]; - GetProfileString(L"windows", L"device", - reinterpret_cast<const wchar_t *>(noPrinters.utf16()), - buffer, 256); - QString output = QString::fromWCharArray(buffer); - if (output.isEmpty() || output == noPrinters) // no printers - return; - - QStringList info = output.split(QLatin1Char(',')); - int infoSize = info.size(); - if (infoSize > 0) { - if (name.isEmpty()) - name = info.at(0); - if (program.isEmpty() && infoSize > 1) - program = info.at(1); - if (port.isEmpty() && infoSize > 2) - port = info.at(2); - } -} - -QWin32PrintEnginePrivate::~QWin32PrintEnginePrivate() -{ - if (hdc) - release(); -} - -void QWin32PrintEnginePrivate::initialize() -{ - if (hdc) - release(); - Q_ASSERT(!hPrinter); - Q_ASSERT(!hdc); - Q_ASSERT(!devMode); - Q_ASSERT(!pInfo); - - if (name.isEmpty()) - return; - - txop = QTransform::TxNone; - - bool ok = OpenPrinter((LPWSTR)name.utf16(), (LPHANDLE)&hPrinter, 0); - if (!ok) { - qErrnoWarning("QWin32PrintEngine::initialize: OpenPrinter failed"); - return; - } - - // Fetch the PRINTER_INFO_2 with DEVMODE data containing the - // printer settings. - DWORD infoSize, numBytes; - GetPrinter(hPrinter, 2, NULL, 0, &infoSize); - hMem = GlobalAlloc(GHND, infoSize); - pInfo = (PRINTER_INFO_2*) GlobalLock(hMem); - ok = GetPrinter(hPrinter, 2, (LPBYTE)pInfo, infoSize, &numBytes); - - if (!ok) { - qErrnoWarning("QWin32PrintEngine::initialize: GetPrinter failed"); - GlobalUnlock(pInfo); - GlobalFree(hMem); - ClosePrinter(hPrinter); - pInfo = 0; - hMem = 0; - hPrinter = 0; - return; - } - - devMode = pInfo->pDevMode; - hdc = CreateDC(reinterpret_cast<const wchar_t *>(program.utf16()), - reinterpret_cast<const wchar_t *>(name.utf16()), 0, devMode); - - Q_ASSERT(hPrinter); - Q_ASSERT(pInfo); - - if (devMode) { - num_copies = devMode->dmCopies; - } - - initHDC(); - -#ifdef QT_DEBUG_DRAW - qDebug() << "QWin32PrintEngine::initialize()" << endl - << " - paperRect" << devPaperRect << endl - << " - pageRect" << devPageRect << endl - << " - stretch_x" << stretch_x << endl - << " - stretch_y" << stretch_y << endl - << " - origin_x" << origin_x << endl - << " - origin_y" << origin_y << endl; -#endif -} - -void QWin32PrintEnginePrivate::initHDC() -{ - Q_ASSERT(hdc); - - HDC display_dc = GetDC(0); - dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); - dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); - dpi_display = GetDeviceCaps(display_dc, LOGPIXELSY); - ReleaseDC(0, display_dc); - if (dpi_display == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - dpi_display = 96; // Reasonable default - } - - switch(mode) { - case QPrinter::ScreenResolution: - resolution = dpi_display; - stretch_x = dpi_x / double(dpi_display); - stretch_y = dpi_y / double(dpi_display); - break; - case QPrinter::PrinterResolution: - case QPrinter::HighResolution: - resolution = dpi_y; - stretch_x = 1; - stretch_y = 1; - break; - default: - break; - } - - initDevRects(); -} - -void QWin32PrintEnginePrivate::initDevRects() -{ - devPaperRect = QRect(0, 0, - GetDeviceCaps(hdc, PHYSICALWIDTH), - GetDeviceCaps(hdc, PHYSICALHEIGHT)); - devPhysicalPageRect = QRect(GetDeviceCaps(hdc, PHYSICALOFFSETX), - GetDeviceCaps(hdc, PHYSICALOFFSETY), - GetDeviceCaps(hdc, HORZRES), - GetDeviceCaps(hdc, VERTRES)); - if (!pageMarginsSet) - devPageRect = devPhysicalPageRect; - else - devPageRect = devPaperRect.adjusted(qRound(mmToInches(previousDialogMargins.left() / 100.0) * dpi_x), - qRound(mmToInches(previousDialogMargins.top() / 100.0) * dpi_y), - -qRound(mmToInches(previousDialogMargins.width() / 100.0) * dpi_x), - -qRound(mmToInches(previousDialogMargins.height() / 100.0) * dpi_y)); - updateOrigin(); -} - -void QWin32PrintEnginePrivate::setPageMargins(int marginLeft, int marginTop, int marginRight, int marginBottom) -{ - pageMarginsSet = true; - previousDialogMargins = QRect(marginLeft, marginTop, marginRight, marginBottom); - - devPageRect = devPaperRect.adjusted(qRound(mmToInches(marginLeft / 100.0) * dpi_x), - qRound(mmToInches(marginTop / 100.0) * dpi_y), - - qRound(mmToInches(marginRight / 100.0) * dpi_x), - - qRound(mmToInches(marginBottom / 100.0) * dpi_y)); - updateOrigin(); -} - -QRect QWin32PrintEnginePrivate::getPageMargins() const -{ - if (pageMarginsSet) - return previousDialogMargins; - else - return QRect(qRound(inchesToMM(devPhysicalPageRect.left()) * 100.0 / dpi_x), - qRound(inchesToMM(devPhysicalPageRect.top()) * 100.0 / dpi_y), - qRound(inchesToMM(devPaperRect.right() - devPhysicalPageRect.right()) * 100.0 / dpi_x), - qRound(inchesToMM(devPaperRect.bottom() - devPhysicalPageRect.bottom()) * 100.0 / dpi_y)); -} - -void QWin32PrintEnginePrivate::release() -{ - if (hdc == 0) - return; - - if (globalDevMode) { // Devmode comes from print dialog - GlobalUnlock(globalDevMode); - } else { // Devmode comes from initialize... - // devMode is a part of the same memory block as pInfo so one free is enough... - GlobalUnlock(hMem); - GlobalFree(hMem); - } - if (hPrinter) - ClosePrinter(hPrinter); - DeleteDC(hdc); - - hdc = 0; - hPrinter = 0; - pInfo = 0; - hMem = 0; - devMode = 0; -} - -QList<QVariant> QWin32PrintEnginePrivate::queryResolutions() const -{ - // Read the supported resolutions of the printer. - QList<QVariant> list; - - DWORD numRes = DeviceCapabilities(reinterpret_cast<const wchar_t *>(name.utf16()), - reinterpret_cast<const wchar_t *>(port.utf16()), - DC_ENUMRESOLUTIONS, 0, 0); - if (numRes == (DWORD)-1) - return list; - - LONG *enumRes = (LONG*)malloc(numRes * 2 * sizeof(LONG)); - DWORD errRes = DeviceCapabilities(reinterpret_cast<const wchar_t *>(name.utf16()), - reinterpret_cast<const wchar_t *>(port.utf16()), - DC_ENUMRESOLUTIONS, (LPWSTR)enumRes, 0); - - if (errRes == (DWORD)-1) { - qErrnoWarning("QWin32PrintEngine::queryResolutions: DeviceCapabilities failed"); - return list; - } - - for (uint i=0; i<numRes; ++i) - list.append(int(enumRes[i * 2])); - - return list; -} - -void QWin32PrintEnginePrivate::doReinit() -{ - if (state == QPrinter::Active) { - reinit = true; - } else { - resetDC(); - initDevRects(); - reinit = false; - } -} - -void QWin32PrintEnginePrivate::updateOrigin() -{ - if (fullPage) { - // subtract physical margins to make (0,0) absolute top corner of paper - // then add user defined margins - origin_x = -devPhysicalPageRect.x(); - origin_y = -devPhysicalPageRect.y(); - if (pageMarginsSet) { - origin_x += devPageRect.left(); - origin_y += devPageRect.top(); - } - } else { - origin_x = 0; - origin_y = 0; - if (pageMarginsSet) { - origin_x = devPageRect.left() - devPhysicalPageRect.x(); - origin_y = devPageRect.top() - devPhysicalPageRect.y(); - } - } -} - -void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) -{ - Q_D(QWin32PrintEngine); - switch (key) { - case PPK_CollateCopies: - { - if (!d->devMode) - break; - d->devMode->dmCollate = value.toBool() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE; - d->doReinit(); - } - break; - - case PPK_ColorMode: - { - if (!d->devMode) - break; - d->devMode->dmColor = (value.toInt() == QPrinter::Color) ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; - d->doReinit(); - } - break; - - case PPK_Creator: - - break; - - case PPK_DocumentName: - if (isActive()) { - qWarning("QWin32PrintEngine: Cannot change document name while printing is active"); - return; - } - d->docName = value.toString(); - break; - - case PPK_FullPage: - d->fullPage = value.toBool(); - d->updateOrigin(); - break; - - case PPK_CopyCount: // fallthrough - case PPK_NumberOfCopies: - if (!d->devMode) - break; - d->num_copies = value.toInt(); - d->devMode->dmCopies = d->num_copies; - d->doReinit(); - break; - - case PPK_Orientation: - { - if (!d->devMode) - break; - int orientation = value.toInt() == QPrinter::Landscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT; - int old_orientation = d->devMode->dmOrientation; - d->devMode->dmOrientation = orientation; - if (d->has_custom_paper_size && old_orientation != orientation) - d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width()); - d->doReinit(); - } - break; - - case PPK_OutputFileName: - if (isActive()) { - qWarning("QWin32PrintEngine: Cannot change filename while printing"); - } else { - d->fileName = value.toString(); - d->printToFile = !value.toString().isEmpty(); - } - break; - - case PPK_PaperSize: - if (!d->devMode) - break; - d->devMode->dmPaperSize = mapPaperSizeDevmode(QPrinter::PaperSize(value.toInt())); - d->has_custom_paper_size = (QPrinter::PaperSize(value.toInt()) == QPrinter::Custom); - d->doReinit(); - break; - - case PPK_PaperSource: - { - if (!d->devMode) - break; - int dmMapped = DMBIN_AUTO; - - QList<QVariant> v = property(PPK_PaperSources).toList(); - if (v.contains(value)) - dmMapped = mapPaperSourceDevmode(QPrinter::PaperSource(value.toInt())); - - d->devMode->dmDefaultSource = dmMapped; - d->doReinit(); - } - break; - - case PPK_PrinterName: - d->name = value.toString(); - if(d->name.isEmpty()) - d->queryDefault(); - d->initialize(); - break; - - case PPK_Resolution: - { - d->resolution = value.toInt(); - - d->stretch_x = d->dpi_x / double(d->resolution); - d->stretch_y = d->dpi_y / double(d->resolution); - } - break; - - case PPK_SelectionOption: - - break; - - case PPK_SupportedResolutions: - - break; - - - case PPK_WindowsPageSize: - if (!d->devMode) - break; - d->has_custom_paper_size = false; - d->devMode->dmPaperSize = value.toInt(); - d->doReinit(); - break; - - case PPK_CustomPaperSize: - { - d->has_custom_paper_size = true; - d->paper_size = value.toSizeF(); - if (!d->devMode) - break; - int orientation = d->devMode->dmOrientation; - DWORD needed = 0; - DWORD returned = 0; - if (!EnumForms(d->hPrinter, 1, 0, 0, &needed, &returned)) { - BYTE *forms = (BYTE *) malloc(needed); - if (EnumForms(d->hPrinter, 1, forms, needed, &needed, &returned)) { - for (DWORD i=0; i< returned; ++i) { - FORM_INFO_1 *formArray = reinterpret_cast<FORM_INFO_1 *>(forms); - // the form sizes are specified in 1000th of a mm, - // convert the size to Points - QSizeF size((formArray[i].Size.cx * 72/25.4)/1000.0, - (formArray[i].Size.cy * 72/25.4)/1000.0); - if (qAbs(d->paper_size.width() - size.width()) <= 2 - && qAbs(d->paper_size.height() - size.height()) <= 2) - { - d->devMode->dmPaperSize = i + 1; - break; - } - } - } - free(forms); - } - if (orientation != DMORIENT_PORTRAIT) - d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width()); - break; - } - - case PPK_PageMargins: - { - QList<QVariant> margins(value.toList()); - Q_ASSERT(margins.size() == 4); - int left, top, right, bottom; - // specified in 1/100 mm - left = (margins.at(0).toReal()*25.4/72.0) * 100; - top = (margins.at(1).toReal()*25.4/72.0) * 100; - right = (margins.at(2).toReal()*25.4/72.0) * 100; - bottom = (margins.at(3).toReal()*25.4/72.0) * 100; - d->setPageMargins(left, top, right, bottom); - break; - } - default: - // Do nothing - break; - } -} - -QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const -{ - Q_D(const QWin32PrintEngine); - QVariant value; - switch (key) { - - case PPK_CollateCopies: - value = false; - break; - - case PPK_ColorMode: - { - if (!d->devMode) { - value = QPrinter::Color; - } else { - value = (d->devMode->dmColor == DMCOLOR_COLOR) ? QPrinter::Color : QPrinter::GrayScale; - } - } - break; - - case PPK_DocumentName: - value = d->docName; - break; - - case PPK_FullPage: - value = d->fullPage; - break; - - case PPK_CopyCount: - value = d->num_copies; - break; - - case PPK_SupportsMultipleCopies: - value = true; - break; - - case PPK_NumberOfCopies: - value = 1; - break; - - case PPK_Orientation: - { - if (!d->devMode) { - value = QPrinter::Portrait; - } else { - value = (d->devMode->dmOrientation == DMORIENT_LANDSCAPE) ? QPrinter::Landscape : QPrinter::Portrait; - } - } - break; - - case PPK_OutputFileName: - value = d->fileName; - break; - - case PPK_PageRect: - if (d->has_custom_paper_size) { - QRect rect(0, 0, - qRound(d->paper_size.width() * d->resolution / 72.0), - qRound(d->paper_size.height() * d->resolution / 72.0)); - if (d->pageMarginsSet) { - rect = rect.adjusted(qRound(mmToInches(d->previousDialogMargins.left()/100.0) * d->resolution), - qRound(mmToInches(d->previousDialogMargins.top()/100.0) * d->resolution), - -qRound(mmToInches(d->previousDialogMargins.width()/100.0) * d->resolution), - -qRound(mmToInches(d->previousDialogMargins.height()/100.0) * d->resolution)); - } - value = rect; - } else { - value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0) - .mapRect(d->fullPage ? d->devPhysicalPageRect : d->devPageRect); - } - break; - - case PPK_PaperSize: - if (d->has_custom_paper_size) { - value = QPrinter::Custom; - } else { - if (!d->devMode) { - value = QPrinter::A4; - } else { - value = mapDevmodePaperSize(d->devMode->dmPaperSize); - } - } - break; - - case PPK_PaperRect: - if (d->has_custom_paper_size) { - value = QRect(0, 0, - qRound(d->paper_size.width() * d->resolution / 72.0), - qRound(d->paper_size.height() * d->resolution / 72.0)); - } else { - value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0).mapRect(d->devPaperRect); - } - break; - - case PPK_PaperSource: - if (!d->devMode) { - value = QPrinter::Auto; - } else { - value = mapDevmodePaperSource(d->devMode->dmDefaultSource); - } - break; - - case PPK_PrinterName: - value = d->name; - break; - - case PPK_Resolution: - if (d->resolution || !d->name.isEmpty()) - value = d->resolution; - break; - - case PPK_SupportedResolutions: - value = d->queryResolutions(); - break; - - case PPK_WindowsPageSize: - if (!d->devMode) { - value = -1; - } else { - value = d->devMode->dmPaperSize; - } - break; - - case PPK_PaperSources: - { - int available = DeviceCapabilities((const wchar_t *)d->name.utf16(), - (const wchar_t *)d->port.utf16(), DC_BINS, 0, d->devMode); - - if (available <= 0) - break; - - wchar_t *data = new wchar_t[available]; - int count = DeviceCapabilities((const wchar_t *)d->name.utf16(), - (const wchar_t *)d->port.utf16(), DC_BINS, data, d->devMode); - - QList<QVariant> out; - for (int i=0; i<count; ++i) { - QPrinter::PaperSource src = mapDevmodePaperSource(data[i]); - if (src != -1) - out << (int) src; - } - value = out; - - delete [] data; - } - break; - - case PPK_CustomPaperSize: - value = d->paper_size; - break; - - case PPK_PageMargins: - { - QList<QVariant> margins; - QRect pageMargins(d->getPageMargins()); - - // specified in 1/100 mm - margins << (mmToInches(pageMargins.left()/100.0) * 72) - << (mmToInches(pageMargins.top()/100.0) * 72) - << (mmToInches(pageMargins.width()/100.0) * 72) - << (mmToInches(pageMargins.height()/100.0) * 72); - value = margins; - break; - } - default: - // Do nothing - break; - } - return value; -} - -QPrinter::PrinterState QWin32PrintEngine::printerState() const -{ - return d_func()->state; -} - -HDC QWin32PrintEngine::getDC() const -{ - return d_func()->hdc; -} - -void QWin32PrintEngine::releaseDC(HDC) const -{ - -} - -HGLOBAL *QWin32PrintEnginePrivate::createDevNames() -{ - int size = sizeof(DEVNAMES) - + program.length() * 2 + 2 - + name.length() * 2 + 2 - + port.length() * 2 + 2; - HGLOBAL *hGlobal = (HGLOBAL *) GlobalAlloc(GMEM_MOVEABLE, size); - DEVNAMES *dn = (DEVNAMES*) GlobalLock(hGlobal); - - dn->wDriverOffset = sizeof(DEVNAMES) / sizeof(wchar_t); - dn->wDeviceOffset = dn->wDriverOffset + program.length() + 1; - dn->wOutputOffset = dn->wDeviceOffset + name.length() + 1; - - memcpy((ushort*)dn + dn->wDriverOffset, program.utf16(), program.length() * 2 + 2); - memcpy((ushort*)dn + dn->wDeviceOffset, name.utf16(), name.length() * 2 + 2); - memcpy((ushort*)dn + dn->wOutputOffset, port.utf16(), port.length() * 2 + 2); - dn->wDefault = 0; - - GlobalUnlock(hGlobal); - -// printf("QPrintDialogWinPrivate::createDevNames()\n" -// " -> wDriverOffset: %d\n" -// " -> wDeviceOffset: %d\n" -// " -> wOutputOffset: %d\n", -// dn->wDriverOffset, -// dn->wDeviceOffset, -// dn->wOutputOffset); - -// printf("QPrintDialogWinPrivate::createDevNames(): %s, %s, %s\n", -// QString::fromWCharArray((wchar_t*)(dn) + dn->wDriverOffset).latin1(), -// QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset).latin1(), -// QString::fromWCharArray((wchar_t*)(dn) + dn->wOutputOffset).latin1()); - - return hGlobal; -} - -void QWin32PrintEnginePrivate::readDevnames(HGLOBAL globalDevnames) -{ - if (globalDevnames) { - DEVNAMES *dn = (DEVNAMES*) GlobalLock(globalDevnames); - name = QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset); - port = QString::fromWCharArray((wchar_t*)(dn) + dn->wOutputOffset); - program = QString::fromWCharArray((wchar_t*)(dn) + dn->wDriverOffset); - GlobalUnlock(globalDevnames); - } -} - -void QWin32PrintEnginePrivate::readDevmode(HGLOBAL globalDevmode) -{ - if (globalDevmode) { - DEVMODE *dm = (DEVMODE*) GlobalLock(globalDevmode); - release(); - globalDevMode = globalDevmode; - devMode = dm; - hdc = CreateDC(reinterpret_cast<const wchar_t *>(program.utf16()), - reinterpret_cast<const wchar_t *>(name.utf16()), 0, dm); - - num_copies = devMode->dmCopies; - if (!OpenPrinter((wchar_t*)name.utf16(), &hPrinter, 0)) - qWarning("QPrinter: OpenPrinter() failed after reading DEVMODE."); - } - - if (hdc) - initHDC(); -} - -static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC hdc, - bool convertToText, const QTransform &xform, const QPointF &topLeft) -{ - QFontEngine *fe = ti.fontEngine; - QPointF baseline_pos = xform.inverted().map(xform.map(pos) - topLeft); - - SetTextAlign(hdc, TA_BASELINE); - SetBkMode(hdc, TRANSPARENT); - - bool has_kerning = ti.f && ti.f->kerning(); - QFontEngineWin *winfe = (fe->type() == QFontEngine::Win) ? static_cast<QFontEngineWin *>(fe) : 0; - - HFONT hfont; - bool ttf = false; - - if (winfe) { - hfont = winfe->hfont; - ttf = winfe->ttf; - } else { - hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); - } - - HGDIOBJ old_font = SelectObject(hdc, hfont); - unsigned int options = (ttf && !convertToText) ? ETO_GLYPH_INDEX : 0; - wchar_t *convertedGlyphs = (wchar_t *)ti.chars; - QGlyphLayout glyphs = ti.glyphs; - - bool fast = !has_kerning && !(ti.flags & QTextItem::RightToLeft); - for (int i = 0; fast && i < glyphs.numGlyphs; i++) { - if (glyphs.offsets[i].x != 0 || glyphs.offsets[i].y != 0 || glyphs.justifications[i].space_18d6 != 0 - || glyphs.attributes[i].dontPrint) { - fast = false; - break; - } - } - -#if !defined(Q_OS_WINCE) - // Scale, rotate and translate here. - XFORM win_xform; - win_xform.eM11 = xform.m11(); - win_xform.eM12 = xform.m12(); - win_xform.eM21 = xform.m21(); - win_xform.eM22 = xform.m22(); - win_xform.eDx = xform.dx(); - win_xform.eDy = xform.dy(); - - SetGraphicsMode(hdc, GM_ADVANCED); - SetWorldTransform(hdc, &win_xform); -#endif - - if (fast) { - // fast path - QVarLengthArray<wchar_t> g(glyphs.numGlyphs); - for (int i = 0; i < glyphs.numGlyphs; ++i) - g[i] = glyphs.glyphs[i]; - ExtTextOut(hdc, - qRound(baseline_pos.x() + glyphs.offsets[0].x.toReal()), - qRound(baseline_pos.y() + glyphs.offsets[0].y.toReal()), - options, 0, convertToText ? convertedGlyphs : g.data(), glyphs.numGlyphs, 0); - } else { - QVarLengthArray<QFixedPoint> positions; - QVarLengthArray<glyph_t> _glyphs; - - QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y()); - ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, - _glyphs, positions); - if (_glyphs.size() == 0) { - SelectObject(hdc, old_font); - return; - } - - convertToText = convertToText && glyphs.numGlyphs == _glyphs.size(); - bool outputEntireItem = _glyphs.size() > 0; - - if (outputEntireItem) { - options |= ETO_PDY; - QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2); - QVarLengthArray<wchar_t> g(_glyphs.size()); - for (int i=0; i<_glyphs.size() - 1; ++i) { - glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x); - glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y); - g[i] = _glyphs[i]; - } - glyphDistances[(_glyphs.size() - 1) * 2] = 0; - glyphDistances[(_glyphs.size() - 1) * 2 + 1] = 0; - g[_glyphs.size() - 1] = _glyphs[_glyphs.size() - 1]; - ExtTextOut(hdc, qRound(positions[0].x), qRound(positions[0].y), options, 0, - convertToText ? convertedGlyphs : g.data(), _glyphs.size(), - glyphDistances.data()); - } else { - int i = 0; - while(i < _glyphs.size()) { - wchar_t g = _glyphs[i]; - - ExtTextOut(hdc, qRound(positions[i].x), - qRound(positions[i].y), options, 0, - convertToText ? convertedGlyphs + i : &g, 1, 0); - ++i; - } - } - } - -#if !defined(Q_OS_WINCE) - win_xform.eM11 = win_xform.eM22 = 1.0; - win_xform.eM12 = win_xform.eM21 = win_xform.eDx = win_xform.eDy = 0.0; - SetWorldTransform(hdc, &win_xform); -#endif - - SelectObject(hdc, old_font); -} - - -void QWin32PrintEnginePrivate::updateCustomPaperSize() -{ - uint paperSize = devMode->dmPaperSize; - if (paperSize > 0 && mapDevmodePaperSize(paperSize) == QPrinter::Custom) { - has_custom_paper_size = true; - DWORD needed = 0; - DWORD returned = 0; - if (!EnumForms(hPrinter, 1, 0, 0, &needed, &returned)) { - BYTE *forms = (BYTE *) malloc(needed); - if (EnumForms(hPrinter, 1, forms, needed, &needed, &returned)) { - if (paperSize <= returned) { - FORM_INFO_1 *formArray = (FORM_INFO_1 *) forms; - int width = formArray[paperSize - 1].Size.cx; // 1/1000 of a mm - int height = formArray[paperSize - 1].Size.cy; // 1/1000 of a mm - paper_size = QSizeF((width * 72 /25.4) / 1000.0, (height * 72 / 25.4) / 1000.0); - } else { - has_custom_paper_size = false; - } - } - free(forms); - } - } else { - has_custom_paper_size = false; - } -} - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER diff --git a/src/gui/painting/qprintengine_win_p.h b/src/gui/painting/qprintengine_win_p.h deleted file mode 100644 index eeb097fd17..0000000000 --- a/src/gui/painting/qprintengine_win_p.h +++ /dev/null @@ -1,261 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPRINTENGINE_WIN_P_H -#define QPRINTENGINE_WIN_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QT_NO_PRINTER - -#include "QtGui/qprinter.h" -#include "QtGui/qprintengine.h" -#include "QtGui/qpaintengine.h" -#include "QtCore/qt_windows.h" -#include "private/qpaintengine_alpha_p.h" - -QT_BEGIN_NAMESPACE - -class QWin32PrintEnginePrivate; -class QPrinterPrivate; -class QPainterState; - -class QWin32PrintEngine : public QAlphaPaintEngine, public QPrintEngine -{ - Q_DECLARE_PRIVATE(QWin32PrintEngine) -public: - QWin32PrintEngine(QPrinter::PrinterMode mode); - - // override QWin32PaintEngine - bool begin(QPaintDevice *dev); - bool end(); - - void updateState(const QPaintEngineState &state); - - void updateMatrix(const QTransform &matrix); - void updateClipPath(const QPainterPath &clip, Qt::ClipOperation op); - - void drawPath(const QPainterPath &path); - void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); - void drawTextItem(const QPointF &p, const QTextItem &textItem); - - void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p); - void setProperty(PrintEnginePropertyKey key, const QVariant &value); - QVariant property(PrintEnginePropertyKey key) const; - - bool newPage(); - bool abort(); - int metric(QPaintDevice::PaintDeviceMetric) const; - - QPrinter::PrinterState printerState() const; - - QPaintEngine::Type type() const { return Windows; } - - HDC getDC() const; - void releaseDC(HDC) const; - - HDC getPrinterDC() const { return getDC(); } - void releasePrinterDC(HDC dc) const { releaseDC(dc); } - -private: - friend class QPrintDialog; - friend class QPageSetupDialog; -}; - -class QWin32PrintEnginePrivate : public QAlphaPaintEnginePrivate -{ - Q_DECLARE_PUBLIC(QWin32PrintEngine) -public: - QWin32PrintEnginePrivate() : - hPrinter(0), - globalDevMode(0), - devMode(0), - pInfo(0), - hdc(0), - mode(QPrinter::ScreenResolution), - state(QPrinter::Idle), - resolution(0), - pageMarginsSet(false), - num_copies(1), - printToFile(false), - fullPage(false), - reinit(false), - has_custom_paper_size(false) - { - } - - ~QWin32PrintEnginePrivate(); - - - /* Reads the default printer name and its driver (printerProgram) into - the engines private data. */ - void queryDefault(); - - /* Initializes the printer data based on the current printer name. This - function creates a DEVMODE struct, HDC and a printer handle. If these - structures are already in use, they are freed using release - */ - void initialize(); - - /* Initializes data in the print engine whenever the HDC has been renewed - */ - void initHDC(); - - /* Releases all the handles the printer currently holds, HDC, DEVMODE, - etc and resets the corresponding members to 0. */ - void release(); - - /* Queries the resolutions for the current printer, and returns them - in a list. */ - QList<QVariant> queryResolutions() const; - - /* Resets the DC with changes in devmode. If the printer is active - this function only sets the reinit variable to true so it - is handled in the next begin or newpage. */ - void doReinit(); - - /* Used by print/page setup dialogs */ - HGLOBAL *createDevNames(); - - void readDevmode(HGLOBAL globalDevmode); - void readDevnames(HGLOBAL globalDevnames); - - inline bool resetDC() { - hdc = ResetDC(hdc, devMode); - return hdc != 0; - } - - void strokePath(const QPainterPath &path, const QColor &color); - void fillPath(const QPainterPath &path, const QColor &color); - - void composeGdiPath(const QPainterPath &path); - void fillPath_dev(const QPainterPath &path, const QColor &color); - void strokePath_dev(const QPainterPath &path, const QColor &color, qreal width); - - void updateOrigin(); - - void initDevRects(); - void setPageMargins(int margin_left, int margin_top, int margin_right, int margin_bottom); - QRect getPageMargins() const; - void updateCustomPaperSize(); - - // Windows GDI printer references. - HANDLE hPrinter; - - HGLOBAL globalDevMode; - DEVMODE *devMode; - PRINTER_INFO_2 *pInfo; - HGLOBAL hMem; - - HDC hdc; - - QPrinter::PrinterMode mode; - - // Printer info - QString name; - QString program; - QString port; - - // Document info - QString docName; - QString fileName; - - QPrinter::PrinterState state; - int resolution; - - // This QRect is used to store the exact values - // entered into the PageSetup Dialog because those are - // entered in mm but are since converted to device coordinates. - // If they were to be converted back when displaying the dialog - // again, there would be inaccuracies so when the user entered 10 - // it may show up as 9.99 the next time the dialog is opened. - // We don't want that confusion. - QRect previousDialogMargins; - - bool pageMarginsSet; - QRect devPageRect; - QRect devPhysicalPageRect; - QRect devPaperRect; - qreal stretch_x; - qreal stretch_y; - int origin_x; - int origin_y; - - int dpi_x; - int dpi_y; - int dpi_display; - int num_copies; - - uint printToFile : 1; - uint fullPage : 1; - uint reinit : 1; - - uint complex_xform : 1; - uint has_pen : 1; - uint has_brush : 1; - uint has_custom_paper_size : 1; - - uint txop; - - QColor brush_color; - QPen pen; - QColor pen_color; - QSizeF paper_size; - - QTransform painterMatrix; - QTransform matrix; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER - -#endif // QPRINTENGINE_WIN_P_H diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp index 74a8f6a9d8..059331f5f9 100644 --- a/src/gui/painting/qprinter.cpp +++ b/src/gui/painting/qprinter.cpp @@ -44,8 +44,7 @@ #include "qprintengine.h" #include "qprinterinfo.h" #include "qlist.h" -#include <qpagesetupdialog.h> -#include <qapplication.h> +#include <qcoreapplication.h> #include <qfileinfo.h> #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) #include "private/qcups_p.h" @@ -53,6 +52,9 @@ #ifndef QT_NO_PRINTER +#include <private/qguiapplication_p.h> +#include <QtGui/QPlatformPrinterSupport> + #if defined (Q_WS_WIN) #include <private/qprintengine_win_p.h> #elif defined (Q_WS_MAC) @@ -60,7 +62,6 @@ #elif defined (QTOPIA_PRINTENGINE) #include <private/qprintengine_qws_p.h> #endif -#include <private/qprintengine_ps_p.h> #if defined(Q_WS_X11) #include <private/qt_x11_p.h> @@ -73,10 +74,6 @@ #include <qpicture.h> #include <private/qpaintengine_preview_p.h> -#if defined(QT3_SUPPORT) -# include "qprintdialog.h" -#endif // QT3_SUPPORT - QT_BEGIN_NAMESPACE #define ABORT_IF_ACTIVE(location) \ @@ -120,7 +117,7 @@ static const float qt_paperSizes[][2] = { }; /// return the multiplier of converting from the unit value to postscript-points. -double qt_multiplierForUnit(QPrinter::Unit unit, int resolution) +Q_GUI_EXPORT double qt_multiplierForUnit(QPrinter::Unit unit, int resolution) { switch(unit) { case QPrinter::Millimeter: @@ -142,7 +139,7 @@ double qt_multiplierForUnit(QPrinter::Unit unit, int resolution) } // not static: it's needed in qpagesetupdialog_unix.cpp -QSizeF qt_printerPaperSize(QPrinter::Orientation orientation, +Q_GUI_EXPORT QSizeF qt_printerPaperSize(QPrinter::Orientation orientation, QPrinter::PaperSize paperSize, QPrinter::Unit unit, int resolution) @@ -164,14 +161,17 @@ void QPrinterPrivate::createDefaultEngines() #if !defined (QTOPIA_PRINTENGINE) #if defined (Q_OS_UNIX) && ! defined (Q_WS_MAC) if(outputFormat == QPrinter::NativeFormat) { - realOutputFormat = QPrinter::PostScriptFormat; + realOutputFormat = QPrinter::PdfFormat; } #endif #endif switch (realOutputFormat) { case QPrinter::NativeFormat: { -#if defined (Q_WS_WIN) +#if defined (Q_WS_QPA) + printEngine = QGuiApplicationPrivate::platformIntegration()->printerSupport()->createNativePrintEngine(printerMode); + paintEngine = QGuiApplicationPrivate::platformIntegration()->printerSupport()->createPaintEngine(printEngine, printerMode); +#elif defined (Q_WS_WIN) QWin32PrintEngine *winEngine = new QWin32PrintEngine(printerMode); paintEngine = winEngine; printEngine = winEngine; @@ -194,12 +194,6 @@ void QPrinterPrivate::createDefaultEngines() printEngine = pdfEngine; } break; - case QPrinter::PostScriptFormat: { - QPSPrintEngine *psEngine = new QPSPrintEngine(printerMode); - paintEngine = psEngine; - printEngine = psEngine; - } - break; } use_default_engine = true; had_default_engines = true; @@ -260,7 +254,7 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke When printing directly to a printer on Windows or Mac OS X, QPrinter uses the built-in printer drivers. On X11, QPrinter uses the \l{Common Unix Printing System (CUPS)} or the standard Unix \l lpr utility - to send PostScript or PDF output to the printer. As an alternative, + to send PDF output to the printer. As an alternative, the printProgram() function can be used to specify the command or utility to use instead of the system default. @@ -347,8 +341,8 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke printer code. \value HighResolution On Windows, sets the printer resolution to that - defined for the printer in use. For PostScript printing, sets the - resolution of the PostScript driver to 1200 dpi. + defined for the printer in use. For PDF printing, sets the + resolution of the PDF driver to 1200 dpi. \note When rendering text on a QPrinter device, it is important to realize that the size of text, when specified in points, is @@ -627,9 +621,9 @@ QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode) void QPrinter::init(PrinterMode mode) { #if !defined(Q_WS_X11) - if (!qApp) { + if (!QCoreApplication::instance()) { #else - if (!qApp || !X11) { + if (!QCoreApplication::instance() || !X11) { #endif qFatal("QPrinter: Must construct a QApplication before a QPaintDevice"); return; @@ -709,9 +703,6 @@ QPrinter::~QPrinter() \value PdfFormat QPrinter will generate its output as a searchable PDF file. This mode is the default when printing to a file. - \value PostScriptFormat QPrinter will generate its output as in the PostScript format. - (This feature was introduced in Qt 4.2.) - \sa outputFormat(), setOutputFormat(), setOutputFileName() */ @@ -753,7 +744,7 @@ void QPrinter::setOutputFormat(OutputFormat format) if (def_engine) delete oldPrintEngine; - if (d->outputFormat == QPrinter::PdfFormat || d->outputFormat == QPrinter::PostScriptFormat) + if (d->outputFormat == QPrinter::PdfFormat) d->validPrinter = true; #else Q_UNUSED(format); @@ -803,20 +794,15 @@ void QPrinter::setPrinterName(const QString &name) ABORT_IF_ACTIVE("QPrinter::setPrinterName"); #if defined(Q_OS_UNIX) && !defined(QT_NO_CUPS) - if(d->use_default_engine - && d->outputFormat == QPrinter::NativeFormat) { - if (QCUPSSupport::cupsVersion() >= 10200 - && QCUPSSupport::printerHasPPD(name.toLocal8Bit().constData())) - setOutputFormat(QPrinter::PdfFormat); - else - setOutputFormat(QPrinter::PostScriptFormat); + if(d->use_default_engine && d->outputFormat == QPrinter::NativeFormat) { + setOutputFormat(QPrinter::PdfFormat); d->outputFormat = QPrinter::NativeFormat; } #endif QList<QPrinterInfo> prnList = QPrinterInfo::availablePrinters(); if (name.isEmpty()) { - d->validPrinter = d->outputFormat == QPrinter::PdfFormat || d->outputFormat == QPrinter::PostScriptFormat; + d->validPrinter = d->outputFormat == QPrinter::PdfFormat; } else { d->validPrinter = false; for (int i = 0; i < prnList.size(); ++i) { @@ -836,7 +822,7 @@ void QPrinter::setPrinterName(const QString &name) \since 4.4 Returns true if the printer currently selected is a valid printer - in the system, or a pure PDF/PostScript printer; otherwise returns false. + in the system, or a pure PDF printer; otherwise returns false. To detect other failures check the output of QPainter::begin() or QPrinter::newPage(). @@ -902,13 +888,12 @@ QString QPrinter::outputFileName() const Setting a null or empty name (0 or "") disables printing to a file. Setting a non-empty name enables printing to a file. - This can change the value of outputFormat(). If the file name has the - suffix ".ps" then PostScript is automatically selected as output format. + This can change the value of outputFormat(). If the file name has the ".pdf" suffix PDF is generated. If the file name - has a suffix other than ".ps" and ".pdf", the output format used is the + has a suffix other than ".pdf", the output format used is the one set with setOutputFormat(). - QPrinter uses Qt's cross-platform PostScript or PDF print engines + QPrinter uses Qt's cross-platform PDF print engines respectively. If you can produce this format natively, for example Mac OS X can generate PDF's from its print engine, set the output format back to NativeFormat. @@ -922,9 +907,7 @@ void QPrinter::setOutputFileName(const QString &fileName) ABORT_IF_ACTIVE("QPrinter::setOutputFileName"); QFileInfo fi(fileName); - if (!fi.suffix().compare(QLatin1String("ps"), Qt::CaseInsensitive)) - setOutputFormat(QPrinter::PostScriptFormat); - else if (!fi.suffix().compare(QLatin1String("pdf"), Qt::CaseInsensitive)) + if (!fi.suffix().compare(QLatin1String("pdf"), Qt::CaseInsensitive)) setOutputFormat(QPrinter::PdfFormat); else if (fileName.isEmpty()) setOutputFormat(QPrinter::NativeFormat); @@ -956,7 +939,7 @@ QString QPrinter::printProgram() const Sets the name of the program that should do the print job to \a printProg. - On X11, this function sets the program to call with the PostScript + On X11, this function sets the program to call with the PDF output. On other platforms, it has no effect. \sa printProgram() @@ -1798,9 +1781,9 @@ int QPrinter::winPageSize() const Returns a list of the resolutions (a list of dots-per-inch integers) that the printer says it supports. - For X11 where all printing is directly to postscript, this + For X11 where all printing is directly to PDF, this function will always return a one item list containing only the - postscript resolution, i.e., 72 (72 dpi -- but see PrinterMode). + PDF resolution, i.e., 72 (72 dpi -- but see PrinterMode). */ QList<int> QPrinter::supportedResolutions() const { @@ -2073,7 +2056,6 @@ void QPrinter::setFromTo(int from, int to) if (d->minPage == 0 && d->maxPage == 0) { d->minPage = 1; d->maxPage = to; - d->options |= QAbstractPrintDialog::PrintPageRange; } } @@ -2085,7 +2067,7 @@ void QPrinter::setFromTo(int from, int to) void QPrinter::setPrintRange( PrintRange range ) { Q_D(QPrinter); - d->printRange = QAbstractPrintDialog::PrintRange(range); + d->printRange = range; } /*! @@ -2100,164 +2082,9 @@ void QPrinter::setPrintRange( PrintRange range ) QPrinter::PrintRange QPrinter::printRange() const { Q_D(const QPrinter); - return PrintRange(d->printRange); -} - -#if defined(QT3_SUPPORT) - -void QPrinter::setOutputToFile(bool f) -{ - if (f) { - if (outputFileName().isEmpty()) - setOutputFileName(QLatin1String("untitled_printer_document")); - } else { - setOutputFileName(QString()); - } -} - -bool qt_compat_QPrinter_printSetup(QPrinter *printer, QPrinterPrivate *pd, QWidget *parent) -{ - Q_UNUSED(pd); - QPrintDialog dlg(printer, parent); - return dlg.exec() != 0; -} - - -#ifdef Q_WS_MAC -bool qt_compat_QPrinter_pageSetup(QPrinter *p, QWidget *parent) -{ - QPageSetupDialog psd(p, parent); - return psd.exec() != 0; -} - -/*! - Executes a page setup dialog so that the user can configure the type of - page used for printing. Returns true if the contents of the dialog are - accepted; returns false if the dialog is canceled. -*/ -bool QPrinter::pageSetup(QWidget *parent) -{ - return qt_compat_QPrinter_pageSetup(this, parent); -} - -/*! - Executes a print setup dialog so that the user can configure the printing - process. Returns true if the contents of the dialog are accepted; returns - false if the dialog is canceled. -*/ -bool QPrinter::printSetup(QWidget *parent) -{ - Q_D(QPrinter); - return qt_compat_QPrinter_printSetup(this, d, parent); -} -#endif // Q_WS_MAC - -/*! - Use QPrintDialog instead. - - \oldcode - if (printer->setup(parent)) - ... - \newcode - QPrintDialog dialog(printer, parent); - if (dialog.exec()) - ... - \endcode -*/ -bool QPrinter::setup(QWidget *parent) -{ - Q_D(QPrinter); - return qt_compat_QPrinter_printSetup(this, d, parent) -#ifdef Q_WS_MAC - && qt_compat_QPrinter_pageSetup(this, parent); -#endif - ; -} - -/*! - Use QPrintDialog::minPage() instead. -*/ -int QPrinter::minPage() const -{ - Q_D(const QPrinter); - return d->minPage; -} - -/*! - Use QPrintDialog::maxPage() instead. -*/ -int QPrinter::maxPage() const -{ - Q_D(const QPrinter); - return d->maxPage; -} - -/*! - Use QPrintDialog::setMinMax() instead. -*/ -void QPrinter::setMinMax( int minPage, int maxPage ) -{ - Q_D(QPrinter); - Q_ASSERT_X(minPage <= maxPage, "QPrinter::setMinMax", - "'min' must be less than or equal to 'max'"); - d->minPage = minPage; - d->maxPage = maxPage; - d->options |= QPrintDialog::PrintPageRange; -} - -/*! - Returns true if the printer is set up to collate copies of printed documents; - otherwise returns false. - - Use QPrintDialog::isOptionEnabled(QPrintDialog::PrintCollateCopies) - instead. - - \sa collateCopies() -*/ -bool QPrinter::collateCopiesEnabled() const -{ - Q_D(const QPrinter); - return (d->options & QPrintDialog::PrintCollateCopies); -} - -/*! - Use QPrintDialog::setOption(QPrintDialog::PrintCollateCopies) - or QPrintDialog::setOptions(QPrintDialog::options() - & ~QPrintDialog::PrintCollateCopies) instead, depending on \a - enable. -*/ -void QPrinter::setCollateCopiesEnabled(bool enable) -{ - Q_D(QPrinter); - - if (enable) - d->options |= QPrintDialog::PrintCollateCopies; - else - d->options &= ~QPrintDialog::PrintCollateCopies; -} - -/*! - Use QPrintDialog instead. -*/ -void QPrinter::setOptionEnabled( PrinterOption option, bool enable ) -{ - Q_D(QPrinter); - if (enable) - d->options |= QPrintDialog::PrintDialogOption(1 << option); - else - d->options &= ~QPrintDialog::PrintDialogOption(1 << option); -} - -/*! - Use QPrintDialog instead. -*/ -bool QPrinter::isOptionEnabled( PrinterOption option ) const -{ - Q_D(const QPrinter); - return (d->options & QPrintDialog::PrintDialogOption(option)); + return d->printRange; } -#endif // QT3_SUPPORT /*! \class QPrintEngine diff --git a/src/gui/painting/qprinter.h b/src/gui/painting/qprinter.h index 58db6122e0..d551489bb8 100644 --- a/src/gui/painting/qprinter.h +++ b/src/gui/painting/qprinter.h @@ -121,9 +121,9 @@ public: Aborted, Error }; - enum OutputFormat { NativeFormat, PdfFormat, PostScriptFormat }; + enum OutputFormat { NativeFormat, PdfFormat }; - // ### Qt 5: Merge with QAbstractPrintDialog::PrintRange + // Keep in sync with QAbstractPrintDialog::PrintRange enum PrintRange { AllPages, Selection, PageRange, CurrentPage }; enum Unit { @@ -143,10 +143,6 @@ public: DuplexShortSide }; -#ifdef QT3_SUPPORT - enum PrinterOption { PrintToFile, PrintSelection, PrintPageRange }; -#endif // QT3_SUPPORT - void setOutputFormat(OutputFormat format); OutputFormat outputFormat() const; @@ -259,33 +255,6 @@ public: void setPageMargins(qreal left, qreal top, qreal right, qreal bottom, Unit unit); void getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, Unit unit) const; -#ifdef QT3_SUPPORT -#ifdef Q_WS_MAC - QT3_SUPPORT bool pageSetup(QWidget *parent = 0); - QT3_SUPPORT bool printSetup(QWidget *parent = 0); -#endif - - QT3_SUPPORT bool setup(QWidget *parent = 0); - - QT3_SUPPORT void setMinMax(int minPage, int maxPage); - QT3_SUPPORT int minPage() const; - QT3_SUPPORT int maxPage() const; - - QT3_SUPPORT void setCollateCopiesEnabled(bool); - QT3_SUPPORT bool collateCopiesEnabled() const; - - QT3_SUPPORT void setOptionEnabled(PrinterOption, bool enable); - QT3_SUPPORT bool isOptionEnabled(PrinterOption) const; - - inline QT3_SUPPORT QSize margins() const; - inline QT3_SUPPORT void margins(uint *top, uint *left, uint *bottom, uint *right) const; - - inline QT3_SUPPORT bool aborted() { return printerState() == Aborted; } - - QT3_SUPPORT void setOutputToFile(bool); - inline QT3_SUPPORT bool outputToFile() const { return !outputFileName().isEmpty(); } -#endif - protected: int metric(PaintDeviceMetric) const; void setEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine); @@ -305,29 +274,6 @@ private: friend class QPageSetupWidget; }; -#ifdef QT3_SUPPORT -inline QSize QPrinter::margins() const -{ - QRect page = pageRect(); - QRect paper = paperRect(); - return QSize(page.left() - paper.left(), page.top() - paper.top()); -} - -inline void QPrinter::margins(uint *top, uint *left, uint *bottom, uint *right) const -{ - QRect page = pageRect(); - QRect paper = paperRect(); - if (top) - *top = page.top() - paper.top(); - if (left) - *left = page.left() - paper.left(); - if (bottom) - *bottom = paper.bottom() - page.bottom(); - if (right) - *right = paper.right() - page.right(); -} -#endif - #endif // QT_NO_PRINTER QT_END_NAMESPACE diff --git a/src/gui/painting/qprinter_p.h b/src/gui/painting/qprinter_p.h index 2d35672c2c..2ba0f0dbb8 100644 --- a/src/gui/painting/qprinter_p.h +++ b/src/gui/painting/qprinter_p.h @@ -60,7 +60,6 @@ #include "QtGui/qprinter.h" #include "QtGui/qprintengine.h" -#include "QtGui/qprintdialog.h" #include "QtCore/qpointer.h" #include <limits.h> @@ -71,7 +70,7 @@ class QPrintEngine; class QPreviewPaintEngine; class QPicture; -class QPrinterPrivate +class Q_GUI_EXPORT QPrinterPrivate { Q_DECLARE_PUBLIC(QPrinter) public: @@ -79,9 +78,7 @@ public: : printEngine(0) , paintEngine(0) , q_ptr(printer) - , options(QAbstractPrintDialog::PrintToFile | QAbstractPrintDialog::PrintPageRange | - QAbstractPrintDialog::PrintCollateCopies | QAbstractPrintDialog::PrintShowPageSize) - , printRange(QAbstractPrintDialog::AllPages) + , printRange(QPrinter::AllPages) , minPage(1) , maxPage(INT_MAX) , fromPage(0) @@ -118,8 +115,7 @@ public: QPrinter *q_ptr; - QAbstractPrintDialog::PrintDialogOptions options; - QAbstractPrintDialog::PrintRange printRange; + QPrinter::PrintRange printRange; int minPage, maxPage, fromPage, toPage; uint use_default_engine : 1; diff --git a/src/gui/painting/qprinterinfo.cpp b/src/gui/painting/qprinterinfo.cpp index a7ddc85a54..0049bd248a 100644 --- a/src/gui/painting/qprinterinfo.cpp +++ b/src/gui/painting/qprinterinfo.cpp @@ -30,6 +30,9 @@ #ifndef QT_NO_PRINTER +#include <private/qguiapplication_p.h> +#include <QtGui/QPlatformPrinterSupport> + QT_BEGIN_NAMESPACE QPrinterInfoPrivate QPrinterInfoPrivate::shared_null; @@ -168,6 +171,29 @@ bool QPrinterInfo::isDefault() const On Mac OS X 10.3, this function always returns an empty list. */ +#ifdef Q_WS_QPA +QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const +{ + const Q_D(QPrinterInfo); + if (!isNull() && !d->hasPaperSizes) { + d->paperSizes = QGuiApplicationPrivate::platformIntegration()->printerSupport()->supportedPaperSizes(*this); + d->hasPaperSizes = true; + } + return d->paperSizes; +} + +QList<QPrinterInfo> QPrinterInfo::availablePrinters() +{ + return QGuiApplicationPrivate::platformIntegration()->printerSupport()->availablePrinters(); +} + +QPrinterInfo QPrinterInfo::defaultPrinter() +{ + return QGuiApplicationPrivate::platformIntegration()->printerSupport()->defaultPrinter(); +} + +#endif //Q_WS_QPA + QT_END_NAMESPACE #endif // QT_NO_PRINTER diff --git a/src/gui/painting/qprinterinfo.h b/src/gui/painting/qprinterinfo.h index 9ff1bd16bd..72082cf299 100644 --- a/src/gui/painting/qprinterinfo.h +++ b/src/gui/painting/qprinterinfo.h @@ -77,6 +77,7 @@ private: QPrinterInfo(const QString &name); private: + friend class QPlatformPrinterSupport; Q_DECLARE_PRIVATE(QPrinterInfo) QScopedPointer<QPrinterInfoPrivate, QPrinterInfoPrivateDeleter> d_ptr; }; diff --git a/src/gui/painting/qprinterinfo_mac.cpp b/src/gui/painting/qprinterinfo_mac.cpp deleted file mode 100644 index 455510d5d3..0000000000 --- a/src/gui/painting/qprinterinfo_mac.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qprinterinfo.h" -#include "qprinterinfo_p.h" - -#include "private/qt_mac_p.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_PRINTER - -extern QPrinter::PaperSize qSizeFTopaperSize(const QSizeF &size); - -QList<QPrinterInfo> QPrinterInfo::availablePrinters() -{ - QList<QPrinterInfo> printers; - - QCFType<CFArrayRef> array; - if (PMServerCreatePrinterList(kPMServerLocal, &array) == noErr) { - CFIndex count = CFArrayGetCount(array); - for (int i = 0; i < count; ++i) { - PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(array, i))); - QString printerName = QCFString::toQString(PMPrinterGetName(printer)); - - QPrinterInfo printerInfo(printerName); - if (PMPrinterIsDefault(printer)) - printerInfo.d_ptr->isDefault = true; - printers.append(printerInfo); - } - } - - return printers; -} - -QPrinterInfo QPrinterInfo::defaultPrinter() -{ - QList<QPrinterInfo> printers = availablePrinters(); - foreach (const QPrinterInfo &printerInfo, printers) { - if (printerInfo.isDefault()) - return printerInfo; - } - - return printers.value(0); -} - -QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const -{ - const Q_D(QPrinterInfo); - - QList<QPrinter::PaperSize> paperSizes; - if (isNull()) - return paperSizes; - - PMPrinter cfPrn = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(d->name)); - if (!cfPrn) - return paperSizes; - - CFArrayRef array; - if (PMPrinterGetPaperList(cfPrn, &array) != noErr) { - PMRelease(cfPrn); - return paperSizes; - } - - int count = CFArrayGetCount(array); - for (int i = 0; i < count; ++i) { - PMPaper paper = static_cast<PMPaper>(const_cast<void *>(CFArrayGetValueAtIndex(array, i))); - double width, height; - if (PMPaperGetWidth(paper, &width) == noErr && PMPaperGetHeight(paper, &height) == noErr) { - QSizeF size(width * 0.3527, height * 0.3527); - paperSizes.append(qSizeFTopaperSize(size)); - } - } - - PMRelease(cfPrn); - - return paperSizes; -} - -#endif // QT_NO_PRINTER - -QT_END_NAMESPACE diff --git a/src/gui/painting/qprinterinfo_p.h b/src/gui/painting/qprinterinfo_p.h index a3f7d5d252..a3c654e7b7 100644 --- a/src/gui/painting/qprinterinfo_p.h +++ b/src/gui/painting/qprinterinfo_p.h @@ -68,9 +68,10 @@ public: name(name), isDefault(false) #if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA) #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - , cupsPrinterIndex(0), hasPaperSizes(false) + , cupsPrinterIndex(0) #endif #endif + , hasPaperSizes(false) {} ~QPrinterInfoPrivate() {} @@ -83,10 +84,10 @@ public: #if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA) #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) int cupsPrinterIndex; - mutable bool hasPaperSizes; - mutable QList<QPrinter::PaperSize> paperSizes; #endif #endif + mutable bool hasPaperSizes; + mutable QList<QPrinter::PaperSize> paperSizes; }; diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp index aa220aad57..3c66481b4d 100644 --- a/src/gui/painting/qprinterinfo_unix.cpp +++ b/src/gui/painting/qprinterinfo_unix.cpp @@ -45,9 +45,9 @@ #include <qfile.h> #include <qfileinfo.h> #include <qdir.h> -#include <qprintdialog.h> #include <qlibrary.h> #include <qtextstream.h> +#include <qcoreapplication.h> #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) # include <private/qcups_p.h> @@ -130,10 +130,8 @@ void qt_perhapsAddPrinter(QList<QPrinterDescription> *printers, const QString &n if (printers->at(i).samePrinter(name)) return; -#ifndef QT_NO_PRINTDIALOG if (host.isEmpty()) - host = QPrintDialog::tr("locally connected"); -#endif + host = QCoreApplication::translate("QPrinter", "locally connected"); printers->append(QPrinterDescription(name.simplified(), host.simplified(), comment.simplified(), aliases)); } @@ -153,11 +151,9 @@ void qt_parsePrinterDesc(QString printerDesc, QList<QPrinterDescription> *printe if (j > 0 && j < i) { printerName = printerDesc.left(j); aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|')); -#ifndef QT_NO_PRINTDIALOG // try extracting a comment from the aliases - printerComment = QPrintDialog::tr("Aliases: %1") + printerComment = QCoreApplication::translate("QPrinter", "Aliases: %1") .arg(aliases.join(QLatin1String(", "))); -#endif } else { printerName = printerDesc.left(i); } @@ -379,10 +375,8 @@ char *qt_parsePrintersConf(QList<QPrinterDescription> *printers, bool *found) if (j > 0) { // try extracting a comment from the aliases aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|')); -#ifndef QT_NO_PRINTDIALOG - printerComment = QPrintDialog::tr("Aliases: %1") + printerComment = QCoreApplication::translate("QPrinter", "Aliases: %1") .arg(aliases.join(QLatin1String(", "))); -#endif } // look for signs of this being a remote printer i = printerDesc.indexOf( @@ -593,9 +587,6 @@ void qt_parseEtcLpMember(QList<QPrinterDescription> *printers) if (dirs.isEmpty()) return; -#ifdef QT_NO_PRINTDIALOG - Q_UNUSED(printers); -#else QString tmp; for (int i = 0; i < dirs.size(); ++i) { QFileInfo printer = dirs.at(i); @@ -605,10 +596,9 @@ void qt_parseEtcLpMember(QList<QPrinterDescription> *printers) // decent way to locate aliases and remote printers. if (printer.isFile()) qt_perhapsAddPrinter(printers, printer.fileName(), - QPrintDialog::tr("unknown"), + QCoreApplication::translate("QPrinter", "unknown"), QLatin1String("")); } -#endif } // IRIX 6.x @@ -751,7 +741,7 @@ void qt_parseQconfig(QList<QPrinterDescription> *printers) } while (!ts.atEnd()); } -int qt_getLprPrinters(QList<QPrinterDescription>& printers) +Q_GUI_EXPORT int qt_getLprPrinters(QList<QPrinterDescription>& printers) { QByteArray etcLpDefault; qt_parsePrintcap(&printers, QLatin1String("/etc/printcap")); @@ -801,12 +791,10 @@ int qt_getLprPrinters(QList<QPrinterDescription>& printers) dollarPrinter = QString::fromLocal8Bit(qgetenv("NPRINTER")); if (dollarPrinter.isEmpty()) dollarPrinter = QString::fromLocal8Bit(qgetenv("NGPRINTER")); -#ifndef QT_NO_PRINTDIALOG if (!dollarPrinter.isEmpty()) qt_perhapsAddPrinter(&printers, dollarPrinter, - QPrintDialog::tr("unknown"), + QCoreApplication::translate("QPrinter", "unknown"), QLatin1String("")); -#endif } QRegExp ps(QLatin1String("[^a-z]ps(?:[^a-z]|$)")); @@ -847,78 +835,20 @@ int qt_getLprPrinters(QList<QPrinterDescription>& printers) ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -QList<QPrinterInfo> QPrinterInfo::availablePrinters() -{ - QList<QPrinterInfo> printers; - -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - if (QCUPSSupport::isAvailable()) { - QCUPSSupport cups; - int cupsPrinterCount = cups.availablePrintersCount(); - const cups_dest_t* cupsPrinters = cups.availablePrinters(); - for (int i = 0; i < cupsPrinterCount; ++i) { - QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name)); - if (cupsPrinters[i].instance) - printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance); - - QPrinterInfo printerInfo(printerName); - if (cupsPrinters[i].is_default) - printerInfo.d_ptr->isDefault = true; - printerInfo.d_ptr->cupsPrinterIndex = i; - printers.append(printerInfo); - } - } else -#endif - { - QList<QPrinterDescription> lprPrinters; - int defprn = qt_getLprPrinters(lprPrinters); - // populating printer combo - foreach (const QPrinterDescription &description, lprPrinters) - printers.append(QPrinterInfo(description.name)); - if (defprn >= 0 && defprn < printers.size()) - printers[defprn].d_ptr->isDefault = true; - } - - return printers; -} - -QPrinterInfo QPrinterInfo::defaultPrinter() -{ - QList<QPrinterInfo> printers = availablePrinters(); - foreach (const QPrinterInfo &printerInfo, printers) { - if (printerInfo.isDefault()) - return printerInfo; - } - - return printers.value(0); -} - -QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const +QList<QPrinter::PaperSize> qt_getCupsPrinterPaperSizes(int cupsPrinterIndex) { + QList<QPrinter::PaperSize> result; #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - const Q_D(QPrinterInfo); - - if (isNull()) - return d->paperSizes; - - if (!d->hasPaperSizes) { - d->hasPaperSizes = true; - - if (QCUPSSupport::isAvailable()) { - // Find paper sizes from CUPS. - QCUPSSupport cups; - cups.setCurrentPrinter(d->cupsPrinterIndex); - const ppd_option_t* sizes = cups.pageSizes(); - if (sizes) { - for (int j = 0; j < sizes->num_choices; ++j) - d->paperSizes.append(string2PaperSize(sizes->choices[j].choice)); - } - } + if (!QCUPSSupport::isAvailable() || cupsPrinterIndex < 0) + return result; + // Find paper sizes from CUPS. + QCUPSSupport cups; + cups.setCurrentPrinter(cupsPrinterIndex); + if (const ppd_option_t* size = cups.pageSizes()) { + for (int j = 0; j < size->num_choices; ++j) + result.append(string2PaperSize(size->choices[j].choice)); } - - return d->paperSizes; -#else - return QList<QPrinter::PaperSize>(); + return result; #endif } diff --git a/src/gui/painting/qprinterinfo_unix_p.h b/src/gui/painting/qprinterinfo_unix_p.h index 1ededf5a36..f8721deaa9 100644 --- a/src/gui/painting/qprinterinfo_unix_p.h +++ b/src/gui/painting/qprinterinfo_unix_p.h @@ -42,6 +42,9 @@ #ifndef QPRINTERINFO_UNIX_P_H #define QPRINTERINFO_UNIX_P_H +#include <QtGui/qprinter.h> +#include <QtCore/qstringlist.h> + #ifndef QT_NO_NIS # ifndef BOOL_DEFINED # define BOOL_DEFINED @@ -118,6 +121,8 @@ void qt_parseSpoolInterface(QList<QPrinterDescription> *printers); void qt_parseQconfig(QList<QPrinterDescription> *printers); int qt_getLprPrinters(QList<QPrinterDescription>& printers); +QList<QPrinter::PaperSize> qt_getCupsPrinterPaperSizes(int cupsPrinterIndex); + #endif // QT_NO_PRINTER QT_END_NAMESPACE diff --git a/src/gui/painting/qprinterinfo_win.cpp b/src/gui/painting/qprinterinfo_win.cpp deleted file mode 100644 index cc0cd0232d..0000000000 --- a/src/gui/painting/qprinterinfo_win.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qprinterinfo.h" -#include "qprinterinfo_p.h" - -#include <qstringlist.h> - -#include <qt_windows.h> - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_PRINTER - -extern QPrinter::PaperSize mapDevmodePaperSize(int s); - -QList<QPrinterInfo> QPrinterInfo::availablePrinters() -{ - QList<QPrinterInfo> printers; - - DWORD needed = 0; - DWORD returned = 0; - if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) { - LPBYTE buffer = new BYTE[needed]; - if (EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer, needed, &needed, &returned)) { - PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer); - QPrinterInfo defPrn = defaultPrinter(); - for (uint i = 0; i < returned; ++i) { - QString printerName(QString::fromWCharArray(infoList[i].pPrinterName)); - - QPrinterInfo printerInfo(printerName); - if (printerInfo.printerName() == defPrn.printerName()) - printerInfo.d_ptr->isDefault = true; - printers.append(printerInfo); - } - } - delete [] buffer; - } - - return printers; -} - -QPrinterInfo QPrinterInfo::defaultPrinter() -{ - QString noPrinters(QLatin1String("qt_no_printers")); - wchar_t buffer[256]; - GetProfileString(L"windows", L"device", (wchar_t*)noPrinters.utf16(), buffer, 256); - QString output = QString::fromWCharArray(buffer); - if (output != noPrinters) { - // Filter out the name of the printer, which should be everything before a comma. - QString printerName = output.split(QLatin1Char(',')).value(0); - QPrinterInfo printerInfo(printerName); - printerInfo.d_ptr->isDefault = true; - return printerInfo; - } - - return QPrinterInfo(); -} - -QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const -{ - const Q_D(QPrinterInfo); - - QList<QPrinter::PaperSize> paperSizes; - if (isNull()) - return paperSizes; - - DWORD size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()), - NULL, DC_PAPERS, NULL, NULL); - if ((int)size != -1) { - wchar_t *papers = new wchar_t[size]; - size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()), - NULL, DC_PAPERS, papers, NULL); - for (int c = 0; c < (int)size; ++c) - paperSizes.append(mapDevmodePaperSize(papers[c])); - delete [] papers; - } - - return paperSizes; -} - -#endif // QT_NO_PRINTER - -QT_END_NAMESPACE diff --git a/src/gui/painting/qpsprinter.agl b/src/gui/painting/qpsprinter.agl deleted file mode 100644 index 137b64c53b..0000000000 --- a/src/gui/painting/qpsprinter.agl +++ /dev/null @@ -1,452 +0,0 @@ -# the next table is derived from a list provided by Adobe on its web -# server: http://partners.adobe.com/asn/developer/typeforum/glyphlist.txt - -# the start of the header comment: -# -# Name: Adobe Glyph List -# Table version: 1.2 -# Date: 22 Oct 1998 -# -# Description: -# -# The Adobe Glyph List (AGL) list relates Unicode values (UVs) to glyph -# names, and should be used only as described in the document "Unicode and -# Glyph Names," at -# http://partners.adobe.com:80/asn/developer/type/unicodegn.html -# -# IMPORTANT NOTE: -# the list contains glyphs in the private use area of unicode. -# These should get removed when regenerating the glyphlist. -# -# also 0 should be mapped to .notdef -# -# grep '^[0-9A-F][0-9A-F][0-9A-F][0-9A-F];' < /tmp/glyphlist.txt | sed -e 's/;/, "/' -e 's-;-" }, // -' -e 's/^/ { 0x/' | sort -# -0x0000, ".notdef" -0x0020, "space" # SPACE -0x0021, "exclam" # EXCLAMATION MARK -0x0022, "quotedbl" # QUOTATION MARK -0x0023, "numbersign" # NUMBER SIGN -0x0024, "dollar" # DOLLAR SIGN -0x0025, "percent" # PERCENT SIGN -0x0026, "ampersand" # AMPERSAND -0x0027, "quotesingle" # APOSTROPHE -0x0028, "parenleft" # LEFT PARENTHESIS -0x0029, "parenright" # RIGHT PARENTHESIS -0x002A, "asterisk" # ASTERISK -0x002B, "plus" # PLUS SIGN -0x002C, "comma" # COMMA -0x002D, "hyphen" # HYPHEN-MINUS -0x002E, "period" # FULL STOP -0x002F, "slash" # SOLIDUS -0x0030, "zero" # DIGIT ZERO -0x0031, "one" # DIGIT ONE -0x0032, "two" # DIGIT TWO -0x0033, "three" # DIGIT THREE -0x0034, "four" # DIGIT FOUR -0x0035, "five" # DIGIT FIVE -0x0036, "six" # DIGIT SIX -0x0037, "seven" # DIGIT SEVEN -0x0038, "eight" # DIGIT EIGHT -0x0039, "nine" # DIGIT NINE -0x003A, "colon" # COLON -0x003B, "semicolon" # SEMICOLON -0x003C, "less" # LESS-THAN SIGN -0x003D, "equal" # EQUALS SIGN -0x003E, "greater" # GREATER-THAN SIGN -0x003F, "question" # QUESTION MARK -0x0040, "at" # COMMERCIAL AT -0x0041, "A" # LATIN CAPITAL LETTER A -0x0042, "B" # LATIN CAPITAL LETTER B -0x0043, "C" # LATIN CAPITAL LETTER C -0x0044, "D" # LATIN CAPITAL LETTER D -0x0045, "E" # LATIN CAPITAL LETTER E -0x0046, "F" # LATIN CAPITAL LETTER F -0x0047, "G" # LATIN CAPITAL LETTER G -0x0048, "H" # LATIN CAPITAL LETTER H -0x0049, "I" # LATIN CAPITAL LETTER I -0x004A, "J" # LATIN CAPITAL LETTER J -0x004B, "K" # LATIN CAPITAL LETTER K -0x004C, "L" # LATIN CAPITAL LETTER L -0x004D, "M" # LATIN CAPITAL LETTER M -0x004E, "N" # LATIN CAPITAL LETTER N -0x004F, "O" # LATIN CAPITAL LETTER O -0x0050, "P" # LATIN CAPITAL LETTER P -0x0051, "Q" # LATIN CAPITAL LETTER Q -0x0052, "R" # LATIN CAPITAL LETTER R -0x0053, "S" # LATIN CAPITAL LETTER S -0x0054, "T" # LATIN CAPITAL LETTER T -0x0055, "U" # LATIN CAPITAL LETTER U -0x0056, "V" # LATIN CAPITAL LETTER V -0x0057, "W" # LATIN CAPITAL LETTER W -0x0058, "X" # LATIN CAPITAL LETTER X -0x0059, "Y" # LATIN CAPITAL LETTER Y -0x005A, "Z" # LATIN CAPITAL LETTER Z -0x005B, "bracketleft" # LEFT SQUARE BRACKET -0x005C, "backslash" # REVERSE SOLIDUS -0x005D, "bracketright" # RIGHT SQUARE BRACKET -0x005E, "asciicircum" # CIRCUMFLEX ACCENT -0x005F, "underscore" # LOW LINE -0x0060, "grave" # GRAVE ACCENT -0x0061, "a" # LATIN SMALL LETTER A -0x0062, "b" # LATIN SMALL LETTER B -0x0063, "c" # LATIN SMALL LETTER C -0x0064, "d" # LATIN SMALL LETTER D -0x0065, "e" # LATIN SMALL LETTER E -0x0066, "f" # LATIN SMALL LETTER F -0x0067, "g" # LATIN SMALL LETTER G -0x0068, "h" # LATIN SMALL LETTER H -0x0069, "i" # LATIN SMALL LETTER I -0x006A, "j" # LATIN SMALL LETTER J -0x006B, "k" # LATIN SMALL LETTER K -0x006C, "l" # LATIN SMALL LETTER L -0x006D, "m" # LATIN SMALL LETTER M -0x006E, "n" # LATIN SMALL LETTER N -0x006F, "o" # LATIN SMALL LETTER O -0x0070, "p" # LATIN SMALL LETTER P -0x0071, "q" # LATIN SMALL LETTER Q -0x0072, "r" # LATIN SMALL LETTER R -0x0073, "s" # LATIN SMALL LETTER S -0x0074, "t" # LATIN SMALL LETTER T -0x0075, "u" # LATIN SMALL LETTER U -0x0076, "v" # LATIN SMALL LETTER V -0x0077, "w" # LATIN SMALL LETTER W -0x0078, "x" # LATIN SMALL LETTER X -0x0079, "y" # LATIN SMALL LETTER Y -0x007A, "z" # LATIN SMALL LETTER Z -0x007B, "braceleft" # LEFT CURLY BRACKET -0x007C, "bar" # VERTICAL LINE -0x007D, "braceright" # RIGHT CURLY BRACKET -0x007E, "asciitilde" # TILDE -0x00A0, "space" # NO-BREAK SPACE;Duplicate -0x00A1, "exclamdown" # INVERTED EXCLAMATION MARK -0x00A2, "cent" # CENT SIGN -0x00A3, "sterling" # POUND SIGN -0x00A4, "currency" # CURRENCY SIGN -0x00A5, "yen" # YEN SIGN -0x00A6, "brokenbar" # BROKEN BAR -0x00A7, "section" # SECTION SIGN -0x00A8, "dieresis" # DIAERESIS -0x00A9, "copyright" # COPYRIGHT SIGN -0x00AA, "ordfeminine" # FEMININE ORDINAL INDICATOR -0x00AB, "guillemotleft" # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -0x00AC, "logicalnot" # NOT SIGN -0x00AD, "hyphen" # SOFT HYPHEN;Duplicate -0x00AE, "registered" # REGISTERED SIGN -0x00AF, "macron" # MACRON -0x00B0, "degree" # DEGREE SIGN -0x00B1, "plusminus" # PLUS-MINUS SIGN -0x00B2, "twosuperior" # SUPERSCRIPT TWO -0x00B3, "threesuperior" # SUPERSCRIPT THREE -0x00B4, "acute" # ACUTE ACCENT -0x00B5, "mu" # MICRO SIGN -0x00B6, "paragraph" # PILCROW SIGN -0x00B7, "periodcentered" # MIDDLE DOT -0x00B8, "cedilla" # CEDILLA -0x00B9, "onesuperior" # SUPERSCRIPT ONE -0x00BA, "ordmasculine" # MASCULINE ORDINAL INDICATOR -0x00BB, "guillemotright" # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -0x00BC, "onequarter" # VULGAR FRACTION ONE QUARTER -0x00BD, "onehalf" # VULGAR FRACTION ONE HALF -0x00BE, "threequarters" # VULGAR FRACTION THREE QUARTERS -0x00BF, "questiondown" # INVERTED QUESTION MARK -0x00C0, "Agrave" # LATIN CAPITAL LETTER A WITH GRAVE -0x00C1, "Aacute" # LATIN CAPITAL LETTER A WITH ACUTE -0x00C2, "Acircumflex" # LATIN CAPITAL LETTER A WITH CIRCUMFLEX -0x00C3, "Atilde" # LATIN CAPITAL LETTER A WITH TILDE -0x00C4, "Adieresis" # LATIN CAPITAL LETTER A WITH DIAERESIS -0x00C5, "Aring" # LATIN CAPITAL LETTER A WITH RING ABOVE -0x00C6, "AE" # LATIN CAPITAL LETTER AE -0x00C7, "Ccedilla" # LATIN CAPITAL LETTER C WITH CEDILLA -0x00C8, "Egrave" # LATIN CAPITAL LETTER E WITH GRAVE -0x00C9, "Eacute" # LATIN CAPITAL LETTER E WITH ACUTE -0x00CA, "Ecircumflex" # LATIN CAPITAL LETTER E WITH CIRCUMFLEX -0x00CB, "Edieresis" # LATIN CAPITAL LETTER E WITH DIAERESIS -0x00CC, "Igrave" # LATIN CAPITAL LETTER I WITH GRAVE -0x00CD, "Iacute" # LATIN CAPITAL LETTER I WITH ACUTE -0x00CE, "Icircumflex" # LATIN CAPITAL LETTER I WITH CIRCUMFLEX -0x00CF, "Idieresis" # LATIN CAPITAL LETTER I WITH DIAERESIS -0x00D0, "Eth" # LATIN CAPITAL LETTER ETH -0x00D1, "Ntilde" # LATIN CAPITAL LETTER N WITH TILDE -0x00D2, "Ograve" # LATIN CAPITAL LETTER O WITH GRAVE -0x00D3, "Oacute" # LATIN CAPITAL LETTER O WITH ACUTE -0x00D4, "Ocircumflex" # LATIN CAPITAL LETTER O WITH CIRCUMFLEX -0x00D5, "Otilde" # LATIN CAPITAL LETTER O WITH TILDE -0x00D6, "Odieresis" # LATIN CAPITAL LETTER O WITH DIAERESIS -0x00D7, "multiply" # MULTIPLICATION SIGN -0x00D8, "Oslash" # LATIN CAPITAL LETTER O WITH STROKE -0x00D9, "Ugrave" # LATIN CAPITAL LETTER U WITH GRAVE -0x00DA, "Uacute" # LATIN CAPITAL LETTER U WITH ACUTE -0x00DB, "Ucircumflex" # LATIN CAPITAL LETTER U WITH CIRCUMFLEX -0x00DC, "Udieresis" # LATIN CAPITAL LETTER U WITH DIAERESIS -0x00DD, "Yacute" # LATIN CAPITAL LETTER Y WITH ACUTE -0x00DE, "Thorn" # LATIN CAPITAL LETTER THORN -0x00DF, "germandbls" # LATIN SMALL LETTER SHARP S -0x00E0, "agrave" # LATIN SMALL LETTER A WITH GRAVE -0x00E1, "aacute" # LATIN SMALL LETTER A WITH ACUTE -0x00E2, "acircumflex" # LATIN SMALL LETTER A WITH CIRCUMFLEX -0x00E3, "atilde" # LATIN SMALL LETTER A WITH TILDE -0x00E4, "adieresis" # LATIN SMALL LETTER A WITH DIAERESIS -0x00E5, "aring" # LATIN SMALL LETTER A WITH RING ABOVE -0x00E6, "ae" # LATIN SMALL LETTER AE -0x00E7, "ccedilla" # LATIN SMALL LETTER C WITH CEDILLA -0x00E8, "egrave" # LATIN SMALL LETTER E WITH GRAVE -0x00E9, "eacute" # LATIN SMALL LETTER E WITH ACUTE -0x00EA, "ecircumflex" # LATIN SMALL LETTER E WITH CIRCUMFLEX -0x00EB, "edieresis" # LATIN SMALL LETTER E WITH DIAERESIS -0x00EC, "igrave" # LATIN SMALL LETTER I WITH GRAVE -0x00ED, "iacute" # LATIN SMALL LETTER I WITH ACUTE -0x00EE, "icircumflex" # LATIN SMALL LETTER I WITH CIRCUMFLEX -0x00EF, "idieresis" # LATIN SMALL LETTER I WITH DIAERESIS -0x00F0, "eth" # LATIN SMALL LETTER ETH -0x00F1, "ntilde" # LATIN SMALL LETTER N WITH TILDE -0x00F2, "ograve" # LATIN SMALL LETTER O WITH GRAVE -0x00F3, "oacute" # LATIN SMALL LETTER O WITH ACUTE -0x00F4, "ocircumflex" # LATIN SMALL LETTER O WITH CIRCUMFLEX -0x00F5, "otilde" # LATIN SMALL LETTER O WITH TILDE -0x00F6, "odieresis" # LATIN SMALL LETTER O WITH DIAERESIS -0x00F7, "divide" # DIVISION SIGN -0x00F8, "oslash" # LATIN SMALL LETTER O WITH STROKE -0x00F9, "ugrave" # LATIN SMALL LETTER U WITH GRAVE -0x00FA, "uacute" # LATIN SMALL LETTER U WITH ACUTE -0x00FB, "ucircumflex" # LATIN SMALL LETTER U WITH CIRCUMFLEX -0x00FC, "udieresis" # LATIN SMALL LETTER U WITH DIAERESIS -0x00FD, "yacute" # LATIN SMALL LETTER Y WITH ACUTE -0x00FE, "thorn" # LATIN SMALL LETTER THORN -0x00FF, "ydieresis" # LATIN SMALL LETTER Y WITH DIAERESIS -0x0100, "Amacron" # LATIN CAPITAL LETTER A WITH MACRON -0x0101, "amacron" # LATIN SMALL LETTER A WITH MACRON -0x0102, "Abreve" # LATIN CAPITAL LETTER A WITH BREVE -0x0103, "abreve" # LATIN SMALL LETTER A WITH BREVE -0x0104, "Aogonek" # LATIN CAPITAL LETTER A WITH OGONEK -0x0105, "aogonek" # LATIN SMALL LETTER A WITH OGONEK -0x0106, "Cacute" # LATIN CAPITAL LETTER C WITH ACUTE -0x0107, "cacute" # LATIN SMALL LETTER C WITH ACUTE -0x0108, "Ccircumflex" # LATIN CAPITAL LETTER C WITH CIRCUMFLEX -0x0109, "ccircumflex" # LATIN SMALL LETTER C WITH CIRCUMFLEX -0x010A, "Cdotaccent" # LATIN CAPITAL LETTER C WITH DOT ABOVE -0x010B, "cdotaccent" # LATIN SMALL LETTER C WITH DOT ABOVE -0x010C, "Ccaron" # LATIN CAPITAL LETTER C WITH CARON -0x010D, "ccaron" # LATIN SMALL LETTER C WITH CARON -0x010E, "Dcaron" # LATIN CAPITAL LETTER D WITH CARON -0x010F, "dcaron" # LATIN SMALL LETTER D WITH CARON -0x0110, "Dcroat" # LATIN CAPITAL LETTER D WITH STROKE -0x0111, "dcroat" # LATIN SMALL LETTER D WITH STROKE -0x0112, "Emacron" # LATIN CAPITAL LETTER E WITH MACRON -0x0113, "emacron" # LATIN SMALL LETTER E WITH MACRON -0x0114, "Ebreve" # LATIN CAPITAL LETTER E WITH BREVE -0x0115, "ebreve" # LATIN SMALL LETTER E WITH BREVE -0x0116, "Edotaccent" # LATIN CAPITAL LETTER E WITH DOT ABOVE -0x0117, "edotaccent" # LATIN SMALL LETTER E WITH DOT ABOVE -0x0118, "Eogonek" # LATIN CAPITAL LETTER E WITH OGONEK -0x0119, "eogonek" # LATIN SMALL LETTER E WITH OGONEK -0x011A, "Ecaron" # LATIN CAPITAL LETTER E WITH CARON -0x011B, "ecaron" # LATIN SMALL LETTER E WITH CARON -0x011C, "Gcircumflex" # LATIN CAPITAL LETTER G WITH CIRCUMFLEX -0x011D, "gcircumflex" # LATIN SMALL LETTER G WITH CIRCUMFLEX -0x011E, "Gbreve" # LATIN CAPITAL LETTER G WITH BREVE -0x011F, "gbreve" # LATIN SMALL LETTER G WITH BREVE -0x0120, "Gdotaccent" # LATIN CAPITAL LETTER G WITH DOT ABOVE -0x0121, "gdotaccent" # LATIN SMALL LETTER G WITH DOT ABOVE -0x0122, "Gcommaaccent" # LATIN CAPITAL LETTER G WITH CEDILLA -0x0123, "gcommaaccent" # LATIN SMALL LETTER G WITH CEDILLA -0x0124, "Hcircumflex" # LATIN CAPITAL LETTER H WITH CIRCUMFLEX -0x0125, "hcircumflex" # LATIN SMALL LETTER H WITH CIRCUMFLEX -0x0126, "Hbar" # LATIN CAPITAL LETTER H WITH STROKE -0x0127, "hbar" # LATIN SMALL LETTER H WITH STROKE -0x0128, "Itilde" # LATIN CAPITAL LETTER I WITH TILDE -0x0129, "itilde" # LATIN SMALL LETTER I WITH TILDE -0x012A, "Imacron" # LATIN CAPITAL LETTER I WITH MACRON -0x012B, "imacron" # LATIN SMALL LETTER I WITH MACRON -0x012C, "Ibreve" # LATIN CAPITAL LETTER I WITH BREVE -0x012D, "ibreve" # LATIN SMALL LETTER I WITH BREVE -0x012E, "Iogonek" # LATIN CAPITAL LETTER I WITH OGONEK -0x012F, "iogonek" # LATIN SMALL LETTER I WITH OGONEK -0x0130, "Idotaccent" # LATIN CAPITAL LETTER I WITH DOT ABOVE -0x0131, "dotlessi" # LATIN SMALL LETTER DOTLESS I -0x0132, "IJ" # LATIN CAPITAL LIGATURE IJ -0x0133, "ij" # LATIN SMALL LIGATURE IJ -0x0134, "Jcircumflex" # LATIN CAPITAL LETTER J WITH CIRCUMFLEX -0x0135, "jcircumflex" # LATIN SMALL LETTER J WITH CIRCUMFLEX -0x0136, "Kcommaaccent" # LATIN CAPITAL LETTER K WITH CEDILLA -0x0137, "kcommaaccent" # LATIN SMALL LETTER K WITH CEDILLA -0x0138, "kgreenlandic" # LATIN SMALL LETTER KRA -0x0139, "Lacute" # LATIN CAPITAL LETTER L WITH ACUTE -0x013A, "lacute" # LATIN SMALL LETTER L WITH ACUTE -0x013B, "Lcommaaccent" # LATIN CAPITAL LETTER L WITH CEDILLA -0x013C, "lcommaaccent" # LATIN SMALL LETTER L WITH CEDILLA -0x013D, "Lcaron" # LATIN CAPITAL LETTER L WITH CARON -0x013E, "lcaron" # LATIN SMALL LETTER L WITH CARON -0x013F, "Ldot" # LATIN CAPITAL LETTER L WITH MIDDLE DOT -0x0140, "ldot" # LATIN SMALL LETTER L WITH MIDDLE DOT -0x0141, "Lslash" # LATIN CAPITAL LETTER L WITH STROKE -0x0142, "lslash" # LATIN SMALL LETTER L WITH STROKE -0x0143, "Nacute" # LATIN CAPITAL LETTER N WITH ACUTE -0x0144, "nacute" # LATIN SMALL LETTER N WITH ACUTE -0x0145, "Ncommaaccent" # LATIN CAPITAL LETTER N WITH CEDILLA -0x0146, "ncommaaccent" # LATIN SMALL LETTER N WITH CEDILLA -0x0147, "Ncaron" # LATIN CAPITAL LETTER N WITH CARON -0x0148, "ncaron" # LATIN SMALL LETTER N WITH CARON -0x0149, "napostrophe" # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE -0x014A, "Eng" # LATIN CAPITAL LETTER ENG -0x014B, "eng" # LATIN SMALL LETTER ENG -0x014C, "Omacron" # LATIN CAPITAL LETTER O WITH MACRON -0x014D, "omacron" # LATIN SMALL LETTER O WITH MACRON -0x014E, "Obreve" # LATIN CAPITAL LETTER O WITH BREVE -0x014F, "obreve" # LATIN SMALL LETTER O WITH BREVE -0x0150, "Ohungarumlaut" # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -0x0151, "ohungarumlaut" # LATIN SMALL LETTER O WITH DOUBLE ACUTE -0x0152, "OE" # LATIN CAPITAL LIGATURE OE -0x0153, "oe" # LATIN SMALL LIGATURE OE -0x0154, "Racute" # LATIN CAPITAL LETTER R WITH ACUTE -0x0155, "racute" # LATIN SMALL LETTER R WITH ACUTE -0x0156, "Rcommaaccent" # LATIN CAPITAL LETTER R WITH CEDILLA -0x0157, "rcommaaccent" # LATIN SMALL LETTER R WITH CEDILLA -0x0158, "Rcaron" # LATIN CAPITAL LETTER R WITH CARON -0x0159, "rcaron" # LATIN SMALL LETTER R WITH CARON -0x015A, "Sacute" # LATIN CAPITAL LETTER S WITH ACUTE -0x015B, "sacute" # LATIN SMALL LETTER S WITH ACUTE -0x015C, "Scircumflex" # LATIN CAPITAL LETTER S WITH CIRCUMFLEX -0x015D, "scircumflex" # LATIN SMALL LETTER S WITH CIRCUMFLEX -0x015E, "Scedilla" # LATIN CAPITAL LETTER S WITH CEDILLA -0x015F, "scedilla" # LATIN SMALL LETTER S WITH CEDILLA -0x0160, "Scaron" # LATIN CAPITAL LETTER S WITH CARON -0x0161, "scaron" # LATIN SMALL LETTER S WITH CARON -0x0164, "Tcaron" # LATIN CAPITAL LETTER T WITH CARON -0x0165, "tcaron" # LATIN SMALL LETTER T WITH CARON -0x0166, "Tbar" # LATIN CAPITAL LETTER T WITH STROKE -0x0167, "tbar" # LATIN SMALL LETTER T WITH STROKE -0x0168, "Utilde" # LATIN CAPITAL LETTER U WITH TILDE -0x0169, "utilde" # LATIN SMALL LETTER U WITH TILDE -0x016A, "Umacron" # LATIN CAPITAL LETTER U WITH MACRON -0x016B, "umacron" # LATIN SMALL LETTER U WITH MACRON -0x016C, "Ubreve" # LATIN CAPITAL LETTER U WITH BREVE -0x016D, "ubreve" # LATIN SMALL LETTER U WITH BREVE -0x016E, "Uring" # LATIN CAPITAL LETTER U WITH RING ABOVE -0x016F, "uring" # LATIN SMALL LETTER U WITH RING ABOVE -0x0170, "Uhungarumlaut" # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -0x0171, "uhungarumlaut" # LATIN SMALL LETTER U WITH DOUBLE ACUTE -0x0172, "Uogonek" # LATIN CAPITAL LETTER U WITH OGONEK -0x0173, "uogonek" # LATIN SMALL LETTER U WITH OGONEK -0x0174, "Wcircumflex" # LATIN CAPITAL LETTER W WITH CIRCUMFLEX -0x0175, "wcircumflex" # LATIN SMALL LETTER W WITH CIRCUMFLEX -0x0176, "Ycircumflex" # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX -0x0177, "ycircumflex" # LATIN SMALL LETTER Y WITH CIRCUMFLEX -0x0178, "Ydieresis" # LATIN CAPITAL LETTER Y WITH DIAERESIS -0x0179, "Zacute" # LATIN CAPITAL LETTER Z WITH ACUTE -0x017A, "zacute" # LATIN SMALL LETTER Z WITH ACUTE -0x017B, "Zdotaccent" # LATIN CAPITAL LETTER Z WITH DOT ABOVE -0x017C, "zdotaccent" # LATIN SMALL LETTER Z WITH DOT ABOVE -0x017D, "Zcaron" # LATIN CAPITAL LETTER Z WITH CARON -0x017E, "zcaron" # LATIN SMALL LETTER Z WITH CARON -0x017F, "longs" # LATIN SMALL LETTER LONG S -0x0192, "florin" # LATIN SMALL LETTER F WITH HOOK -0x01A0, "Ohorn" # LATIN CAPITAL LETTER O WITH HORN -0x01A1, "ohorn" # LATIN SMALL LETTER O WITH HORN -0x01AF, "Uhorn" # LATIN CAPITAL LETTER U WITH HORN -0x01B0, "uhorn" # LATIN SMALL LETTER U WITH HORN -0x01E6, "Gcaron" # LATIN CAPITAL LETTER G WITH CARON -0x01E7, "gcaron" # LATIN SMALL LETTER G WITH CARON -0x01FA, "Aringacute" # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE -0x01FB, "aringacute" # LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE -0x01FC, "AEacute" # LATIN CAPITAL LETTER AE WITH ACUTE -0x01FD, "aeacute" # LATIN SMALL LETTER AE WITH ACUTE -0x01FE, "Oslashacute" # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE -0x01FF, "oslashacute" # LATIN SMALL LETTER O WITH STROKE AND ACUTE -0x0218, "Scommaaccent" # LATIN CAPITAL LETTER S WITH COMMA BELOW -0x0219, "scommaaccent" # LATIN SMALL LETTER S WITH COMMA BELOW -0x021A, "Tcommaaccent" # LATIN CAPITAL LETTER T WITH COMMA BELOW -0x021B, "tcommaaccent" # LATIN SMALL LETTER T WITH COMMA BELOW -0x02BC, "afii57929" # MODIFIER LETTER APOSTROPHE -0x02BD, "afii64937" # MODIFIER LETTER REVERSED COMMA -0x02C6, "circumflex" # MODIFIER LETTER CIRCUMFLEX ACCENT -0x02C7, "caron" # CARON -0x02D8, "breve" # BREVE -0x02D9, "dotaccent" # DOT ABOVE -0x02DA, "ring" # RING ABOVE -0x02DB, "ogonek" # OGONEK -0x02DC, "tilde" # SMALL TILDE -0x02DD, "hungarumlaut" # DOUBLE ACUTE ACCENT -0x0300, "gravecomb" # COMBINING GRAVE ACCENT -0x0301, "acutecomb" # COMBINING ACUTE ACCENT -0x0303, "tildecomb" # COMBINING TILDE -0x0309, "hookabovecomb" # COMBINING HOOK ABOVE -0x0323, "dotbelowcomb" # COMBINING DOT BELOW -0x0384, "tonos" # GREEK TONOS -0x0385, "dieresistonos" # GREEK DIALYTIKA TONOS -0x0386, "Alphatonos" # GREEK CAPITAL LETTER ALPHA WITH TONOS -0x0387, "anoteleia" # GREEK ANO TELEIA -0x0388, "Epsilontonos" # GREEK CAPITAL LETTER EPSILON WITH TONOS -0x0389, "Etatonos" # GREEK CAPITAL LETTER ETA WITH TONOS -0x038A, "Iotatonos" # GREEK CAPITAL LETTER IOTA WITH TONOS -0x038C, "Omicrontonos" # GREEK CAPITAL LETTER OMICRON WITH TONOS -0x038E, "Upsilontonos" # GREEK CAPITAL LETTER UPSILON WITH TONOS -0x038F, "Omegatonos" # GREEK CAPITAL LETTER OMEGA WITH TONOS -0x0390, "iotadieresistonos" # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -0x0391, "Alpha" # GREEK CAPITAL LETTER ALPHA -0x0392, "Beta" # GREEK CAPITAL LETTER BETA -0x0393, "Gamma" # GREEK CAPITAL LETTER GAMMA -0x0394, "Delta" # GREEK CAPITAL LETTER DELTA -0x0395, "Epsilon" # GREEK CAPITAL LETTER EPSILON -0x0396, "Zeta" # GREEK CAPITAL LETTER ZETA -0x0397, "Eta" # GREEK CAPITAL LETTER ETA -0x0398, "Theta" # GREEK CAPITAL LETTER THETA -0x0399, "Iota" # GREEK CAPITAL LETTER IOTA -0x039A, "Kappa" # GREEK CAPITAL LETTER KAPPA -0x039B, "Lambda" # GREEK CAPITAL LETTER LAMDA -0x039C, "Mu" # GREEK CAPITAL LETTER MU -0x039D, "Nu" # GREEK CAPITAL LETTER NU -0x039E, "Xi" # GREEK CAPITAL LETTER XI -0x039F, "Omicron" # GREEK CAPITAL LETTER OMICRON -0x03A0, "Pi" # GREEK CAPITAL LETTER PI -0x03A1, "Rho" # GREEK CAPITAL LETTER RHO -0x03A3, "Sigma" # GREEK CAPITAL LETTER SIGMA -0x03A4, "Tau" # GREEK CAPITAL LETTER TAU -0x03A5, "Upsilon" # GREEK CAPITAL LETTER UPSILON -0x03A6, "Phi" # GREEK CAPITAL LETTER PHI -0x03A7, "Chi" # GREEK CAPITAL LETTER CHI -0x03A8, "Psi" # GREEK CAPITAL LETTER PSI -0x03A9, "Omega" # GREEK CAPITAL LETTER OMEGA -0x03AA, "Iotadieresis" # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -0x03AB, "Upsilondieresis" # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -0x03AC, "alphatonos" # GREEK SMALL LETTER ALPHA WITH TONOS -0x03AD, "epsilontonos" # GREEK SMALL LETTER EPSILON WITH TONOS -0x03AE, "etatonos" # GREEK SMALL LETTER ETA WITH TONOS -0x03AF, "iotatonos" # GREEK SMALL LETTER IOTA WITH TONOS -0x03B0, "upsilondieresistonos" # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -0x03B1, "alpha" # GREEK SMALL LETTER ALPHA -0x03B2, "beta" # GREEK SMALL LETTER BETA -0x03B3, "gamma" # GREEK SMALL LETTER GAMMA -0x03B4, "delta" # GREEK SMALL LETTER DELTA -0x03B5, "epsilon" # GREEK SMALL LETTER EPSILON -0x03B6, "zeta" # GREEK SMALL LETTER ZETA -0x03B7, "eta" # GREEK SMALL LETTER ETA -0x03B8, "theta" # GREEK SMALL LETTER THETA -0x03B9, "iota" # GREEK SMALL LETTER IOTA -0x03BA, "kappa" # GREEK SMALL LETTER KAPPA -0x03BB, "lambda" # GREEK SMALL LETTER LAMDA -0x03BC, "mu" # GREEK SMALL LETTER MU;Duplicate -0x03BD, "nu" # GREEK SMALL LETTER NU -0x03BE, "xi" # GREEK SMALL LETTER XI -0x03BF, "omicron" # GREEK SMALL LETTER OMICRON -0x03C0, "pi" # GREEK SMALL LETTER PI -0x03C1, "rho" # GREEK SMALL LETTER RHO -0x03C2, "sigma1" # GREEK SMALL LETTER FINAL SIGMA -0x03C3, "sigma" # GREEK SMALL LETTER SIGMA -0x03C4, "tau" # GREEK SMALL LETTER TAU -0x03C5, "upsilon" # GREEK SMALL LETTER UPSILON -0x03C6, "phi" # GREEK SMALL LETTER PHI -0x03C7, "chi" # GREEK SMALL LETTER CHI -0x03C8, "psi" # GREEK SMALL LETTER PSI -0x03C9, "omega" # GREEK SMALL LETTER OMEGA -0x03CA, "iotadieresis" # GREEK SMALL LETTER IOTA WITH DIALYTIKA -0x03CB, "upsilondieresis" # GREEK SMALL LETTER UPSILON WITH DIALYTIKA -0x03CC, "omicrontonos" # GREEK SMALL LETTER OMICRON WITH TONOS -0x03CD, "upsilontonos" # GREEK SMALL LETTER UPSILON WITH TONOS -0x03CE, "omegatonos" # GREEK SMALL LETTER OMEGA WITH TONOS -0x03D1, "theta1" # GREEK THETA SYMBOL -0x03D2, "Upsilon1" # GREEK UPSILON WITH HOOK SYMBOL -0x03D5, "phi1" # GREEK PHI SYMBOL -0x03D6, "omega1" # GREEK PI SYMBOL -# end of stuff from glyphlist.txt -0xFFFF, "" diff --git a/src/gui/painting/qpsprinter.ps b/src/gui/painting/qpsprinter.ps deleted file mode 100644 index ef3f42970b..0000000000 --- a/src/gui/painting/qpsprinter.ps +++ /dev/null @@ -1,449 +0,0 @@ -% the postscript header we use for our qpsprinter in uncompressed and commented form. -% use the makepsheader perl script to generate a compressed version of this header -% you can then paste into qpsprinter.cpp -% -% some compression of the code is done by the makepsheader script, so we don't need to -% write too criptically here. - -/BD {bind def} bind def -/d2 {dup dup} BD -/ED {exch def} BD -/D0 {0 ED} BD - -/F {setfont} BD -/RL {rlineto} BD -/CM {currentmatrix} BD -/SM {setmatrix} BD -/TR {translate} BD -/SD {setdash} BD -/SC {aload pop setrgbcolor} BD -/CR {currentfile read pop} BD -/i {index} BD -/scs {setcolorspace} BD -/DB {dict dup begin} BD -/DE {end def} BD -/ie {ifelse} BD -/gs {gsave} BD -/gr {grestore} BD - -% these use PDF syntax -/w {setlinewidth} BD -/d {setdash} BD -/J {setlinecap} BD -/j {setlinejoin} BD -/scn {3 array astore /BCol exch def} BD -/SCN {3 array astore /PCol exch def} BD -/cm {6 array astore concat} BD - -/m {moveto} BD -/l {lineto} BD -/c {curveto} BD -/h {closepath} BD - -/W {clip} BD -/W* {eoclip} BD -/n {newpath} BD -% ENDUNCOMPRESSED: Warning: leave this line in. -% Everything before this line will be left untouched by the compression - -/q {gsave 10 dict begin} BD -/Q {end grestore} BD - -% PDF operators -/re { % PDF re operator - 4 2 roll % w h x y - moveto % w h - dup % w h h - 0 exch rlineto % w h - exch 0 rlineto % h - 0 exch neg rlineto - closepath -} bind def - -/S { - gsave - PCol SC stroke - grestore - newpath -} BD - -% PDF text operators -/BT {gsave 10 dict begin /_m matrix currentmatrix def BCol SC} BD -/ET {end grestore} BD -/Tf { - /_fs exch def - findfont - [ _fs 0 0 _fs 0 0 ] - makefont - setfont -} BD -/Tm {6 array astore concat} BD -/Td {translate} BD -/Tj {0 0 moveto show} BD -/BDC {pop pop} BD -/EMC {} BD - -% old operators - -/BSt 0 def % brush style -/WFi false def % winding fill - -/BCol [ 1 1 1 ] def % brush color -/PCol [ 0 0 0 ] def % pen color -/BDArr [ % Brush dense patterns - 0.94 - 0.88 - 0.63 - 0.50 - 0.37 - 0.12 - 0.06 -] def - -% -- level3 true/false -/level3 { - /languagelevel where { - pop - languagelevel 3 ge - } { false } ifelse -} bind def - - -%% image drawing routines - -% defines for QCI -/QCIgray D0 /QCIcolor D0 /QCIindex D0 - -% this method prints color images if colorimage is available, otherwise -% converts the string to a grayscale image and uses the reular postscript image -% operator for printing. -% Arguments are the same as for the image operator: -% -% width height bits/sample matrix datasrc QCI - -/QCI { - /colorimage where { - pop - false 3 colorimage - }{ % the hard way, based on PD code by John Walker <kelvin@autodesk.com> - exec /QCIcolor exch def - /QCIgray QCIcolor length 3 idiv string def - 0 1 QCIcolor length 3 idiv 1 sub - { /QCIindex exch def - /_x QCIindex 3 mul def - QCIgray QCIindex - QCIcolor _x get 0.30 mul - QCIcolor _x 1 add get 0.59 mul - QCIcolor _x 2 add get 0.11 mul - add add cvi - put - } for - QCIgray image - } ifelse -} bind def - -% general image drawing routine, used from the postscript driver -% -% Draws images with and without mask with 1, 8 and 24(rgb) bits depth. -% -% width height matrix image 1|8|24 mask|false x y di -% -% width and height specify the width/height of the image, -% matrix a transformation matrix, image a procedure holding the image data -% (same for mask) and x/y an additional translation. -% -% ### should move the translation into the matrix!!! -/di -{ - gsave - translate - 1 index 1 eq { % bitmap - pop pop % get rid of mask and depth - false 3 1 roll % width height false matrix image - BCol SC - imagemask - } { - dup false ne { - % have a mask, see if we can use it - level3 - } { - false - } ifelse - - { - % languagelevel3, we can use image mask and dicts - - % store the image mask - /_ma exch def - % select colorspace according to 8|24 bit depth and set the decode array /dc - 8 eq { - /_dc [0 1] def - /DeviceGray - } { - /_dc [0 1 0 1 0 1] def - /DeviceRGB - } ifelse - setcolorspace - % the image data - /_im exch def - % transformation matrix - /_mt exch def - % width and height - /_h exch def - /_w exch def - % and the combined image dict - << - /ImageType 3 - % the image dict - /DataDict << - /ImageType 1 - /Width _w - /Height _h - /ImageMatrix _mt - /DataSource _im - /BitsPerComponent 8 - /Decode _dc - >> - % the mask dictionary - /MaskDict << - /ImageType 1 - /Width _w - /Height _h - /ImageMatrix _mt - /DataSource _ma - /BitsPerComponent 1 - /Decode [0 1] - >> - /InterleaveType 3 - >> - image - } { - pop % no mask or can't use it, get rid of it - 8 % width height image 8|24 8 matrix - 4 1 roll - 8 eq { % grayscale - image - } { %color - QCI - } ifelse - } ifelse - } ifelse - grestore -} bind def - - -/BF { % brush fill - gsave - BSt 1 eq % solid brush? - { - BCol SC - WFi { fill } { eofill } ifelse - } if - BSt 2 ge BSt 8 le and % dense pattern? - { - BDArr BSt 2 sub get /_sc exch def - % the following line scales the brush color according to the pattern. the higher the pattern the lighter the color. - BCol - { - 1. exch sub _sc mul 1. exch sub - } forall - 3 array astore - SC - WFi { fill } { eofill } ifelse - } if - BSt 9 ge BSt 14 le and % brush pattern? - { - WFi { clip } { eoclip } ifelse - pathbbox % left upper right lower - 3 index 3 index translate - 4 2 roll % right lower left upper - 3 2 roll % right left upper lower - exch % left right lower upper - sub /_h exch def - sub /_w exch def - BCol SC - 0.3 setlinewidth - newpath - BSt 9 eq BSt 11 eq or % horiz or cross pattern - { 0 4 _h - { dup 0 exch moveto _w exch lineto } for - } if - BSt 10 eq BSt 11 eq or % vert or cross pattern - { 0 4 _w - { dup 0 moveto _h lineto } for - } if - BSt 12 eq BSt 14 eq or % F-diag or diag cross - { _w _h gt - { 0 6 _w _h add - { dup 0 moveto _h sub _h lineto } for - } { 0 6 _w _h add - { dup 0 exch moveto _w sub _w exch lineto } for - } ifelse - } if - BSt 13 eq BSt 14 eq or % B-diag or diag cross - { _w _h gt - { 0 6 _w _h add - { dup _h moveto _h sub 0 lineto } for - } { 0 6 _w _h add - { dup _w exch moveto _w sub 0 exch lineto } for - } ifelse - } if - stroke - } if - BSt 15 eq - { - } if - BSt 24 eq % TexturePattern - { - } if - grestore -} bind def - -% more PDF operators -/f { /WFi true def BF newpath } bind def -/f* { /WFi false def BF newpath } bind def -/B { /WFi true def BF S newpath } bind def -/B* { /WFi false def BF S newpath } bind def - -%% start of page -/QI { - /C save def - pageinit - q - newpath -} bind def - -%% end of page -/QP { - Q % show page - C restore - showpage -} bind def - -% merges one key value pair into the page device dict -% -% key value SPD - -/SPD { - /setpagedevice where { - << 3 1 roll >> - setpagedevice - } { pop pop } ifelse -} bind def - - -% font handling - -/T1AddMapping { % basefont [glyphname ...] T1AddMapping - - 10 dict begin - /glyphs exch def - /fnt exch def - /current fnt /NumGlyphs get def - /CMap fnt /CMap get def - - 0 1 glyphs length 1 sub % 0 1 (num glyphs - 1) - { - glyphs exch get /gn exch def - - current dup % glyph_index glyph_index - 256 mod /min exch def % glyph_index - 256 idiv /maj exch def % - - CMap dup maj get dup % cmap cmap_maj cmap_maj - null eq { - pop 256 array - 0 1 255 {1 index exch /.notdef put} for - } if - dup % cmap cmap_maj cmap_maj - min gn put % cmap cmap_maj - maj exch put % - - - /current current 1 add def - } for - - fnt /CMap CMap put - fnt /NumGlyphs current put - end -} def - -/T1AddGlyphs { % basefont [glyphname charstring ...] T1AddGlyphs - - 10 dict begin - /glyphs exch def - /fnt exch def - /current fnt /NumGlyphs get def - /CMap fnt /CMap get def - /CharStrings fnt /CharStrings get def - - 0 1 glyphs length 2 idiv 1 sub % 0 1 (num glyphs - 1) - { - 2 mul dup - glyphs exch get /gn exch def - 1 add - glyphs exch get /cs exch def - - current dup % glyph_index glyph_index - 256 mod /min exch def % glyph_index - 256 idiv /maj exch def % - - CMap dup maj get dup % cmap cmap_maj cmap_maj - null eq { - pop 256 array - 0 1 255 {1 index exch /.notdef put} for - } if - dup % cmap cmap_maj cmap_maj - min gn put % cmap cmap_maj - maj exch put % - - - CharStrings gn cs put - /current current 1 add def - } for - - fnt /CharStrings CharStrings put - fnt /CMap CMap put - fnt /NumGlyphs current put - end -} def - - - -/StringAdd { % string1 string2 stringadd result - 1 index length 1 index length add - string - 3 1 roll - 2 index 0 3 index putinterval - 2 index 2 index length 2 index putinterval - pop pop -} def - - -/T1Setup { % fontname T1Setup - -10 dict begin - dup /FontName exch def - (-Base) StringAdd cvx cvn /Font exch def - /MaxPage Font /NumGlyphs get 1 sub 256 idiv def - - /FDepVector MaxPage 1 add array def - /Encoding MaxPage 1 add array def - - 0 1 MaxPage { - dup Encoding exch dup put - - - dup /Page exch def - FontName (-) StringAdd - exch - 20 string cvs StringAdd % page fontname - cvn - - Font 0 dict copy dup dup /CMap get - Page get - /Encoding exch put definefont - FDepVector exch Page exch put - } for - - FontName cvn << - /FontType 0 - /FMapType 2 - /FontMatrix[1 0 0 1 0 0] - /Encoding Encoding - /FDepVector FDepVector - >> definefont pop - end -} def - diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index eb9fbf7ba1..0e58331768 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -252,17 +252,6 @@ QRegion::QRegion(int x, int y, int w, int h, RegionType t) d = tmp.d; } -#ifdef QT3_SUPPORT -/*! - Use the constructor tha takes a Qt::FillRule as the second - argument instead. -*/ -QRegion::QRegion(const QPolygon &pa, bool winding) -{ - new (this) QRegion(pa, winding ? Qt::WindingFill : Qt::OddEvenFill); -} -#endif - /*! \fn QRegion::~QRegion() \internal @@ -553,7 +542,7 @@ QRegion& QRegion::operator|=(const QRegion &r) \sa intersected() */ -#if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN) +#if !defined (Q_OS_UNIX) && !defined (Q_OS_WIN) QRegion& QRegion::operator+=(const QRect &r) { return operator+=(QRegion(r)); @@ -576,7 +565,7 @@ QRegion& QRegion::operator&=(const QRegion &r) \overload \since 4.4 */ -#if defined (Q_OS_UNIX) || defined (Q_WS_WIN) +#if defined (Q_OS_UNIX) || defined (Q_OS_WIN) QRegion& QRegion::operator&=(const QRect &r) { return *this = *this & r; @@ -720,7 +709,7 @@ bool QRegion::intersects(const QRegion ®ion) const */ -#if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN) +#if !defined (Q_OS_UNIX) && !defined (Q_OS_WIN) /*! \overload \since 4.4 @@ -1083,7 +1072,7 @@ Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion ®ion) return result; } -#if defined(Q_OS_UNIX) || defined(Q_WS_WIN) +#if defined(Q_OS_UNIX) || defined(Q_OS_WIN) //#define QT_REGION_DEBUG /* diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h index f4c68a9102..75d29e1ef5 100644 --- a/src/gui/painting/qregion.h +++ b/src/gui/painting/qregion.h @@ -74,9 +74,6 @@ public: QRegion(int x, int y, int w, int h, RegionType t = Rectangle); QRegion(const QRect &r, RegionType t = Rectangle); QRegion(const QPolygon &pa, Qt::FillRule fillRule = Qt::OddEvenFill); -#ifdef QT3_SUPPORT - QT3_SUPPORT_CONSTRUCTOR QRegion(const QPolygon &pa, bool winding); -#endif QRegion(const QRegion ®ion); QRegion(const QBitmap &bitmap); ~QRegion(); @@ -86,9 +83,6 @@ public: { qSwap(d, other.d); return *this; } #endif inline void swap(QRegion &other) { qSwap(d, other.d); } -#ifdef QT3_SUPPORT - inline QT3_SUPPORT bool isNull() const { return isEmpty(); } -#endif bool isEmpty() const; bool contains(const QPoint &p) const; @@ -190,6 +184,9 @@ private: static OSStatus shape2QRegionHelper(int inMessage, HIShapeRef inShape, const CGRect *inRect, void *inRefcon); #endif +#if defined(Q_WS_QWS) || defined(Q_WS_QPA) +Q_GUI_EXPORT +#endif friend bool qt_region_strictContains(const QRegion ®ion, const QRect &rect); friend struct QRegionPrivate; diff --git a/src/gui/painting/qregion_mac.cpp b/src/gui/painting/qregion_mac.cpp deleted file mode 100644 index 3a0346abc4..0000000000 --- a/src/gui/painting/qregion_mac.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qt_mac_p.h> -#include "qcoreapplication.h" -#include <qlibrary.h> - -QT_BEGIN_NAMESPACE - -QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0 }; - -#if defined(Q_WS_MAC32) && !defined(QT_MAC_USE_COCOA) -#define RGN_CACHE_SIZE 200 -#ifdef RGN_CACHE_SIZE -static bool rgncache_init = false; -static int rgncache_used; -static RgnHandle rgncache[RGN_CACHE_SIZE]; -static void qt_mac_cleanup_rgncache() -{ - rgncache_init = false; - for(int i = 0; i < RGN_CACHE_SIZE; ++i) { - if(rgncache[i]) { - --rgncache_used; - DisposeRgn(rgncache[i]); - rgncache[i] = 0; - } - } -} -#endif - -Q_GUI_EXPORT RgnHandle qt_mac_get_rgn() -{ -#ifdef RGN_CACHE_SIZE - if(!rgncache_init) { - rgncache_used = 0; - rgncache_init = true; - for(int i = 0; i < RGN_CACHE_SIZE; ++i) - rgncache[i] = 0; - qAddPostRoutine(qt_mac_cleanup_rgncache); - } else if(rgncache_used) { - for(int i = 0; i < RGN_CACHE_SIZE; ++i) { - if(rgncache[i]) { - RgnHandle ret = rgncache[i]; - SetEmptyRgn(ret); - rgncache[i] = 0; - --rgncache_used; - return ret; - } - } - } -#endif - return NewRgn(); -} - -Q_GUI_EXPORT void qt_mac_dispose_rgn(RgnHandle r) -{ -#ifdef RGN_CACHE_SIZE - if(rgncache_init && rgncache_used < RGN_CACHE_SIZE) { - for(int i = 0; i < RGN_CACHE_SIZE; ++i) { - if(!rgncache[i]) { - ++rgncache_used; - rgncache[i] = r; - return; - } - } - } -#endif - DisposeRgn(r); -} - -static OSStatus qt_mac_get_rgn_rect(UInt16 msg, RgnHandle, const Rect *rect, void *reg) -{ - if(msg == kQDRegionToRectsMsgParse) { - QRect rct(rect->left, rect->top, (rect->right - rect->left), (rect->bottom - rect->top)); - if(!rct.isEmpty()) - *((QRegion *)reg) += rct; - } - return noErr; -} - -Q_GUI_EXPORT QRegion qt_mac_convert_mac_region(RgnHandle rgn) -{ - return QRegion::fromQDRgn(rgn); -} - -QRegion QRegion::fromQDRgn(RgnHandle rgn) -{ - QRegion ret; - ret.detach(); - OSStatus oss = QDRegionToRects(rgn, kQDParseRegionFromTopLeft, qt_mac_get_rgn_rect, (void *)&ret); - if(oss != noErr) - return QRegion(); - return ret; -} - -/*! - \internal - Create's a RegionHandle, it's the caller's responsibility to release. -*/ -RgnHandle QRegion::toQDRgn() const -{ - RgnHandle rgnHandle = qt_mac_get_rgn(); - if(d->qt_rgn && d->qt_rgn->numRects) { - RgnHandle tmp_rgn = qt_mac_get_rgn(); - int n = d->qt_rgn->numRects; - const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData(); - while (n--) { - SetRectRgn(tmp_rgn, - qMax(SHRT_MIN, qt_r->x()), - qMax(SHRT_MIN, qt_r->y()), - qMin(SHRT_MAX, qt_r->right() + 1), - qMin(SHRT_MAX, qt_r->bottom() + 1)); - UnionRgn(rgnHandle, tmp_rgn, rgnHandle); - ++qt_r; - } - qt_mac_dispose_rgn(tmp_rgn); - } - return rgnHandle; -} - -/*! - \internal - Create's a RegionHandle, it's the caller's responsibility to release. - Returns 0 if the QRegion overflows. -*/ -RgnHandle QRegion::toQDRgnForUpdate_sys() const -{ - RgnHandle rgnHandle = qt_mac_get_rgn(); - if(d->qt_rgn && d->qt_rgn->numRects) { - RgnHandle tmp_rgn = qt_mac_get_rgn(); - int n = d->qt_rgn->numRects; - const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData(); - while (n--) { - - // detect overflow. Tested for use with HIViewSetNeedsDisplayInRegion - // in QWidgetPrivate::update_sys(). - enum { HIViewSetNeedsDisplayInRegionOverflow = 10000 }; // empirically determined conservative value - if (qt_r->right() > HIViewSetNeedsDisplayInRegionOverflow || qt_r->bottom() > HIViewSetNeedsDisplayInRegionOverflow) { - qt_mac_dispose_rgn(tmp_rgn); - qt_mac_dispose_rgn(rgnHandle); - return 0; - } - - SetRectRgn(tmp_rgn, - qMax(SHRT_MIN, qt_r->x()), - qMax(SHRT_MIN, qt_r->y()), - qMin(SHRT_MAX, qt_r->right() + 1), - qMin(SHRT_MAX, qt_r->bottom() + 1)); - UnionRgn(rgnHandle, tmp_rgn, rgnHandle); - ++qt_r; - } - qt_mac_dispose_rgn(tmp_rgn); - } - return rgnHandle; -} - -#endif - -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) -OSStatus QRegion::shape2QRegionHelper(int inMessage, HIShapeRef, - const CGRect *inRect, void *inRefcon) -{ - QRegion *region = static_cast<QRegion *>(inRefcon); - if (!region) - return paramErr; - - switch (inMessage) { - case kHIShapeEnumerateRect: - *region += QRect(inRect->origin.x, inRect->origin.y, - inRect->size.width, inRect->size.height); - break; - case kHIShapeEnumerateInit: - // Assume the region is already setup correctly - case kHIShapeEnumerateTerminate: - default: - break; - } - return noErr; -} -#endif - -/*! - \internal - Create's a mutable shape, it's the caller's responsibility to release. - WARNING: this function clamps the coordinates to SHRT_MIN/MAX on 10.4 and below. -*/ -HIMutableShapeRef QRegion::toHIMutableShape() const -{ - HIMutableShapeRef shape = HIShapeCreateMutable(); -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { - if (d->qt_rgn && d->qt_rgn->numRects) { - int n = d->qt_rgn->numRects; - const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData(); - while (n--) { - CGRect cgRect = CGRectMake(qt_r->x(), qt_r->y(), qt_r->width(), qt_r->height()); - HIShapeUnionWithRect(shape, &cgRect); - ++qt_r; - } - } - } else -#endif - { -#ifndef QT_MAC_USE_COCOA - QCFType<HIShapeRef> qdShape = HIShapeCreateWithQDRgn(QMacSmartQuickDrawRegion(toQDRgn())); - HIShapeUnion(qdShape, shape, shape); -#endif - } - return shape; -} - -#if !defined(Q_WS_MAC64) && !defined(QT_MAC_USE_COCOA) -typedef OSStatus (*PtrHIShapeGetAsQDRgn)(HIShapeRef, RgnHandle); -static PtrHIShapeGetAsQDRgn ptrHIShapeGetAsQDRgn = 0; -#endif - - -QRegion QRegion::fromHIShapeRef(HIShapeRef shape) -{ - QRegion returnRegion; - returnRegion.detach(); - // Begin gratuitous #if-defery -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) -# ifndef Q_WS_MAC64 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { -# endif - HIShapeEnumerate(shape, kHIShapeParseFromTopLeft, shape2QRegionHelper, &returnRegion); -# ifndef Q_WS_MAC64 - } else -# endif -#endif - { -#if !defined(Q_WS_MAC64) && !defined(QT_MAC_USE_COCOA) - if (ptrHIShapeGetAsQDRgn == 0) { - QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon")); - library.setLoadHints(QLibrary::ExportExternalSymbolsHint); - ptrHIShapeGetAsQDRgn = reinterpret_cast<PtrHIShapeGetAsQDRgn>(library.resolve("HIShapeGetAsQDRgn")); - } - RgnHandle rgn = qt_mac_get_rgn(); - ptrHIShapeGetAsQDRgn(shape, rgn); - returnRegion = QRegion::fromQDRgn(rgn); - qt_mac_dispose_rgn(rgn); -#endif - } - return returnRegion; -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qregion_qws.cpp b/src/gui/painting/qregion_qws.cpp deleted file mode 100644 index 3ec1112aa3..0000000000 --- a/src/gui/painting/qregion_qws.cpp +++ /dev/null @@ -1,3183 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// XXX - add appropriate friendship relationships -#define private public -#include "qregion.h" -#undef private -#include "qpainterpath.h" -#include "qpolygon.h" -#include "qbuffer.h" -#include "qimage.h" -#include <qdebug.h> -#include "qbitmap.h" -#include <stdlib.h> -#include <qatomic.h> -#include <qsemaphore.h> - -QT_BEGIN_NAMESPACE - -class QFastMutex -{ - QAtomicInt contenders; - QSemaphore semaphore; -public: - inline QFastMutex() - : contenders(0), semaphore(0) - { } - inline void lock() - { - if (contenders.fetchAndAddAcquire(1) != 0) { - semaphore.acquire(); - contenders.deref(); - } - } - inline bool tryLock() - { - return contenders.testAndSetAcquire(0, 1); - } - inline void unlock() - { - if (!contenders.testAndSetRelease(1, 0)) - semaphore.release(); - } -}; - - -/* - * 1 if r1 contains r2 - * 0 if r1 does not completely contain r2 - */ -#define CONTAINSCHECK(r1, r2) \ - ((r2).left() >= (r1).left() && (r2).right() <= (r1).right() && \ - (r2).top() >= (r1).top() && (r2).bottom() <= (r1).bottom()) - -/* - * clip region - */ -struct QRegionPrivate : public QRegion::QRegionData { - enum { Single, Vector } mode; - int numRects; - QVector<QRect> rects; - QRect single; - QRect extents; - QRect innerRect; - union { - int innerArea; - QRegionPrivate *next; - }; - - inline void vector() - { - if(mode != Vector && numRects) { - if(rects.size() < 1) rects.resize(1); - rects[0] = single; - } - mode = Vector; - } - - inline QRegionPrivate() : mode(Single), numRects(0), innerArea(-1) {} - inline QRegionPrivate(const QRect &r) : mode(Single) { - numRects = 1; -// rects[0] = r; - single = r; - extents = r; - innerRect = r; - innerArea = r.width() * r.height(); - } - - inline QRegionPrivate(const QRegionPrivate &r) { - mode = r.mode; - rects = r.rects; - single = r.single; - numRects = r.numRects; - extents = r.extents; - innerRect = r.innerRect; - innerArea = r.innerArea; - } - - inline QRegionPrivate &operator=(const QRegionPrivate &r) { - mode = r.mode; - rects = r.rects; - single = r.single; - numRects = r.numRects; - extents = r.extents; - innerRect = r.innerRect; - innerArea = r.innerArea; - return *this; - } - - /* - * Returns true if r is guaranteed to be fully contained in this region. - * A false return value does not guarantee the opposite. - */ - inline bool contains(const QRegionPrivate &r) const { - const QRect &r1 = innerRect; - const QRect &r2 = r.extents; - return CONTAINSCHECK(r1, r2); - } - - inline void updateInnerRect(const QRect &rect) { - const int area = rect.width() * rect.height(); - if (area > innerArea) { - innerArea = area; - innerRect = rect; - } - } - - void append(const QRegionPrivate *r); - void prepend(const QRegionPrivate *r); - inline bool canAppend(const QRegionPrivate *r) const; - inline bool canPrepend(const QRegionPrivate *r) const; -}; - -static QRegionPrivate *qt_nextRegionPtr = 0; -static QFastMutex qt_nextRegionLock; - -static QRegionPrivate *qt_allocRegionMemory() -{ - QRegionPrivate *rv = 0; - qt_nextRegionLock.lock(); - - if(qt_nextRegionPtr) { - rv = qt_nextRegionPtr; - qt_nextRegionPtr = rv->next; - } else { - qt_nextRegionPtr = - (QRegionPrivate *)malloc(256 * sizeof(QRegionPrivate)); - for(int ii = 0; ii < 256; ++ii) { - if(ii == 255) { - qt_nextRegionPtr[ii].next = 0; - } else { - qt_nextRegionPtr[ii].next = &qt_nextRegionPtr[ii + 1]; - } - } - - rv = qt_nextRegionPtr; - qt_nextRegionPtr = rv->next; - } - - qt_nextRegionLock.unlock(); - return rv; -} - -static void qt_freeRegionMemory(QRegionPrivate *rp) -{ - qt_nextRegionLock.lock(); - rp->next = qt_nextRegionPtr; - qt_nextRegionPtr = rp; - qt_nextRegionLock.unlock(); -} - -static QRegionPrivate *qt_allocRegion() -{ - QRegionPrivate *mem = qt_allocRegionMemory(); - return new (mem) QRegionPrivate; -} - -static QRegionPrivate *qt_allocRegion(const QRect &r) -{ - QRegionPrivate *mem = qt_allocRegionMemory(); - return new (mem) QRegionPrivate(r); -} - -static QRegionPrivate *qt_allocRegion(const QRegionPrivate &r) -{ - QRegionPrivate *mem = qt_allocRegionMemory(); - return new (mem) QRegionPrivate(r); -} - -void qt_freeRegion(QRegionPrivate *rp) -{ - rp->~QRegionPrivate(); - qt_freeRegionMemory(rp); -// delete rp; -} - -static inline bool isEmptyHelper(const QRegionPrivate *preg) -{ - return !preg || preg->numRects == 0; -} - -void QRegionPrivate::append(const QRegionPrivate *r) -{ - Q_ASSERT(!isEmptyHelper(r)); - - vector(); - QRect *destRect = rects.data() + numRects; - const QRect *srcRect = (r->mode==Vector)?r->rects.constData():&r->single; - int numAppend = r->numRects; - - // test for merge in x direction - { - const QRect *rFirst = srcRect; - QRect *myLast = rects.data() + (numRects - 1); - if (rFirst->top() == myLast->top() - && rFirst->height() == myLast->height() - && rFirst->left() == (myLast->right() + 1)) - { - myLast->setWidth(myLast->width() + rFirst->width()); - updateInnerRect(*myLast); - ++srcRect; - --numAppend; - } - } - - // append rectangles - const int newNumRects = numRects + numAppend; - if (newNumRects > rects.size()) { - rects.resize(newNumRects); - destRect = rects.data() + numRects; - } - memcpy(destRect, srcRect, numAppend * sizeof(QRect)); - - // update inner rectangle - if (innerArea < r->innerArea) { - innerArea = r->innerArea; - innerRect = r->innerRect; - } - - // update extents - destRect = &extents; - srcRect = &r->extents; - extents.setCoords(qMin(destRect->left(), srcRect->left()), - qMin(destRect->top(), srcRect->top()), - qMax(destRect->right(), srcRect->right()), - qMax(destRect->bottom(), srcRect->bottom())); - - numRects = newNumRects; -} - -void QRegionPrivate::prepend(const QRegionPrivate *r) -{ -#if 1 - Q_UNUSED(r); -#else - // XXX ak: does not respect vectorization of region - - Q_ASSERT(!isEmpty(r)); - - // move existing rectangles - memmove(rects.data() + r->numRects, rects.constData(), - numRects * sizeof(QRect)); - - // prepend new rectangles - memcpy(rects.data(), r->rects.constData(), r->numRects * sizeof(QRect)); - - // update inner rectangle - if (innerArea < r->innerArea) { - innerArea = r->innerArea; - innerRect = r->innerRect; - } - - // update extents - destRect = &extents; - srcRect = &r->extents; - extents.setCoords(qMin(destRect->left(), srcRect->left()), - qMin(destRect->top(), srcRect->top()), - qMax(destRect->right(), srcRect->right()), - qMax(destRect->bottom(), srcRect->bottom())); - - numRects = newNumRects; -#endif -} - -bool QRegionPrivate::canAppend(const QRegionPrivate *r) const -{ - Q_ASSERT(!isEmptyHelper(r)); - - const QRect *rFirst = (r->mode==Vector)?r->rects.constData():&r->single; - const QRect *myLast = (mode==Vector)?(rects.constData() + (numRects - 1)):&single; - // XXX: possible improvements: - // - nFirst->top() == myLast->bottom() + 1, must possibly merge bands - if (rFirst->top() > (myLast->bottom() + 1) - || (rFirst->top() == myLast->top() - && rFirst->height() == myLast->height() - && rFirst->left() > myLast->right())) - { - return true; - } - - return false; -} - -bool QRegionPrivate::canPrepend(const QRegionPrivate *r) const -{ -#if 1 - Q_UNUSED(r); - return false; -#else - return r->canAppend(this); -#endif -} - -#if defined(Q_WS_X11) -QT_BEGIN_INCLUDE_NAMESPACE -# include "qregion_x11.cpp" -QT_END_INCLUDE_NAMESPACE -#elif defined(Q_WS_MAC) -QT_BEGIN_INCLUDE_NAMESPACE -# include "qregion_mac.cpp" -QT_END_INCLUDE_NAMESPACE -#elif defined(Q_WS_QWS) -static QRegionPrivate qrp; -QRegion::QRegionData QRegion::shared_empty = {Q_BASIC_ATOMIC_INITIALIZER(1), &qrp}; -#endif - -typedef void (*OverlapFunc)(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, - register const QRect *r2, const QRect *r2End, register int y1, register int y2); -typedef void (*NonOverlapFunc)(register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, - register int y1, register int y2); - -static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2); -static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest); -static void miRegionOp(register QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2, - OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func, - NonOverlapFunc nonOverlap2Func); - -#define RectangleOut 0 -#define RectangleIn 1 -#define RectanglePart 2 -#define EvenOddRule 0 -#define WindingRule 1 - -// START OF region.h extract -/* $XConsortium: region.h,v 11.14 94/04/17 20:22:20 rws Exp $ */ -/************************************************************************ - -Copyright (c) 1987 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ - -#ifndef _XREGION_H -#define _XREGION_H - -QT_BEGIN_INCLUDE_NAMESPACE -#include <limits.h> -QT_END_INCLUDE_NAMESPACE - -/* 1 if two BOXs overlap. - * 0 if two BOXs do not overlap. - * Remember, x2 and y2 are not in the region - */ -#define EXTENTCHECK(r1, r2) \ - ((r1)->right() >= (r2)->left() && \ - (r1)->left() <= (r2)->right() && \ - (r1)->bottom() >= (r2)->top() && \ - (r1)->top() <= (r2)->bottom()) - -/* - * update region extents - */ -#define EXTENTS(r,idRect){\ - if((r)->left() < (idRect)->extents.left())\ - (idRect)->extents.setLeft((r)->left());\ - if((r)->top() < (idRect)->extents.top())\ - (idRect)->extents.setTop((r)->top());\ - if((r)->right() > (idRect)->extents.right())\ - (idRect)->extents.setRight((r)->right());\ - if((r)->bottom() > (idRect)->extents.bottom())\ - (idRect)->extents.setBottom((r)->bottom());\ - } - -/* - * Check to see if there is enough memory in the present region. - */ -#define MEMCHECK(dest, rect, firstrect){\ - if ((dest).numRects >= ((dest).rects.size()-1)){\ - firstrect.resize(firstrect.size() * 2); \ - (rect) = (firstrect).data() + (dest).numRects;\ - }\ - } - - -/* - * number of points to buffer before sending them off - * to scanlines(): Must be an even number - */ -#define NUMPTSTOBUFFER 200 - -/* - * used to allocate buffers for points and link - * the buffers together - */ -typedef struct _POINTBLOCK { - QPoint pts[NUMPTSTOBUFFER]; - struct _POINTBLOCK *next; -} POINTBLOCK; - -#endif -// END OF region.h extract - -// START OF Region.c extract -/* $XConsortium: Region.c /main/30 1996/10/22 14:21:24 kaleb $ */ -/************************************************************************ - -Copyright (c) 1987, 1988 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - - -Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ -/* - * The functions in this file implement the Region abstraction, similar to one - * used in the X11 sample server. A Region is simply an area, as the name - * implies, and is implemented as a "y-x-banded" array of rectangles. To - * explain: Each Region is made up of a certain number of rectangles sorted - * by y coordinate first, and then by x coordinate. - * - * Furthermore, the rectangles are banded such that every rectangle with a - * given upper-left y coordinate (y1) will have the same lower-right y - * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it - * will span the entire vertical distance of the band. This means that some - * areas that could be merged into a taller rectangle will be represented as - * several shorter rectangles to account for shorter rectangles to its left - * or right but within its "vertical scope". - * - * An added constraint on the rectangles is that they must cover as much - * horizontal area as possible. E.g. no two rectangles in a band are allowed - * to touch. - * - * Whenever possible, bands will be merged together to cover a greater vertical - * distance (and thus reduce the number of rectangles). Two bands can be merged - * only if the bottom of one touches the top of the other and they have - * rectangles in the same places (of the same width, of course). This maintains - * the y-x-banding that's so nice to have... - */ -/* $XFree86: xc/lib/X11/Region.c,v 1.1.1.2.2.2 1998/10/04 15:22:50 hohndel Exp $ */ - -static void UnionRectWithRegion(register const QRect *rect, const QRegionPrivate *source, - QRegionPrivate &dest) -{ - if (!rect->width() || !rect->height()) - return; - - QRegionPrivate region(*rect); - - Q_ASSERT(EqualRegion(source, &dest)); - Q_ASSERT(!isEmptyHelper(®ion)); - - if (dest.numRects == 0) - dest = region; - else if (dest.canAppend(®ion)) - dest.append(®ion); - else - UnionRegion(®ion, source, dest); -} - -/*- - *----------------------------------------------------------------------- - * miSetExtents -- - * Reset the extents and innerRect of a region to what they should be. - * Called by miSubtract and miIntersect b/c they can't figure it out - * along the way or do so easily, as miUnion can. - * - * Results: - * None. - * - * Side Effects: - * The region's 'extents' and 'innerRect' structure is overwritten. - * - *----------------------------------------------------------------------- - */ -static void miSetExtents(QRegionPrivate &dest) -{ - register const QRect *pBox, - *pBoxEnd; - register QRect *pExtents; - - dest.innerRect.setCoords(0, 0, -1, -1); - dest.innerArea = -1; - if (dest.numRects == 0) { - dest.extents.setCoords(0, 0, 0, 0); - return; - } - - pExtents = &dest.extents; - pBox = (dest.mode==QRegionPrivate::Vector)?(dest.rects.constData()):(&dest.single); - pBoxEnd = (dest.mode==QRegionPrivate::Vector)?(&pBox[dest.numRects - 1]):(&dest.single); - - /* - * Since pBox is the first rectangle in the region, it must have the - * smallest y1 and since pBoxEnd is the last rectangle in the region, - * it must have the largest y2, because of banding. Initialize x1 and - * x2 from pBox and pBoxEnd, resp., as good things to initialize them - * to... - */ - pExtents->setLeft(pBox->left()); - pExtents->setTop(pBox->top()); - pExtents->setRight(pBoxEnd->right()); - pExtents->setBottom(pBoxEnd->bottom()); - - Q_ASSERT(pExtents->top() <= pExtents->bottom()); - while (pBox <= pBoxEnd) { - if (pBox->left() < pExtents->left()) - pExtents->setLeft(pBox->left()); - if (pBox->right() > pExtents->right()) - pExtents->setRight(pBox->right()); - dest.updateInnerRect(*pBox); - ++pBox; - } - Q_ASSERT(pExtents->left() <= pExtents->right()); -} - -/* TranslateRegion(pRegion, x, y) - translates in place - added by raymond -*/ - -static void OffsetRegion(register QRegionPrivate ®ion, register int x, register int y) -{ - register int nbox; - register QRect *pbox; - - if(region.mode == QRegionPrivate::Single) { - region.single.translate(x, y); - } else { - pbox = region.rects.data(); - nbox = region.numRects; - - while (nbox--) { - pbox->translate(x, y); - ++pbox; - } - } - region.extents.translate(x, y); - region.innerRect.translate(x, y); -} - -/*====================================================================== - * Region Intersection - *====================================================================*/ -/*- - *----------------------------------------------------------------------- - * miIntersectO -- - * Handle an overlapping band for miIntersect. - * - * Results: - * None. - * - * Side Effects: - * Rectangles may be added to the region. - * - *----------------------------------------------------------------------- - */ -static void miIntersectO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, - register const QRect *r2, const QRect *r2End, int y1, int y2) -{ - register int x1; - register int x2; - register QRect *pNextRect; - - pNextRect = dest.rects.data() + dest.numRects; - - while (r1 != r1End && r2 != r2End) { - x1 = qMax(r1->left(), r2->left()); - x2 = qMin(r1->right(), r2->right()); - - /* - * If there's any overlap between the two rectangles, add that - * overlap to the new region. - * There's no need to check for subsumption because the only way - * such a need could arise is if some region has two rectangles - * right next to each other. Since that should never happen... - */ - if (x1 <= x2) { - Q_ASSERT(y1 <= y2); - MEMCHECK(dest, pNextRect, dest.rects) - pNextRect->setCoords(x1, y1, x2, y2); - ++dest.numRects; - ++pNextRect; - } - - /* - * Need to advance the pointers. Shift the one that extends - * to the right the least, since the other still has a chance to - * overlap with that region's next rectangle, if you see what I mean. - */ - if (r1->right() < r2->right()) { - ++r1; - } else if (r2->right() < r1->right()) { - ++r2; - } else { - ++r1; - ++r2; - } - } -} - -/*====================================================================== - * Generic Region Operator - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * miCoalesce -- - * Attempt to merge the boxes in the current band with those in the - * previous one. Used only by miRegionOp. - * - * Results: - * The new index for the previous band. - * - * Side Effects: - * If coalescing takes place: - * - rectangles in the previous band will have their y2 fields - * altered. - * - dest.numRects will be decreased. - * - *----------------------------------------------------------------------- - */ -static int miCoalesce(register QRegionPrivate &dest, int prevStart, int curStart) -{ - register QRect *pPrevBox; /* Current box in previous band */ - register QRect *pCurBox; /* Current box in current band */ - register QRect *pRegEnd; /* End of region */ - int curNumRects; /* Number of rectangles in current band */ - int prevNumRects; /* Number of rectangles in previous band */ - int bandY1; /* Y1 coordinate for current band */ - QRect *rData = dest.rects.data(); - - pRegEnd = rData + dest.numRects; - - pPrevBox = rData + prevStart; - prevNumRects = curStart - prevStart; - - /* - * Figure out how many rectangles are in the current band. Have to do - * this because multiple bands could have been added in miRegionOp - * at the end when one region has been exhausted. - */ - pCurBox = rData + curStart; - bandY1 = pCurBox->top(); - for (curNumRects = 0; pCurBox != pRegEnd && pCurBox->top() == bandY1; ++curNumRects) { - ++pCurBox; - } - - if (pCurBox != pRegEnd) { - /* - * If more than one band was added, we have to find the start - * of the last band added so the next coalescing job can start - * at the right place... (given when multiple bands are added, - * this may be pointless -- see above). - */ - --pRegEnd; - while ((pRegEnd - 1)->top() == pRegEnd->top()) - --pRegEnd; - curStart = pRegEnd - rData; - pRegEnd = rData + dest.numRects; - } - - if (curNumRects == prevNumRects && curNumRects != 0) { - pCurBox -= curNumRects; - /* - * The bands may only be coalesced if the bottom of the previous - * matches the top scanline of the current. - */ - if (pPrevBox->bottom() == pCurBox->top() - 1) { - /* - * Make sure the bands have boxes in the same places. This - * assumes that boxes have been added in such a way that they - * cover the most area possible. I.e. two boxes in a band must - * have some horizontal space between them. - */ - do { - if (pPrevBox->left() != pCurBox->left() || pPrevBox->right() != pCurBox->right()) { - // The bands don't line up so they can't be coalesced. - return curStart; - } - ++pPrevBox; - ++pCurBox; - --prevNumRects; - } while (prevNumRects != 0); - - dest.numRects -= curNumRects; - pCurBox -= curNumRects; - pPrevBox -= curNumRects; - - /* - * The bands may be merged, so set the bottom y of each box - * in the previous band to that of the corresponding box in - * the current band. - */ - do { - pPrevBox->setBottom(pCurBox->bottom()); - dest.updateInnerRect(*pPrevBox); - ++pPrevBox; - ++pCurBox; - curNumRects -= 1; - } while (curNumRects != 0); - - /* - * If only one band was added to the region, we have to backup - * curStart to the start of the previous band. - * - * If more than one band was added to the region, copy the - * other bands down. The assumption here is that the other bands - * came from the same region as the current one and no further - * coalescing can be done on them since it's all been done - * already... curStart is already in the right place. - */ - if (pCurBox == pRegEnd) { - curStart = prevStart; - } else { - do { - *pPrevBox++ = *pCurBox++; - dest.updateInnerRect(*pPrevBox); - } while (pCurBox != pRegEnd); - } - } - } - return curStart; -} - -/*- - *----------------------------------------------------------------------- - * miRegionOp -- - * Apply an operation to two regions. Called by miUnion, miInverse, - * miSubtract, miIntersect... - * - * Results: - * None. - * - * Side Effects: - * The new region is overwritten. - * - * Notes: - * The idea behind this function is to view the two regions as sets. - * Together they cover a rectangle of area that this function divides - * into horizontal bands where points are covered only by one region - * or by both. For the first case, the nonOverlapFunc is called with - * each the band and the band's upper and lower extents. For the - * second, the overlapFunc is called to process the entire band. It - * is responsible for clipping the rectangles in the band, though - * this function provides the boundaries. - * At the end of each band, the new region is coalesced, if possible, - * to reduce the number of rectangles in the region. - * - *----------------------------------------------------------------------- - */ -static void miRegionOp(register QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2, - OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func, - NonOverlapFunc nonOverlap2Func) -{ - register const QRect *r1; // Pointer into first region - register const QRect *r2; // Pointer into 2d region - const QRect *r1End; // End of 1st region - const QRect *r2End; // End of 2d region - register int ybot; // Bottom of intersection - register int ytop; // Top of intersection - int prevBand; // Index of start of previous band in dest - int curBand; // Index of start of current band in dest - register const QRect *r1BandEnd; // End of current band in r1 - register const QRect *r2BandEnd; // End of current band in r2 - int top; // Top of non-overlapping band - int bot; // Bottom of non-overlapping band - - /* - * Initialization: - * set r1, r2, r1End and r2End appropriately, preserve the important - * parts of the destination region until the end in case it's one of - * the two source regions, then mark the "new" region empty, allocating - * another array of rectangles for it to use. - */ - r1 = (reg1->mode==QRegionPrivate::Vector)?reg1->rects.data():®1->single; - r2 = (reg2->mode==QRegionPrivate::Vector)?reg2->rects.data():®2->single; - r1End = r1 + reg1->numRects; - r2End = r2 + reg2->numRects; - - dest.vector(); - QVector<QRect> oldRects = dest.rects; - - dest.numRects = 0; - - /* - * Allocate a reasonable number of rectangles for the new region. The idea - * is to allocate enough so the individual functions don't need to - * reallocate and copy the array, which is time consuming, yet we don't - * have to worry about using too much memory. I hope to be able to - * nuke the realloc() at the end of this function eventually. - */ - dest.rects.resize(qMax(reg1->numRects,reg2->numRects) * 2); - - /* - * Initialize ybot and ytop. - * In the upcoming loop, ybot and ytop serve different functions depending - * on whether the band being handled is an overlapping or non-overlapping - * band. - * In the case of a non-overlapping band (only one of the regions - * has points in the band), ybot is the bottom of the most recent - * intersection and thus clips the top of the rectangles in that band. - * ytop is the top of the next intersection between the two regions and - * serves to clip the bottom of the rectangles in the current band. - * For an overlapping band (where the two regions intersect), ytop clips - * the top of the rectangles of both regions and ybot clips the bottoms. - */ - if (reg1->extents.top() < reg2->extents.top()) - ybot = reg1->extents.top() - 1; - else - ybot = reg2->extents.top() - 1; - - /* - * prevBand serves to mark the start of the previous band so rectangles - * can be coalesced into larger rectangles. qv. miCoalesce, above. - * In the beginning, there is no previous band, so prevBand == curBand - * (curBand is set later on, of course, but the first band will always - * start at index 0). prevBand and curBand must be indices because of - * the possible expansion, and resultant moving, of the new region's - * array of rectangles. - */ - prevBand = 0; - - do { - curBand = dest.numRects; - - /* - * This algorithm proceeds one source-band (as opposed to a - * destination band, which is determined by where the two regions - * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the - * rectangle after the last one in the current band for their - * respective regions. - */ - r1BandEnd = r1; - while (r1BandEnd != r1End && r1BandEnd->top() == r1->top()) - ++r1BandEnd; - - r2BandEnd = r2; - while (r2BandEnd != r2End && r2BandEnd->top() == r2->top()) - ++r2BandEnd; - - /* - * First handle the band that doesn't intersect, if any. - * - * Note that attention is restricted to one band in the - * non-intersecting region at once, so if a region has n - * bands between the current position and the next place it overlaps - * the other, this entire loop will be passed through n times. - */ - if (r1->top() < r2->top()) { - top = qMax(r1->top(), ybot + 1); - bot = qMin(r1->bottom(), r2->top() - 1); - - if (nonOverlap1Func != 0 && bot >= top) - (*nonOverlap1Func)(dest, r1, r1BandEnd, top, bot); - ytop = r2->top(); - } else if (r2->top() < r1->top()) { - top = qMax(r2->top(), ybot + 1); - bot = qMin(r2->bottom(), r1->top() - 1); - - if (nonOverlap2Func != 0 && bot >= top) - (*nonOverlap2Func)(dest, r2, r2BandEnd, top, bot); - ytop = r1->top(); - } else { - ytop = r1->top(); - } - - /* - * If any rectangles got added to the region, try and coalesce them - * with rectangles from the previous band. Note we could just do - * this test in miCoalesce, but some machines incur a not - * inconsiderable cost for function calls, so... - */ - if (dest.numRects != curBand) - prevBand = miCoalesce(dest, prevBand, curBand); - - /* - * Now see if we've hit an intersecting band. The two bands only - * intersect if ybot >= ytop - */ - ybot = qMin(r1->bottom(), r2->bottom()); - curBand = dest.numRects; - if (ybot >= ytop) - (*overlapFunc)(dest, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot); - - if (dest.numRects != curBand) - prevBand = miCoalesce(dest, prevBand, curBand); - - /* - * If we've finished with a band (y2 == ybot) we skip forward - * in the region to the next band. - */ - if (r1->bottom() == ybot) - r1 = r1BandEnd; - if (r2->bottom() == ybot) - r2 = r2BandEnd; - } while (r1 != r1End && r2 != r2End); - - /* - * Deal with whichever region still has rectangles left. - */ - curBand = dest.numRects; - if (r1 != r1End) { - if (nonOverlap1Func != 0) { - do { - r1BandEnd = r1; - while (r1BandEnd < r1End && r1BandEnd->top() == r1->top()) - ++r1BandEnd; - (*nonOverlap1Func)(dest, r1, r1BandEnd, qMax(r1->top(), ybot + 1), r1->bottom()); - r1 = r1BandEnd; - } while (r1 != r1End); - } - } else if ((r2 != r2End) && (nonOverlap2Func != 0)) { - do { - r2BandEnd = r2; - while (r2BandEnd < r2End && r2BandEnd->top() == r2->top()) - ++r2BandEnd; - (*nonOverlap2Func)(dest, r2, r2BandEnd, qMax(r2->top(), ybot + 1), r2->bottom()); - r2 = r2BandEnd; - } while (r2 != r2End); - } - - if (dest.numRects != curBand) - (void)miCoalesce(dest, prevBand, curBand); - - /* - * A bit of cleanup. To keep regions from growing without bound, - * we shrink the array of rectangles to match the new number of - * rectangles in the region. - * - * Only do this stuff if the number of rectangles allocated is more than - * twice the number of rectangles in the region (a simple optimization). - */ - if (qMax(4, dest.numRects) < (dest.rects.size() >> 1)) - dest.rects.resize(dest.numRects); -} - -/*====================================================================== - * Region Union - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * miUnionNonO -- - * Handle a non-overlapping band for the union operation. Just - * Adds the rectangles into the region. Doesn't have to check for - * subsumption or anything. - * - * Results: - * None. - * - * Side Effects: - * dest.numRects is incremented and the final rectangles overwritten - * with the rectangles we're passed. - * - *----------------------------------------------------------------------- - */ - -static void miUnionNonO(register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, - register int y1, register int y2) -{ - register QRect *pNextRect; - - pNextRect = dest.rects.data() + dest.numRects; - - Q_ASSERT(y1 <= y2); - - while (r != rEnd) { - Q_ASSERT(r->left() <= r->right()); - MEMCHECK(dest, pNextRect, dest.rects) - pNextRect->setCoords(r->left(), y1, r->right(), y2); - dest.numRects++; - ++pNextRect; - ++r; - } -} - - -/*- - *----------------------------------------------------------------------- - * miUnionO -- - * Handle an overlapping band for the union operation. Picks the - * left-most rectangle each time and merges it into the region. - * - * Results: - * None. - * - * Side Effects: - * Rectangles are overwritten in dest.rects and dest.numRects will - * be changed. - * - *----------------------------------------------------------------------- - */ - -static void miUnionO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, - register const QRect *r2, const QRect *r2End, register int y1, register int y2) -{ - register QRect *pNextRect; - - pNextRect = dest.rects.data() + dest.numRects; - -#define MERGERECT(r) \ - if ((dest.numRects != 0) && \ - (pNextRect[-1].top() == y1) && \ - (pNextRect[-1].bottom() == y2) && \ - (pNextRect[-1].right() >= r->left()-1)) { \ - if (pNextRect[-1].right() < r->right()) { \ - pNextRect[-1].setRight(r->right()); \ - dest.updateInnerRect(pNextRect[-1]); \ - Q_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \ - } \ - } else { \ - MEMCHECK(dest, pNextRect, dest.rects) \ - pNextRect->setCoords(r->left(), y1, r->right(), y2); \ - dest.updateInnerRect(*pNextRect); \ - dest.numRects++; \ - pNextRect++; \ - } \ - r++; - - Q_ASSERT(y1 <= y2); - while (r1 != r1End && r2 != r2End) { - if (r1->left() < r2->left()) { - MERGERECT(r1) - } else { - MERGERECT(r2) - } - } - - if (r1 != r1End) { - do { - MERGERECT(r1) - } while (r1 != r1End); - } else { - while (r2 != r2End) { - MERGERECT(r2) - } - } -} - -static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest) -{ - Q_ASSERT(!isEmptyHelper(reg1) && !isEmptyHelper(reg2)); - Q_ASSERT(!reg1->contains(*reg2)); - Q_ASSERT(!reg2->contains(*reg1)); - Q_ASSERT(!EqualRegion(reg1, reg2)); - Q_ASSERT(!reg1->canAppend(reg2)); - Q_ASSERT(!reg2->canAppend(reg1)); - - if (reg1->innerArea > reg2->innerArea) { - dest.innerArea = reg1->innerArea; - dest.innerRect = reg1->innerRect; - } else { - dest.innerArea = reg2->innerArea; - dest.innerRect = reg2->innerRect; - } - miRegionOp(dest, reg1, reg2, miUnionO, miUnionNonO, miUnionNonO); - - dest.extents.setCoords(qMin(reg1->extents.left(), reg2->extents.left()), - qMin(reg1->extents.top(), reg2->extents.top()), - qMax(reg1->extents.right(), reg2->extents.right()), - qMax(reg1->extents.bottom(), reg2->extents.bottom())); -} - -/*====================================================================== - * Region Subtraction - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * miSubtractNonO -- - * Deal with non-overlapping band for subtraction. Any parts from - * region 2 we discard. Anything from region 1 we add to the region. - * - * Results: - * None. - * - * Side Effects: - * dest may be affected. - * - *----------------------------------------------------------------------- - */ - -static void miSubtractNonO1(register QRegionPrivate &dest, register const QRect *r, - const QRect *rEnd, register int y1, register int y2) -{ - register QRect *pNextRect; - - pNextRect = dest.rects.data() + dest.numRects; - - Q_ASSERT(y1<=y2); - - while (r != rEnd) { - Q_ASSERT(r->left() <= r->right()); - MEMCHECK(dest, pNextRect, dest.rects) - pNextRect->setCoords(r->left(), y1, r->right(), y2); - ++dest.numRects; - ++pNextRect; - ++r; - } -} - -/*- - *----------------------------------------------------------------------- - * miSubtractO -- - * Overlapping band subtraction. x1 is the left-most point not yet - * checked. - * - * Results: - * None. - * - * Side Effects: - * dest may have rectangles added to it. - * - *----------------------------------------------------------------------- - */ - -static void miSubtractO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, - register const QRect *r2, const QRect *r2End, register int y1, register int y2) -{ - register QRect *pNextRect; - register int x1; - - x1 = r1->left(); - - Q_ASSERT(y1 <= y2); - pNextRect = dest.rects.data() + dest.numRects; - - while (r1 != r1End && r2 != r2End) { - if (r2->right() < x1) { - /* - * Subtrahend missed the boat: go to next subtrahend. - */ - ++r2; - } else if (r2->left() <= x1) { - /* - * Subtrahend precedes minuend: nuke left edge of minuend. - */ - x1 = r2->right() + 1; - if (x1 > r1->right()) { - /* - * Minuend completely covered: advance to next minuend and - * reset left fence to edge of new minuend. - */ - ++r1; - if (r1 != r1End) - x1 = r1->left(); - } else { - // Subtrahend now used up since it doesn't extend beyond minuend - ++r2; - } - } else if (r2->left() <= r1->right()) { - /* - * Left part of subtrahend covers part of minuend: add uncovered - * part of minuend to region and skip to next subtrahend. - */ - Q_ASSERT(x1 < r2->left()); - MEMCHECK(dest, pNextRect, dest.rects) - pNextRect->setCoords(x1, y1, r2->left() - 1, y2); - ++dest.numRects; - ++pNextRect; - - x1 = r2->right() + 1; - if (x1 > r1->right()) { - /* - * Minuend used up: advance to new... - */ - ++r1; - if (r1 != r1End) - x1 = r1->left(); - } else { - // Subtrahend used up - ++r2; - } - } else { - /* - * Minuend used up: add any remaining piece before advancing. - */ - if (r1->right() >= x1) { - MEMCHECK(dest, pNextRect, dest.rects) - pNextRect->setCoords(x1, y1, r1->right(), y2); - ++dest.numRects; - ++pNextRect; - } - ++r1; - if (r1 != r1End) - x1 = r1->left(); - } - } - - /* - * Add remaining minuend rectangles to region. - */ - while (r1 != r1End) { - Q_ASSERT(x1 <= r1->right()); - MEMCHECK(dest, pNextRect, dest.rects) - pNextRect->setCoords(x1, y1, r1->right(), y2); - ++dest.numRects; - ++pNextRect; - - ++r1; - if (r1 != r1End) - x1 = r1->left(); - } -} - -/*- - *----------------------------------------------------------------------- - * miSubtract -- - * Subtract regS from regM and leave the result in regD. - * S stands for subtrahend, M for minuend and D for difference. - * - * Side Effects: - * regD is overwritten. - * - *----------------------------------------------------------------------- - */ - -static void SubtractRegion(QRegionPrivate *regM, QRegionPrivate *regS, - register QRegionPrivate &dest) -{ - Q_ASSERT(!isEmptyHelper(regM)); - Q_ASSERT(!isEmptyHelper(regS)); - Q_ASSERT(EXTENTCHECK(®M->extents, ®S->extents)); - Q_ASSERT(!regS->contains(*regM)); - Q_ASSERT(!EqualRegion(regM, regS)); - - miRegionOp(dest, regM, regS, miSubtractO, miSubtractNonO1, 0); - - /* - * Can't alter dest's extents before we call miRegionOp because - * it might be one of the source regions and miRegionOp depends - * on the extents of those regions being the unaltered. Besides, this - * way there's no checking against rectangles that will be nuked - * due to coalescing, so we have to examine fewer rectangles. - */ - miSetExtents(dest); -} - -static void XorRegion(QRegionPrivate *sra, QRegionPrivate *srb, QRegionPrivate &dest) -{ - Q_ASSERT(!isEmptyHelper(sra) && !isEmptyHelper(srb)); - Q_ASSERT(EXTENTCHECK(&sra->extents, &srb->extents)); - Q_ASSERT(!EqualRegion(sra, srb)); - - QRegionPrivate tra, trb; - - if (!srb->contains(*sra)) - SubtractRegion(sra, srb, tra); - if (!sra->contains(*srb)) - SubtractRegion(srb, sra, trb); - - Q_ASSERT(isEmptyHelper(&trb) || !tra.contains(trb)); - Q_ASSERT(isEmptyHelper(&tra) || !trb.contains(tra)); - - if (isEmptyHelper(&tra)) { - dest = trb; - } else if (isEmptyHelper(&trb)) { - dest = tra; - } else if (tra.canAppend(&trb)) { - dest = tra; - dest.append(&trb); - } else if (trb.canAppend(&tra)) { - dest = trb; - dest.append(&tra); - } else { - UnionRegion(&tra, &trb, dest); - } -} - -/* - * Check to see if two regions are equal - */ -static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2) -{ - if (r1->numRects != r2->numRects) { - return false; - } else if (r1->numRects == 0) { - return true; - } else if (r1->extents != r2->extents) { - return false; - } else if (r1->mode == QRegionPrivate::Single && r2->mode == QRegionPrivate::Single) { - return r1->single == r2->single; - } else { - const QRect *rr1 = (r1->mode==QRegionPrivate::Vector)?r1->rects.constData():&r1->single; - const QRect *rr2 = (r2->mode==QRegionPrivate::Vector)?r2->rects.constData():&r2->single; - for (int i = 0; i < r1->numRects; ++i, ++rr1, ++rr2) { - if (*rr1 != *rr2) - return false; - } - } - - return true; -} - -static bool PointInRegion(QRegionPrivate *pRegion, int x, int y) -{ - int i; - - if (pRegion->mode == QRegionPrivate::Single) - return pRegion->single.contains(x, y); - if (isEmptyHelper(pRegion)) - return false; - if (!pRegion->extents.contains(x, y)) - return false; - if (pRegion->innerRect.contains(x, y)) - return true; - for (i = 0; i < pRegion->numRects; ++i) { - if (pRegion->rects[i].contains(x, y)) - return true; - } - return false; -} - -static bool RectInRegion(register QRegionPrivate *region, int rx, int ry, uint rwidth, uint rheight) -{ - register const QRect *pbox; - register const QRect *pboxEnd; - QRect rect(rx, ry, rwidth, rheight); - register QRect *prect = ▭ - int partIn, partOut; - - if (!region || region->numRects == 0 || !EXTENTCHECK(®ion->extents, prect)) - return RectangleOut; - - partOut = false; - partIn = false; - - /* can stop when both partOut and partIn are true, or we reach prect->y2 */ - for (pbox = (region->mode==QRegionPrivate::Vector)?region->rects.constData():®ion->single, pboxEnd = pbox + region->numRects; - pbox < pboxEnd; ++pbox) { - if (pbox->bottom() < ry) - continue; - - if (pbox->top() > ry) { - partOut = true; - if (partIn || pbox->top() > prect->bottom()) - break; - ry = pbox->top(); - } - - if (pbox->right() < rx) - continue; /* not far enough over yet */ - - if (pbox->left() > rx) { - partOut = true; /* missed part of rectangle to left */ - if (partIn) - break; - } - - if (pbox->left() <= prect->right()) { - partIn = true; /* definitely overlap */ - if (partOut) - break; - } - - if (pbox->right() >= prect->right()) { - ry = pbox->bottom() + 1; /* finished with this band */ - if (ry > prect->bottom()) - break; - rx = prect->left(); /* reset x out to left again */ - } else { - /* - * Because boxes in a band are maximal width, if the first box - * to overlap the rectangle doesn't completely cover it in that - * band, the rectangle must be partially out, since some of it - * will be uncovered in that band. partIn will have been set true - * by now... - */ - break; - } - } - return partIn ? ((ry <= prect->bottom()) ? RectanglePart : RectangleIn) : RectangleOut; -} -// END OF Region.c extract -// START OF poly.h extract -/* $XConsortium: poly.h,v 1.4 94/04/17 20:22:19 rws Exp $ */ -/************************************************************************ - -Copyright (c) 1987 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ - -/* - * This file contains a few macros to help track - * the edge of a filled object. The object is assumed - * to be filled in scanline order, and thus the - * algorithm used is an extension of Bresenham's line - * drawing algorithm which assumes that y is always the - * major axis. - * Since these pieces of code are the same for any filled shape, - * it is more convenient to gather the library in one - * place, but since these pieces of code are also in - * the inner loops of output primitives, procedure call - * overhead is out of the question. - * See the author for a derivation if needed. - */ - - -/* - * In scan converting polygons, we want to choose those pixels - * which are inside the polygon. Thus, we add .5 to the starting - * x coordinate for both left and right edges. Now we choose the - * first pixel which is inside the pgon for the left edge and the - * first pixel which is outside the pgon for the right edge. - * Draw the left pixel, but not the right. - * - * How to add .5 to the starting x coordinate: - * If the edge is moving to the right, then subtract dy from the - * error term from the general form of the algorithm. - * If the edge is moving to the left, then add dy to the error term. - * - * The reason for the difference between edges moving to the left - * and edges moving to the right is simple: If an edge is moving - * to the right, then we want the algorithm to flip immediately. - * If it is moving to the left, then we don't want it to flip until - * we traverse an entire pixel. - */ -#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \ - int dx; /* local storage */ \ -\ - /* \ - * if the edge is horizontal, then it is ignored \ - * and assumed not to be processed. Otherwise, do this stuff. \ - */ \ - if ((dy) != 0) { \ - xStart = (x1); \ - dx = (x2) - xStart; \ - if (dx < 0) { \ - m = dx / (dy); \ - m1 = m - 1; \ - incr1 = -2 * dx + 2 * (dy) * m1; \ - incr2 = -2 * dx + 2 * (dy) * m; \ - d = 2 * m * (dy) - 2 * dx - 2 * (dy); \ - } else { \ - m = dx / (dy); \ - m1 = m + 1; \ - incr1 = 2 * dx - 2 * (dy) * m1; \ - incr2 = 2 * dx - 2 * (dy) * m; \ - d = -2 * m * (dy) + 2 * dx; \ - } \ - } \ -} - -#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \ - if (m1 > 0) { \ - if (d > 0) { \ - minval += m1; \ - d += incr1; \ - } \ - else { \ - minval += m; \ - d += incr2; \ - } \ - } else {\ - if (d >= 0) { \ - minval += m1; \ - d += incr1; \ - } \ - else { \ - minval += m; \ - d += incr2; \ - } \ - } \ -} - - -/* - * This structure contains all of the information needed - * to run the bresenham algorithm. - * The variables may be hardcoded into the declarations - * instead of using this structure to make use of - * register declarations. - */ -typedef struct { - int minor_axis; /* minor axis */ - int d; /* decision variable */ - int m, m1; /* slope and slope+1 */ - int incr1, incr2; /* error increments */ -} BRESINFO; - - -#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \ - BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \ - bres.m, bres.m1, bres.incr1, bres.incr2) - -#define BRESINCRPGONSTRUCT(bres) \ - BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2) - - - -/* - * These are the data structures needed to scan - * convert regions. Two different scan conversion - * methods are available -- the even-odd method, and - * the winding number method. - * The even-odd rule states that a point is inside - * the polygon if a ray drawn from that point in any - * direction will pass through an odd number of - * path segments. - * By the winding number rule, a point is decided - * to be inside the polygon if a ray drawn from that - * point in any direction passes through a different - * number of clockwise and counter-clockwise path - * segments. - * - * These data structures are adapted somewhat from - * the algorithm in (Foley/Van Dam) for scan converting - * polygons. - * The basic algorithm is to start at the top (smallest y) - * of the polygon, stepping down to the bottom of - * the polygon by incrementing the y coordinate. We - * keep a list of edges which the current scanline crosses, - * sorted by x. This list is called the Active Edge Table (AET) - * As we change the y-coordinate, we update each entry in - * in the active edge table to reflect the edges new xcoord. - * This list must be sorted at each scanline in case - * two edges intersect. - * We also keep a data structure known as the Edge Table (ET), - * which keeps track of all the edges which the current - * scanline has not yet reached. The ET is basically a - * list of ScanLineList structures containing a list of - * edges which are entered at a given scanline. There is one - * ScanLineList per scanline at which an edge is entered. - * When we enter a new edge, we move it from the ET to the AET. - * - * From the AET, we can implement the even-odd rule as in - * (Foley/Van Dam). - * The winding number rule is a little trickier. We also - * keep the EdgeTableEntries in the AET linked by the - * nextWETE (winding EdgeTableEntry) link. This allows - * the edges to be linked just as before for updating - * purposes, but only uses the edges linked by the nextWETE - * link as edges representing spans of the polygon to - * drawn (as with the even-odd rule). - */ - -/* - * for the winding number rule - */ -#define CLOCKWISE 1 -#define COUNTERCLOCKWISE -1 - -typedef struct _EdgeTableEntry { - int ymax; /* ycoord at which we exit this edge. */ - BRESINFO bres; /* Bresenham info to run the edge */ - struct _EdgeTableEntry *next; /* next in the list */ - struct _EdgeTableEntry *back; /* for insertion sort */ - struct _EdgeTableEntry *nextWETE; /* for winding num rule */ - int ClockWise; /* flag for winding number rule */ -} EdgeTableEntry; - - -typedef struct _ScanLineList{ - int scanline; /* the scanline represented */ - EdgeTableEntry *edgelist; /* header node */ - struct _ScanLineList *next; /* next in the list */ -} ScanLineList; - - -typedef struct { - int ymax; /* ymax for the polygon */ - int ymin; /* ymin for the polygon */ - ScanLineList scanlines; /* header node */ -} EdgeTable; - - -/* - * Here is a struct to help with storage allocation - * so we can allocate a big chunk at a time, and then take - * pieces from this heap when we need to. - */ -#define SLLSPERBLOCK 25 - -typedef struct _ScanLineListBlock { - ScanLineList SLLs[SLLSPERBLOCK]; - struct _ScanLineListBlock *next; -} ScanLineListBlock; - - - -/* - * - * a few macros for the inner loops of the fill code where - * performance considerations don't allow a procedure call. - * - * Evaluate the given edge at the given scanline. - * If the edge has expired, then we leave it and fix up - * the active edge table; otherwise, we increment the - * x value to be ready for the next scanline. - * The winding number rule is in effect, so we must notify - * the caller when the edge has been removed so he - * can reorder the Winding Active Edge Table. - */ -#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \ - if (pAET->ymax == y) { /* leaving this edge */ \ - pPrevAET->next = pAET->next; \ - pAET = pPrevAET->next; \ - fixWAET = 1; \ - if (pAET) \ - pAET->back = pPrevAET; \ - } \ - else { \ - BRESINCRPGONSTRUCT(pAET->bres) \ - pPrevAET = pAET; \ - pAET = pAET->next; \ - } \ -} - - -/* - * Evaluate the given edge at the given scanline. - * If the edge has expired, then we leave it and fix up - * the active edge table; otherwise, we increment the - * x value to be ready for the next scanline. - * The even-odd rule is in effect. - */ -#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \ - if (pAET->ymax == y) { /* leaving this edge */ \ - pPrevAET->next = pAET->next; \ - pAET = pPrevAET->next; \ - if (pAET) \ - pAET->back = pPrevAET; \ - } \ - else { \ - BRESINCRPGONSTRUCT(pAET->bres) \ - pPrevAET = pAET; \ - pAET = pAET->next; \ - } \ -} -// END OF poly.h extract -// START OF PolyReg.c extract -/* $XConsortium: PolyReg.c,v 11.23 94/11/17 21:59:37 converse Exp $ */ -/************************************************************************ - -Copyright (c) 1987 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ -/* $XFree86: xc/lib/X11/PolyReg.c,v 1.1.1.2.8.2 1998/10/04 15:22:49 hohndel Exp $ */ - -#define LARGE_COORDINATE 1000000 -#define SMALL_COORDINATE -LARGE_COORDINATE - -/* - * InsertEdgeInET - * - * Insert the given edge into the edge table. - * First we must find the correct bucket in the - * Edge table, then find the right slot in the - * bucket. Finally, we can insert it. - * - */ -static void InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline, - ScanLineListBlock **SLLBlock, int *iSLLBlock) -{ - register EdgeTableEntry *start, *prev; - register ScanLineList *pSLL, *pPrevSLL; - ScanLineListBlock *tmpSLLBlock; - - /* - * find the right bucket to put the edge into - */ - pPrevSLL = &ET->scanlines; - pSLL = pPrevSLL->next; - while (pSLL && (pSLL->scanline < scanline)) { - pPrevSLL = pSLL; - pSLL = pSLL->next; - } - - /* - * reassign pSLL (pointer to ScanLineList) if necessary - */ - if ((!pSLL) || (pSLL->scanline > scanline)) { - if (*iSLLBlock > SLLSPERBLOCK-1) - { - tmpSLLBlock = - (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock)); - (*SLLBlock)->next = tmpSLLBlock; - tmpSLLBlock->next = (ScanLineListBlock *)NULL; - *SLLBlock = tmpSLLBlock; - *iSLLBlock = 0; - } - pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]); - - pSLL->next = pPrevSLL->next; - pSLL->edgelist = (EdgeTableEntry *)NULL; - pPrevSLL->next = pSLL; - } - pSLL->scanline = scanline; - - /* - * now insert the edge in the right bucket - */ - prev = 0; - start = pSLL->edgelist; - while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) { - prev = start; - start = start->next; - } - ETE->next = start; - - if (prev) - prev->next = ETE; - else - pSLL->edgelist = ETE; -} - -/* - * CreateEdgeTable - * - * This routine creates the edge table for - * scan converting polygons. - * The Edge Table (ET) looks like: - * - * EdgeTable - * -------- - * | ymax | ScanLineLists - * |scanline|-->------------>-------------->... - * -------- |scanline| |scanline| - * |edgelist| |edgelist| - * --------- --------- - * | | - * | | - * V V - * list of ETEs list of ETEs - * - * where ETE is an EdgeTableEntry data structure, - * and there is one ScanLineList per scanline at - * which an edge is initially entered. - * - */ - -static void CreateETandAET(register int count, register const QPoint *pts, - EdgeTable *ET, EdgeTableEntry *AET, register EdgeTableEntry *pETEs, - ScanLineListBlock *pSLLBlock) -{ - register const QPoint *top, - *bottom, - *PrevPt, - *CurrPt; - int iSLLBlock = 0; - int dy; - - if (count < 2) - return; - - /* - * initialize the Active Edge Table - */ - AET->next = 0; - AET->back = 0; - AET->nextWETE = 0; - AET->bres.minor_axis = SMALL_COORDINATE; - - /* - * initialize the Edge Table. - */ - ET->scanlines.next = 0; - ET->ymax = SMALL_COORDINATE; - ET->ymin = LARGE_COORDINATE; - pSLLBlock->next = 0; - - PrevPt = &pts[count - 1]; - - /* - * for each vertex in the array of points. - * In this loop we are dealing with two vertices at - * a time -- these make up one edge of the polygon. - */ - while (count--) { - CurrPt = pts++; - - /* - * find out which point is above and which is below. - */ - if (PrevPt->y() > CurrPt->y()) { - bottom = PrevPt; - top = CurrPt; - pETEs->ClockWise = 0; - } else { - bottom = CurrPt; - top = PrevPt; - pETEs->ClockWise = 1; - } - - /* - * don't add horizontal edges to the Edge table. - */ - if (bottom->y() != top->y()) { - pETEs->ymax = bottom->y() - 1; /* -1 so we don't get last scanline */ - - /* - * initialize integer edge algorithm - */ - dy = bottom->y() - top->y(); - BRESINITPGONSTRUCT(dy, top->x(), bottom->x(), pETEs->bres) - - InsertEdgeInET(ET, pETEs, top->y(), &pSLLBlock, &iSLLBlock); - - if (PrevPt->y() > ET->ymax) - ET->ymax = PrevPt->y(); - if (PrevPt->y() < ET->ymin) - ET->ymin = PrevPt->y(); - ++pETEs; - } - - PrevPt = CurrPt; - } -} - -/* - * loadAET - * - * This routine moves EdgeTableEntries from the - * EdgeTable into the Active Edge Table, - * leaving them sorted by smaller x coordinate. - * - */ - -static void loadAET(register EdgeTableEntry *AET, register EdgeTableEntry *ETEs) -{ - register EdgeTableEntry *pPrevAET; - register EdgeTableEntry *tmp; - - pPrevAET = AET; - AET = AET->next; - while (ETEs) { - while (AET && AET->bres.minor_axis < ETEs->bres.minor_axis) { - pPrevAET = AET; - AET = AET->next; - } - tmp = ETEs->next; - ETEs->next = AET; - if (AET) - AET->back = ETEs; - ETEs->back = pPrevAET; - pPrevAET->next = ETEs; - pPrevAET = ETEs; - - ETEs = tmp; - } -} - -/* - * computeWAET - * - * This routine links the AET by the - * nextWETE (winding EdgeTableEntry) link for - * use by the winding number rule. The final - * Active Edge Table (AET) might look something - * like: - * - * AET - * ---------- --------- --------- - * |ymax | |ymax | |ymax | - * | ... | |... | |... | - * |next |->|next |->|next |->... - * |nextWETE| |nextWETE| |nextWETE| - * --------- --------- ^-------- - * | | | - * V-------------------> V---> ... - * - */ -static void computeWAET(register EdgeTableEntry *AET) -{ - register EdgeTableEntry *pWETE; - register int inside = 1; - register int isInside = 0; - - AET->nextWETE = 0; - pWETE = AET; - AET = AET->next; - while (AET) { - if (AET->ClockWise) - ++isInside; - else - --isInside; - - if (!inside && !isInside || inside && isInside) { - pWETE->nextWETE = AET; - pWETE = AET; - inside = !inside; - } - AET = AET->next; - } - pWETE->nextWETE = 0; -} - -/* - * InsertionSort - * - * Just a simple insertion sort using - * pointers and back pointers to sort the Active - * Edge Table. - * - */ - -static int InsertionSort(register EdgeTableEntry *AET) -{ - register EdgeTableEntry *pETEchase; - register EdgeTableEntry *pETEinsert; - register EdgeTableEntry *pETEchaseBackTMP; - register int changed = 0; - - AET = AET->next; - while (AET) { - pETEinsert = AET; - pETEchase = AET; - while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis) - pETEchase = pETEchase->back; - - AET = AET->next; - if (pETEchase != pETEinsert) { - pETEchaseBackTMP = pETEchase->back; - pETEinsert->back->next = AET; - if (AET) - AET->back = pETEinsert->back; - pETEinsert->next = pETEchase; - pETEchase->back->next = pETEinsert; - pETEchase->back = pETEinsert; - pETEinsert->back = pETEchaseBackTMP; - changed = 1; - } - } - return changed; -} - -/* - * Clean up our act. - */ -static void FreeStorage(register ScanLineListBlock *pSLLBlock) -{ - register ScanLineListBlock *tmpSLLBlock; - - while (pSLLBlock) { - tmpSLLBlock = pSLLBlock->next; - free(pSLLBlock); - pSLLBlock = tmpSLLBlock; - } -} - -/* - * Create an array of rectangles from a list of points. - * If indeed these things (POINTS, RECTS) are the same, - * then this proc is still needed, because it allocates - * storage for the array, which was allocated on the - * stack by the calling procedure. - * - */ -static void PtsToRegion(register int numFullPtBlocks, register int iCurPtBlock, - POINTBLOCK *FirstPtBlock, QRegionPrivate *reg) -{ - register QRect *rects; - register QPoint *pts; - register POINTBLOCK *CurPtBlock; - register int i; - register QRect *extents; - register int numRects; - - extents = ®->extents; - numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1; - - reg->rects.resize(numRects); - - CurPtBlock = FirstPtBlock; - rects = reg->rects.data() - 1; - numRects = 0; - extents->setLeft(INT_MAX); - extents->setRight(INT_MIN); - reg->innerArea = -1; - - for (; numFullPtBlocks >= 0; --numFullPtBlocks) { - /* the loop uses 2 points per iteration */ - i = NUMPTSTOBUFFER >> 1; - if (!numFullPtBlocks) - i = iCurPtBlock >> 1; - if(i) { - for (pts = CurPtBlock->pts; i--; pts += 2) { - if (pts->x() == pts[1].x()) - continue; - if (numRects && pts->x() == rects->left() && pts->y() == rects->bottom() + 1 - && pts[1].x() == rects->right()+1 && (numRects == 1 || rects[-1].top() != rects->top()) - && (i && pts[2].y() > pts[1].y())) { - rects->setBottom(pts[1].y()); - reg->updateInnerRect(*rects); - continue; - } - ++numRects; - ++rects; - rects->setCoords(pts->x(), pts->y(), pts[1].x() - 1, pts[1].y()); - if (rects->left() < extents->left()) - extents->setLeft(rects->left()); - if (rects->right() > extents->right()) - extents->setRight(rects->right()); - reg->updateInnerRect(*rects); - } - } - CurPtBlock = CurPtBlock->next; - } - - if (numRects) { - extents->setTop(reg->rects[0].top()); - extents->setBottom(rects->bottom()); - } else { - extents->setCoords(0, 0, 0, 0); - } - reg->numRects = numRects; -} - -/* - * polytoregion - * - * Scan converts a polygon by returning a run-length - * encoding of the resultant bitmap -- the run-length - * encoding is in the form of an array of rectangles. - */ -static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule, - QRegionPrivate *region) - //Point *Pts; /* the pts */ - //int Count; /* number of pts */ - //int rule; /* winding rule */ -{ - register EdgeTableEntry *pAET; /* Active Edge Table */ - register int y; /* current scanline */ - register int iPts = 0; /* number of pts in buffer */ - register EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/ - register ScanLineList *pSLL; /* current scanLineList */ - register QPoint *pts; /* output buffer */ - EdgeTableEntry *pPrevAET; /* ptr to previous AET */ - EdgeTable ET; /* header node for ET */ - EdgeTableEntry AET; /* header node for AET */ - EdgeTableEntry *pETEs; /* EdgeTableEntries pool */ - ScanLineListBlock SLLBlock; /* header for scanlinelist */ - int fixWAET = false; - POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */ - POINTBLOCK *tmpPtBlock; - int numFullPtBlocks = 0; - - region->vector(); - - /* special case a rectangle */ - if (((Count == 4) || - ((Count == 5) && (Pts[4].x() == Pts[0].x()) && (Pts[4].y() == Pts[0].y()))) - && (((Pts[0].y() == Pts[1].y()) && (Pts[1].x() == Pts[2].x()) && (Pts[2].y() == Pts[3].y()) - && (Pts[3].x() == Pts[0].x())) || ((Pts[0].x() == Pts[1].x()) - && (Pts[1].y() == Pts[2].y()) && (Pts[2].x() == Pts[3].x()) - && (Pts[3].y() == Pts[0].y())))) { - int x = qMin(Pts[0].x(), Pts[2].x()); - region->extents.setLeft(x); - int y = qMin(Pts[0].y(), Pts[2].y()); - region->extents.setTop(y); - region->extents.setWidth(qMax(Pts[0].x(), Pts[2].x()) - x); - region->extents.setHeight(qMax(Pts[0].y(), Pts[2].y()) - y); - if ((region->extents.left() <= region->extents.right()) && - (region->extents.top() <= region->extents.bottom())) { - region->numRects = 1; - region->rects.resize(1); - region->rects[0] = region->extents; - region->innerRect = region->extents; - region->innerArea = region->innerRect.width() * region->innerRect.height(); - } - return region; - } - - if (!(pETEs = static_cast<EdgeTableEntry *>(malloc(sizeof(EdgeTableEntry) * Count)))) - return 0; - - pts = FirstPtBlock.pts; - CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock); - pSLL = ET.scanlines.next; - curPtBlock = &FirstPtBlock; - - if (rule == EvenOddRule) { - /* - * for each scanline - */ - for (y = ET.ymin; y < ET.ymax; ++y) { - /* - * Add a new edge to the active edge table when we - * get to the next edge. - */ - if (pSLL && y == pSLL->scanline) { - loadAET(&AET, pSLL->edgelist); - pSLL = pSLL->next; - } - pPrevAET = &AET; - pAET = AET.next; - - /* - * for each active edge - */ - while (pAET) { - pts->setX(pAET->bres.minor_axis); - pts->setY(y); - ++pts; - ++iPts; - - /* - * send out the buffer - */ - if (iPts == NUMPTSTOBUFFER) { - tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK)); - curPtBlock->next = tmpPtBlock; - curPtBlock = tmpPtBlock; - pts = curPtBlock->pts; - ++numFullPtBlocks; - iPts = 0; - } - EVALUATEEDGEEVENODD(pAET, pPrevAET, y) - } - InsertionSort(&AET); - } - } else { - /* - * for each scanline - */ - for (y = ET.ymin; y < ET.ymax; ++y) { - /* - * Add a new edge to the active edge table when we - * get to the next edge. - */ - if (pSLL && y == pSLL->scanline) { - loadAET(&AET, pSLL->edgelist); - computeWAET(&AET); - pSLL = pSLL->next; - } - pPrevAET = &AET; - pAET = AET.next; - pWETE = pAET; - - /* - * for each active edge - */ - while (pAET) { - /* - * add to the buffer only those edges that - * are in the Winding active edge table. - */ - if (pWETE == pAET) { - pts->setX(pAET->bres.minor_axis); - pts->setY(y); - ++pts; - ++iPts; - - /* - * send out the buffer - */ - if (iPts == NUMPTSTOBUFFER) { - tmpPtBlock = static_cast<POINTBLOCK *>(malloc(sizeof(POINTBLOCK))); - curPtBlock->next = tmpPtBlock; - curPtBlock = tmpPtBlock; - pts = curPtBlock->pts; - ++numFullPtBlocks; - iPts = 0; - } - pWETE = pWETE->nextWETE; - } - EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) - } - - /* - * recompute the winding active edge table if - * we just resorted or have exited an edge. - */ - if (InsertionSort(&AET) || fixWAET) { - computeWAET(&AET); - fixWAET = false; - } - } - } - FreeStorage(SLLBlock.next); - PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); - for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { - tmpPtBlock = curPtBlock->next; - free(curPtBlock); - curPtBlock = tmpPtBlock; - } - free(pETEs); - return region; -} -// END OF PolyReg.c extract - -QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap, QRegionPrivate *region) -{ - region->vector(); - - QImage image = bitmap.toImage(); - - QRect xr; - -#define AddSpan \ - { \ - xr.setCoords(prev1, y, x-1, y); \ - UnionRectWithRegion(&xr, region, *region); \ - } - - const uchar zero = 0; - bool little = image.format() == QImage::Format_MonoLSB; - - int x, - y; - for (y = 0; y < image.height(); ++y) { - uchar *line = image.scanLine(y); - int w = image.width(); - uchar all = zero; - int prev1 = -1; - for (x = 0; x < w;) { - uchar byte = line[x / 8]; - if (x > w - 8 || byte!=all) { - if (little) { - for (int b = 8; b > 0 && x < w; --b) { - if (!(byte & 0x01) == !all) { - // More of the same - } else { - // A change. - if (all!=zero) { - AddSpan - all = zero; - } else { - prev1 = x; - all = ~zero; - } - } - byte >>= 1; - ++x; - } - } else { - for (int b = 8; b > 0 && x < w; --b) { - if (!(byte & 0x80) == !all) { - // More of the same - } else { - // A change. - if (all != zero) { - AddSpan - all = zero; - } else { - prev1 = x; - all = ~zero; - } - } - byte <<= 1; - ++x; - } - } - } else { - x += 8; - } - } - if (all != zero) { - AddSpan - } - } -#undef AddSpan - - return region; -} - -/* - Constructs an empty region. - - \sa isEmpty() -*/ - -QRegion::QRegion() - : d(&shared_empty) -{ - d->ref.ref(); -} - -/* - \overload - - Create a region based on the rectange \a r with region type \a t. - - If the rectangle is invalid a null region will be created. - - \sa QRegion::RegionType -*/ - -QRegion::QRegion(const QRect &r, RegionType t) -{ - if (r.isEmpty()) { - d = &shared_empty; - d->ref.ref(); - } else { -// d = new QRegionData; - QRegionPrivate *rp = 0; - if (t == Rectangle) { -// rp = new QRegionPrivate(r); - rp = qt_allocRegion(r); - } else if (t == Ellipse) { - QPainterPath path; - path.addEllipse(r.x(), r.y(), r.width(), r.height()); - QPolygon a = path.toSubpathPolygons().at(0).toPolygon(); - rp = qt_allocRegion(); -// rp = new QRegionPrivate; - PolygonRegion(a.constData(), a.size(), EvenOddRule, rp); - } - d = rp; - d->ref = 1; -#if defined(Q_WS_X11) - d->rgn = 0; - d->xrectangles = 0; -#elif defined(Q_WS_MAC) - d->rgn = 0; -#endif - d->qt_rgn = rp; - } -} - -/* - Constructs a polygon region from the point array \a a with the fill rule - specified by \a fillRule. - - If \a fillRule is \l{Qt::WindingFill}, the polygon region is defined - using the winding algorithm; if it is \l{Qt::OddEvenFill}, the odd-even fill - algorithm is used. - - \warning This constructor can be used to create complex regions that will - slow down painting when used. -*/ - -QRegion::QRegion(const QPolygon &a, Qt::FillRule fillRule) -{ - if (a.count() > 2) { - //d = new QRegionData; - // QRegionPrivate *rp = new QRegionPrivate; - QRegionPrivate *rp = qt_allocRegion(); - PolygonRegion(a.constData(), a.size(), - fillRule == Qt::WindingFill ? WindingRule : EvenOddRule, rp); - d = rp; - d->ref = 1; -#if defined(Q_WS_X11) - d->rgn = 0; - d->xrectangles = 0; -#elif defined(Q_WS_MAC) - d->rgn = 0; -#endif - d->qt_rgn = rp; - } else { - d = &shared_empty; - d->ref.ref(); - } -} - - -/* - Constructs a new region which is equal to region \a r. -*/ - -QRegion::QRegion(const QRegion &r) -{ - d = r.d; - d->ref.ref(); -} - - -/* - Constructs a region from the bitmap \a bm. - - The resulting region consists of the pixels in bitmap \a bm that - are Qt::color1, as if each pixel was a 1 by 1 rectangle. - - This constructor may create complex regions that will slow down - painting when used. Note that drawing masked pixmaps can be done - much faster using QPixmap::setMask(). -*/ -QRegion::QRegion(const QBitmap &bm) -{ - if (bm.isNull()) { - d = &shared_empty; - d->ref.ref(); - } else { - // d = new QRegionData; -// QRegionPrivate *rp = new QRegionPrivate; - QRegionPrivate *rp = qt_allocRegion(); - - qt_bitmapToRegion(bm, rp); - d = rp; - d->ref = 1; -#if defined(Q_WS_X11) - d->rgn = 0; - d->xrectangles = 0; -#elif defined(Q_WS_MAC) - d->rgn = 0; -#endif - d->qt_rgn = rp; - } -} - -void QRegion::cleanUp(QRegion::QRegionData *x) -{ - // delete x->qt_rgn; -#if defined(Q_WS_X11) - if (x->rgn) - XDestroyRegion(x->rgn); - if (x->xrectangles) - free(x->xrectangles); -#elif defined(Q_WS_MAC) - if (x->rgn) - qt_mac_dispose_rgn(x->rgn); -#endif - if(x->qt_rgn) { -// delete x->qt_rgn; - qt_freeRegion(x->qt_rgn); - } else { - delete x; - } -} - -/* - Destroys the region. -*/ - -QRegion::~QRegion() -{ - if (!d->ref.deref()) - cleanUp(d); -} - - -/* - Assigns \a r to this region and returns a reference to the region. -*/ - -QRegion &QRegion::operator=(const QRegion &r) -{ - r.d->ref.ref(); - if (!d->ref.deref()) - cleanUp(d); - d = r.d; - return *this; -} - - -/* - \internal -*/ - -QRegion QRegion::copy() const -{ - QRegion r; - QRegionData *x = 0; // new QRegionData; - QRegionPrivate *rp = 0; - if (d->qt_rgn) -// rp = new QRegionPrivate(*d->qt_rgn); - rp = qt_allocRegion(*d->qt_rgn); - else - rp = qt_allocRegion(); - x = rp; - x->qt_rgn = rp; - x->ref = 1; -#if defined(Q_WS_X11) - x->rgn = 0; - x->xrectangles = 0; -#elif defined(Q_WS_MAC) - x->rgn = 0; -#endif - - if (!r.d->ref.deref()) - cleanUp(r.d); - r.d = x; - return r; -} - -/* - Returns true if the region is empty; otherwise returns false. An - empty region is a region that contains no points. - - Example: - \snippet doc/src/snippets/code/src.gui.painting.qregion_qws.cpp 0 -*/ - -bool QRegion::isEmpty() const -{ - return d == &shared_empty || d->qt_rgn->numRects == 0; -} - - -/* - Returns true if the region contains the point \a p; otherwise - returns false. -*/ - -bool QRegion::contains(const QPoint &p) const -{ - return PointInRegion(d->qt_rgn, p.x(), p.y()); -} - -/* - \overload - - Returns true if the region overlaps the rectangle \a r; otherwise - returns false. -*/ - -bool QRegion::contains(const QRect &r) const -{ - if(!d->qt_rgn) - return false; - if(d->qt_rgn->mode == QRegionPrivate::Single) - return d->qt_rgn->single.contains(r); - - return RectInRegion(d->qt_rgn, r.left(), r.top(), r.width(), r.height()) != RectangleOut; -} - - - -/* - Translates (moves) the region \a dx along the X axis and \a dy - along the Y axis. -*/ - -void QRegion::translate(int dx, int dy) -{ - if ((dx == 0 && dy == 0) || isEmptyHelper(d->qt_rgn)) - return; - - detach(); - OffsetRegion(*d->qt_rgn, dx, dy); -#if defined(Q_WS_X11) - if (d->xrectangles) { - free(d->xrectangles); - d->xrectangles = 0; - } -#elif defined(Q_WS_MAC) - if(d->rgn) { - qt_mac_dispose_rgn(d->rgn); - d->rgn = 0; - } -#endif -} - -/* - \fn QRegion QRegion::unite(const QRegion &r) const - \obsolete - - Use united(\a r) instead. -*/ - -/* - \fn QRegion QRegion::united(const QRegion &r) const - \since 4.2 - - Returns a region which is the union of this region and \a r. - - \img runion.png Region Union - - The figure shows the union of two elliptical regions. - - \sa intersected(), subtracted(), xored() -*/ - -QRegion QRegion::unite(const QRegion &r) const -{ - if (isEmptyHelper(d->qt_rgn)) - return r; - if (isEmptyHelper(r.d->qt_rgn)) - return *this; - - if (d->qt_rgn->contains(*r.d->qt_rgn)) { - return *this; - } else if (r.d->qt_rgn->contains(*d->qt_rgn)) { - return r; - } else if (d->qt_rgn->canAppend(r.d->qt_rgn)) { - QRegion result(*this); - result.detach(); - result.d->qt_rgn->append(r.d->qt_rgn); - return result; - } else if (r.d->qt_rgn->canAppend(d->qt_rgn)) { - QRegion result(r); - result.detach(); - result.d->qt_rgn->append(d->qt_rgn); - return result; - } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) { - return *this; - } else { - QRegion result; - result.detach(); - UnionRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn); - return result; - } -} - -QRegion& QRegion::operator+=(const QRegion &r) -{ - if (isEmptyHelper(d->qt_rgn)) - return *this = r; - if (isEmptyHelper(r.d->qt_rgn)) - return *this; - - if (d->qt_rgn->contains(*r.d->qt_rgn)) { - return *this; - } else if (r.d->qt_rgn->contains(*d->qt_rgn)) { - return *this = r; - } else if (d->qt_rgn->canAppend(r.d->qt_rgn)) { - detach(); - d->qt_rgn->append(r.d->qt_rgn); - return *this; - } else if (d->qt_rgn->canPrepend(r.d->qt_rgn)) { - detach(); - d->qt_rgn->prepend(r.d->qt_rgn); - return *this; - } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) { - return *this; - } - - return *this = unite(r); -} - -/* - \fn QRegion QRegion::intersect(const QRegion &r) const - \obsolete - - Use intersected(\a r) instead. -*/ - -/* - \fn QRegion QRegion::intersected(const QRegion &r) const - \since 4.2 - - Returns a region which is the intersection of this region and \a r. - - \img rintersect.png Region Intersection - - The figure shows the intersection of two elliptical regions. -*/ - -QRegion QRegion::intersect(const QRegion &r) const -{ - if (isEmptyHelper(d->qt_rgn) || isEmptyHelper(r.d->qt_rgn) - || !EXTENTCHECK(&d->qt_rgn->extents, &r.d->qt_rgn->extents)) - return QRegion(); - - /* this is fully contained in r */ - if (r.d->qt_rgn->contains(*d->qt_rgn)) - return *this; - - /* r is fully contained in this */ - if (d->qt_rgn->contains(*r.d->qt_rgn)) - return r; - - if(r.d->qt_rgn->mode == QRegionPrivate::Single && - d->qt_rgn->mode == QRegionPrivate::Single) - return QRegion(r.d->qt_rgn->single.intersected(d->qt_rgn->single)); -#ifdef QT_GREENPHONE_OPT - else if(r.d->qt_rgn->mode == QRegionPrivate::Single) - return intersect(r.d->qt_rgn->single); - else if(d->qt_rgn->mode == QRegionPrivate::Single) - return r.intersect(d->qt_rgn->single); -#endif - - QRegion result; - result.detach(); - miRegionOp(*result.d->qt_rgn, d->qt_rgn, r.d->qt_rgn, miIntersectO, 0, 0); - - /* - * Can't alter dest's extents before we call miRegionOp because - * it might be one of the source regions and miRegionOp depends - * on the extents of those regions being the same. Besides, this - * way there's no checking against rectangles that will be nuked - * due to coalescing, so we have to examine fewer rectangles. - */ - miSetExtents(*result.d->qt_rgn); - return result; -} - -#ifdef QT_GREENPHONE_OPT -/* - \overload - */ -QRegion QRegion::intersect(const QRect &r) const -{ - // No intersection - if(r.isEmpty() || isEmpty() || !EXTENTCHECK(&r, &d->qt_rgn->extents)) - return QRegion(); - - // This is fully contained in r - if(CONTAINSCHECK(r, d->qt_rgn->extents)) - return *this; - - // r is fully contained in this - if(CONTAINSCHECK(d->qt_rgn->innerRect, r)) - return QRegion(r); - - if(d->qt_rgn->mode == QRegionPrivate::Single) { - return QRegion(d->qt_rgn->single & r); - } else { - QRegion rv(*this); - rv.detach(); - - rv.d->qt_rgn->extents &= r; - rv.d->qt_rgn->innerRect &= r; - rv.d->qt_rgn->innerArea = rv.d->qt_rgn->innerRect.height() * - rv.d->qt_rgn->innerRect.width(); - - int numRects = 0; - for(int ii = 0; ii < rv.d->qt_rgn->numRects; ++ii) { - QRect result = rv.d->qt_rgn->rects[ii] & r; - if(!result.isEmpty()) - rv.d->qt_rgn->rects[numRects++] = result; - } - rv.d->qt_rgn->numRects = numRects; - return rv; - } -} - -/* - \overload - */ -const QRegion QRegion::operator&(const QRect &r) const -{ - return intersect(r); -} - -/* - \overload - */ -QRegion& QRegion::operator&=(const QRect &r) -{ - if(isEmpty() || CONTAINSCHECK(r, d->qt_rgn->extents)) { - // Do nothing - } else if(r.isEmpty() || !EXTENTCHECK(&r, &d->qt_rgn->extents)) { - *this = QRegion(); - } else if(CONTAINSCHECK(d->qt_rgn->innerRect, r)) { - *this = QRegion(r); - } else { - detach(); - if(d->qt_rgn->mode == QRegionPrivate::Single) { - QRect result = d->qt_rgn->single & r; - d->qt_rgn->single = result; - d->qt_rgn->extents = result; - d->qt_rgn->innerRect = result; - d->qt_rgn->innerArea = result.height() * result.width(); - } else { - d->qt_rgn->extents &= r; - d->qt_rgn->innerRect &= r; - d->qt_rgn->innerArea = d->qt_rgn->innerRect.height() * - d->qt_rgn->innerRect.width(); - - int numRects = 0; - for(int ii = 0; ii < d->qt_rgn->numRects; ++ii) { - QRect result = d->qt_rgn->rects[ii] & r; - if(!result.isEmpty()) - d->qt_rgn->rects[numRects++] = result; - } - d->qt_rgn->numRects = numRects; - } - } - return *this; -} -#endif - -/* - \fn QRegion QRegion::subtract(const QRegion &r) const - \obsolete - - Use subtracted(\a r) instead. -*/ - -/* - \fn QRegion QRegion::subtracted(const QRegion &r) const - \since 4.2 - - Returns a region which is \a r subtracted from this region. - - \img rsubtract.png Region Subtraction - - The figure shows the result when the ellipse on the right is - subtracted from the ellipse on the left (\c {left - right}). - - \sa intersected(), united(), xored() -*/ - -QRegion QRegion::subtract(const QRegion &r) const -{ - if (isEmptyHelper(d->qt_rgn) || isEmptyHelper(r.d->qt_rgn)) - return *this; - if (r.d->qt_rgn->contains(*d->qt_rgn)) - return QRegion(); - if (!EXTENTCHECK(&d->qt_rgn->extents, &r.d->qt_rgn->extents)) - return *this; - if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) - return QRegion(); - - QRegion result; - result.detach(); - SubtractRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn); - return result; -} - -/* - \fn QRegion QRegion::eor(const QRegion &r) const - \obsolete - - Use xored(\a r) instead. -*/ - -/* - \fn QRegion QRegion::xored(const QRegion &r) const - \since 4.2 - - Returns a region which is the exclusive or (XOR) of this region - and \a r. - - \img rxor.png Region XORed - - The figure shows the exclusive or of two elliptical regions. - - \sa intersected(), united(), subtracted() -*/ - -QRegion QRegion::eor(const QRegion &r) const -{ - if (isEmptyHelper(d->qt_rgn)) { - return r; - } else if (isEmptyHelper(r.d->qt_rgn)) { - return *this; - } else if (!EXTENTCHECK(&d->qt_rgn->extents, &r.d->qt_rgn->extents)) { - return (*this + r); - } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) { - return QRegion(); - } else { - QRegion result; - result.detach(); - XorRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn); - return result; - } -} - -/* - Returns the bounding rectangle of this region. An empty region - gives a rectangle that is QRect::isNull(). -*/ - -QRect QRegion::boundingRect() const -{ - if (isEmpty()) - return QRect(); - return d->qt_rgn->extents; -} - -/* \internal - Returns true if \a rect is guaranteed to be fully contained in \a region. - A false return value does not guarantee the opposite. -*/ -bool qt_region_strictContains(const QRegion ®ion, const QRect &rect) -{ - if (isEmptyHelper(region.d->qt_rgn) || !rect.isValid()) - return false; - -#if 0 // TEST_INNERRECT - static bool guard = false; - if (guard) - return QRect(); - guard = true; - QRegion inner = region.d->qt_rgn->innerRect; - Q_ASSERT((inner - region).isEmpty()); - guard = false; - - int maxArea = 0; - for (int i = 0; i < region.d->qt_rgn->numRects; ++i) { - const QRect r = region.d->qt_rgn->rects.at(i); - if (r.width() * r.height() > maxArea) - maxArea = r.width() * r.height(); - } - - if (maxArea > region.d->qt_rgn->innerArea) { - qDebug() << "not largest rectangle" << region << region.d->qt_rgn->innerRect; - } - Q_ASSERT(maxArea <= region.d->qt_rgn->innerArea); -#endif - - const QRect r1 = region.d->qt_rgn->innerRect; - return (rect.left() >= r1.left() && rect.right() <= r1.right() - && rect.top() >= r1.top() && rect.bottom() <= r1.bottom()); -} - -/* - Returns an array of non-overlapping rectangles that make up the - region. - - The union of all the rectangles is equal to the original region. -*/ -QVector<QRect> QRegion::rects() const -{ - if (d->qt_rgn) { - d->qt_rgn->vector(); - d->qt_rgn->rects.resize(d->qt_rgn->numRects); - return d->qt_rgn->rects; - } else { - return QVector<QRect>(); - } -} - -/* - \fn void QRegion::setRects(const QRect *rects, int number) - - Sets the region using the array of rectangles specified by \a rects and - \a number. - The rectangles \e must be optimally Y-X sorted and follow these restrictions: - - \list - \o The rectangles must not intersect. - \o All rectangles with a given top coordinate must have the same height. - \o No two rectangles may abut horizontally (they should be combined - into a single wider rectangle in that case). - \o The rectangles must be sorted in ascending order, with Y as the major - sort key and X as the minor sort key. - \endlist - \omit - Only some platforms have these restrictions (Qt for Embedded Linux, X11 and Mac OS X). - \endomit -*/ -void QRegion::setRects(const QRect *rects, int num) -{ - *this = QRegion(); - if (!rects || num == 0 || (num == 1 && rects->isEmpty())) - return; - - detach(); - - if(num == 1) { - d->qt_rgn->single = *rects; - d->qt_rgn->mode = QRegionPrivate::Single; - d->qt_rgn->numRects = num; - d->qt_rgn->extents = *rects; - d->qt_rgn->innerRect = *rects; - } else { - d->qt_rgn->mode = QRegionPrivate::Vector; - d->qt_rgn->rects.resize(num); - d->qt_rgn->numRects = num; - int left = INT_MAX, - right = INT_MIN, - top = INT_MAX, - bottom = INT_MIN; - for (int i = 0; i < num; ++i) { - const QRect &rect = rects[i]; - d->qt_rgn->rects[i] = rect; - left = qMin(rect.left(), left); - right = qMax(rect.right(), right); - top = qMin(rect.top(), top); - bottom = qMax(rect.bottom(), bottom); - d->qt_rgn->updateInnerRect(rect); - } - d->qt_rgn->extents = QRect(QPoint(left, top), QPoint(right, bottom)); - } -} - -/* - Returns true if the region is equal to \a r; otherwise returns - false. -*/ - -bool QRegion::operator==(const QRegion &r) const -{ - if (!d->qt_rgn || !r.d->qt_rgn) - return r.d->qt_rgn == d->qt_rgn; - - if (d == r.d) - return true; - else - return EqualRegion(d->qt_rgn, r.d->qt_rgn); -} - -#ifdef QT_GREENPHONE_OPT -bool QRegion::isRect() const -{ - return d->qt_rgn && d->qt_rgn->mode == QRegionPrivate::Single; -} -#endif - -QT_END_NAMESPACE diff --git a/src/gui/painting/qregion_s60.cpp b/src/gui/painting/qregion_s60.cpp deleted file mode 100644 index bd5b701ca8..0000000000 --- a/src/gui/painting/qregion_s60.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbitmap.h" -#include "qbuffer.h" -#include "qimage.h" -#include "qpolygon.h" -#include "qregion.h" - -QT_BEGIN_NAMESPACE - -QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0 }; - -QT_END_NAMESPACE diff --git a/src/gui/painting/qregion_win.cpp b/src/gui/painting/qregion_win.cpp deleted file mode 100644 index 57fd0858e0..0000000000 --- a/src/gui/painting/qregion_win.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qatomic.h" -#include "qbitmap.h" -#include "qbuffer.h" -#include "qimage.h" -#include "qpolygon.h" -#include "qregion.h" -#include "qt_windows.h" -#include "qpainterpath.h" - -QT_BEGIN_NAMESPACE - -QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0 }; - -HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom) -{ - const int tries = 10; - for (int i = 0; i < tries; ++i) { - HRGN region = 0; - switch (type) { - case QRegion::Rectangle: - region = CreateRectRgn(left, top, right, bottom); - break; - case QRegion::Ellipse: -#ifndef Q_OS_WINCE - region = CreateEllipticRgn(left, top, right, bottom); -#endif - break; - } - if (region) { - if (GetRegionData(region, 0, 0)) - return region; - else - DeleteObject(region); - } - } - return 0; -} - -QRegion qt_region_from_HRGN(HRGN rgn) -{ - int numBytes = GetRegionData(rgn, 0, 0); - if (numBytes == 0) - return QRegion(); - - char *buf = new char[numBytes]; - if (buf == 0) - return QRegion(); - - RGNDATA *rd = reinterpret_cast<RGNDATA*>(buf); - if (GetRegionData(rgn, numBytes, rd) == 0) { - delete [] buf; - return QRegion(); - } - - QRegion region; - RECT *r = reinterpret_cast<RECT*>(rd->Buffer); - for (uint i = 0; i < rd->rdh.nCount; ++i) { - QRect rect; - rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1); - ++r; - region |= rect; - } - - delete [] buf; - - return region; -} - -void qt_win_dispose_rgn(HRGN r) -{ - if (r) - DeleteObject(r); -} - -static void qt_add_rect(HRGN &winRegion, QRect r) -{ - HRGN rgn = CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height()); - if (rgn) { - HRGN dest = CreateRectRgn(0,0,0,0); - int result = CombineRgn(dest, winRegion, rgn, RGN_OR); - if (result) { - DeleteObject(winRegion); - winRegion = dest; - } - DeleteObject(rgn); - } -} - -void QRegion::ensureHandle() const -{ - if (d->rgn) - DeleteObject(d->rgn); - d->rgn = CreateRectRgn(0,0,0,0); - if (d->qt_rgn) { - if (d->qt_rgn->numRects == 1) { - QRect r = d->qt_rgn->extents; - qt_add_rect(d->rgn, r); - return; - } - for (int i = 0;i < d->qt_rgn->numRects;i++) { - QRect r = d->qt_rgn->rects.at(i); - qt_add_rect(d->rgn, r); - } - } -} - - -QT_END_NAMESPACE diff --git a/src/gui/painting/qregion_x11.cpp b/src/gui/painting/qregion_x11.cpp deleted file mode 100644 index a96ec6dc96..0000000000 --- a/src/gui/painting/qregion_x11.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qt_x11_p.h> - -#include <limits.h> - -QT_BEGIN_NAMESPACE - -QRegion::QRegionData QRegion::shared_empty = {Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0}; - -void QRegion::updateX11Region() const -{ - d->rgn = XCreateRegion(); - if (!d->qt_rgn) - return; - - int n = d->qt_rgn->numRects; - const QRect *rect = (n == 1 ? &d->qt_rgn->extents : d->qt_rgn->rects.constData()); - while (n--) { - XRectangle r; - r.x = qMax(SHRT_MIN, rect->x()); - r.y = qMax(SHRT_MIN, rect->y()); - r.width = qMin((int)USHRT_MAX, rect->width()); - r.height = qMin((int)USHRT_MAX, rect->height()); - XUnionRectWithRegion(&r, d->rgn, d->rgn); - ++rect; - } -} - -void *QRegion::clipRectangles(int &num) const -{ - if (!d->xrectangles && !(d == &shared_empty || d->qt_rgn->numRects == 0)) { - XRectangle *r = static_cast<XRectangle*>(malloc(d->qt_rgn->numRects * sizeof(XRectangle))); - d->xrectangles = r; - int n = d->qt_rgn->numRects; - const QRect *rect = (n == 1 ? &d->qt_rgn->extents : d->qt_rgn->rects.constData()); - while (n--) { - r->x = qMax(SHRT_MIN, rect->x()); - r->y = qMax(SHRT_MIN, rect->y()); - r->width = qMin((int)USHRT_MAX, rect->width()); - r->height = qMin((int)USHRT_MAX, rect->height()); - ++r; - ++rect; - } - } - if (d == &shared_empty || d->qt_rgn->numRects == 0) - num = 0; - else - num = d->qt_rgn->numRects; - return d->xrectangles; -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qstylepainter.cpp b/src/gui/painting/qstylepainter.cpp deleted file mode 100644 index 180499d791..0000000000 --- a/src/gui/painting/qstylepainter.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qstylepainter.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QStylePainter - - \brief The QStylePainter class is a convenience class for drawing QStyle - elements inside a widget. - - \ingroup appearance - \ingroup painting - - QStylePainter extends QPainter with a set of high-level \c - draw...() functions implemented on top of QStyle's API. The - advantage of using QStylePainter is that the parameter lists get - considerably shorter. Whereas a QStyle object must be able to - draw on any widget using any painter (because the application - normally has one QStyle object shared by all widget), a - QStylePainter is initialized with a widget, eliminating the need - to specify the QWidget, the QPainter, and the QStyle for every - function call. - - Example using QStyle directly: - - \snippet doc/src/snippets/styles/styles.cpp 1 - - Example using QStylePainter: - - \snippet doc/src/snippets/styles/styles.cpp 0 - \snippet doc/src/snippets/styles/styles.cpp 4 - \snippet doc/src/snippets/styles/styles.cpp 6 - - \sa QStyle, QStyleOption -*/ - -/*! - \fn QStylePainter::QStylePainter() - - Constructs a QStylePainter. -*/ - -/*! - \fn QStylePainter::QStylePainter(QWidget *widget) - - Construct a QStylePainter using widget \a widget for its paint device. -*/ - -/*! - \fn QStylePainter::QStylePainter(QPaintDevice *pd, QWidget *widget) - - Construct a QStylePainter using \a pd for its paint device, and - attributes from \a widget. -*/ - - -/*! - \fn bool QStylePainter::begin(QWidget *widget) - - Begin painting operations on the specified \a widget. - Returns true if the painter is ready to use; otherwise returns false. - - This is automatically called by the constructor that takes a QWidget. -*/ - -/*! - \fn bool QStylePainter::begin(QPaintDevice *pd, QWidget *widget) - \overload - - Begin painting operations on paint device \a pd as if it was \a - widget. - - This is automatically called by the constructor that - takes a QPaintDevice and a QWidget. -*/ - - -/*! - \fn void QStylePainter::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &option) - - Use the widget's style to draw a primitive element \a pe specified by QStyleOption \a option. - - \sa QStyle::drawPrimitive() -*/ - -/*! - \fn void QStylePainter::drawControl(QStyle::ControlElement ce, const QStyleOption &option) - - Use the widget's style to draw a control element \a ce specified by QStyleOption \a option. - - \sa QStyle::drawControl() -*/ - -/*! - \fn void QStylePainter::drawComplexControl(QStyle::ComplexControl cc, - const QStyleOptionComplex &option) - - Use the widget's style to draw a complex control \a cc specified by the - QStyleOptionComplex \a option. - - \sa QStyle::drawComplexControl() -*/ - -/*! - \fn void QStylePainter::drawItemText(const QRect &rect, int flags, const QPalette &pal, - bool enabled, const QString &text, - QPalette::ColorRole textRole = QPalette::NoRole) - - Draws the \a text in rectangle \a rect and palette \a pal. - The text is aligned and wrapped according to \a - flags. - - The pen color is specified with \a textRole. The \a enabled bool - indicates whether or not the item is enabled; when reimplementing - this bool should influence how the item is drawn. - - \sa QStyle::drawItemText(), Qt::Alignment -*/ - -/*! - \fn void QStylePainter::drawItemPixmap(const QRect &rect, int flags, const QPixmap &pixmap) - - Draws the \a pixmap in rectangle \a rect. - The pixmap is aligned according to \a flags. - - \sa QStyle::drawItemPixmap(), Qt::Alignment -*/ - -/*! - \fn QStyle *QStylePainter::style() const - - Return the current style used by the QStylePainter. -*/ - -QT_END_NAMESPACE diff --git a/src/gui/painting/qstylepainter.h b/src/gui/painting/qstylepainter.h deleted file mode 100644 index be0ce991cb..0000000000 --- a/src/gui/painting/qstylepainter.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSTYLEPAINTER_H -#define QSTYLEPAINTER_H - -#include <QtGui/qpainter.h> -#include <QtGui/qstyle.h> -#include <QtGui/qwidget.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QStylePainter : public QPainter -{ -public: - inline QStylePainter() : QPainter(), widget(0), wstyle(0) {} - inline explicit QStylePainter(QWidget *w) { begin(w, w); } - inline QStylePainter(QPaintDevice *pd, QWidget *w) { begin(pd, w); } - inline bool begin(QWidget *w) { return begin(w, w); } - inline bool begin(QPaintDevice *pd, QWidget *w) { - Q_ASSERT_X(w, "QStylePainter::QStylePainter", "Widget must be non-zero"); - widget = w; - wstyle = w->style(); - return QPainter::begin(pd); - }; - inline void drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &opt); - inline void drawControl(QStyle::ControlElement ce, const QStyleOption &opt); - inline void drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &opt); - inline void drawItemText(const QRect &r, int flags, const QPalette &pal, bool enabled, - const QString &text, QPalette::ColorRole textRole = QPalette::NoRole); - inline void drawItemPixmap(const QRect &r, int flags, const QPixmap &pixmap); - inline QStyle *style() const { return wstyle; } - -private: - QWidget *widget; - QStyle *wstyle; - Q_DISABLE_COPY(QStylePainter) -}; - -void QStylePainter::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &opt) -{ - wstyle->drawPrimitive(pe, &opt, this, widget); -} - -void QStylePainter::drawControl(QStyle::ControlElement ce, const QStyleOption &opt) -{ - wstyle->drawControl(ce, &opt, this, widget); -} - -void QStylePainter::drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &opt) -{ - wstyle->drawComplexControl(cc, &opt, this, widget); -} - -void QStylePainter::drawItemText(const QRect &r, int flags, const QPalette &pal, bool enabled, - const QString &text, QPalette::ColorRole textRole) -{ - wstyle->drawItemText(this, r, flags, pal, enabled, text, textRole); -} - -void QStylePainter::drawItemPixmap(const QRect &r, int flags, const QPixmap &pixmap) -{ - wstyle->drawItemPixmap(this, r, flags, pixmap); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSTYLEPAINTER_H diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp deleted file mode 100644 index aecbf2b177..0000000000 --- a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qunifiedtoolbarsurface_mac_p.h" -#include <private/qt_cocoa_helpers_mac_p.h> -#include <private/qbackingstore_p.h> -#include <private/qmainwindowlayout_p.h> - -#include <QDebug> - -#ifdef QT_MAC_USE_COCOA - -QT_BEGIN_NAMESPACE - -QUnifiedToolbarSurface::QUnifiedToolbarSurface(QWidget *widget) - : QRasterWindowSurface(widget, false), d_ptr(new QUnifiedToolbarSurfacePrivate) -{ - d_ptr->image = 0; - d_ptr->inSetGeometry = false; - - setGeometry(QRect(QPoint(0, 0), QSize(widget->width(), 100))); // FIXME: Fix height. -} - -QUnifiedToolbarSurface::~QUnifiedToolbarSurface() -{ - if (d_ptr->image) - delete d_ptr->image; -} - -QPaintDevice *QUnifiedToolbarSurface::paintDevice() -{ - return &d_ptr->image->image; -} - -void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, QWidget *parent_toolbar, const QPoint &offset) -{ - if (object != 0) { - if (object->isWidgetType()) { - QWidget *widget = qobject_cast<QWidget *>(object); - - // We redirect the painting only if the widget is in the same window - // and is not a window in itself. - if (!(widget->windowType() & Qt::Window)) { - widget->d_func()->unifiedSurface = this; - widget->d_func()->isInUnifiedToolbar = true; - widget->d_func()->toolbar_offset = offset; - widget->d_func()->toolbar_ancestor = parent_toolbar; - - for (int i = 0; i < object->children().size(); ++i) { - recursiveRedirect(object->children().at(i), parent_toolbar, offset); - } - } - } - } -} - -void QUnifiedToolbarSurface::insertToolbar(QWidget *toolbar, const QPoint &offset) -{ - setGeometry(QRect(QPoint(0, 0), QSize(offset.x() + toolbar->width(), 100))); // FIXME - recursiveRedirect(toolbar, toolbar, offset); -} - -// We basically undo what we set in recursiveRedirect(). -void QUnifiedToolbarSurface::recursiveRemoval(QObject *object) -{ - if (object != 0) { - if (object->isWidgetType()) { - QWidget *widget = qobject_cast<QWidget *>(object); - - // If it's a pop-up or something similar, we don't redirect it. - if (widget->windowType() & Qt::Window) - return; - - widget->d_func()->unifiedSurface = 0; - widget->d_func()->isInUnifiedToolbar = false; - widget->d_func()->toolbar_offset = QPoint(); - widget->d_func()->toolbar_ancestor = 0; - } - - for (int i = 0; i < object->children().size(); ++i) { - recursiveRemoval(object->children().at(i)); - } - } -} - -void QUnifiedToolbarSurface::removeToolbar(QToolBar *toolbar) -{ - recursiveRemoval(toolbar); -} - -void QUnifiedToolbarSurface::setGeometry(const QRect &rect) -{ - QWindowSurface::setGeometry(rect); - Q_D(QUnifiedToolbarSurface); - d->inSetGeometry = true; - if (d->image == 0 || d->image->width() < rect.width() || d->image->height() < rect.height()) - prepareBuffer(QImage::Format_ARGB32_Premultiplied, window()); - d->inSetGeometry = false; - - // FIXME: set unified toolbar height. -} - -void QUnifiedToolbarSurface::beginPaint(const QRegion &rgn) -{ - QPainter p(&d_ptr->image->image); - p.setCompositionMode(QPainter::CompositionMode_Source); - const QVector<QRect> rects = rgn.rects(); - const QColor blank = Qt::transparent; - for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { - p.fillRect(*it, blank); - } -} - -void QUnifiedToolbarSurface::updateToolbarOffset(QWidget *widget) -{ - QMainWindowLayout *mlayout = qobject_cast<QMainWindowLayout*> (widget->window()->layout()); - if (mlayout) - mlayout->updateUnifiedToolbarOffset(); -} - -void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) -{ - Q_UNUSED(region); - Q_UNUSED(offset); - - this->flush(widget); -} - -void QUnifiedToolbarSurface::flush(QWidget *widget) -{ - Q_D(QUnifiedToolbarSurface); - - if (!d->image) - return; - - if (widget->d_func()->flushRequested) { - // We call display: directly to avoid flickering in the toolbar. - qt_mac_display(widget); - } -} - -void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widget) -{ - Q_D(QUnifiedToolbarSurface); - - int width = geometry().width(); - int height = 100; // FIXME - if (d->image) { - width = qMax(d->image->width(), width); - height = qMax(d->image->height(), height); - } - - if (width == 0 || height == 0) { - delete d->image; - d->image = 0; - return; - } - - QNativeImage *oldImage = d->image; - - d->image = new QNativeImage(width, height, format, false, widget); - - if (oldImage && d->inSetGeometry && hasStaticContents()) { - // Make sure we use the const version of bits() (no detach). - const uchar *src = const_cast<const QImage &>(oldImage->image).bits(); - uchar *dst = d->image->image.bits(); - - const int srcBytesPerLine = oldImage->image.bytesPerLine(); - const int dstBytesPerLine = d->image->image.bytesPerLine(); - const int bytesPerPixel = oldImage->image.depth() >> 3; - - QRegion staticRegion(staticContents()); - // Make sure we're inside the boundaries of the old image. - staticRegion &= QRect(0, 0, oldImage->image.width(), oldImage->image.height()); - const QVector<QRect> &rects = staticRegion.rects(); - const QRect *srcRect = rects.constData(); - - // Copy the static content of the old image into the new one. - int numRectsLeft = rects.size(); - do { - const int bytesOffset = srcRect->x() * bytesPerPixel; - const int dy = srcRect->y(); - - // Adjust src and dst to point to the right offset. - const uchar *s = src + dy * srcBytesPerLine + bytesOffset; - uchar *d = dst + dy * dstBytesPerLine + bytesOffset; - const int numBytes = srcRect->width() * bytesPerPixel; - - int numScanLinesLeft = srcRect->height(); - do { - ::memcpy(d, s, numBytes); - d += dstBytesPerLine; - s += srcBytesPerLine; - } while (--numScanLinesLeft); - - ++srcRect; - } while (--numRectsLeft); - } - - delete oldImage; -} - -CGContextRef QUnifiedToolbarSurface::imageContext() -{ - Q_D(QUnifiedToolbarSurface); - return d->image->cg; -} - -void QUnifiedToolbarSurface::renderToolbar(QWidget *widget, bool forceFlush) -{ - QWidget *toolbar = widget->d_func()->toolbar_ancestor; - - updateToolbarOffset(toolbar); - QRect beginPaintRect(toolbar->d_func()->toolbar_offset.x(), toolbar->d_func()->toolbar_offset.y(), toolbar->geometry().width(), toolbar->geometry().height()); - QRegion beginPaintRegion(beginPaintRect); - - beginPaint(beginPaintRegion); - toolbar->render(paintDevice(), toolbar->d_func()->toolbar_offset, QRegion(toolbar->geometry()), QWidget::DrawChildren); - toolbar->d_func()->flushRequested = true; - - if (forceFlush) - flush(toolbar); -} - -QT_END_NAMESPACE - -#endif // QT_MAC_USE_COCOA diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h deleted file mode 100644 index 2a9cedad72..0000000000 --- a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QUNIFIEDTOOLBARSURFACE_MAC_P_H -#define QUNIFIEDTOOLBARSURFACE_MAC_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qwindowsurface_raster_p.h> -#include <QWidget> -#include <QToolBar> -#include <private/qwidget_p.h> -#include <private/qnativeimage_p.h> - -#ifdef QT_MAC_USE_COCOA - -QT_BEGIN_NAMESPACE - -class QNativeImage; - -// -// This is the implementation of the unified toolbar on Mac OS X -// with the graphics system raster. -// -// General idea: -// ------------- -// We redirect the painting of widgets inside the unified toolbar -// to a special window surface, the QUnifiedToolbarSurface. -// We need a separate window surface because the unified toolbar -// is out of the content view. -// The input system is the same as for the unified toolbar with the -// native (CoreGraphics) engine. -// -// Execution flow: -// --------------- -// The unified toolbar is triggered by QMainWindow::setUnifiedTitleAndToolBarOnMac(). -// It calls QMainWindowLayout::insertIntoMacToolbar() which will -// set all the appropriate variables (offsets, redirection, ...). -// When Qt tells a widget to repaint, QWidgetPrivate::drawWidget() -// checks if the widget is inside the unified toolbar and exits without -// painting is that is the case. -// We trigger the rendering of the unified toolbar in QWidget::repaint() -// and QWidget::update(). -// We keep track of flush requests via "flushRequested" variable. That -// allow flush() to be a no-op if no repaint occured for a widget. -// We rely on the needsDisplay: and drawRect: mecanism for drawing our -// content into the graphics context. -// -// Notes: -// ------ -// The painting of items inside the unified toolbar is expensive. -// Too many repaints will drastically slow down the whole application. -// - -class QUnifiedToolbarSurfacePrivate -{ -public: - QNativeImage *image; - uint inSetGeometry : 1; -}; - -class Q_GUI_EXPORT QUnifiedToolbarSurface : public QRasterWindowSurface -{ -public: - QUnifiedToolbarSurface(QWidget *widget); - ~QUnifiedToolbarSurface(); - - void flush(QWidget *widget); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - void setGeometry(const QRect &rect); - void beginPaint(const QRegion &rgn); - void insertToolbar(QWidget *toolbar, const QPoint &offset); - void removeToolbar(QToolBar *toolbar); - void updateToolbarOffset(QWidget *widget); - void renderToolbar(QWidget *widget, bool forceFlush = false); - void recursiveRedirect(QObject *widget, QWidget *parent_toolbar, const QPoint &offset); - - QPaintDevice *paintDevice(); - CGContextRef imageContext(); - -private: - void prepareBuffer(QImage::Format format, QWidget *widget); - void recursiveRemoval(QObject *object); - - Q_DECLARE_PRIVATE(QUnifiedToolbarSurface) - QScopedPointer<QUnifiedToolbarSurfacePrivate> d_ptr; -}; - -QT_END_NAMESPACE - -#endif // QT_MAC_USE_COCOA - -#endif // QUNIFIEDTOOLBARSURFACE_MAC_P_H diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp deleted file mode 100644 index fa3c6837b9..0000000000 --- a/src/gui/painting/qwindowsurface.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qwindowsurface_p.h> -#include <qwidget.h> -#include <private/qwidget_p.h> -#include <private/qbackingstore_p.h> -#include <private/qapplication_p.h> - -QT_BEGIN_NAMESPACE - -class QWindowSurfacePrivate -{ -public: - QWindowSurfacePrivate(QWidget *w) - : window(w) - { - } - - QWidget *window; -#if !defined(Q_WS_QPA) - QRect geometry; -#else - QSize size; -#endif //Q_WS_QPA - QRegion staticContents; - QList<QImage*> bufferImages; -}; - -/*! - \class QWindowSurface - \since 4.3 - \internal - \preliminary - \ingroup qws qpa - - \brief The QWindowSurface class provides the drawing area for top-level - windows. -*/ - - -/*! - \fn void QWindowSurface::beginPaint(const QRegion ®ion) - - This function is called before painting onto the surface begins, - with the \a region in which the painting will occur. - - \sa endPaint(), paintDevice() -*/ - -/*! - \fn void QWindowSurface::endPaint(const QRegion ®ion) - - This function is called after painting onto the surface has ended, - with the \a region in which the painting was performed. - - \sa beginPaint(), paintDevice() -*/ - -/*! - \fn void QWindowSurface::flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset) - - Flushes the given \a region from the specified \a widget onto the - screen. - - Note that the \a offset parameter is currently unused. -*/ - -/*! - \fn QPaintDevice* QWindowSurface::paintDevice() - - Implement this function to return the appropriate paint device. -*/ - -/*! - Constructs an empty surface for the given top-level \a window. -*/ -QWindowSurface::QWindowSurface(QWidget *window, bool setDefaultSurface) - : d_ptr(new QWindowSurfacePrivate(window)) -{ - if (!QApplicationPrivate::runtime_graphics_system) { - if(setDefaultSurface && window) - window->setWindowSurface(this); - } -} - -/*! - Destroys this surface. -*/ -QWindowSurface::~QWindowSurface() -{ - if (d_ptr->window) - d_ptr->window->d_func()->extra->topextra->windowSurface = 0; - delete d_ptr; -} - -/*! - Returns a pointer to the top-level window associated with this - surface. -*/ -QWidget* QWindowSurface::window() const -{ - return d_ptr->window; -} - -void QWindowSurface::beginPaint(const QRegion &) -{ -} - -void QWindowSurface::endPaint(const QRegion &) -{ -// QApplication::syncX(); - qDeleteAll(d_ptr->bufferImages); - d_ptr->bufferImages.clear(); -} - -#if !defined(Q_WS_QPA) -/*! - Sets the currently allocated area to be the given \a rect. - - This function is called whenever area covered by the top-level - window changes. - - \sa geometry() -*/ -void QWindowSurface::setGeometry(const QRect &rect) -{ - d_ptr->geometry = rect; -} - -/*! - Returns the currently allocated area on the screen. -*/ -QRect QWindowSurface::geometry() const -{ - return d_ptr->geometry; -} -#else - -/*! - Sets the size of the windowsurface to be \a size. - - \sa size() -*/ -void QWindowSurface::resize(const QSize &size) -{ - d_ptr->size = size; -} - -/*! - Returns the current size of the windowsurface. -*/ -QSize QWindowSurface::size() const -{ - return d_ptr->size; -} -#endif //Q_WS_QPA - -/*! - Scrolls the given \a area \a dx pixels to the right and \a dy - downward; both \a dx and \a dy may be negative. - - Returns true if the area was scrolled successfully; false otherwise. -*/ -bool QWindowSurface::scroll(const QRegion &area, int dx, int dy) -{ - Q_UNUSED(area); - Q_UNUSED(dx); - Q_UNUSED(dy); - - return false; -} - -/*! - Returns a QImage pointer which represents the actual buffer the \a widget - is drawn into or 0 if this is unavailable. - - You must call beginPaint() before you call this function and the returned - pointer is only valid until endPaint() is called. -*/ -QImage* QWindowSurface::buffer(const QWidget *widget) -{ - if (widget->window() != window()) - return 0; - - QPaintDevice *pdev = paintDevice(); - if (!pdev || pdev->devType() != QInternal::Image) - return 0; - - const QPoint off = offset(widget); - QImage *img = static_cast<QImage*>(pdev); - - QRect rect(off, widget->size()); - rect &= QRect(QPoint(), img->size()); - - if (rect.isEmpty()) - return 0; - - img = new QImage(img->scanLine(rect.y()) + rect.x() * img->depth() / 8, - rect.width(), rect.height(), - img->bytesPerLine(), img->format()); - d_ptr->bufferImages.append(img); - - return img; -} - -/*! - Returns a QPixmap generated from the part of the backing store - corresponding to \a widget. Returns a null QPixmap if an error - occurs. The contents of the pixmap are only defined for the regions - of \a widget that have received paint events since the last resize - of the backing store. - - If \a rectangle is a null rectangle (the default), the entire widget - is grabbed. Otherwise, the grabbed area is limited to \a rectangle. - - The default implementation uses QWindowSurface::buffer(). - - \sa QPixmap::grabWidget() -*/ -QPixmap QWindowSurface::grabWidget(const QWidget *widget, const QRect &rectangle) const -{ - QPixmap result; - - if (widget->window() != window()) - return result; - - const QImage *img = const_cast<QWindowSurface *>(this)->buffer(widget->window()); - - if (!img || img->isNull()) - return result; - - QRect rect = rectangle.isEmpty() ? widget->rect() : (widget->rect() & rectangle); - - rect.translate(offset(widget) - offset(widget->window())); - rect &= QRect(QPoint(), img->size()); - - if (rect.isEmpty()) - return result; - - QImage subimg(img->scanLine(rect.y()) + rect.x() * img->depth() / 8, - rect.width(), rect.height(), - img->bytesPerLine(), img->format()); - subimg.detach(); //### expensive -- maybe we should have a real SubImage that shares reference count - - result = QPixmap::fromImage(subimg); - return result; -} - -/*! - Returns the offset of \a widget in the coordinates of this - window surface. - */ -QPoint QWindowSurface::offset(const QWidget *widget) const -{ - QWidget *window = d_ptr->window; - QPoint offset = widget->mapTo(window, QPoint()); -#ifdef Q_WS_QWS - offset += window->geometry().topLeft() - window->frameGeometry().topLeft(); -#endif - return offset; -} - -/*! - \fn QRect QWindowSurface::rect(const QWidget *widget) const - - Returns the rectangle for \a widget in the coordinates of this - window surface. -*/ - -void QWindowSurface::setStaticContents(const QRegion ®ion) -{ - d_ptr->staticContents = region; -} - -QRegion QWindowSurface::staticContents() const -{ - return d_ptr->staticContents; -} - -bool QWindowSurface::hasStaticContents() const -{ - return hasFeature(QWindowSurface::StaticContents) && !d_ptr->staticContents.isEmpty(); -} - -QWindowSurface::WindowSurfaceFeatures QWindowSurface::features() const -{ - return PartialUpdates | PreservedContents; -} - -#ifdef Q_WS_QPA -#define Q_EXPORT_SCROLLRECT Q_GUI_EXPORT -#else -#define Q_EXPORT_SCROLLRECT -#endif - -void Q_EXPORT_SCROLLRECT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset) -{ - // make sure we don't detach - uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits()); - - int lineskip = img.bytesPerLine(); - int depth = img.depth() >> 3; - - const QRect imageRect(0, 0, img.width(), img.height()); - const QRect r = rect & imageRect & imageRect.translated(-offset); - const QPoint p = rect.topLeft() + offset; - - if (r.isEmpty()) - return; - - const uchar *src; - uchar *dest; - - if (r.top() < p.y()) { - src = mem + r.bottom() * lineskip + r.left() * depth; - dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth; - lineskip = -lineskip; - } else { - src = mem + r.top() * lineskip + r.left() * depth; - dest = mem + p.y() * lineskip + p.x() * depth; - } - - const int w = r.width(); - int h = r.height(); - const int bytes = w * depth; - - // overlapping segments? - if (offset.y() == 0 && qAbs(offset.x()) < w) { - do { - ::memmove(dest, src, bytes); - dest += lineskip; - src += lineskip; - } while (--h); - } else { - do { - ::memcpy(dest, src, bytes); - dest += lineskip; - src += lineskip; - } while (--h); - } -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qwindowsurface_mac.cpp b/src/gui/painting/qwindowsurface_mac.cpp deleted file mode 100644 index ed794ae466..0000000000 --- a/src/gui/painting/qwindowsurface_mac.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwindowsurface_mac_p.h" - -#include <private/qt_mac_p.h> -#include <private/qt_cocoa_helpers_mac_p.h> -#include <QtGui/qwidget.h> - -QT_BEGIN_NAMESPACE - -struct QMacWindowSurfacePrivate -{ - QWidget *widget; - QPixmap device; -}; - -QMacWindowSurface::QMacWindowSurface(QWidget *widget) - : QWindowSurface(widget), d_ptr(new QMacWindowSurfacePrivate) -{ - d_ptr->widget = widget; -} - -QMacWindowSurface::~QMacWindowSurface() -{ - delete d_ptr; -} - -QPaintDevice *QMacWindowSurface::paintDevice() -{ - return &d_ptr->device; -} - -void QMacWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) -{ - Q_UNUSED(offset); - - // Get a context for the widget. -#ifndef QT_MAC_USE_COCOA - CGContextRef context; - CGrafPtr port = GetWindowPort(qt_mac_window_for(widget)); - QDBeginCGContext(port, &context); -#else - extern CGContextRef qt_mac_graphicsContextFor(QWidget *); - CGContextRef context = qt_mac_graphicsContextFor(widget); -#endif - CGContextRetain(context); - CGContextSaveGState(context); - - // Flip context. - CGContextTranslateCTM(context, 0, widget->height()); - CGContextScaleCTM(context, 1, -1); - - // Clip to region. - const QVector<QRect> &rects = rgn.rects(); - for (int i = 0; i < rects.size(); ++i) { - const QRect &rect = rects.at(i); - CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); - } - CGContextClip(context); - - // Draw the image onto the window. - const CGRect dest = CGRectMake(0, 0, widget->width(), widget->height()); - const CGImageRef image = d_ptr->device.toMacCGImageRef(); - qt_mac_drawCGImage(context, &dest, image); - CFRelease(image); - - // Restore context. - CGContextRestoreGState(context); -#ifndef QT_MAC_USE_COCOA - QDEndCGContext(port, &context); -#else - CGContextFlush(context); -#endif - CGContextRelease(context); -} - -void QMacWindowSurface::setGeometry(const QRect &rect) -{ - QWindowSurface::setGeometry(rect); - const QSize size = rect.size(); - if (d_ptr->device.size() != size) - d_ptr->device = QPixmap(size); -} - -bool QMacWindowSurface::scroll(const QRegion &area, int dx, int dy) -{ - if (d_ptr->device.size().isNull()) - return false; - - QCFType<CGImageRef> image = d_ptr->device.toMacCGImageRef(); - const QRect rect(area.boundingRect()); - const CGRect dest = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); - QCFType<CGImageRef> subimage = CGImageCreateWithImageInRect(image, dest); - QCFType<CGContextRef> context = qt_mac_cg_context(&d_ptr->device); - CGContextTranslateCTM(context, dx, dy); - qt_mac_drawCGImage(context, &dest, subimage); - return true; -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h deleted file mode 100644 index 1e6529c788..0000000000 --- a/src/gui/painting/qwindowsurface_p.h +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINDOWSURFACE_P_H -#define QWINDOWSURFACE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/qwidget.h> - -QT_BEGIN_NAMESPACE - -class QPaintDevice; -class QRegion; -class QRect; -class QPoint; -class QImage; -class QWindowSurfacePrivate; -class QPlatformWindow; - -class Q_GUI_EXPORT QWindowSurface -{ -public: - enum WindowSurfaceFeature { - PartialUpdates = 0x00000001, // Supports doing partial updates. - PreservedContents = 0x00000002, // Supports doing flush without first doing a repaint. - StaticContents = 0x00000004, // Supports having static content regions when being resized. - AllFeatures = 0xffffffff // For convenience - }; - Q_DECLARE_FLAGS(WindowSurfaceFeatures, WindowSurfaceFeature) - - QWindowSurface(QWidget *window, bool setDefaultSurface = true); - virtual ~QWindowSurface(); - - QWidget *window() const; - - virtual QPaintDevice *paintDevice() = 0; - - // 'widget' can be a child widget, in which case 'region' is in child widget coordinates and - // offset is the (child) widget's offset in relation to the window surface. On QWS, 'offset' - // can be larger than just the offset from the top-level widget as there may also be window - // decorations which are painted into the window surface. - virtual void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) = 0; -#if !defined(Q_WS_QPA) - virtual void setGeometry(const QRect &rect); - QRect geometry() const; -#else - virtual void resize(const QSize &size); - QSize size() const; - inline QRect geometry() const { return QRect(QPoint(), size()); } //### cleanup before Qt 5 -#endif - - virtual bool scroll(const QRegion &area, int dx, int dy); - - virtual void beginPaint(const QRegion &); - virtual void endPaint(const QRegion &); - - virtual QImage* buffer(const QWidget *widget); - virtual QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const; - - virtual QPoint offset(const QWidget *widget) const; - inline QRect rect(const QWidget *widget) const; - - bool hasFeature(WindowSurfaceFeature feature) const; - virtual WindowSurfaceFeatures features() const; - - void setStaticContents(const QRegion ®ion); - QRegion staticContents() const; - -protected: - bool hasStaticContents() const; - -private: - QWindowSurfacePrivate *d_ptr; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowSurface::WindowSurfaceFeatures) - -inline QRect QWindowSurface::rect(const QWidget *widget) const -{ - return widget->rect().translated(offset(widget)); -} - -inline bool QWindowSurface::hasFeature(WindowSurfaceFeature feature) const -{ - return (features() & feature) != 0; -} - -QT_END_NAMESPACE - -#endif // QWINDOWSURFACE_P_H diff --git a/src/gui/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp deleted file mode 100644 index c52f864b25..0000000000 --- a/src/gui/painting/qwindowsurface_qws.cpp +++ /dev/null @@ -1,1433 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwindowsurface_qws_p.h" -#include <qwidget.h> -#include <qscreen_qws.h> -#include <qwsmanager_qws.h> -#include <qapplication.h> -#include <qwsdisplay_qws.h> -#include <qrgb.h> -#include <qpaintengine.h> -#include <qdesktopwidget.h> -#include <private/qapplication_p.h> -#include <private/qwsdisplay_qws_p.h> -#include <private/qwidget_p.h> -#include <private/qwsmanager_p.h> -#include <private/qwslock_p.h> -#include <private/qbackingstore_p.h> -#include <stdio.h> - -QT_BEGIN_NAMESPACE - -#ifdef Q_BACKINGSTORE_SUBSURFACES - -typedef QMap<int, QWSWindowSurface*> SurfaceMap; -Q_GLOBAL_STATIC(SurfaceMap, winIdToSurfaceMap); - -QWSWindowSurface* qt_findWindowSurface(int winId) -{ - return winIdToSurfaceMap()->value(winId); -} - -static void qt_insertWindowSurface(int winId, QWSWindowSurface *surface) -{ - if (!surface) - winIdToSurfaceMap()->remove(winId); - else - winIdToSurfaceMap()->insert(winId, surface); -} - -#endif // Q_BACKINGSTORE_SUBSURFACES - -inline bool isWidgetOpaque(const QWidget *w) -{ - return w->d_func()->isOpaque && !w->testAttribute(Qt::WA_TranslucentBackground); -} - -static inline QScreen *getScreen(const QWidget *w) -{ - const QList<QScreen*> subScreens = qt_screen->subScreens(); - if (subScreens.isEmpty()) - return qt_screen; - - const int screen = QApplication::desktop()->screenNumber(w); - - return qt_screen->subScreens().at(screen < 0 ? 0 : screen); -} - -static int bytesPerPixel(QImage::Format format) -{ - switch (format) { - case QImage::Format_Invalid: - return 0; -#ifndef QT_NO_DEBUG - case QImage::Format_Mono: - case QImage::Format_MonoLSB: - qFatal("QWSWindowSurface: Invalid backingstore format: %i", - int(format)); -#endif - case QImage::Format_Indexed8: - return 1; - case QImage::Format_RGB32: - case QImage::Format_ARGB32: - case QImage::Format_ARGB32_Premultiplied: - return 4; - case QImage::Format_RGB16: - case QImage::Format_RGB555: - case QImage::Format_RGB444: - case QImage::Format_ARGB4444_Premultiplied: - return 2; - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_ARGB6666_Premultiplied: - case QImage::Format_RGB666: - case QImage::Format_RGB888: - return 3; - default: -#ifndef QT_NO_DEBUG - qFatal("QWSWindowSurface: Invalid backingstore format: %i", - int(format)); -#endif - return 0; - } -} - -static inline int nextMulOf4(int n) -{ - return ((n + 3) & 0xfffffffc); -} - -static inline void setImageMetrics(QImage &img, QWidget *window) { - QScreen *myScreen = getScreen(window); - if (myScreen) { - int dpmx = myScreen->width()*1000 / myScreen->physicalWidth(); - int dpmy = myScreen->height()*1000 / myScreen->physicalHeight(); - img.setDotsPerMeterX(dpmx); - img.setDotsPerMeterY(dpmy); - } -} - -void QWSWindowSurface::invalidateBuffer() -{ - - QWidget *win = window(); - if (win) { - win->d_func()->invalidateBuffer(win->rect()); -#ifndef QT_NO_QWS_MANAGER - QTLWExtra *topextra = win->d_func()->extra->topextra; - QWSManager *manager = topextra->qwsManager; - if (manager) - manager->d_func()->dirtyRegion(QDecoration::All, - QDecoration::Normal); -#endif - } -} - -QWSWindowSurfacePrivate::QWSWindowSurfacePrivate() - : flags(0), -#ifdef QT_QWS_CLIENTBLIT - directId(-1), -#endif - winId(0) -{ -} - -void QWSWindowSurfacePrivate::setWinId(int id) -{ - winId = id; -} - -int QWSWindowSurface::winId() const -{ - // XXX: the widget winId may change during the lifetime of the widget!!! - - const QWidget *win = window(); - if (win && win->isWindow()) - return win->internalWinId(); - -#ifdef Q_BACKINGSTORE_SUBSURFACES - if (!d_ptr->winId) { - QWSWindowSurface *that = const_cast<QWSWindowSurface*>(this); - QWSDisplay *display = QWSDisplay::instance(); - const int id = display->takeId(); - qt_insertWindowSurface(id, that); - that->d_ptr->winId = id; - - if (win) - display->nameRegion(id, win->objectName(), win->windowTitle()); - else - display->nameRegion(id, QString(), QString()); - - display->setAltitude(id, 1, true); // XXX - } -#endif - - return d_ptr->winId; -} - -void QWSWindowSurface::setWinId(int id) -{ - d_ptr->winId = id; -} - -/*! - \class QWSWindowSurface - \since 4.2 - \ingroup qws - \preliminary - \internal - - \brief The QWSWindowSurface class provides the drawing area for top-level - windows in Qt for Embedded Linux. - - Note that this class is only available in Qt for Embedded Linux. - - In \l{Qt for Embedded Linux}, the default behavior is for each client to - render its widgets into memory while the server is responsible for - putting the contents of the memory onto the - screen. QWSWindowSurface is used by the window system to implement - the associated memory allocation. - - When a screen update is required, the server runs through all the - top-level windows that intersect with the region that is about to - be updated, and ensures that the associated clients have updated - their memory buffer. Then the server uses the screen driver to - copy the content of the memory to the screen. To locate the - relevant parts of memory, the driver is provided with the list of - top-level windows that intersect with the given region. Associated - with each of the top-level windows there is a window surface - representing the drawing area of the window. - - When deriving from the QWSWindowSurface class, e.g., when adding - an \l {Adding an Accelerated Graphics Driver to Qt for Embedded Linux} - {accelerated graphics driver}, there are several pure virtual - functions that must be implemented. In addition, QWSWindowSurface - provides several virtual functions that can be reimplemented to - customize the drawing process. - - \tableofcontents - - \section1 Pure Virtual Functions - - There are in fact two window surface instances for each top-level - window; one used by the application when drawing a window, and - another used by the server application to perform window - compositioning. Implement the attach() to create the server-side - representation of the surface. The data() function must be - implemented to provide the required data. - - Implement the key() function to uniquely identify the surface - class, and the isValid() function to determine is a surface - corresponds to a given widget. - - The geometry() function must be implemented to let the window - system determine the area required by the window surface - (QWSWindowSurface also provides a corresponding virtual - setGeometry() function that is called whenever the area necessary - for the top-level window to be drawn, changes). The image() - function is called by the window system during window - compositioning, and must be implemented to return an image of the - top-level window. - - Finally, the paintDevice() function must be implemented to return - the appropriate paint device, and the scroll() function must be - implemented to scroll the given region of the surface the given - number of pixels. - - \section1 Virtual Functions - - When painting onto the surface, the window system will always call - the beginPaint() function before any painting operations are - performed. Likewise the endPaint() function is automatically - called when the painting is done. Reimplement the painterOffset() - function to alter the offset that is applied when drawing. - - The window system uses the flush() function to put a given region - of the widget onto the screen, and the release() function to - deallocate the screen region corresponding to this window surface. - - \section1 Other Members - - QWSWindowSurface provides the window() function returning a - pointer to the top-level window the surface is representing. The - currently visible region of the associated widget can be retrieved - and set using the clipRegion() and setClipRegion() functions, - respectively. - - When the window system performs the window compositioning, it uses - the SurfaceFlag enum describing the surface content. The currently - set surface flags can be retrieved and altered using the - surfaceFlags() and setSurfaceFlags() functions. In addition, - QWSWindowSurface provides the isBuffered(), isOpaque() and - isRegionReserved() convenience functions. - - \sa {Qt for Embedded Linux Architecture#Drawing on Screen}{Qt for - Embedded Linux Architecture} -*/ - -/*! - \enum QWSWindowSurface::SurfaceFlag - - This enum is used to describe the window surface's contents. It - is used by the screen driver to handle region allocation and - composition. - - \value RegionReserved The surface contains a reserved area. Once - allocated, a reserved area can not not be changed by the window - system, i.e., no other widgets can be drawn on top of this. - - \value Buffered - The surface is in a memory area which is not part of a framebuffer. - (A top-level window with QWidget::windowOpacity() other than 1.0 must use - a buffered surface in order to making blending with the background work.) - - \value Opaque - The surface contains only opaque pixels. - - \sa surfaceFlags(), setSurfaceFlags() -*/ - -/*! - \fn bool QWSWindowSurface::isValid() const - \since 4.3 - - Implement this function to return true if the surface is a valid - surface for the given top-level \a window; otherwise return - false. - - \sa window(), key() -*/ - -/*! - \fn QString QWSWindowSurface::key() const - - Implement this function to return a string that uniquely - identifies the class of this surface. - - \sa window(), isValid() -*/ - -/*! - \fn QByteArray QWSWindowSurface::permanentState() const - \since 4.3 - - Implement this function to return the data required for creating a - server-side representation of the surface. - - \sa attach() -*/ - -/*! - \fn void QWSWindowSurface::setPermanentState(const QByteArray &data) - \since 4.3 - - Implement this function to attach a server-side surface instance - to the corresponding client side instance using the given \a - data. Return true if successful; otherwise return false. - - \sa data() -*/ - -/*! - \fn const QImage QWSWindowSurface::image() const - - Implement this function to return an image of the top-level window. - - \sa geometry() -*/ - -/*! - \fn bool QWSWindowSurface::isRegionReserved() const - - Returns true if the QWSWindowSurface::RegionReserved is set; otherwise - returns false. - - \sa surfaceFlags() -*/ - -/*! - \fn bool QWSWindowSurface::isBuffered() const - - Returns true if the QWSWindowSurface::Buffered is set; otherwise returns false. - - \sa surfaceFlags() -*/ - -/*! - \fn bool QWSWindowSurface::isOpaque() const - - Returns true if the QWSWindowSurface::Opaque is set; otherwise - returns false. - - \sa surfaceFlags() -*/ - - -/*! - Constructs an empty surface. -*/ -QWSWindowSurface::QWSWindowSurface() - : QWindowSurface(0), d_ptr(new QWSWindowSurfacePrivate) -{ -} - -/*! - Constructs an empty surface for the given top-level \a widget. -*/ -QWSWindowSurface::QWSWindowSurface(QWidget *widget) - : QWindowSurface(widget), d_ptr(new QWSWindowSurfacePrivate) -{ -} - -QWSWindowSurface::~QWSWindowSurface() -{ -#ifdef Q_BACKINGSTORE_SUBSURFACES - if (d_ptr->winId) - winIdToSurfaceMap()->remove(d_ptr->winId); -#endif - - delete d_ptr; -} - -/*! - Returns the offset to be used when painting. - - \sa paintDevice() -*/ -QPoint QWSWindowSurface::painterOffset() const -{ - const QWidget *w = window(); - if (!w) - return QPoint(); - return w->geometry().topLeft() - w->frameGeometry().topLeft(); -} - -void QWSWindowSurface::beginPaint(const QRegion &) -{ - lock(); -} - -void QWSWindowSurface::endPaint(const QRegion &) -{ - unlock(); -} - -// XXX: documentation!!! -QByteArray QWSWindowSurface::transientState() const -{ - return QByteArray(); -} - -QByteArray QWSWindowSurface::permanentState() const -{ - return QByteArray(); -} - -void QWSWindowSurface::setTransientState(const QByteArray &state) -{ - Q_UNUSED(state); -} - -void QWSWindowSurface::setPermanentState(const QByteArray &state) -{ - Q_UNUSED(state); -} - -bool QWSWindowSurface::lock(int timeout) -{ - Q_UNUSED(timeout); - return true; -} - -void QWSWindowSurface::unlock() -{ -} - -#ifdef QT_QWS_CLIENTBLIT -/*! \internal */ -const QRegion QWSWindowSurface::directRegion() const -{ - return d_ptr->direct; -} - -/*! \internal */ -int QWSWindowSurface::directRegionId() const -{ - return d_ptr->directId; -} - -/*! \internal */ -void QWSWindowSurface::setDirectRegion(const QRegion &r, int id) -{ - d_ptr->direct = r; - d_ptr->directId = id; -} -#endif - -/*! - Returns the region currently visible on the screen. - - \sa setClipRegion() -*/ -const QRegion QWSWindowSurface::clipRegion() const -{ - return d_ptr->clip; -} - -/*! - Sets the region currently visible on the screen to be the given \a - clip region. - - \sa clipRegion() -*/ -void QWSWindowSurface::setClipRegion(const QRegion &clip) -{ - if (clip == d_ptr->clip) - return; - - QRegion expose = (clip - d_ptr->clip); - d_ptr->clip = clip; - - if (expose.isEmpty() || clip.isEmpty()) - return; // No repaint or flush required. - - QWidget *win = window(); - if (!win) - return; - - if (isBuffered()) { - // No repaint required. Flush exposed area via the backing store. - win->d_func()->syncBackingStore(expose); - return; - } - -#ifndef QT_NO_QWS_MANAGER - // Invalidate exposed decoration area. - if (win && win->isWindow()) { - QTLWExtra *topextra = win->d_func()->extra->topextra; - if (QWSManager *manager = topextra->qwsManager) { - QRegion decorationExpose(manager->region()); - decorationExpose.translate(-win->geometry().topLeft()); - decorationExpose &= expose; - if (!decorationExpose.isEmpty()) { - expose -= decorationExpose; - manager->d_func()->dirtyRegion(QDecoration::All, QDecoration::Normal, decorationExpose); - } - } - } -#endif - - // Invalidate exposed widget area. - win->d_func()->invalidateBuffer(expose); -} - -/*! - Returns the surface flags describing the contents of this surface. - - \sa isBuffered(), isOpaque(), isRegionReserved() -*/ -QWSWindowSurface::SurfaceFlags QWSWindowSurface::surfaceFlags() const -{ - return d_ptr->flags; -} - -/*! - Sets the surface flags describing the contents of this surface, to - be the given \a flags. - - \sa surfaceFlags() -*/ -void QWSWindowSurface::setSurfaceFlags(SurfaceFlags flags) -{ - d_ptr->flags = flags; -} - -void QWSWindowSurface::setGeometry(const QRect &rect) -{ - QRegion mask = rect; - - const QWidget *win = window(); - if (win) { -#ifndef QT_NO_QWS_MANAGER - if (win->isWindow()) { - QTLWExtra *topextra = win->d_func()->extra->topextra; - QWSManager *manager = topextra->qwsManager; - - if (manager) { - // The frame geometry is the bounding rect of manager->region, - // which could be too much, so we need to clip. - mask &= (manager->region() + win->geometry()); - } - } -#endif - - const QRegion winMask = win->mask(); - if (!winMask.isEmpty()) - mask &= winMask.translated(win->geometry().topLeft()); - } - - setGeometry(rect, mask); -} - -void QWSWindowSurface::setGeometry(const QRect &rect, const QRegion &mask) -{ - if (rect == geometry()) // XXX: && mask == prevMask - return; - - const bool isResize = rect.size() != geometry().size(); - const bool needsRepaint = isResize || !isBuffered(); - - QWindowSurface::setGeometry(rect); - - const QRegion region = mask & rect; - QWidget *win = window(); - // Only request regions for widgets visible on the screen. - // (Added the !win check for compatibility reasons, because - // there was no "if (win)" check before). - const bool requestQWSRegion = !win || !win->testAttribute(Qt::WA_DontShowOnScreen); - if (requestQWSRegion) - QWidget::qwsDisplay()->requestRegion(winId(), key(), permanentState(), region); - - if (needsRepaint) - invalidateBuffer(); - - if (!requestQWSRegion) { - // We didn't request a region, hence we won't get a QWSRegionEvent::Allocation - // event back from the server so we set the clip directly. We have to - // do this after the invalidateBuffer() call above, as it might trigger a - // backing store sync, resulting in too many update requests. - setClipRegion(region); - } -} - -static inline void flushUpdate(QWidget *widget, const QRegion ®ion, - const QPoint &offset) -{ -#ifdef QT_NO_PAINT_DEBUG - Q_UNUSED(widget); - Q_UNUSED(region); - Q_UNUSED(offset); -#else - static int delay = -1; - - if (delay == -1) - delay = qgetenv("QT_FLUSH_UPDATE").toInt() * 10; - - if (delay == 0) - return; - - static QWSYellowSurface surface(true); - surface.setDelay(delay); - surface.flush(widget, region, offset); -#endif // QT_NO_PAINT_DEBUG -} - -void QWSWindowSurface::flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset) -{ - const QWidget *win = window(); - if (!win) - return; - -#ifndef QT_NO_GRAPHICSVIEW - QWExtra *extra = win->d_func()->extra; - if (extra && extra->proxyWidget) - return; -#endif //QT_NO_GRAPHICSVIEW - - Q_UNUSED(offset); - - const bool opaque = isOpaque(); -#ifdef QT_QWS_DISABLE_FLUSHCLIPPING - QRegion toFlush = region; -#else - QRegion toFlush = region & d_ptr->clip; -#endif - - if (!toFlush.isEmpty()) { - flushUpdate(widget, toFlush, QPoint(0, 0)); - QPoint globalZero = win->mapToGlobal(QPoint(0, 0)); - toFlush.translate(globalZero); - -#ifdef QT_QWS_CLIENTBLIT - bool needRepaint = true; - if (opaque) { - QScreen* widgetScreen = getScreen(widget); - if (widgetScreen->supportsBlitInClients()) { - - QWSDisplay::grab(); - if(directRegion().intersected(toFlush) == toFlush) { - QPoint translate = -globalZero + painterOffset() + geometry().topLeft(); - QRegion flushRegion = toFlush.translated(translate); - widgetScreen->blit(image(), geometry().topLeft(), flushRegion); - widgetScreen->setDirty(toFlush.boundingRect()); - needRepaint = false; - } - QWSDisplay::ungrab(); - } - } - - if(needRepaint) -#endif - win->qwsDisplay()->repaintRegion(winId(), win->windowFlags(), opaque, toFlush); - } -} - -/*! - Move the surface with the given \a offset. - - A subclass may reimplement this function to enable accelerated window move. - It must return true if the move was successful and no repaint is necessary, - false otherwise. - - The default implementation updates the QWindowSurface geometry and - returns true if the surface is buffered; false otherwise. - - This function is called by the window system on the client instance. - - \sa isBuffered() -*/ -bool QWSWindowSurface::move(const QPoint &offset) -{ - QWindowSurface::setGeometry(geometry().translated(offset)); - return isBuffered(); -} - -/*! - Move the surface with the given \a offset. - - The new visible region after the window move is given by \a newClip - in screen coordinates. - - A subclass may reimplement this function to enable accelerated window move. - The returned region indicates the area that still needs to be composed - on the screen. - - The default implementation updates the QWindowSurface geometry and - returns the union of the old and new geometry. - - This function is called by the window system on the server instance. -*/ -QRegion QWSWindowSurface::move(const QPoint &offset, const QRegion &newClip) -{ - const QRegion oldGeometry = geometry(); - QWindowSurface::setGeometry(geometry().translated(offset)); - return oldGeometry + newClip; -} - -void QWSWindowSurface::releaseSurface() -{ -} - -bool QWSMemorySurface::lock(int timeout) -{ - Q_UNUSED(timeout); -#ifndef QT_NO_QWS_MULTIPROCESS - if (memlock && !memlock->lock(QWSLock::BackingStore)) - return false; -#endif -#ifndef QT_NO_THREAD - threadLock.lock(); -#endif - return true; -} - -void QWSMemorySurface::unlock() -{ -#ifndef QT_NO_THREAD - threadLock.unlock(); -#endif -#ifndef QT_NO_QWS_MULTIPROCESS - if (memlock) - memlock->unlock(QWSLock::BackingStore); -#endif -} - -QWSMemorySurface::QWSMemorySurface() - : QWSWindowSurface() -#ifndef QT_NO_QWS_MULTIPROCESS - , memlock(0) -#endif -{ - setSurfaceFlags(Buffered); -} - -QWSMemorySurface::QWSMemorySurface(QWidget *w) - : QWSWindowSurface(w) -{ - SurfaceFlags flags = Buffered; - if (isWidgetOpaque(w)) - flags |= Opaque; - setSurfaceFlags(flags); - -#ifndef QT_NO_QWS_MULTIPROCESS - memlock = QWSDisplay::Data::getClientLock(); -#endif -} - -QWSMemorySurface::~QWSMemorySurface() -{ -} - - -QImage::Format -QWSMemorySurface::preferredImageFormat(const QWidget *widget) const -{ - QScreen *screen = getScreen(widget); - const int depth = screen->depth(); - const bool opaque = isWidgetOpaque(widget); - - if (!opaque) { - if (depth <= 12) - return QImage::Format_ARGB4444_Premultiplied; - else if (depth <= 15) - return QImage::Format_ARGB8555_Premultiplied; - else if (depth <= 16) - return QImage::Format_ARGB8565_Premultiplied; - else if (depth <= 18) - return QImage::Format_ARGB6666_Premultiplied; - else - return QImage::Format_ARGB32_Premultiplied; - } - - QImage::Format format = screen->pixelFormat(); - if (format > QImage::Format_Indexed8) // ### assumes all new image formats supports a QPainter - return format; - - if (depth <= 12) - return QImage::Format_RGB444; - else if (depth <= 15) - return QImage::Format_RGB555; - else if (depth <= 16) - return QImage::Format_RGB16; - else if (depth <= 18) - return QImage::Format_RGB666; - else if (depth <= 24) - return QImage::Format_RGB888; - else - return QImage::Format_ARGB32_Premultiplied; -} - -#ifndef QT_NO_QWS_MULTIPROCESS -void QWSMemorySurface::setLock(int lockId) -{ - if (memlock && memlock->id() == lockId) - return; - delete memlock; - memlock = (lockId == -1 ? 0 : new QWSLock(lockId)); - return; -} -#endif // QT_NO_QWS_MULTIPROCESS - -bool QWSMemorySurface::isValid() const -{ - if (img.isNull()) - return true; - - const QWidget *win = window(); - if (preferredImageFormat(win) != img.format()) - return false; - - if (isOpaque() != isWidgetOpaque(win)) // XXX: use QWidgetPrivate::isOpaque() - return false; - - return true; -} - -// ### copied from qwindowsurface_raster.cpp -- should be cross-platform -void QWSMemorySurface::beginPaint(const QRegion &rgn) -{ - if (!isWidgetOpaque(window())) { - QPainter p(&img); - p.setCompositionMode(QPainter::CompositionMode_Source); - const QVector<QRect> rects = rgn.rects(); - const QColor blank = Qt::transparent; - for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { - QRect r = *it; -#ifdef Q_BACKINGSTORE_SUBSURFACES - r.translate(painterOffset()); -#endif - p.fillRect(r, blank); - } - } - QWSWindowSurface::beginPaint(rgn); -} - -// from qwindowsurface.cpp -extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); - -bool QWSMemorySurface::scroll(const QRegion &area, int dx, int dy) -{ - const QVector<QRect> rects = area.rects(); - for (int i = 0; i < rects.size(); ++i) - qt_scrollRectInImage(img, rects.at(i), QPoint(dx, dy)); - - return true; -} - -QPoint QWSMemorySurface::painterOffset() const -{ - const QWidget *w = window(); - if (!w) - return QPoint(); - - if (w->mask().isEmpty()) - return QWSWindowSurface::painterOffset(); - - const QRegion region = w->mask() - & w->frameGeometry().translated(-w->geometry().topLeft()); - return -region.boundingRect().topLeft(); -} - -QWSLocalMemSurface::QWSLocalMemSurface() - : QWSMemorySurface(), mem(0), memsize(0) -{ -} - -QWSLocalMemSurface::QWSLocalMemSurface(QWidget *w) - : QWSMemorySurface(w), mem(0), memsize(0) -{ -} - -QWSLocalMemSurface::~QWSLocalMemSurface() -{ - if (memsize) - delete[] mem; -} - -void QWSLocalMemSurface::setGeometry(const QRect &rect) -{ - QSize size = rect.size(); - - QWidget *win = window(); - if (win && !win->mask().isEmpty()) { - const QRegion region = win->mask() - & rect.translated(-win->geometry().topLeft()); - size = region.boundingRect().size(); - } - - uchar *deleteLater = 0; - // In case of a Hide event we need to delete the memory after sending the - // event to the server in order to let the server animate the event. - if (size.isEmpty()) { - deleteLater = mem; - mem = 0; - } - - if (img.size() != size) { - delete[] mem; - if (size.isEmpty()) { - mem = 0; - img = QImage(); - } else { - const QImage::Format format = preferredImageFormat(win); - const int bpl = nextMulOf4(bytesPerPixel(format) * size.width()); - const int memsize = bpl * size.height(); - mem = new uchar[memsize]; - img = QImage(mem, size.width(), size.height(), bpl, format); - setImageMetrics(img, win); - } - } - - QWSWindowSurface::setGeometry(rect); - delete[] deleteLater; -} - -QByteArray QWSLocalMemSurface::permanentState() const -{ - QByteArray array; - array.resize(sizeof(uchar*) + 3 * sizeof(int) + - sizeof(SurfaceFlags)); - - char *ptr = array.data(); - - *reinterpret_cast<uchar**>(ptr) = mem; - ptr += sizeof(uchar*); - - reinterpret_cast<int*>(ptr)[0] = img.width(); - reinterpret_cast<int*>(ptr)[1] = img.height(); - ptr += 2 * sizeof(int); - - *reinterpret_cast<int *>(ptr) = img.format(); - ptr += sizeof(int); - - *reinterpret_cast<SurfaceFlags*>(ptr) = surfaceFlags(); - - return array; -} - -void QWSLocalMemSurface::setPermanentState(const QByteArray &data) -{ - int width; - int height; - QImage::Format format; - SurfaceFlags flags; - - const char *ptr = data.constData(); - - mem = *reinterpret_cast<uchar* const*>(ptr); - ptr += sizeof(uchar*); - - width = reinterpret_cast<const int*>(ptr)[0]; - height = reinterpret_cast<const int*>(ptr)[1]; - ptr += 2 * sizeof(int); - - format = QImage::Format(*reinterpret_cast<const int*>(ptr)); - ptr += sizeof(int); - - flags = *reinterpret_cast<const SurfaceFlags*>(ptr); - - const int bpl = nextMulOf4(bytesPerPixel(format) * width); - QWSMemorySurface::img = QImage(mem, width, height, bpl, format); - setSurfaceFlags(flags); -} - -void QWSLocalMemSurface::releaseSurface() -{ - mem = 0; - img = QImage(); -} - -#ifndef QT_NO_QWS_MULTIPROCESS - -QWSSharedMemSurface::QWSSharedMemSurface() - : QWSMemorySurface() -{ -} - -QWSSharedMemSurface::QWSSharedMemSurface(QWidget *widget) - : QWSMemorySurface(widget) -{ -} - -QWSSharedMemSurface::~QWSSharedMemSurface() -{ - // mem.detach() is done automatically by ~QSharedMemory -} - -bool QWSSharedMemSurface::setMemory(int memId) -{ - if (mem.id() == memId) - return true; - - mem.detach(); - if (!mem.attach(memId)) { - perror("QWSSharedMemSurface: attaching to shared memory"); - qCritical("QWSSharedMemSurface: Error attaching to" - " shared memory 0x%x", memId); - return false; - } - - return true; -} - -#ifdef QT_QWS_CLIENTBLIT -void QWSSharedMemSurface::setDirectRegion(const QRegion &r, int id) -{ - QWSMemorySurface::setDirectRegion(r, id); - if(mem.address()) - *(uint *)mem.address() = id; -} - -const QRegion QWSSharedMemSurface::directRegion() const -{ - QWSSharedMemory *cmem = const_cast<QWSSharedMemory *>(&mem); - if (cmem->address() && ((int*)cmem->address())[0] == directRegionId()) - return QWSMemorySurface::directRegion(); - else - return QRegion(); -} -#endif - -void QWSSharedMemSurface::setPermanentState(const QByteArray &data) -{ - int memId; - int width; - int height; - int lockId; - QImage::Format format; - SurfaceFlags flags; - - const int *ptr = reinterpret_cast<const int*>(data.constData()); - - memId = ptr[0]; - width = ptr[1]; - height = ptr[2]; - lockId = ptr[3]; - format = QImage::Format(ptr[4]); - flags = SurfaceFlags(ptr[5]); - - setSurfaceFlags(flags); - setMemory(memId); - setLock(lockId); - -#ifdef QT_QWS_CLIENTBLIT - uchar *base = static_cast<uchar*>(mem.address()) + sizeof(uint); -#else - uchar *base = static_cast<uchar*>(mem.address()); -#endif - const int bpl = nextMulOf4(bytesPerPixel(format) * width); - QWSMemorySurface::img = QImage(base, width, height, bpl, format); -} - -void QWSSharedMemSurface::setGeometry(const QRect &rect) -{ - const QSize size = rect.size(); - if (img.size() != size) { - if (size.isEmpty()) { - mem.detach(); - img = QImage(); - } else { - mem.detach(); - - QWidget *win = window(); - const QImage::Format format = preferredImageFormat(win); - const int bpl = nextMulOf4(bytesPerPixel(format) * size.width()); -#ifdef QT_QWS_CLIENTBLIT - const int imagesize = bpl * size.height() + sizeof(uint); -#else - const int imagesize = bpl * size.height(); -#endif - if (!mem.create(imagesize)) { - perror("QWSSharedMemSurface::setGeometry allocating shared memory"); - qFatal("Error creating shared memory of size %d", imagesize); - } -#ifdef QT_QWS_CLIENTBLIT - *((uint *)mem.address()) = 0; - uchar *base = static_cast<uchar*>(mem.address()) + sizeof(uint); -#else - uchar *base = static_cast<uchar*>(mem.address()); -#endif - img = QImage(base, size.width(), size.height(), bpl, format); - setImageMetrics(img, win); - } - } - - QWSWindowSurface::setGeometry(rect); -} - -QByteArray QWSSharedMemSurface::permanentState() const -{ - QByteArray array; - array.resize(6 * sizeof(int)); - - int *ptr = reinterpret_cast<int*>(array.data()); - - ptr[0] = mem.id(); - ptr[1] = img.width(); - ptr[2] = img.height(); - ptr[3] = (memlock ? memlock->id() : -1); - ptr[4] = int(img.format()); - ptr[5] = int(surfaceFlags()); - - return array; -} - -void QWSSharedMemSurface::releaseSurface() -{ - mem.detach(); - img = QImage(); -} - -#endif // QT_NO_QWS_MULTIPROCESS - -#ifndef QT_NO_PAINTONSCREEN - -QWSOnScreenSurface::QWSOnScreenSurface(QWidget *w) - : QWSMemorySurface(w) -{ - attachToScreen(getScreen(w)); - setSurfaceFlags(Opaque); -} - -QWSOnScreenSurface::QWSOnScreenSurface() - : QWSMemorySurface() -{ - setSurfaceFlags(Opaque); -} - -void QWSOnScreenSurface::attachToScreen(const QScreen *s) -{ - screen = s; - uchar *base = screen->base(); - QImage::Format format = screen->pixelFormat(); - - if (format == QImage::Format_Invalid || format == QImage::Format_Indexed8) { - //### currently we have no paint engine for indexed image formats - qFatal("QWSOnScreenSurface::attachToScreen(): screen depth %d " - "not implemented", screen->depth()); - return; - } - QWSMemorySurface::img = QImage(base, screen->width(), screen->height(), - screen->linestep(), format ); -} - -QWSOnScreenSurface::~QWSOnScreenSurface() -{ -} - -QPoint QWSOnScreenSurface::painterOffset() const -{ - return geometry().topLeft() + QWSWindowSurface::painterOffset(); -} - -bool QWSOnScreenSurface::isValid() const -{ - const QWidget *win = window(); - if (screen != getScreen(win)) - return false; - if (img.isNull()) - return false; - return QScreen::isWidgetPaintOnScreen(win); -} - -QByteArray QWSOnScreenSurface::permanentState() const -{ - QByteArray array; - array.resize(sizeof(int)); - int *ptr = reinterpret_cast<int*>(array.data()); - ptr[0] = QApplication::desktop()->screenNumber(window()); - return array; -} - -void QWSOnScreenSurface::setPermanentState(const QByteArray &data) -{ - const int *ptr = reinterpret_cast<const int*>(data.constData()); - const int screenNo = ptr[0]; - - QScreen *screen = qt_screen; - if (screenNo > 0) - screen = qt_screen->subScreens().at(screenNo); - attachToScreen(screen); -} - -#endif // QT_NO_PAINTONSCREEN - -#ifndef QT_NO_PAINT_DEBUG - -QWSYellowSurface::QWSYellowSurface(bool isClient) - : QWSWindowSurface(), delay(10) -{ - if (isClient) { - setWinId(QWidget::qwsDisplay()->takeId()); - QWidget::qwsDisplay()->nameRegion(winId(), - QLatin1String("Debug flush paint"), - QLatin1String("Silly yellow thing")); - QWidget::qwsDisplay()->setAltitude(winId(), 1, true); - } - setSurfaceFlags(Buffered); -} - -QWSYellowSurface::~QWSYellowSurface() -{ -} - -QByteArray QWSYellowSurface::permanentState() const -{ - QByteArray array; - array.resize(2 * sizeof(int)); - - int *ptr = reinterpret_cast<int*>(array.data()); - ptr[0] = surfaceSize.width(); - ptr[1] = surfaceSize.height(); - - return array; -} - -void QWSYellowSurface::setPermanentState(const QByteArray &data) -{ - const int *ptr = reinterpret_cast<const int*>(data.constData()); - - const int width = ptr[0]; - const int height = ptr[1]; - - img = QImage(width, height, QImage::Format_ARGB32); - img.fill(qRgba(255,255,31,127)); -} - -void QWSYellowSurface::flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset) -{ - Q_UNUSED(offset); - - QWSDisplay *display = QWidget::qwsDisplay(); - QRegion rgn = region; - - if (widget) - rgn.translate(widget->mapToGlobal(QPoint(0, 0))); - - surfaceSize = region.boundingRect().size(); - - const int id = winId(); - display->requestRegion(id, key(), permanentState(), rgn); - display->setAltitude(id, 1, true); - display->repaintRegion(id, 0, false, rgn); - - ::usleep(500 * delay); - display->requestRegion(id, key(), permanentState(), QRegion()); - ::usleep(500 * delay); -} - -#endif // QT_NO_PAINT_DEBUG - -#ifndef QT_NO_DIRECTPAINTER - -static inline QScreen *getPrimaryScreen() -{ - QScreen *screen = QScreen::instance(); - if (!screen->base()) { - QList<QScreen*> subScreens = screen->subScreens(); - if (subScreens.size() < 1) - return 0; - screen = subScreens.at(0); - } - return screen; -} - -QWSDirectPainterSurface::QWSDirectPainterSurface(bool isClient, - QDirectPainter::SurfaceFlag flags) - : QWSWindowSurface(), flushingRegionEvents(false), doLocking(false) -{ - setSurfaceFlags(Opaque); - synchronous = (flags == QDirectPainter::ReservedSynchronous); - - if (isClient) { - setWinId(QWidget::qwsDisplay()->takeId()); - QWidget::qwsDisplay()->nameRegion(winId(), - QLatin1String("QDirectPainter reserved space"), - QLatin1String("reserved")); - } else { - setWinId(0); - } - _screen = QScreen::instance(); - if (!_screen->base()) { - QList<QScreen*> subScreens = _screen->subScreens(); - if (subScreens.size() < 1) - _screen = 0; - else - _screen = subScreens.at(0); - } -} - -QWSDirectPainterSurface::~QWSDirectPainterSurface() -{ - if (winId() && QWSDisplay::instance()) // make sure not in QApplication destructor - QWidget::qwsDisplay()->destroyRegion(winId()); -} - -void QWSDirectPainterSurface::setRegion(const QRegion ®ion) -{ - const int id = winId(); - QWidget::qwsDisplay()->requestRegion(id, key(), permanentState(), region); -#ifndef QT_NO_QWS_MULTIPROCESS - if (synchronous) - QWSDisplay::instance()->d->waitForRegionAck(id); -#endif -} - -void QWSDirectPainterSurface::flush(QWidget *, const QRegion &r, const QPoint &) -{ - QWSDisplay::instance()->repaintRegion(winId(), 0, true, r); -} - -QByteArray QWSDirectPainterSurface::permanentState() const -{ - QByteArray res; - if (isRegionReserved()) - res.append( 'r'); - return res; -} - -void QWSDirectPainterSurface::setPermanentState(const QByteArray &ba) -{ - if (ba.size() > 0 && ba.at(0) == 'r') - setReserved(); - setSurfaceFlags(surfaceFlags() | Opaque); -} - -void QWSDirectPainterSurface::beginPaint(const QRegion ®ion) -{ - QWSWindowSurface::beginPaint(region); -#ifndef QT_NO_QWS_MULTIPROCESS - if (!synchronous) { - flushingRegionEvents = true; - QWSDisplay::instance()->d->waitForRegionEvents(winId(), doLocking); - flushingRegionEvents = false; - } -#endif -} - -bool QWSDirectPainterSurface::hasPendingRegionEvents() const -{ -#ifndef QT_NO_QWS_MULTIPROCESS - if (synchronous) - return false; - - return QWSDisplay::instance()->d->hasPendingRegionEvents(); -#else - return false; -#endif -} - -bool QWSDirectPainterSurface::lock(int timeout) -{ -#ifndef QT_NO_THREAD - threadLock.lock(); -#endif - Q_UNUSED(timeout); - if (doLocking) - QWSDisplay::grab(true); - return true; -} - -void QWSDirectPainterSurface::unlock() -{ - if (doLocking) - QWSDisplay::ungrab(); -#ifndef QT_NO_THREAD - threadLock.unlock(); -#endif -} - -#endif // QT_NO_DIRECTPAINTER - -QT_END_NAMESPACE diff --git a/src/gui/painting/qwindowsurface_qws_p.h b/src/gui/painting/qwindowsurface_qws_p.h deleted file mode 100644 index eaabccf39a..0000000000 --- a/src/gui/painting/qwindowsurface_qws_p.h +++ /dev/null @@ -1,355 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINDOWSURFACE_QWS_P_H -#define QWINDOWSURFACE_QWS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qwindowsurface_p.h" -#include <qregion.h> -#include <qimage.h> -#include <qdirectpainter_qws.h> -#include <qmutex.h> -#include <private/qwssharedmemory_p.h> - -QT_BEGIN_NAMESPACE - -class QScreen; -class QWSWindowSurfacePrivate; - -class Q_GUI_EXPORT QWSWindowSurface : public QWindowSurface -{ -public: - QWSWindowSurface(); - QWSWindowSurface(QWidget *widget); - ~QWSWindowSurface(); - - virtual bool isValid() const = 0; - - virtual void setGeometry(const QRect &rect); - virtual void setGeometry(const QRect &rect, const QRegion &mask); - virtual void flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset); - - virtual bool move(const QPoint &offset); - virtual QRegion move(const QPoint &offset, const QRegion &newClip); - - virtual QPoint painterOffset() const; // remove!!! - - virtual void beginPaint(const QRegion &); - virtual void endPaint(const QRegion &); - - virtual bool lock(int timeout = -1); - virtual void unlock(); - - virtual QString key() const = 0; - - // XXX: not good enough - virtual QByteArray transientState() const; - virtual QByteArray permanentState() const; - virtual void setTransientState(const QByteArray &state); - virtual void setPermanentState(const QByteArray &state); - - virtual QImage image() const = 0; - virtual QPaintDevice *paintDevice() = 0; - - const QRegion clipRegion() const; - void setClipRegion(const QRegion &); - -#ifdef QT_QWS_CLIENTBLIT - virtual const QRegion directRegion() const; - virtual int directRegionId() const; - virtual void setDirectRegion(const QRegion &, int); -#endif - - enum SurfaceFlag { - RegionReserved = 0x1, - Buffered = 0x2, - Opaque = 0x4 - }; - Q_DECLARE_FLAGS(SurfaceFlags, SurfaceFlag) - - SurfaceFlags surfaceFlags() const; - - inline bool isRegionReserved() const { - return surfaceFlags() & RegionReserved; - } - inline bool isBuffered() const { return surfaceFlags() & Buffered; } - inline bool isOpaque() const { return surfaceFlags() & Opaque; } - - int winId() const; - virtual void releaseSurface(); - -protected: - void setSurfaceFlags(SurfaceFlags type); - void setWinId(int id); - -private: - friend class QWidgetPrivate; - - void invalidateBuffer(); - - QWSWindowSurfacePrivate *d_ptr; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QWSWindowSurface::SurfaceFlags) - -class QWSWindowSurfacePrivate -{ -public: - QWSWindowSurfacePrivate(); - - void setWinId(int id); - - QWSWindowSurface::SurfaceFlags flags; - QRegion clip; -#ifdef QT_QWS_CLIENTBLIT - QRegion direct; - int directId; -#endif - - int winId; -}; - -class QWSLock; - -class Q_GUI_EXPORT QWSMemorySurface : public QWSWindowSurface -{ -public: - QWSMemorySurface(); - QWSMemorySurface(QWidget *widget); - ~QWSMemorySurface(); - - bool isValid() const; - - QPaintDevice *paintDevice() { return &img; } - bool scroll(const QRegion &area, int dx, int dy); - - QImage image() const { return img; } - QPoint painterOffset() const; - - void beginPaint(const QRegion &rgn); - - bool lock(int timeout = -1); - void unlock(); - -protected: - QImage::Format preferredImageFormat(const QWidget *widget) const; - -#ifndef QT_NO_QWS_MULTIPROCESS - void setLock(int lockId); - QWSLock *memlock; -#endif -#ifndef QT_NO_THREAD - QMutex threadLock; -#endif - - QImage img; -}; - -class Q_GUI_EXPORT QWSLocalMemSurface : public QWSMemorySurface -{ -public: - QWSLocalMemSurface(); - QWSLocalMemSurface(QWidget *widget); - ~QWSLocalMemSurface(); - - void setGeometry(const QRect &rect); - - QString key() const { return QLatin1String("mem"); } - QByteArray permanentState() const; - - void setPermanentState(const QByteArray &data); - virtual void releaseSurface(); -protected: - uchar *mem; - int memsize; -}; - -#ifndef QT_NO_QWS_MULTIPROCESS -class Q_GUI_EXPORT QWSSharedMemSurface : public QWSMemorySurface -{ -public: - QWSSharedMemSurface(); - QWSSharedMemSurface(QWidget *widget); - ~QWSSharedMemSurface(); - - void setGeometry(const QRect &rect); - - QString key() const { return QLatin1String("shm"); } - QByteArray permanentState() const; - - void setPermanentState(const QByteArray &data); - -#ifdef QT_QWS_CLIENTBLIT - virtual void setDirectRegion(const QRegion &, int); - virtual const QRegion directRegion() const; -#endif - virtual void releaseSurface(); - -private: - bool setMemory(int memId); - - QWSSharedMemory mem; -}; -#endif // QT_NO_QWS_MULTIPROCESS - -#ifndef QT_NO_PAINTONSCREEN -class Q_GUI_EXPORT QWSOnScreenSurface : public QWSMemorySurface -{ -public: - QWSOnScreenSurface(); - QWSOnScreenSurface(QWidget *widget); - ~QWSOnScreenSurface(); - - bool isValid() const; - QPoint painterOffset() const; - - QString key() const { return QLatin1String("OnScreen"); } - QByteArray permanentState() const; - - void setPermanentState(const QByteArray &data); - -private: - void attachToScreen(const QScreen *screen); - - const QScreen *screen; -}; -#endif // QT_NO_PAINTONSCREEN - -#ifndef QT_NO_PAINT_DEBUG -class Q_GUI_EXPORT QWSYellowSurface : public QWSWindowSurface -{ -public: - QWSYellowSurface(bool isClient = false); - ~QWSYellowSurface(); - - void setDelay(int msec) { delay = msec; } - - bool isValid() const { return true; } - - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - - QString key() const { return QLatin1String("Yellow"); } - QByteArray permanentState() const; - - void setPermanentState(const QByteArray &data); - - QPaintDevice *paintDevice() { return &img; } - QImage image() const { return img; } - -private: - int delay; - QSize surfaceSize; // client side - QImage img; // server side -}; -#endif // QT_NO_PAINT_DEBUG - -#ifndef QT_NO_DIRECTPAINTER - -class QScreen; - -class Q_GUI_EXPORT QWSDirectPainterSurface : public QWSWindowSurface -{ -public: - QWSDirectPainterSurface(bool isClient = false, - QDirectPainter::SurfaceFlag flags = QDirectPainter::NonReserved); - ~QWSDirectPainterSurface(); - - void setReserved() { setSurfaceFlags(RegionReserved); } - - void setGeometry(const QRect &rect) { setRegion(rect); } - - void setRegion(const QRegion ®ion); - QRegion region() const { return clipRegion(); } - - void flush(QWidget*, const QRegion &, const QPoint &); - - bool isValid() const { return false; } - - QString key() const { return QLatin1String("DirectPainter"); } - QByteArray permanentState() const; - - void setPermanentState(const QByteArray &); - - QImage image() const { return QImage(); } - QPaintDevice *paintDevice() { return 0; } - - // hw: get rid of this - WId windowId() const { return static_cast<WId>(winId()); } - - QScreen *screen() const { return _screen; } - - void beginPaint(const QRegion &); - bool lock(int timeout = -1); - void unlock(); - - void setLocking(bool b) { doLocking = b; } - - bool hasPendingRegionEvents() const; - -private: - QScreen *_screen; -#ifndef QT_NO_THREAD - QMutex threadLock; -#endif - - friend void qt_directpainter_region(QDirectPainter*, const QRegion&, int); - bool flushingRegionEvents; - bool synchronous; - bool doLocking; -}; - -#endif // QT_NO_DIRECTPAINTER - -QT_END_NAMESPACE - -#endif // QWINDOWSURFACE_QWS_P_H diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp deleted file mode 100644 index d97238427b..0000000000 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qdebug.h> - -#include <qglobal.h> // for Q_WS_WIN define (non-PCH) -#ifdef Q_WS_WIN -#include <qlibrary.h> -#include <qt_windows.h> -#endif - -#include <QtGui/qpaintdevice.h> -#include <QtGui/qwidget.h> - -#include "private/qwindowsurface_raster_p.h" -#include "private/qnativeimage_p.h" -#include "private/qwidget_p.h" - -#ifdef Q_WS_X11 -#include "private/qpixmap_x11_p.h" -#include "private/qt_x11_p.h" -#include "private/qwidget_p.h" -#include "qx11info_x11.h" -#endif -#include "private/qdrawhelper_p.h" - -#ifdef Q_WS_MAC -#include <private/qt_cocoa_helpers_mac_p.h> -#include <QMainWindow> -#include <private/qmainwindowlayout_p.h> -#include <QToolBar> -#endif - -QT_BEGIN_NAMESPACE - -class QRasterWindowSurfacePrivate -{ -public: - QNativeImage *image; - -#ifdef Q_WS_X11 - GC gc; -#ifndef QT_NO_MITSHM - uint needsSync : 1; -#endif -#ifndef QT_NO_XRENDER - uint translucentBackground : 1; -#endif -#endif - uint inSetGeometry : 1; -}; - -QRasterWindowSurface::QRasterWindowSurface(QWidget *window, bool setDefaultSurface) - : QWindowSurface(window, setDefaultSurface), d_ptr(new QRasterWindowSurfacePrivate) -{ -#ifdef Q_WS_X11 - d_ptr->gc = XCreateGC(X11->display, window->handle(), 0, 0); -#ifndef QT_NO_XRENDER - d_ptr->translucentBackground = X11->use_xrender - && window->x11Info().depth() == 32; -#endif -#ifndef QT_NO_MITHSM - d_ptr->needsSync = false; -#endif -#endif - d_ptr->image = 0; - d_ptr->inSetGeometry = false; - -#ifdef QT_MAC_USE_COCOA - needsFlush = false; - regionToFlush = QRegion(); -#endif // QT_MAC_USE_COCOA -} - - -QRasterWindowSurface::~QRasterWindowSurface() -{ -#ifdef Q_WS_X11 - XFreeGC(X11->display, d_ptr->gc); -#endif - if (d_ptr->image) - delete d_ptr->image; -} - - -QPaintDevice *QRasterWindowSurface::paintDevice() -{ - return &d_ptr->image->image; -} - -#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM) -void QRasterWindowSurface::syncX() -{ - // delay writing to the backbuffer until we know for sure X is done reading from it - if (d_ptr->needsSync) { - XSync(X11->display, false); - d_ptr->needsSync = false; - } -} -#endif - -void QRasterWindowSurface::beginPaint(const QRegion &rgn) -{ -#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM) - syncX(); -#endif - -#if (defined(Q_WS_X11) && !defined(QT_NO_XRENDER)) || (defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) - if (!qt_widget_private(window())->isOpaque && window()->testAttribute(Qt::WA_TranslucentBackground)) { -#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) - if (d_ptr->image->image.format() != QImage::Format_ARGB32_Premultiplied) - prepareBuffer(QImage::Format_ARGB32_Premultiplied, window()); -#endif - QPainter p(&d_ptr->image->image); - p.setCompositionMode(QPainter::CompositionMode_Source); - const QVector<QRect> rects = rgn.rects(); - const QColor blank = Qt::transparent; - for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { - p.fillRect(*it, blank); - } - } -#else - Q_UNUSED(rgn); -#endif -} - -void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) -{ - Q_D(QRasterWindowSurface); - - // Not ready for painting yet, bail out. This can happen in - // QWidget::create_sys() - if (!d->image || rgn.rectCount() == 0) - return; - -#ifdef Q_WS_WIN - QRect br = rgn.boundingRect(); - -#ifndef Q_WS_WINCE - if (!qt_widget_private(window())->isOpaque - && window()->testAttribute(Qt::WA_TranslucentBackground) - && (qt_widget_private(window())->data.window_flags & Qt::FramelessWindowHint)) - { - QRect r = window()->frameGeometry(); - QPoint frameOffset = qt_widget_private(window())->frameStrut().topLeft(); - QRect dirtyRect = br.translated(offset + frameOffset); - - SIZE size = {r.width(), r.height()}; - POINT ptDst = {r.x(), r.y()}; - POINT ptSrc = {0, 0}; - BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * window()->windowOpacity()), Q_AC_SRC_ALPHA}; - RECT dirty = {dirtyRect.x(), dirtyRect.y(), - dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()}; - Q_UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, d->image->hdc, &ptSrc, 0, &blend, Q_ULW_ALPHA, &dirty}; - ptrUpdateLayeredWindowIndirect(window()->internalWinId(), &info); - } else -#endif - { - QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft(); - - HDC widget_dc = widget->getDC(); - - QRect wbr = br.translated(-wOffset); - BitBlt(widget_dc, wbr.x(), wbr.y(), wbr.width(), wbr.height(), - d->image->hdc, br.x() + offset.x(), br.y() + offset.y(), SRCCOPY); - widget->releaseDC(widget_dc); - } - -#ifndef QT_NO_DEBUG - static bool flush = !qgetenv("QT_FLUSH_WINDOWSURFACE").isEmpty(); - if (flush) { - SelectObject(qt_win_display_dc(), GetStockObject(BLACK_BRUSH)); - Rectangle(qt_win_display_dc(), 0, 0, d->image->width() + 2, d->image->height() + 2); - BitBlt(qt_win_display_dc(), 1, 1, d->image->width(), d->image->height(), - d->image->hdc, 0, 0, SRCCOPY); - } -#endif - -#endif - -#ifdef Q_WS_X11 - extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp - extern QWidgetData* qt_widget_data(QWidget *); - QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft(); - - if (widget->window() != window()) { - XFreeGC(X11->display, d_ptr->gc); - d_ptr->gc = XCreateGC(X11->display, widget->handle(), 0, 0); - } - - QRegion wrgn(rgn); - if (!wOffset.isNull()) - wrgn.translate(-wOffset); - QRect wbr = wrgn.boundingRect(); - - if (wrgn.rectCount() != 1) { - int num; - XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num); - XSetClipRectangles(X11->display, d_ptr->gc, 0, 0, rects, num, YXBanded); - } - - QRect br = rgn.boundingRect().translated(offset); -#ifndef QT_NO_MITSHM - if (d_ptr->image->xshmpm) { - XCopyArea(X11->display, d_ptr->image->xshmpm, widget->handle(), d_ptr->gc, - br.x(), br.y(), br.width(), br.height(), wbr.x(), wbr.y()); - d_ptr->needsSync = true; - } else if (d_ptr->image->xshmimg) { - const QImage &src = d->image->image; - br = br.intersected(src.rect()); - XShmPutImage(X11->display, widget->handle(), d_ptr->gc, d_ptr->image->xshmimg, - br.x(), br.y(), wbr.x(), wbr.y(), br.width(), br.height(), False); - d_ptr->needsSync = true; - } else -#endif - { - const QImage &src = d->image->image; - br = br.intersected(src.rect()); - if (src.format() != QImage::Format_RGB32 || widget->x11Info().depth() < 24) { - Q_ASSERT(src.depth() >= 16); - const QImage sub_src(src.scanLine(br.y()) + br.x() * (uint(src.depth()) / 8), - br.width(), br.height(), src.bytesPerLine(), src.format()); - QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType); - data->xinfo = widget->x11Info(); - data->fromImage(sub_src, Qt::NoOpaqueDetection); - QPixmap pm = QPixmap(data); - XCopyArea(X11->display, pm.handle(), widget->handle(), d_ptr->gc, 0 , 0 , br.width(), br.height(), wbr.x(), wbr.y()); - } else { - // qpaintengine_x11.cpp - extern void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image, Drawable hd, GC gc, Display *dpy, Visual *visual, int depth); - qt_x11_drawImage(br, wbr.topLeft(), src, widget->handle(), d_ptr->gc, X11->display, (Visual *)widget->x11Info().visual(), widget->x11Info().depth()); - } - } - - if (wrgn.rectCount() != 1) - XSetClipMask(X11->display, d_ptr->gc, XNone); -#endif // FALCON - -#ifdef Q_WS_MAC - - Q_UNUSED(offset); - - // This is mainly done for native components like native "open file" dialog. - if (widget->testAttribute(Qt::WA_DontShowOnScreen)) { - return; - } - -#ifdef QT_MAC_USE_COCOA - - this->needsFlush = true; - this->regionToFlush += rgn; - - // The actual flushing will be processed in [view drawRect:rect] - qt_mac_setNeedsDisplay(widget); - -#else - // Get a context for the widget. - CGContextRef context; - CGrafPtr port = GetWindowPort(qt_mac_window_for(widget)); - QDBeginCGContext(port, &context); - CGContextRetain(context); - CGContextSaveGState(context); - - // Flip context. - CGContextTranslateCTM(context, 0, widget->height()); - CGContextScaleCTM(context, 1, -1); - - // Clip to region. - const QVector<QRect> &rects = rgn.rects(); - for (int i = 0; i < rects.size(); ++i) { - const QRect &rect = rects.at(i); - CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); - } - CGContextClip(context); - - QRect r = rgn.boundingRect(); - const CGRect area = CGRectMake(r.x(), r.y(), r.width(), r.height()); - CGImageRef image = CGBitmapContextCreateImage(d->image->cg); - CGImageRef subImage = CGImageCreateWithImageInRect(image, area); - - qt_mac_drawCGImage(context, &area, subImage); - - CGImageRelease(subImage); - CGImageRelease(image); - - QDEndCGContext(port, &context); - - // Restore context. - CGContextRestoreGState(context); - CGContextRelease(context); -#endif // QT_MAC_USE_COCOA - -#endif // Q_WS_MAC - -#ifdef Q_OS_SYMBIAN - Q_UNUSED(widget); - Q_UNUSED(rgn); - Q_UNUSED(offset); -#endif -} - -void QRasterWindowSurface::setGeometry(const QRect &rect) -{ - QWindowSurface::setGeometry(rect); - Q_D(QRasterWindowSurface); - d->inSetGeometry = true; - if (d->image == 0 || d->image->width() < rect.width() || d->image->height() < rect.height()) { -#if (defined(Q_WS_X11) && !defined(QT_NO_XRENDER)) || (defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) -#ifndef Q_WS_WIN - if (d_ptr->translucentBackground) -#else - if (!qt_widget_private(window())->isOpaque) -#endif - prepareBuffer(QImage::Format_ARGB32_Premultiplied, window()); - else -#endif - prepareBuffer(QNativeImage::systemFormat(), window()); - } - d->inSetGeometry = false; - -#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA) - QMainWindow* mWindow = qobject_cast<QMainWindow*>(window()); - if (mWindow) { - QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout()); - QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList; - - for (int i = 0; i < toolbarList.size(); ++i) { - QToolBar* toolbar = toolbarList.at(i); - if (mLayout->toolBarArea(toolbar) == Qt::TopToolBarArea) { - QWidget* tbWidget = (QWidget*) toolbar; - if (tbWidget->d_func()->unifiedSurface) { - tbWidget->d_func()->unifiedSurface->setGeometry(rect); - } - } - } - } -#endif // Q_WS_MAC && QT_MAC_USE_COCOA - -} - -// from qwindowsurface.cpp -extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); - -bool QRasterWindowSurface::scroll(const QRegion &area, int dx, int dy) -{ -#ifdef Q_WS_WIN - Q_D(QRasterWindowSurface); - - if (!d->image || !d->image->hdc) - return false; - - QRect rect = area.boundingRect(); - BitBlt(d->image->hdc, rect.x()+dx, rect.y()+dy, rect.width(), rect.height(), - d->image->hdc, rect.x(), rect.y(), SRCCOPY); - - return true; -#else - Q_D(QRasterWindowSurface); - - if (!d->image || d->image->image.isNull()) - return false; - -#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM) - syncX(); -#endif - - const QVector<QRect> rects = area.rects(); - for (int i = 0; i < rects.size(); ++i) - qt_scrollRectInImage(d->image->image, rects.at(i), QPoint(dx, dy)); - - return true; -#endif -} - -QWindowSurface::WindowSurfaceFeatures QRasterWindowSurface::features() const -{ - return QWindowSurface::AllFeatures; -} - -void QRasterWindowSurface::prepareBuffer(QImage::Format format, QWidget *widget) -{ - Q_D(QRasterWindowSurface); - - int width = window()->width(); - int height = window()->height(); - if (d->image) { - width = qMax(d->image->width(), width); - height = qMax(d->image->height(), height); - } - - if (width == 0 || height == 0) { - delete d->image; - d->image = 0; - return; - } - - QNativeImage *oldImage = d->image; - - d->image = new QNativeImage(width, height, format, false, widget); - - if (oldImage && d->inSetGeometry && hasStaticContents()) { - // Make sure we use the const version of bits() (no detach). - const uchar *src = const_cast<const QImage &>(oldImage->image).bits(); - uchar *dst = d->image->image.bits(); - - const int srcBytesPerLine = oldImage->image.bytesPerLine(); - const int dstBytesPerLine = d->image->image.bytesPerLine(); - const int bytesPerPixel = oldImage->image.depth() >> 3; - - QRegion staticRegion(staticContents()); - // Make sure we're inside the boundaries of the old image. - staticRegion &= QRect(0, 0, oldImage->image.width(), oldImage->image.height()); - const QVector<QRect> &rects = staticRegion.rects(); - const QRect *srcRect = rects.constData(); - - // Copy the static content of the old image into the new one. - int numRectsLeft = rects.size(); - do { - const int bytesOffset = srcRect->x() * bytesPerPixel; - const int dy = srcRect->y(); - - // Adjust src and dst to point to the right offset. - const uchar *s = src + dy * srcBytesPerLine + bytesOffset; - uchar *d = dst + dy * dstBytesPerLine + bytesOffset; - const int numBytes = srcRect->width() * bytesPerPixel; - - int numScanLinesLeft = srcRect->height(); - do { - ::memcpy(d, s, numBytes); - d += dstBytesPerLine; - s += srcBytesPerLine; - } while (--numScanLinesLeft); - - ++srcRect; - } while (--numRectsLeft); - } - - delete oldImage; -} - -#ifdef QT_MAC_USE_COCOA -CGContextRef QRasterWindowSurface::imageContext() -{ - Q_D(QRasterWindowSurface); - return d->image->cg; -} -#endif // QT_MAC_USE_COCOA - -QT_END_NAMESPACE diff --git a/src/gui/painting/qwindowsurface_raster_p.h b/src/gui/painting/qwindowsurface_raster_p.h deleted file mode 100644 index 7bac561fa7..0000000000 --- a/src/gui/painting/qwindowsurface_raster_p.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINDOWSURFACE_RASTER_P_H -#define QWINDOWSURFACE_RASTER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the QLibrary class. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include <qglobal.h> -#include "private/qwindowsurface_p.h" - -#ifdef QT_MAC_USE_COCOA -# include <private/qt_cocoa_helpers_mac_p.h> -#endif // QT_MAC_USE_COCOA - -QT_BEGIN_NAMESPACE - -#ifdef Q_WS_WIN -#define Q_WS_EX_LAYERED 0x00080000 // copied from WS_EX_LAYERED in winuser.h -#define Q_LWA_ALPHA 0x00000002 // copied from LWA_ALPHA in winuser.h -#define Q_ULW_ALPHA 0x00000002 // copied from ULW_ALPHA in winuser.h -#define Q_AC_SRC_ALPHA 0x00000001 // copied from AC_SRC_ALPHA in winuser.h - -struct Q_UPDATELAYEREDWINDOWINFO { - DWORD cbSize; - HDC hdcDst; - const POINT *pptDst; - const SIZE *psize; - HDC hdcSrc; - const POINT *pptSrc; - COLORREF crKey; - const BLENDFUNCTION *pblend; - DWORD dwFlags; - const RECT *prcDirty; -}; - -typedef BOOL (WINAPI *PtrUpdateLayeredWindow)(HWND hwnd, HDC hdcDst, const POINT *pptDst, - const SIZE *psize, HDC hdcSrc, const POINT *pptSrc, COLORREF crKey, - const BLENDFUNCTION *pblend, DWORD dwflags); -typedef BOOL (WINAPI *PtrUpdateLayeredWindowIndirect)(HWND hwnd, const Q_UPDATELAYEREDWINDOWINFO *pULWInfo); -extern PtrUpdateLayeredWindow ptrUpdateLayeredWindow; -extern PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect; -#endif - -class QPaintDevice; -class QPoint; -class QRegion; -class QRegion; -class QSize; -class QWidget; -class QRasterWindowSurfacePrivate; -class QNativeImage; - -class Q_GUI_EXPORT QRasterWindowSurface : public QWindowSurface -{ -public: - QRasterWindowSurface(QWidget *widget, bool setDefaultSurface = true); - ~QRasterWindowSurface(); - - QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - void beginPaint(const QRegion &rgn); - void setGeometry(const QRect &rect); - bool scroll(const QRegion &area, int dx, int dy); - WindowSurfaceFeatures features() const; - -#ifdef QT_MAC_USE_COCOA - CGContextRef imageContext(); - - bool needsFlush; - QRegion regionToFlush; -#endif // QT_MAC_USE_COCOA - -private: -#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM) - void syncX(); -#endif - void prepareBuffer(QImage::Format format, QWidget *widget); - Q_DECLARE_PRIVATE(QRasterWindowSurface) - QScopedPointer<QRasterWindowSurfacePrivate> d_ptr; -}; - -QT_END_NAMESPACE - -#endif // QWINDOWSURFACE_RASTER_P_H diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp deleted file mode 100644 index 8801d75f0f..0000000000 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qglobal.h> // for Q_WS_WIN define (non-PCH) - -#include <QtGui/qpaintdevice.h> -#include <private/qwidget_p.h> -#include <private/qwindowsurface_s60_p.h> -#include <private/qpixmap_s60_p.h> -#include <private/qt_s60_p.h> -#include <private/qapplication_p.h> -#include <private/qdrawhelper_p.h> - -#ifdef QT_GRAPHICSSYSTEM_RUNTIME -#include <private/qgraphicssystem_runtime_p.h> -#endif - -QT_BEGIN_NAMESPACE - -struct QS60WindowSurfacePrivate -{ - QPixmap device; - QList<QImage*> bufferImages; -}; - -TDisplayMode displayMode(bool opaque) -{ - TDisplayMode mode = S60->screenDevice()->DisplayMode(); - if (opaque) { - mode = EColor16MU; - } else { - if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_3) - mode = Q_SYMBIAN_ECOLOR16MAP; // Symbian^3 WServ has support for ARGB32_PRE - else - mode = EColor16MA; // Symbian prior to Symbian^3 sw accelerates EColor16MA - } - return mode; -} - -bool blitWriteAlpha(QWidgetPrivate *widgetPrivate) -{ - QWExtra *extra = widgetPrivate->extraData(); - return extra ? extra->nativePaintMode == QWExtra::BlitWriteAlpha : false; -} - -QS60WindowSurface::QS60WindowSurface(QWidget* widget) - : QWindowSurface(widget), d_ptr(new QS60WindowSurfacePrivate) -{ - QWidgetPrivate *widgetPrivate = qt_widget_private(widget); - const bool opaque = widgetPrivate->isOpaque && !blitWriteAlpha(widgetPrivate); - TDisplayMode mode = displayMode(opaque); - // We create empty CFbsBitmap here -> it will be resized in setGeometry - CFbsBitmap *bitmap = new CFbsBitmap; // CBase derived object needs check on new - Q_CHECK_PTR(bitmap); - qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) ); - - QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType); - if (data) { - data->fromSymbianBitmap(bitmap, true); - d_ptr->device = QPixmap(data); - } -} - -QS60WindowSurface::~QS60WindowSurface() -{ -#if defined(QT_GRAPHICSSYSTEM_RUNTIME) && defined(Q_SYMBIAN_SUPPORTS_SURFACES) - if(QApplicationPrivate::runtime_graphics_system) { - QRuntimeGraphicsSystem *runtimeGraphicsSystem = - static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system); - if(runtimeGraphicsSystem->graphicsSystemName() == QLatin1String("openvg")) { - - // Graphics system has been switched from raster to openvg. - // Issue empty redraw to clear the UI surface - - QWidget *w = window(); - if (w->testAttribute(Qt::WA_WState_Created)) { - RWindow *const window = static_cast<RWindow *>(w->winId()->DrawableWindow()); - window->BeginRedraw(); - window->EndRedraw(); - } - } - } -#endif - - delete d_ptr; -} - -void QS60WindowSurface::beginPaint(const QRegion &rgn) -{ -#ifdef Q_SYMBIAN_SUPPORTS_SURFACES - S60->wsSession().Finish(); -#endif - - QWidgetPrivate *windowPrivate = qt_widget_private(window()); - if (!windowPrivate->isOpaque || blitWriteAlpha(windowPrivate)) { - QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data()); - - TDisplayMode mode = displayMode(false); - if (pixmapData->cfbsBitmap->DisplayMode() != mode) - pixmapData->convertToDisplayMode(mode); - - pixmapData->beginDataAccess(); - - if (!windowPrivate->isOpaque) { - QPainter p(&pixmapData->image); - p.setCompositionMode(QPainter::CompositionMode_Source); - const QVector<QRect> rects = rgn.rects(); - const QColor blank = Qt::transparent; - for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { - p.fillRect(*it, blank); - } - } - - pixmapData->endDataAccess(); - } -} - -void QS60WindowSurface::endPaint(const QRegion &) -{ - qDeleteAll(d_ptr->bufferImages); - d_ptr->bufferImages.clear(); -} - -QImage* QS60WindowSurface::buffer(const QWidget *widget) -{ - if (widget->window() != window()) - return 0; - - QPaintDevice *pdev = paintDevice(); - if (!pdev) - return 0; - - const QPoint off = offset(widget); - QImage *img = &(static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image); - - QRect rect(off, widget->size()); - rect &= QRect(QPoint(), img->size()); - - if (rect.isEmpty()) - return 0; - - img = new QImage(img->scanLine(rect.y()) + rect.x() * img->depth() / 8, - rect.width(), rect.height(), - img->bytesPerLine(), img->format()); - d_ptr->bufferImages.append(img); - - return img; -} - -void QS60WindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &) -{ - QWidget *window = widget->window(); - Q_ASSERT(window); - QTLWExtra *topExtra = window->d_func()->maybeTopData(); - Q_ASSERT(topExtra); - QRect qr = region.boundingRect(); - if (!topExtra->inExpose) { - topExtra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again - TRect tr = qt_QRect2TRect(qr); - widget->winId()->DrawNow(tr); - topExtra->inExpose = false; - } else { - // This handles the case when syncBackingStore updates content outside of the - // original drawing rectangle. This might happen if there are pending update() - // events at the same time as we get a Draw() from Symbian. - QRect drawRect = qt_TRect2QRect(widget->winId()->DrawableWindow()->GetDrawRect()); - if (!drawRect.contains(qr)) - widget->winId()->DrawDeferred(); - } -} - -bool QS60WindowSurface::scroll(const QRegion &area, int dx, int dy) -{ - QRect rect = area.boundingRect(); - - if (dx == 0 && dy == 0) - return false; - - if (d_ptr->device.isNull()) - return false; - - QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); - data->scroll(dx, dy, rect); - - return true; -} - -QPaintDevice* QS60WindowSurface::paintDevice() -{ - return &d_ptr->device; -} - -void QS60WindowSurface::setGeometry(const QRect& rect) -{ - if (rect == geometry()) - return; - - QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); - data->resize(rect.width(), rect.height()); - - QWindowSurface::setGeometry(rect); -} - -QWindowSurface::WindowSurfaceFeatures QS60WindowSurface::features() const -{ - return QWindowSurface::AllFeatures; -} - -CFbsBitmap* QS60WindowSurface::symbianBitmap() const -{ - QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); - return data->cfbsBitmap; -} - -QT_END_NAMESPACE - diff --git a/src/gui/painting/qwindowsurface_x11.cpp b/src/gui/painting/qwindowsurface_x11.cpp deleted file mode 100644 index 1a62f47722..0000000000 --- a/src/gui/painting/qwindowsurface_x11.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui/QPaintDevice> -#include <QtGui/QPainter> -#include <QtGui/QPixmap> -#include <QtGui/QWidget> - -#include "private/qt_x11_p.h" -#include "private/qpixmap_x11_p.h" -#include "private/qwidget_p.h" -#include "qx11info_x11.h" -#include "qwindowsurface_x11_p.h" - -QT_BEGIN_NAMESPACE - -extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp - -struct QX11WindowSurfacePrivate -{ - QWidget *widget; - QPixmap device; -#ifndef QT_NO_XRENDER - bool translucentBackground; -#endif -}; - -QX11WindowSurface::QX11WindowSurface(QWidget *widget) - : QWindowSurface(widget), d_ptr(new QX11WindowSurfacePrivate), gc(0) -{ - d_ptr->widget = widget; -#ifndef QT_NO_XRENDER - d_ptr->translucentBackground = X11->use_xrender - && widget->x11Info().depth() == 32; -#endif -} - - -QX11WindowSurface::~QX11WindowSurface() -{ - delete d_ptr; - if (gc) { - XFreeGC(X11->display, gc); - gc = 0; - } -} - -QPaintDevice *QX11WindowSurface::paintDevice() -{ - return &d_ptr->device; -} - -void QX11WindowSurface::beginPaint(const QRegion &rgn) -{ -#ifndef QT_NO_XRENDER - Q_ASSERT(!d_ptr->device.isNull()); - - if (d_ptr->translucentBackground) { - if (d_ptr->device.depth() != 32) - static_cast<QX11PixmapData *>(d_ptr->device.data_ptr().data())->convertToARGB32(); - ::Picture src = X11->getSolidFill(d_ptr->device.x11Info().screen(), Qt::transparent); - ::Picture dst = d_ptr->device.x11PictureHandle(); - const QVector<QRect> rects = rgn.rects(); - const int w = d_ptr->device.width(); - const int h = d_ptr->device.height(); - for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) - XRenderComposite(X11->display, PictOpSrc, src, 0, dst, - 0, 0, w, h, it->x(), it->y(), - it->width(), it->height()); - } -#endif -} - -void QX11WindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) -{ - if (d_ptr->device.isNull()) - return; - - QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft(); - QRegion wrgn(rgn); - QRect br = rgn.boundingRect(); - if (!wOffset.isNull()) - wrgn.translate(-wOffset); - QRect wbr = wrgn.boundingRect(); - - int num; - XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num); - if (num <= 0) - return; -// qDebug() << "XSetClipRectangles"; -// for (int i = 0; i < num; ++i) -// qDebug() << ' ' << i << rects[i].x << rects[i].x << rects[i].y << rects[i].width << rects[i].height; - if (num != 1) - XSetClipRectangles(X11->display, gc, 0, 0, rects, num, YXBanded); - XCopyArea(X11->display, d_ptr->device.handle(), widget->handle(), gc, - br.x() + offset.x(), br.y() + offset.y(), br.width(), br.height(), wbr.x(), wbr.y()); - if (num != 1) - XSetClipMask(X11->display, gc, XNone); -} - -void QX11WindowSurface::setGeometry(const QRect &rect) -{ - QWindowSurface::setGeometry(rect); - - const QSize size = rect.size(); - - if (d_ptr->device.size() == size || size.width() <= 0 || size.height() <= 0) - return; -#ifndef QT_NO_XRENDER - if (d_ptr->translucentBackground) { - QPixmap::x11SetDefaultScreen(d_ptr->widget->x11Info().screen()); - - QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType); - data->xinfo = d_ptr->widget->x11Info(); - data->resize(size.width(), size.height()); - d_ptr->device = QPixmap(data); - } else -#endif - { - QPixmap::x11SetDefaultScreen(d_ptr->widget->x11Info().screen()); - - QX11PixmapData *oldData = static_cast<QX11PixmapData *>(d_ptr->device.pixmapData()); - - if (oldData && !(oldData->flags & QX11PixmapData::Uninitialized) && hasStaticContents()) { - // Copy the content of the old pixmap into the new one. - QX11PixmapData *newData = new QX11PixmapData(QPixmapData::PixmapType); - newData->resize(size.width(), size.height()); - Q_ASSERT(oldData->d == newData->d); - - QRegion staticRegion(staticContents()); - // Make sure we're inside the boundaries of the old pixmap. - staticRegion &= QRect(0, 0, oldData->w, oldData->h); - const QRect boundingRect(staticRegion.boundingRect()); - const int dx = boundingRect.x(); - const int dy = boundingRect.y(); - - int num; - XRectangle *rects = (XRectangle *)qt_getClipRects(staticRegion, num); - GC tmpGc = XCreateGC(X11->display, oldData->hd, 0, 0); - XSetClipRectangles(X11->display, tmpGc, 0, 0, rects, num, YXBanded); - XCopyArea(X11->display, oldData->hd, newData->hd, tmpGc, - dx, dy, qMin(boundingRect.width(), size.width()), - qMin(boundingRect.height(), size.height()), dx, dy); - XFreeGC(X11->display, tmpGc); - newData->flags &= ~QX11PixmapData::Uninitialized; - - d_ptr->device = QPixmap(newData); - } else { - d_ptr->device = QPixmap(size); - } - } - - if (gc) { - XFreeGC(X11->display, gc); - gc = 0; - } - if (!d_ptr->device.isNull()) { - gc = XCreateGC(X11->display, d_ptr->device.handle(), 0, 0); - XSetGraphicsExposures(X11->display, gc, False); - } -} - -bool QX11WindowSurface::scroll(const QRegion &area, int dx, int dy) -{ - QRect rect = area.boundingRect(); - - if (d_ptr->device.isNull()) - return false; - - GC gc = XCreateGC(X11->display, d_ptr->device.handle(), 0, 0); - XCopyArea(X11->display, d_ptr->device.handle(), d_ptr->device.handle(), gc, - rect.x(), rect.y(), rect.width(), rect.height(), - rect.x()+dx, rect.y()+dy); - XFreeGC(X11->display, gc); - - return true; -} - -QPixmap QX11WindowSurface::grabWidget(const QWidget *widget, - const QRect& rect) const -{ - if (!widget || d_ptr->device.isNull()) - return QPixmap(); - - QRect srcRect; - - // make sure the rect is inside the widget & clip to widget's rect - if (!rect.isEmpty()) - srcRect = rect & widget->rect(); - else - srcRect = widget->rect(); - - if (srcRect.isEmpty()) - return QPixmap(); - - // If it's a child widget we have to translate the coordinates - if (widget != window()) - srcRect.translate(widget->mapTo(window(), QPoint(0, 0))); - - QPixmap::x11SetDefaultScreen(widget->x11Info().screen()); - QPixmap px(srcRect.width(), srcRect.height()); - - GC tmpGc = XCreateGC(X11->display, d_ptr->device.handle(), 0, 0); - - // Copy srcRect from the backing store to the new pixmap - XSetGraphicsExposures(X11->display, tmpGc, False); - XCopyArea(X11->display, d_ptr->device.handle(), px.handle(), tmpGc, - srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), 0, 0); - - XFreeGC(X11->display, tmpGc); - - return px; -} - -QWindowSurface::WindowSurfaceFeatures QX11WindowSurface::features() const -{ - WindowSurfaceFeatures features = QWindowSurface::PartialUpdates | QWindowSurface::PreservedContents; -#ifndef QT_NO_XRENDER - if (!d_ptr->translucentBackground) - features |= QWindowSurface::StaticContents; -#else - features |= QWindowSurface::StaticContents; -#endif - return features; -} - -QT_END_NAMESPACE diff --git a/src/gui/painting/qwindowsurface_x11_p.h b/src/gui/painting/qwindowsurface_x11_p.h deleted file mode 100644 index 23c00a1f63..0000000000 --- a/src/gui/painting/qwindowsurface_x11_p.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINDOWSURFACE_X11_P_H -#define QWINDOWSURFACE_X11_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <qglobal.h> -#include "private/qwindowsurface_p.h" - -QT_BEGIN_NAMESPACE - -class QPaintDevice; -class QPoint; -class QRegion; -class QRegion; -class QSize; -class QWidget; -struct QX11WindowSurfacePrivate; - -class QX11WindowSurface : public QWindowSurface -{ -public: - QX11WindowSurface(QWidget *widget); - ~QX11WindowSurface(); - - QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - - void beginPaint(const QRegion &rgn); - void setGeometry(const QRect &rect); - bool scroll(const QRegion &area, int dx, int dy); - QPixmap grabWidget(const QWidget *widget, - const QRect& rectangle = QRect()) const; - WindowSurfaceFeatures features() const; - -private: - QX11WindowSurfacePrivate *d_ptr; - GC gc; -}; - -QT_END_NAMESPACE - -#endif // QWINDOWSURFACE_X11_P_H diff --git a/src/gui/painting/qwmatrix.h b/src/gui/painting/qwmatrix.h deleted file mode 100644 index 914d574f90..0000000000 --- a/src/gui/painting/qwmatrix.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.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 the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWMATRIX_H -#define QWMATRIX_H - -#include <QtGui/qmatrix.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#if defined(QT3_SUPPORT) -typedef QMatrix QWMatrix; -#endif - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QWMATRIX_H |