src/gui/image/qpicture.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qpicture.h"
       
    43 #include <private/qpicture_p.h>
       
    44 
       
    45 #ifndef QT_NO_PICTURE
       
    46 
       
    47 #include <private/qfactoryloader_p.h>
       
    48 #include <private/qpaintengine_pic_p.h>
       
    49 
       
    50 #include "qdatastream.h"
       
    51 #include "qfile.h"
       
    52 #include "qimage.h"
       
    53 #include "qmutex.h"
       
    54 #include "qpainter.h"
       
    55 #include "qpainterpath.h"
       
    56 #include "qpixmap.h"
       
    57 #include "qregion.h"
       
    58 #include "qdebug.h"
       
    59 
       
    60 QT_BEGIN_NAMESPACE
       
    61 
       
    62 void qt_format_text(const QFont &fnt, const QRectF &_r,
       
    63                     int tf, const QTextOption *opt, const QString& str, QRectF *brect,
       
    64                     int tabstops, int *, int tabarraylen,
       
    65                     QPainter *painter);
       
    66 
       
    67 /*!
       
    68     \class QPicture
       
    69     \brief The QPicture class is a paint device that records and
       
    70     replays QPainter commands.
       
    71 
       
    72     \ingroup painting
       
    73     \ingroup shared
       
    74 
       
    75 
       
    76     A picture serializes painter commands to an IO device in a
       
    77     platform-independent format. They are sometimes referred to as meta-files.
       
    78 
       
    79     Qt pictures use a proprietary binary format. Unlike native picture
       
    80     (meta-file) formats on many window systems, Qt pictures have no
       
    81     limitations regarding their contents. Everything that can be
       
    82     painted on a widget or pixmap (e.g., fonts, pixmaps, regions,
       
    83     transformed graphics, etc.)  can also be stored in a picture.
       
    84 
       
    85     QPicture is resolution independent, i.e. a QPicture can be
       
    86     displayed on different devices (for example svg, pdf, ps, printer
       
    87     and screen) looking the same. This is, for instance, needed for
       
    88     WYSIWYG print preview. QPicture runs in the default system dpi,
       
    89     and scales the painter to match differences in resolution
       
    90     depending on the window system.
       
    91 
       
    92     Example of how to record a picture:
       
    93     \snippet doc/src/snippets/picture/picture.cpp 0
       
    94 
       
    95     Note that the list of painter commands is reset on each call to
       
    96     the QPainter::begin() function.
       
    97 
       
    98     Example of how to replay a picture:
       
    99     \snippet doc/src/snippets/picture/picture.cpp 1
       
   100 
       
   101     Pictures can also be drawn using play(). Some basic data about a
       
   102     picture is available, for example, size(), isNull() and
       
   103     boundingRect().
       
   104 
       
   105     \sa QMovie
       
   106 */
       
   107 
       
   108 const char  *qt_mfhdr_tag = "QPIC"; // header tag
       
   109 static const quint16 mfhdr_maj = 11; // major version #
       
   110 static const quint16 mfhdr_min = 0; // minor version #
       
   111 extern int qt_defaultDpiX();
       
   112 extern int qt_defaultDpiY();
       
   113 
       
   114 /*!
       
   115     Constructs an empty picture.
       
   116 
       
   117     The \a formatVersion parameter may be used to \e create a QPicture
       
   118     that can be read by applications that are compiled with earlier
       
   119     versions of Qt.
       
   120 
       
   121     Note that the default formatVersion is -1 which signifies the
       
   122     current release, i.e. for Qt 4.0 a formatVersion of 7 is the same
       
   123     as the default formatVersion of -1.
       
   124 
       
   125     Reading pictures generated by earlier versions of Qt is not
       
   126     supported in Qt 4.0.
       
   127 */
       
   128 
       
   129 QPicture::QPicture(int formatVersion)
       
   130     : QPaintDevice(),
       
   131       d_ptr(new QPicturePrivate)
       
   132 {
       
   133     Q_D(QPicture);
       
   134 
       
   135     if (formatVersion == 0)
       
   136         qWarning("QPicture: invalid format version 0");
       
   137 
       
   138     // still accept the 0 default from before Qt 3.0.
       
   139     if (formatVersion > 0 && formatVersion != (int)mfhdr_maj) {
       
   140         d->formatMajor = formatVersion;
       
   141         d->formatMinor = 0;
       
   142         d->formatOk = false;
       
   143     } else {
       
   144         d->resetFormat();
       
   145     }
       
   146 }
       
   147 
       
   148 /*!
       
   149     Constructs a copy of \a pic.
       
   150 
       
   151     This constructor is fast thanks to \l{implicit sharing}.
       
   152 */
       
   153 
       
   154 QPicture::QPicture(const QPicture &pic)
       
   155     : QPaintDevice(), d_ptr(pic.d_ptr)
       
   156 {
       
   157 }
       
   158 
       
   159 /*! \internal */
       
   160 QPicture::QPicture(QPicturePrivate &dptr)
       
   161     : QPaintDevice(),
       
   162       d_ptr(&dptr)
       
   163 {
       
   164 }
       
   165 
       
   166 /*!
       
   167     Destroys the picture.
       
   168 */
       
   169 QPicture::~QPicture()
       
   170 {
       
   171 }
       
   172 
       
   173 /*!
       
   174   \internal
       
   175 */
       
   176 int QPicture::devType() const
       
   177 {
       
   178     return QInternal::Picture;
       
   179 }
       
   180 
       
   181 /*!
       
   182     \fn bool QPicture::isNull() const
       
   183 
       
   184     Returns true if the picture contains no data; otherwise returns
       
   185     false.
       
   186 */
       
   187 
       
   188 /*!
       
   189     \fn uint QPicture::size() const
       
   190 
       
   191     Returns the size of the picture data.
       
   192 
       
   193     \sa data()
       
   194 */
       
   195 
       
   196 /*!
       
   197     \fn const char* QPicture::data() const
       
   198 
       
   199     Returns a pointer to the picture data. The pointer is only valid
       
   200     until the next non-const function is called on this picture. The
       
   201     returned pointer is 0 if the picture contains no data.
       
   202 
       
   203     \sa size(), isNull()
       
   204 */
       
   205 
       
   206 
       
   207 bool QPicture::isNull() const
       
   208 {
       
   209     return d_func()->pictb.buffer().isNull();
       
   210 }
       
   211 
       
   212 uint QPicture::size() const
       
   213 {
       
   214     return d_func()->pictb.buffer().size();
       
   215 }
       
   216 
       
   217 const char* QPicture::data() const
       
   218 {
       
   219     return d_func()->pictb.buffer();
       
   220 }
       
   221 
       
   222 void QPicture::detach()
       
   223 {
       
   224     d_ptr.detach();
       
   225 }
       
   226 
       
   227 bool QPicture::isDetached() const
       
   228 {
       
   229     return d_func()->ref == 1;
       
   230 }
       
   231 
       
   232 /*!
       
   233     Sets the picture data directly from \a data and \a size. This
       
   234     function copies the input data.
       
   235 
       
   236     \sa data(), size()
       
   237 */
       
   238 
       
   239 void QPicture::setData(const char* data, uint size)
       
   240 {
       
   241     detach();
       
   242     d_func()->pictb.setData(data, size);
       
   243     d_func()->resetFormat();                                // we'll have to check
       
   244 }
       
   245 
       
   246 
       
   247 /*!
       
   248     Loads a picture from the file specified by \a fileName and returns
       
   249     true if successful; otherwise returns false.
       
   250 
       
   251     Please note that the \a format parameter has been deprecated and
       
   252     will have no effect.
       
   253 
       
   254     \sa save()
       
   255 */
       
   256 
       
   257 bool QPicture::load(const QString &fileName, const char *format)
       
   258 {
       
   259     QFile f(fileName);
       
   260     if (!f.open(QIODevice::ReadOnly))
       
   261         return false;
       
   262     return load(&f, format);
       
   263 }
       
   264 
       
   265 /*!
       
   266     \overload
       
   267 
       
   268     \a dev is the device to use for loading.
       
   269 */
       
   270 
       
   271 bool QPicture::load(QIODevice *dev, const char *format)
       
   272 {
       
   273     if(format) {
       
   274 #ifndef QT_NO_PICTUREIO
       
   275         QPictureIO io(dev, format);
       
   276         bool result = io.read();
       
   277         if (result) {
       
   278             operator=(io.picture());
       
   279 
       
   280         } else if (format)
       
   281 #else
       
   282             bool result = false;
       
   283 #endif
       
   284         {
       
   285             qWarning("QPicture::load: No such picture format: %s", format);
       
   286         }
       
   287         return result;
       
   288     }
       
   289 
       
   290     detach();
       
   291     QByteArray a = dev->readAll();
       
   292 
       
   293     d_func()->pictb.setData(a);                        // set byte array in buffer
       
   294     return d_func()->checkFormat();
       
   295 }
       
   296 
       
   297 /*!
       
   298     Saves a picture to the file specified by \a fileName and returns
       
   299     true if successful; otherwise returns false.
       
   300 
       
   301     Please note that the \a format parameter has been deprecated and
       
   302     will have no effect.
       
   303 
       
   304     \sa load()
       
   305 */
       
   306 
       
   307 bool QPicture::save(const QString &fileName, const char *format)
       
   308 {
       
   309     if (paintingActive()) {
       
   310         qWarning("QPicture::save: still being painted on. "
       
   311                   "Call QPainter::end() first");
       
   312         return false;
       
   313     }
       
   314 
       
   315 
       
   316     if(format) {
       
   317 #ifndef QT_NO_PICTUREIO
       
   318         QPictureIO io(fileName, format);
       
   319         bool result = io.write();
       
   320         if (result) {
       
   321             operator=(io.picture());
       
   322         } else if (format)
       
   323 #else
       
   324         bool result = false;
       
   325 #endif
       
   326         {
       
   327             qWarning("QPicture::save: No such picture format: %s", format);
       
   328         }
       
   329         return result;
       
   330     }
       
   331 
       
   332     QFile f(fileName);
       
   333     if (!f.open(QIODevice::WriteOnly))
       
   334         return false;
       
   335     return save(&f, format);
       
   336 }
       
   337 
       
   338 /*!
       
   339     \overload
       
   340 
       
   341     \a dev is the device to use for saving.
       
   342 */
       
   343 
       
   344 bool QPicture::save(QIODevice *dev, const char *format)
       
   345 {
       
   346     if (paintingActive()) {
       
   347         qWarning("QPicture::save: still being painted on. "
       
   348                   "Call QPainter::end() first");
       
   349         return false;
       
   350     }
       
   351 
       
   352     if(format) {
       
   353 #ifndef QT_NO_PICTUREIO
       
   354         QPictureIO io(dev, format);
       
   355         bool result = io.write();
       
   356         if (result) {
       
   357             operator=(io.picture());
       
   358         } else if (format)
       
   359 #else
       
   360         bool result = false;
       
   361 #endif
       
   362         {
       
   363             qWarning("QPicture::save: No such picture format: %s", format);
       
   364         }
       
   365         return result;
       
   366     }
       
   367 
       
   368     dev->write(d_func()->pictb.buffer(), d_func()->pictb.buffer().size());
       
   369     return true;
       
   370 }
       
   371 
       
   372 /*!
       
   373     Returns the picture's bounding rectangle or an invalid rectangle
       
   374     if the picture contains no data.
       
   375 */
       
   376 
       
   377 QRect QPicture::boundingRect() const
       
   378 {
       
   379     Q_D(const QPicture);
       
   380     // Use override rect where possible.
       
   381     if (!d->override_rect.isEmpty())
       
   382         return d->override_rect;
       
   383 
       
   384     if (!d->formatOk)
       
   385         d_ptr->checkFormat();
       
   386 
       
   387     return d->brect;
       
   388 }
       
   389 
       
   390 /*!
       
   391     Sets the picture's bounding rectangle to \a r. The automatically
       
   392     calculated value is overridden.
       
   393 */
       
   394 
       
   395 void QPicture::setBoundingRect(const QRect &r)
       
   396 {
       
   397     d_func()->override_rect = r;
       
   398 }
       
   399 
       
   400 /*!
       
   401     Replays the picture using \a painter, and returns true if
       
   402     successful; otherwise returns false.
       
   403 
       
   404     This function does exactly the same as QPainter::drawPicture()
       
   405     with (x, y) = (0, 0).
       
   406 */
       
   407 
       
   408 bool QPicture::play(QPainter *painter)
       
   409 {
       
   410     Q_D(QPicture);
       
   411 
       
   412     if (d->pictb.size() == 0)                        // nothing recorded
       
   413         return true;
       
   414 
       
   415     if (!d->formatOk && !d->checkFormat())
       
   416         return false;
       
   417 
       
   418     d->pictb.open(QIODevice::ReadOnly);                // open buffer device
       
   419     QDataStream s;
       
   420     s.setDevice(&d->pictb);                        // attach data stream to buffer
       
   421     s.device()->seek(10);                        // go directly to the data
       
   422     s.setVersion(d->formatMajor == 4 ? 3 : d->formatMajor);
       
   423 
       
   424     quint8  c, clen;
       
   425     quint32 nrecords;
       
   426     s >> c >> clen;
       
   427     Q_ASSERT(c == QPicturePrivate::PdcBegin);
       
   428     // bounding rect was introduced in ver 4. Read in checkFormat().
       
   429     if (d->formatMajor >= 4) {
       
   430         qint32 dummy;
       
   431         s >> dummy >> dummy >> dummy >> dummy;
       
   432     }
       
   433     s >> nrecords;
       
   434     if (!exec(painter, s, nrecords)) {
       
   435         qWarning("QPicture::play: Format error");
       
   436         d->pictb.close();
       
   437         return false;
       
   438     }
       
   439     d->pictb.close();
       
   440     return true;                                // no end-command
       
   441 }
       
   442 
       
   443 
       
   444 //
       
   445 // QFakeDevice is used to create fonts with a custom DPI
       
   446 //
       
   447 class QFakeDevice : public QPaintDevice
       
   448 {
       
   449 public:
       
   450     QFakeDevice() { dpi_x = qt_defaultDpiX(); dpi_y = qt_defaultDpiY(); }
       
   451     void setDpiX(int dpi) { dpi_x = dpi; }
       
   452     void setDpiY(int dpi) { dpi_y = dpi; }
       
   453     QPaintEngine *paintEngine() const { return 0; }
       
   454     int metric(PaintDeviceMetric m) const
       
   455     {
       
   456         switch(m) {
       
   457             case PdmPhysicalDpiX:
       
   458             case PdmDpiX:
       
   459                 return dpi_x;
       
   460             case PdmPhysicalDpiY:
       
   461             case PdmDpiY:
       
   462                 return dpi_y;
       
   463             default:
       
   464                 return QPaintDevice::metric(m);
       
   465         }
       
   466     }
       
   467 
       
   468 private:
       
   469     int dpi_x;
       
   470     int dpi_y;
       
   471 };
       
   472 
       
   473 /*!
       
   474   \internal
       
   475   Iterates over the internal picture data and draws the picture using
       
   476   \a painter.
       
   477 */
       
   478 
       
   479 bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords)
       
   480 {
       
   481     Q_D(QPicture);
       
   482 #if defined(QT_DEBUG)
       
   483     int                strm_pos;
       
   484 #endif
       
   485     quint8     c;                      // command id
       
   486     quint8     tiny_len;               // 8-bit length descriptor
       
   487     qint32     len;                    // 32-bit length descriptor
       
   488     qint16     i_16, i1_16, i2_16;     // parameters...
       
   489     qint8      i_8;
       
   490     quint32    ul;
       
   491     double     dbl;
       
   492     bool       bl;
       
   493     QByteArray  str1;
       
   494     QString     str;
       
   495     QPointF     p, p1, p2;
       
   496     QPoint      ip, ip1, ip2;
       
   497     QRect       ir;
       
   498     QRectF      r;
       
   499     QPolygonF   a;
       
   500     QPolygon    ia;
       
   501     QColor      color;
       
   502     QFont       font;
       
   503     QPen        pen;
       
   504     QBrush      brush;
       
   505     QRegion     rgn;
       
   506     QMatrix     wmatrix;
       
   507     QTransform  matrix;
       
   508 
       
   509     QTransform worldMatrix = painter->transform();
       
   510     worldMatrix.scale(qreal(painter->device()->logicalDpiX()) / qreal(qt_defaultDpiX()),
       
   511                       qreal(painter->device()->logicalDpiY()) / qreal(qt_defaultDpiY()));
       
   512     painter->setTransform(worldMatrix);
       
   513 
       
   514     while (nrecords-- && !s.atEnd()) {
       
   515         s >> c;                 // read cmd
       
   516         s >> tiny_len;          // read param length
       
   517         if (tiny_len == 255)    // longer than 254 bytes
       
   518             s >> len;
       
   519         else
       
   520             len = tiny_len;
       
   521 #if defined(QT_DEBUG)
       
   522         strm_pos = s.device()->pos();
       
   523 #endif
       
   524         switch (c) {            // exec cmd
       
   525         case QPicturePrivate::PdcNOP:
       
   526             break;
       
   527         case QPicturePrivate::PdcDrawPoint:
       
   528             if (d->formatMajor <= 5) {
       
   529                 s >> ip;
       
   530                 painter->drawPoint(ip);
       
   531             } else {
       
   532                 s >> p;
       
   533                 painter->drawPoint(p);
       
   534             }
       
   535             break;
       
   536         case QPicturePrivate::PdcDrawPoints:
       
   537 // ## implement me in the picture paint engine
       
   538 //                 s >> a >> i1_32 >> i2_32;
       
   539 //                 painter->drawPoints(a.mid(i1_32, i2_32));
       
   540             break;
       
   541         case QPicturePrivate::PdcDrawPath: {
       
   542             QPainterPath path;
       
   543             s >> path;
       
   544             painter->drawPath(path);
       
   545             break;
       
   546         }
       
   547         case QPicturePrivate::PdcDrawLine:
       
   548             if (d->formatMajor <= 5) {
       
   549                 s >> ip1 >> ip2;
       
   550                 painter->drawLine(ip1, ip2);
       
   551             } else {
       
   552                 s >> p1 >> p2;
       
   553                 painter->drawLine(p1, p2);
       
   554             }
       
   555             break;
       
   556         case QPicturePrivate::PdcDrawRect:
       
   557             if (d->formatMajor <= 5) {
       
   558                 s >> ir;
       
   559                 painter->drawRect(ir);
       
   560             } else {
       
   561                 s >> r;
       
   562                 painter->drawRect(r);
       
   563             }
       
   564             break;
       
   565         case QPicturePrivate::PdcDrawRoundRect:
       
   566             if (d->formatMajor <= 5) {
       
   567                 s >> ir >> i1_16 >> i2_16;
       
   568                 painter->drawRoundedRect(ir, i1_16, i2_16, Qt::RelativeSize);
       
   569             } else {
       
   570                 s >> r >> i1_16 >> i2_16;
       
   571                 painter->drawRoundedRect(r, i1_16, i2_16, Qt::RelativeSize);
       
   572             }
       
   573             break;
       
   574         case QPicturePrivate::PdcDrawEllipse:
       
   575             if (d->formatMajor <= 5) {
       
   576                 s >> ir;
       
   577                 painter->drawEllipse(ir);
       
   578             } else {
       
   579                 s >> r;
       
   580                 painter->drawEllipse(r);
       
   581             }
       
   582             break;
       
   583         case QPicturePrivate::PdcDrawArc:
       
   584             if (d->formatMajor <= 5) {
       
   585                 s >> ir;
       
   586                 r = ir;
       
   587             } else {
       
   588                 s >> r;
       
   589             }
       
   590             s >> i1_16 >> i2_16;
       
   591             painter->drawArc(r, i1_16, i2_16);
       
   592             break;
       
   593         case QPicturePrivate::PdcDrawPie:
       
   594             if (d->formatMajor <= 5) {
       
   595                 s >> ir;
       
   596                 r = ir;
       
   597             } else {
       
   598                 s >> r;
       
   599             }
       
   600             s >> i1_16 >> i2_16;
       
   601             painter->drawPie(r, i1_16, i2_16);
       
   602             break;
       
   603         case QPicturePrivate::PdcDrawChord:
       
   604             if (d->formatMajor <= 5) {
       
   605                 s >> ir;
       
   606                 r = ir;
       
   607             } else {
       
   608                 s >> r;
       
   609             }
       
   610             s >> i1_16 >> i2_16;
       
   611             painter->drawChord(r, i1_16, i2_16);
       
   612             break;
       
   613         case QPicturePrivate::PdcDrawLineSegments:
       
   614             s >> ia;
       
   615             painter->drawLines(ia);
       
   616             ia.clear();
       
   617             break;
       
   618         case QPicturePrivate::PdcDrawPolyline:
       
   619             if (d->formatMajor <= 5) {
       
   620                 s >> ia;
       
   621                 painter->drawPolyline(ia);
       
   622                 ia.clear();
       
   623             } else {
       
   624                 s >> a;
       
   625                 painter->drawPolyline(a);
       
   626                 a.clear();
       
   627             }
       
   628             break;
       
   629         case QPicturePrivate::PdcDrawPolygon:
       
   630             if (d->formatMajor <= 5) {
       
   631                 s >> ia >> i_8;
       
   632                 painter->drawPolygon(ia, i_8 ? Qt::WindingFill : Qt::OddEvenFill);
       
   633                 a.clear();
       
   634             } else {
       
   635                 s >> a >> i_8;
       
   636                 painter->drawPolygon(a, i_8 ? Qt::WindingFill : Qt::OddEvenFill);
       
   637                 a.clear();
       
   638             }
       
   639             break;
       
   640         case QPicturePrivate::PdcDrawCubicBezier: {
       
   641             s >> ia;
       
   642             QPainterPath path;
       
   643             Q_ASSERT(ia.size() == 4);
       
   644             path.moveTo(ia.at(0));
       
   645             path.cubicTo(ia.at(1), ia.at(2), ia.at(3));
       
   646             painter->strokePath(path, painter->pen());
       
   647             a.clear();
       
   648         }
       
   649             break;
       
   650         case QPicturePrivate::PdcDrawText:
       
   651             s >> ip >> str1;
       
   652             painter->drawText(ip, QString::fromLatin1(str1));
       
   653             break;
       
   654         case QPicturePrivate::PdcDrawTextFormatted:
       
   655             s >> ir >> i_16 >> str1;
       
   656             painter->drawText(ir, i_16, QString::fromLatin1(str1));
       
   657             break;
       
   658         case QPicturePrivate::PdcDrawText2:
       
   659             if (d->formatMajor <= 5) {
       
   660                 s >> ip >> str;
       
   661                 painter->drawText(ip, str);
       
   662             } else {
       
   663                 s >> p >> str;
       
   664                 painter->drawText(p, str);
       
   665             }
       
   666             break;
       
   667         case QPicturePrivate::PdcDrawText2Formatted:
       
   668             s >> ir;
       
   669             s >> i_16;
       
   670             s >> str;
       
   671             painter->drawText(ir, i_16, str);
       
   672             break;
       
   673         case QPicturePrivate::PdcDrawTextItem: {
       
   674             s >> p >> str >> font >> ul;
       
   675 
       
   676             // the text layout direction is not used here because it's already
       
   677             // aligned when QPicturePaintEngine::drawTextItem() serializes the
       
   678             // drawText() call, therefore ul is unsed in this context
       
   679 
       
   680             if (d->formatMajor >= 9) {
       
   681                 s >> dbl;
       
   682                 QFont fnt(font);
       
   683                 if (dbl != 1.0) {
       
   684                     QFakeDevice fake;
       
   685                     fake.setDpiX(qRound(dbl*qt_defaultDpiX()));
       
   686                     fake.setDpiY(qRound(dbl*qt_defaultDpiY()));
       
   687                     fnt = QFont(font, &fake);
       
   688                 }
       
   689 
       
   690                 qreal justificationWidth;
       
   691                 s >> justificationWidth;
       
   692 
       
   693                 int flags = Qt::TextSingleLine | Qt::TextDontClip | Qt::TextForceLeftToRight;
       
   694 
       
   695                 QSizeF size(1, 1);
       
   696                 if (justificationWidth > 0) {
       
   697                     size.setWidth(justificationWidth);
       
   698                     flags |= Qt::TextJustificationForced;
       
   699                     flags |= Qt::AlignJustify;
       
   700                 }
       
   701 
       
   702                 QFontMetrics fm(fnt);
       
   703                 QPointF pt(p.x(), p.y() - fm.ascent());
       
   704                 qt_format_text(fnt, QRectF(pt, size), flags, /*opt*/0,
       
   705                                str, /*brect=*/0, /*tabstops=*/0, /*...*/0, /*tabarraylen=*/0, painter);
       
   706             } else {
       
   707                 qt_format_text(font, QRectF(p, QSizeF(1, 1)), Qt::TextSingleLine | Qt::TextDontClip, /*opt*/0,
       
   708                                str, /*brect=*/0, /*tabstops=*/0, /*...*/0, /*tabarraylen=*/0, painter);
       
   709             }
       
   710 
       
   711             break;
       
   712         }
       
   713         case QPicturePrivate::PdcDrawPixmap: {
       
   714             QPixmap pixmap;
       
   715             if (d->formatMajor < 4) {
       
   716                 s >> ip >> pixmap;
       
   717                 painter->drawPixmap(ip, pixmap);
       
   718             } else if (d->formatMajor <= 5) {
       
   719                 s >> ir >> pixmap;
       
   720                 painter->drawPixmap(ir, pixmap);
       
   721             } else {
       
   722                 QRectF sr;
       
   723                 if (d->in_memory_only) {
       
   724                     int index;
       
   725                     s >> r >> index >> sr;
       
   726                     Q_ASSERT(index < d->pixmap_list.size());
       
   727                     pixmap = d->pixmap_list.at(index);
       
   728                 } else {
       
   729                     s >> r >> pixmap >> sr;
       
   730                 }
       
   731                 painter->drawPixmap(r, pixmap, sr);
       
   732             }
       
   733         }
       
   734             break;
       
   735         case QPicturePrivate::PdcDrawTiledPixmap: {
       
   736             QPixmap pixmap;
       
   737             if (d->in_memory_only) {
       
   738                 int index;
       
   739                 s >> r >> index >> p;
       
   740                 Q_ASSERT(index < d->pixmap_list.size());
       
   741                 pixmap = d->pixmap_list.at(index);
       
   742             } else {
       
   743                 s >> r >> pixmap >> p;
       
   744             }
       
   745             painter->drawTiledPixmap(r, pixmap, p);
       
   746         }
       
   747             break;
       
   748         case QPicturePrivate::PdcDrawImage: {
       
   749             QImage image;
       
   750             if (d->formatMajor < 4) {
       
   751                 s >> p >> image;
       
   752                 painter->drawImage(p, image);
       
   753             } else if (d->formatMajor <= 5){
       
   754                 s >> ir >> image;
       
   755                 painter->drawImage(ir, image, QRect(0, 0, ir.width(), ir.height()));
       
   756             } else {
       
   757                 QRectF sr;
       
   758                 if (d->in_memory_only) {
       
   759                     int index;
       
   760                     s >> r >> index >> sr >> ul;
       
   761                     Q_ASSERT(index < d->image_list.size());
       
   762                     image = d->image_list.at(index);
       
   763                 } else {
       
   764                     s >> r >> image >> sr >> ul;
       
   765                 }
       
   766                 painter->drawImage(r, image, sr, Qt::ImageConversionFlags(ul));
       
   767             }
       
   768         }
       
   769             break;
       
   770         case QPicturePrivate::PdcBegin:
       
   771             s >> ul;                        // number of records
       
   772             if (!exec(painter, s, ul))
       
   773                 return false;
       
   774             break;
       
   775         case QPicturePrivate::PdcEnd:
       
   776             if (nrecords == 0)
       
   777                 return true;
       
   778             break;
       
   779         case QPicturePrivate::PdcSave:
       
   780             painter->save();
       
   781             break;
       
   782         case QPicturePrivate::PdcRestore:
       
   783             painter->restore();
       
   784             break;
       
   785         case QPicturePrivate::PdcSetBkColor:
       
   786             s >> color;
       
   787             painter->setBackground(color);
       
   788             break;
       
   789         case QPicturePrivate::PdcSetBkMode:
       
   790             s >> i_8;
       
   791             painter->setBackgroundMode((Qt::BGMode)i_8);
       
   792             break;
       
   793         case QPicturePrivate::PdcSetROP: // NOP
       
   794             s >> i_8;
       
   795             break;
       
   796         case QPicturePrivate::PdcSetBrushOrigin:
       
   797             if (d->formatMajor <= 5) {
       
   798                 s >> ip;
       
   799                 painter->setBrushOrigin(ip);
       
   800             } else {
       
   801                 s >> p;
       
   802                 painter->setBrushOrigin(p);
       
   803             }
       
   804             break;
       
   805         case QPicturePrivate::PdcSetFont:
       
   806             s >> font;
       
   807             painter->setFont(font);
       
   808             break;
       
   809         case QPicturePrivate::PdcSetPen:
       
   810             if (d->in_memory_only) {
       
   811                 int index;
       
   812                 s >> index;
       
   813                 Q_ASSERT(index < d->pen_list.size());
       
   814                 pen = d->pen_list.at(index);
       
   815             } else {
       
   816                 s >> pen;
       
   817             }
       
   818             painter->setPen(pen);
       
   819             break;
       
   820         case QPicturePrivate::PdcSetBrush:
       
   821             if (d->in_memory_only) {
       
   822                 int index;
       
   823                 s >> index;
       
   824                 Q_ASSERT(index < d->brush_list.size());
       
   825                 brush = d->brush_list.at(index);
       
   826             } else {
       
   827                 s >> brush;
       
   828             }
       
   829             painter->setBrush(brush);
       
   830             break;
       
   831 // #ifdef Q_Q3PAINTER
       
   832 //         case QPicturePrivate::PdcSetTabStops:
       
   833 //                 s >> i_16;
       
   834 //                 painter->setTabStops(i_16);
       
   835 //                 break;
       
   836 //             case QPicturePrivate::PdcSetTabArray:
       
   837 //                 s >> i_16;
       
   838 //                 if (i_16 == 0) {
       
   839 //                     painter->setTabArray(0);
       
   840 //                 } else {
       
   841 //                     int *ta = new int[i_16];
       
   842 //                     for (int i=0; i<i_16; i++) {
       
   843 //                         s >> i1_16;
       
   844 //                         ta[i] = i1_16;
       
   845 //                     }
       
   846 //                     painter->setTabArray(ta);
       
   847 //                     delete [] ta;
       
   848 //                 }
       
   849 //                 break;
       
   850 // #endif
       
   851         case QPicturePrivate::PdcSetVXform:
       
   852             s >> i_8;
       
   853             painter->setViewTransformEnabled(i_8);
       
   854             break;
       
   855         case QPicturePrivate::PdcSetWindow:
       
   856             if (d->formatMajor <= 5) {
       
   857                 s >> ir;
       
   858                 painter->setWindow(ir);
       
   859             } else {
       
   860                 s >> r;
       
   861                 painter->setWindow(r.toRect());
       
   862             }
       
   863             break;
       
   864         case QPicturePrivate::PdcSetViewport:
       
   865             if (d->formatMajor <= 5) {
       
   866                 s >> ir;
       
   867                 painter->setViewport(ir);
       
   868             } else {
       
   869                 s >> r;
       
   870                 painter->setViewport(r.toRect());
       
   871             }
       
   872             break;
       
   873         case QPicturePrivate::PdcSetWXform:
       
   874             s >> i_8;
       
   875             painter->setMatrixEnabled(i_8);
       
   876             break;
       
   877         case QPicturePrivate::PdcSetWMatrix:
       
   878             if (d->formatMajor >= 8) {
       
   879                 s >> matrix >> i_8;
       
   880             } else {
       
   881                 s >> wmatrix >> i_8;
       
   882                 matrix = QTransform(wmatrix);
       
   883             }
       
   884             // i_8 is always false due to updateXForm() in qpaintengine_pic.cpp
       
   885             painter->setTransform(matrix * worldMatrix, i_8);
       
   886             break;
       
   887 // #ifdef Q_Q3PAINTER
       
   888 //             case QPicturePrivate::PdcSaveWMatrix:
       
   889 //                 painter->saveWorldMatrix();
       
   890 //                 break;
       
   891 //             case QPicturePrivate::PdcRestoreWMatrix:
       
   892 //                 painter->restoreWorldMatrix();
       
   893 //                 break;
       
   894 // #endif
       
   895         case QPicturePrivate::PdcSetClip:
       
   896             s >> i_8;
       
   897             painter->setClipping(i_8);
       
   898             break;
       
   899         case QPicturePrivate::PdcSetClipRegion:
       
   900             s >> rgn >> i_8;
       
   901             if (d->formatMajor >= 9) {
       
   902                 painter->setClipRegion(rgn, Qt::ClipOperation(i_8));
       
   903             } else {
       
   904                 painter->setClipRegion(rgn);
       
   905             }
       
   906             break;
       
   907         case QPicturePrivate::PdcSetClipPath:
       
   908             {
       
   909                 QPainterPath path;
       
   910                 s >> path >> i_8;
       
   911                 painter->setClipPath(path, Qt::ClipOperation(i_8));
       
   912                 break;
       
   913             }
       
   914         case QPicturePrivate::PdcSetRenderHint:
       
   915             s >> ul;
       
   916             painter->setRenderHint(QPainter::Antialiasing,
       
   917                                    bool(ul & QPainter::Antialiasing));
       
   918             painter->setRenderHint(QPainter::SmoothPixmapTransform,
       
   919                                    bool(ul & QPainter::SmoothPixmapTransform));
       
   920             break;
       
   921         case QPicturePrivate::PdcSetCompositionMode:
       
   922             s >> ul;
       
   923             painter->setCompositionMode((QPainter::CompositionMode)ul);
       
   924             break;
       
   925         case QPicturePrivate::PdcSetClipEnabled:
       
   926             s >> bl;
       
   927             painter->setClipping(bl);
       
   928             break;
       
   929         case QPicturePrivate::PdcSetOpacity:
       
   930             s >> dbl;
       
   931             painter->setOpacity(qreal(dbl));
       
   932             break;
       
   933         default:
       
   934             qWarning("QPicture::play: Invalid command %d", c);
       
   935             if (len)                        // skip unknown command
       
   936                 s.device()->seek(s.device()->pos()+len);
       
   937         }
       
   938 #if defined(QT_DEBUG)
       
   939         //qDebug("device->at(): %i, strm_pos: %i len: %i", (int)s.device()->pos(), strm_pos, len);
       
   940         Q_ASSERT(qint32(s.device()->pos() - strm_pos) == len);
       
   941 #endif
       
   942     }
       
   943     return false;
       
   944 }
       
   945 
       
   946 /*!
       
   947     \internal
       
   948 
       
   949     Internal implementation of the virtual QPaintDevice::metric()
       
   950     function.
       
   951 
       
   952     A picture has the following hard-coded values: numcolors=16777216
       
   953     and depth=24.
       
   954 
       
   955     \a m is the metric to get.
       
   956 */
       
   957 
       
   958 int QPicture::metric(PaintDeviceMetric m) const
       
   959 {
       
   960     int val;
       
   961     QRect brect = boundingRect();
       
   962     switch (m) {
       
   963         case PdmWidth:
       
   964             val = brect.width();
       
   965             break;
       
   966         case PdmHeight:
       
   967             val = brect.height();
       
   968             break;
       
   969         case PdmWidthMM:
       
   970             val = int(25.4/qt_defaultDpiX()*brect.width());
       
   971             break;
       
   972         case PdmHeightMM:
       
   973             val = int(25.4/qt_defaultDpiY()*brect.height());
       
   974             break;
       
   975         case PdmDpiX:
       
   976         case PdmPhysicalDpiX:
       
   977             val = qt_defaultDpiX();
       
   978             break;
       
   979         case PdmDpiY:
       
   980         case PdmPhysicalDpiY:
       
   981             val = qt_defaultDpiY();
       
   982             break;
       
   983         case PdmNumColors:
       
   984             val = 16777216;
       
   985             break;
       
   986         case PdmDepth:
       
   987             val = 24;
       
   988             break;
       
   989         default:
       
   990             val = 0;
       
   991             qWarning("QPicture::metric: Invalid metric command");
       
   992     }
       
   993     return val;
       
   994 }
       
   995 
       
   996 /*!
       
   997     \fn void QPicture::detach()
       
   998     \internal
       
   999     Detaches from shared picture data and makes sure that this picture
       
  1000     is the only one referring to the data.
       
  1001 
       
  1002     If multiple pictures share common data, this picture makes a copy
       
  1003     of the data and detaches itself from the sharing mechanism.
       
  1004     Nothing is done if there is just a single reference.
       
  1005 */
       
  1006 
       
  1007 /*! \fn bool QPicture::isDetached() const
       
  1008 \internal
       
  1009 */
       
  1010 
       
  1011 /*! \internal
       
  1012 ### Qt 5 - remove me
       
  1013  */
       
  1014 void QPicture::detach_helper()
       
  1015 {
       
  1016     // QExplicitelySharedDataPointer takes care of cloning using
       
  1017     // QPicturePrivate's copy constructor. Do not call detach_helper() anymore
       
  1018     // and remove in Qt 5, please.
       
  1019     Q_ASSERT_X(false, "QPicture::detach_helper()", "Do not call this function");
       
  1020 }
       
  1021 
       
  1022 /*!
       
  1023     Assigns picture \a p to this picture and returns a reference to
       
  1024     this picture.
       
  1025 */
       
  1026 QPicture& QPicture::operator=(const QPicture &p)
       
  1027 {
       
  1028     d_ptr = p.d_ptr;
       
  1029     return *this;
       
  1030 }
       
  1031 
       
  1032 /*!
       
  1033   \internal
       
  1034 
       
  1035   Constructs a QPicturePrivate
       
  1036 */
       
  1037 QPicturePrivate::QPicturePrivate()
       
  1038     : in_memory_only(false)
       
  1039 {
       
  1040 }
       
  1041 
       
  1042 /*!
       
  1043   \internal
       
  1044 
       
  1045   Copy-Constructs a QPicturePrivate. Needed when detaching.
       
  1046 */
       
  1047 QPicturePrivate::QPicturePrivate(const QPicturePrivate &other)
       
  1048     : trecs(other.trecs),
       
  1049       formatOk(other.formatOk),
       
  1050       formatMinor(other.formatMinor),
       
  1051       brect(other.brect),
       
  1052       override_rect(other.override_rect),
       
  1053       in_memory_only(false)
       
  1054 {
       
  1055     pictb.setData(other.pictb.data(), other.pictb.size());
       
  1056     if (other.pictb.isOpen()) {
       
  1057         pictb.open(other.pictb.openMode());
       
  1058         pictb.seek(other.pictb.pos());
       
  1059     }
       
  1060 }
       
  1061 
       
  1062 /*!
       
  1063   \internal
       
  1064 
       
  1065   Sets formatOk to false and resets the format version numbers to default
       
  1066 */
       
  1067 
       
  1068 void QPicturePrivate::resetFormat()
       
  1069 {
       
  1070     formatOk = false;
       
  1071     formatMajor = mfhdr_maj;
       
  1072     formatMinor = mfhdr_min;
       
  1073 }
       
  1074 
       
  1075 
       
  1076 /*!
       
  1077   \internal
       
  1078 
       
  1079   Checks data integrity and format version number. Set formatOk to
       
  1080   true on success, to false otherwise. Returns the resulting formatOk
       
  1081   value.
       
  1082 */
       
  1083 bool QPicturePrivate::checkFormat()
       
  1084 {
       
  1085     resetFormat();
       
  1086 
       
  1087     // can't check anything in an empty buffer
       
  1088     if (pictb.size() == 0 || pictb.isOpen())
       
  1089         return false;
       
  1090 
       
  1091     pictb.open(QIODevice::ReadOnly);                        // open buffer device
       
  1092     QDataStream s;
       
  1093     s.setDevice(&pictb);                        // attach data stream to buffer
       
  1094 
       
  1095     char mf_id[4];                                // picture header tag
       
  1096     s.readRawData(mf_id, 4);                        // read actual tag
       
  1097     if (memcmp(mf_id, qt_mfhdr_tag, 4) != 0) {         // wrong header id
       
  1098         qWarning("QPicturePaintEngine::checkFormat: Incorrect header");
       
  1099         pictb.close();
       
  1100         return false;
       
  1101     }
       
  1102 
       
  1103     int cs_start = sizeof(quint32);                // pos of checksum word
       
  1104     int data_start = cs_start + sizeof(quint16);
       
  1105     quint16 cs,ccs;
       
  1106     QByteArray buf = pictb.buffer();        // pointer to data
       
  1107 
       
  1108     s >> cs;                                // read checksum
       
  1109     ccs = (quint16) qChecksum(buf.constData() + data_start, buf.size() - data_start);
       
  1110     if (ccs != cs) {
       
  1111         qWarning("QPicturePaintEngine::checkFormat: Invalid checksum %x, %x expected",
       
  1112                   ccs, cs);
       
  1113         pictb.close();
       
  1114         return false;
       
  1115     }
       
  1116 
       
  1117     quint16 major, minor;
       
  1118     s >> major >> minor;                        // read version number
       
  1119     if (major > mfhdr_maj) {                // new, incompatible version
       
  1120         qWarning("QPicturePaintEngine::checkFormat: Incompatible version %d.%d",
       
  1121                   major, minor);
       
  1122         pictb.close();
       
  1123         return false;
       
  1124     }
       
  1125     s.setVersion(major != 4 ? major : 3);
       
  1126 
       
  1127     quint8  c, clen;
       
  1128     s >> c >> clen;
       
  1129     if (c == QPicturePrivate::PdcBegin) {
       
  1130         if (!(major >= 1 && major <= 3)) {
       
  1131             qint32 l, t, w, h;
       
  1132             s >> l >> t >> w >> h;
       
  1133             brect = QRect(l, t, w, h);
       
  1134         }
       
  1135     } else {
       
  1136         qWarning("QPicturePaintEngine::checkFormat: Format error");
       
  1137         pictb.close();
       
  1138         return false;
       
  1139     }
       
  1140     pictb.close();
       
  1141 
       
  1142     formatOk = true;                        // picture seems to be ok
       
  1143     formatMajor = major;
       
  1144     formatMinor = minor;
       
  1145     return true;
       
  1146 }
       
  1147 
       
  1148 /*! \internal */
       
  1149 QPaintEngine *QPicture::paintEngine() const
       
  1150 {
       
  1151     if (!d_func()->paintEngine)
       
  1152         const_cast<QPicture*>(this)->d_func()->paintEngine.reset(new QPicturePaintEngine);
       
  1153     return d_func()->paintEngine.data();
       
  1154 }
       
  1155 
       
  1156 /*****************************************************************************
       
  1157   QPicture stream functions
       
  1158  *****************************************************************************/
       
  1159 
       
  1160 #ifndef QT_NO_DATASTREAM
       
  1161 /*!
       
  1162     \relates QPicture
       
  1163 
       
  1164     Writes picture \a r to the stream \a s and returns a reference to
       
  1165     the stream.
       
  1166 */
       
  1167 
       
  1168 QDataStream &operator<<(QDataStream &s, const QPicture &r)
       
  1169 {
       
  1170     quint32 size = r.d_func()->pictb.buffer().size();
       
  1171     s << size;
       
  1172     // null picture ?
       
  1173     if (size == 0)
       
  1174         return s;
       
  1175     // just write the whole buffer to the stream
       
  1176     s.writeRawData (r.d_func()->pictb.buffer(), r.d_func()->pictb.buffer().size());
       
  1177     return s;
       
  1178 }
       
  1179 
       
  1180 /*!
       
  1181     \relates QPicture
       
  1182 
       
  1183     Reads a picture from the stream \a s into picture \a r and returns
       
  1184     a reference to the stream.
       
  1185 */
       
  1186 
       
  1187 QDataStream &operator>>(QDataStream &s, QPicture &r)
       
  1188 {
       
  1189     QDataStream sr;
       
  1190 
       
  1191     // "init"; this code is similar to the beginning of QPicture::cmd()
       
  1192     sr.setDevice(&r.d_func()->pictb);
       
  1193     sr.setVersion(r.d_func()->formatMajor);
       
  1194     quint32 len;
       
  1195     s >> len;
       
  1196     QByteArray data;
       
  1197     if (len > 0) {
       
  1198         data.resize(len);
       
  1199         s.readRawData(data.data(), len);
       
  1200     }
       
  1201 
       
  1202     r.d_func()->pictb.setData(data);
       
  1203     r.d_func()->resetFormat();
       
  1204     return s;
       
  1205 }
       
  1206 #endif // QT_NO_DATASTREAM
       
  1207 
       
  1208 
       
  1209 #ifndef QT_NO_PICTUREIO
       
  1210 
       
  1211 QT_BEGIN_INCLUDE_NAMESPACE
       
  1212 #include "qregexp.h"
       
  1213 #include "qapplication.h"
       
  1214 #include "qpictureformatplugin.h"
       
  1215 QT_END_INCLUDE_NAMESPACE
       
  1216 
       
  1217 /*!
       
  1218     \obsolete
       
  1219 
       
  1220     Returns a string that specifies the picture format of the file \a
       
  1221     fileName, or 0 if the file cannot be read or if the format is not
       
  1222     recognized.
       
  1223 
       
  1224     \sa load() save()
       
  1225 */
       
  1226 
       
  1227 const char* QPicture::pictureFormat(const QString &fileName)
       
  1228 {
       
  1229     return QPictureIO::pictureFormat(fileName);
       
  1230 }
       
  1231 
       
  1232 /*!
       
  1233     \obsolete
       
  1234 
       
  1235     Returns a list of picture formats that are supported for picture
       
  1236     input.
       
  1237 
       
  1238     \sa outputFormats() inputFormatList() QPictureIO
       
  1239 */
       
  1240 QList<QByteArray> QPicture::inputFormats()
       
  1241 {
       
  1242     return QPictureIO::inputFormats();
       
  1243 }
       
  1244 
       
  1245 static QStringList qToStringList(const QList<QByteArray> arr)
       
  1246 {
       
  1247     QStringList list;
       
  1248     for (int i = 0; i < arr.count(); ++i)
       
  1249         list.append(QString::fromLatin1(arr.at(i)));
       
  1250     return list;
       
  1251 }
       
  1252 
       
  1253 /*!
       
  1254     \obsolete
       
  1255 
       
  1256     Returns a list of picture formats that are supported for picture
       
  1257     input.
       
  1258 
       
  1259     Note that if you want to iterate over the list, you should iterate
       
  1260     over a copy, e.g.
       
  1261     \snippet doc/src/snippets/picture/picture.cpp 2
       
  1262 
       
  1263     \sa outputFormatList() inputFormats() QPictureIO
       
  1264 */
       
  1265 QStringList QPicture::inputFormatList()
       
  1266 {
       
  1267     return qToStringList(QPictureIO::inputFormats());
       
  1268 }
       
  1269 
       
  1270 
       
  1271 /*!
       
  1272     \obsolete
       
  1273 
       
  1274     Returns a list of picture formats that are supported for picture
       
  1275     output.
       
  1276 
       
  1277     Note that if you want to iterate over the list, you should iterate
       
  1278     over a copy, e.g.
       
  1279     \snippet doc/src/snippets/picture/picture.cpp 3
       
  1280 
       
  1281     \sa inputFormatList() outputFormats() QPictureIO
       
  1282 */
       
  1283 QStringList QPicture::outputFormatList()
       
  1284 {
       
  1285     return qToStringList(QPictureIO::outputFormats());
       
  1286 }
       
  1287 
       
  1288 /*!
       
  1289     \obsolete
       
  1290 
       
  1291     Returns a list of picture formats that are supported for picture
       
  1292     output.
       
  1293 
       
  1294     \sa inputFormats() outputFormatList() QPictureIO
       
  1295 */
       
  1296 QList<QByteArray> QPicture::outputFormats()
       
  1297 {
       
  1298     return QPictureIO::outputFormats();
       
  1299 }
       
  1300 
       
  1301 /*****************************************************************************
       
  1302   QPictureIO member functions
       
  1303  *****************************************************************************/
       
  1304 
       
  1305 /*!
       
  1306     \obsolete
       
  1307 
       
  1308     \class QPictureIO
       
  1309 
       
  1310     \brief The QPictureIO class contains parameters for loading and
       
  1311     saving pictures.
       
  1312 
       
  1313     \ingroup painting
       
  1314     \ingroup io
       
  1315 
       
  1316     QPictureIO contains a QIODevice object that is used for picture data
       
  1317     I/O. The programmer can install new picture file formats in addition
       
  1318     to those that Qt provides.
       
  1319 
       
  1320     You don't normally need to use this class; QPicture::load(),
       
  1321     QPicture::save().
       
  1322 
       
  1323     \sa QPicture QPixmap QFile
       
  1324 */
       
  1325 
       
  1326 struct QPictureIOData
       
  1327 {
       
  1328     QPicture        pi;                                // picture
       
  1329     int                iostat;                                // IO status
       
  1330     QByteArray        frmt;                                // picture format
       
  1331     QIODevice  *iodev;                                // IO device
       
  1332     QString        fname;                                // file name
       
  1333     QString     descr;                                // picture description
       
  1334     const char *parameters;
       
  1335     int quality;
       
  1336     float gamma;
       
  1337 };
       
  1338 
       
  1339 /*!
       
  1340     Constructs a QPictureIO object with all parameters set to zero.
       
  1341 */
       
  1342 
       
  1343 QPictureIO::QPictureIO()
       
  1344 {
       
  1345     init();
       
  1346 }
       
  1347 
       
  1348 /*!
       
  1349     Constructs a QPictureIO object with the I/O device \a ioDevice and a
       
  1350     \a format tag.
       
  1351 */
       
  1352 
       
  1353 QPictureIO::QPictureIO(QIODevice *ioDevice, const char *format)
       
  1354 {
       
  1355     init();
       
  1356     d->iodev = ioDevice;
       
  1357     d->frmt = format;
       
  1358 }
       
  1359 
       
  1360 /*!
       
  1361     Constructs a QPictureIO object with the file name \a fileName and a
       
  1362     \a format tag.
       
  1363 */
       
  1364 
       
  1365 QPictureIO::QPictureIO(const QString &fileName, const char* format)
       
  1366 {
       
  1367     init();
       
  1368     d->frmt = format;
       
  1369     d->fname = fileName;
       
  1370 }
       
  1371 
       
  1372 /*!
       
  1373     Contains initialization common to all QPictureIO constructors.
       
  1374 */
       
  1375 
       
  1376 void QPictureIO::init()
       
  1377 {
       
  1378     d = new QPictureIOData();
       
  1379     d->parameters = 0;
       
  1380     d->quality = -1; // default quality of the current format
       
  1381     d->gamma=0.0f;
       
  1382     d->iostat = 0;
       
  1383     d->iodev  = 0;
       
  1384 }
       
  1385 
       
  1386 /*!
       
  1387     Destroys the object and all related data.
       
  1388 */
       
  1389 
       
  1390 QPictureIO::~QPictureIO()
       
  1391 {
       
  1392     if (d->parameters)
       
  1393         delete [] (char*)d->parameters;
       
  1394     delete d;
       
  1395 }
       
  1396 
       
  1397 
       
  1398 /*****************************************************************************
       
  1399   QPictureIO picture handler functions
       
  1400  *****************************************************************************/
       
  1401 
       
  1402 class QPictureHandler
       
  1403 {
       
  1404 public:
       
  1405     QPictureHandler(const char *f, const char *h, const QByteArray& fl,
       
  1406                      picture_io_handler r, picture_io_handler w);
       
  1407     QByteArray              format;                        // picture format
       
  1408     QRegExp              header;                        // picture header pattern
       
  1409     enum TMode { Untranslated=0, TranslateIn, TranslateInOut } text_mode;
       
  1410     picture_io_handler  read_picture;                // picture read function
       
  1411     picture_io_handler  write_picture;                // picture write function
       
  1412     bool              obsolete;                        // support not "published"
       
  1413 };
       
  1414 
       
  1415 QPictureHandler::QPictureHandler(const char *f, const char *h, const QByteArray& fl,
       
  1416                               picture_io_handler r, picture_io_handler w)
       
  1417     : format(f), header(QString::fromLatin1(h))
       
  1418 {
       
  1419     text_mode = Untranslated;
       
  1420     if (fl.contains('t'))
       
  1421         text_mode = TranslateIn;
       
  1422     else if (fl.contains('T'))
       
  1423         text_mode = TranslateInOut;
       
  1424     obsolete = fl.contains('O');
       
  1425     read_picture  = r;
       
  1426     write_picture = w;
       
  1427 }
       
  1428 
       
  1429 typedef QList<QPictureHandler *> QPHList;
       
  1430 Q_GLOBAL_STATIC(QPHList, pictureHandlers)
       
  1431 
       
  1432 #ifndef QT_NO_LIBRARY
       
  1433 Q_GLOBAL_STATIC(QMutex, mutex)
       
  1434 Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, factoryLoader,
       
  1435                           (QPictureFormatInterface_iid,
       
  1436                            QLatin1String("/pictureformats")))
       
  1437 #endif
       
  1438 void qt_init_picture_plugins()
       
  1439 {
       
  1440 #ifndef QT_NO_LIBRARY
       
  1441     QMutexLocker locker(mutex());
       
  1442     QFactoryLoader *loader = factoryLoader();
       
  1443     QStringList keys = loader->keys();
       
  1444     for (int i = 0; i < keys.count(); ++i)
       
  1445         if (QPictureFormatInterface *format = qobject_cast<QPictureFormatInterface*>(loader->instance(keys.at(i))))
       
  1446             format->installIOHandler(keys.at(i));
       
  1447 #endif
       
  1448 }
       
  1449 
       
  1450 static void cleanup()
       
  1451 {
       
  1452     // make sure that picture handlers are delete before plugin manager
       
  1453     if (QPHList *list = pictureHandlers()) {
       
  1454         qDeleteAll(*list);
       
  1455         list->clear();
       
  1456     }
       
  1457 }
       
  1458 
       
  1459 void qt_init_picture_handlers()                // initialize picture handlers
       
  1460 {
       
  1461     static QBasicAtomicInt done = Q_BASIC_ATOMIC_INITIALIZER(0);
       
  1462     if (done.testAndSetRelaxed(0, 1)) {
       
  1463         qAddPostRoutine(cleanup);
       
  1464     }
       
  1465 }
       
  1466 
       
  1467 static QPictureHandler *get_picture_handler(const char *format)
       
  1468 {                                                // get pointer to handler
       
  1469     qt_init_picture_handlers();
       
  1470     qt_init_picture_plugins();
       
  1471     if (QPHList *list = pictureHandlers()) {
       
  1472         for (int i = 0; i < list->size(); ++i) {
       
  1473             if (list->at(i)->format == format)
       
  1474                 return list->at(i);
       
  1475         }
       
  1476     }
       
  1477     return 0;                                        // no such handler
       
  1478 }
       
  1479 
       
  1480 
       
  1481 /*!
       
  1482     Defines a picture I/O handler for the picture format called \a
       
  1483     format, which is recognized using the regular
       
  1484     expression defined in \a header, read using \a readPicture and
       
  1485     written using \a writePicture.
       
  1486 
       
  1487     \a flags is a string of single-character flags for this format.
       
  1488     The only flag defined currently is T (upper case), so the only
       
  1489     legal value for \a flags are "T" and the empty string. The "T"
       
  1490     flag means that the picture file is a text file, and Qt should treat
       
  1491     all newline conventions as equivalent. (XPM files and some PPM
       
  1492     files are text files for example.)
       
  1493 
       
  1494     \a format is used to select a handler to write a QPicture; \a header
       
  1495     is used to select a handler to read an picture file.
       
  1496 
       
  1497     If \a readPicture is a null pointer, the QPictureIO will not be able
       
  1498     to read pictures in \a format. If \a writePicture is a null pointer,
       
  1499     the QPictureIO will not be able to write pictures in \a format. If
       
  1500     both are null, the QPictureIO object is valid but useless.
       
  1501 
       
  1502     Example:
       
  1503     \snippet doc/src/snippets/picture/picture.cpp 6
       
  1504     \codeline
       
  1505     \snippet doc/src/snippets/picture/picture.cpp 7
       
  1506     \codeline
       
  1507     \snippet doc/src/snippets/picture/picture.cpp 8
       
  1508 
       
  1509     Before the regular expression test, all the 0 bytes in the file header are
       
  1510     converted to 1 bytes. This is done because when Qt was ASCII-based, QRegExp
       
  1511     could not handle 0 bytes in strings.
       
  1512 
       
  1513     The regexp is only applied on the first 14 bytes of the file.
       
  1514 
       
  1515     (Note that if one handlerIO supports writing a format and another
       
  1516     supports reading it, Qt supports both reading and writing. If two
       
  1517     handlers support the same operation, Qt chooses one arbitrarily.)
       
  1518 */
       
  1519 
       
  1520 void QPictureIO::defineIOHandler(const char *format,
       
  1521                                  const char *header,
       
  1522                                  const char *flags,
       
  1523                                  picture_io_handler readPicture,
       
  1524                                  picture_io_handler writePicture)
       
  1525 {
       
  1526     qt_init_picture_handlers();
       
  1527     if (QPHList *list = pictureHandlers()) {
       
  1528         QPictureHandler *p;
       
  1529         p = new QPictureHandler(format, header, QByteArray(flags), readPicture, writePicture);
       
  1530         list->prepend(p);
       
  1531     }
       
  1532 }
       
  1533 
       
  1534 
       
  1535 /*****************************************************************************
       
  1536   QPictureIO normal member functions
       
  1537  *****************************************************************************/
       
  1538 
       
  1539 /*!
       
  1540     Returns the picture currently set.
       
  1541 
       
  1542     \sa setPicture()
       
  1543 */
       
  1544 const QPicture &QPictureIO::picture() const { return d->pi; }
       
  1545 
       
  1546 /*!
       
  1547     Returns the picture's IO status. A non-zero value indicates an
       
  1548     error, whereas 0 means that the IO operation was successful.
       
  1549 
       
  1550     \sa setStatus()
       
  1551 */
       
  1552 int QPictureIO::status() const { return d->iostat; }
       
  1553 
       
  1554 /*!
       
  1555     Returns the picture format string or 0 if no format has been
       
  1556     explicitly set.
       
  1557 */
       
  1558 const char *QPictureIO::format() const { return d->frmt; }
       
  1559 
       
  1560 /*!
       
  1561     Returns the IO device currently set.
       
  1562 
       
  1563     \sa setIODevice()
       
  1564 */
       
  1565 QIODevice *QPictureIO::ioDevice() const { return d->iodev; }
       
  1566 
       
  1567 /*!
       
  1568     Returns the file name currently set.
       
  1569 
       
  1570     \sa setFileName()
       
  1571 */
       
  1572 QString QPictureIO::fileName() const { return d->fname; }
       
  1573 
       
  1574 
       
  1575 /*!
       
  1576     Returns the picture description string.
       
  1577 
       
  1578     \sa setDescription()
       
  1579 */
       
  1580 QString QPictureIO::description() const { return d->descr; }
       
  1581 
       
  1582 /*!
       
  1583     Sets the picture to \a picture.
       
  1584 
       
  1585     \sa picture()
       
  1586 */
       
  1587 void QPictureIO::setPicture(const QPicture &picture)
       
  1588 {
       
  1589     d->pi = picture;
       
  1590 }
       
  1591 
       
  1592 /*!
       
  1593     Sets the picture IO status to \a status. A non-zero value indicates
       
  1594     an error, whereas 0 means that the IO operation was successful.
       
  1595 
       
  1596     \sa status()
       
  1597 */
       
  1598 void QPictureIO::setStatus(int status)
       
  1599 {
       
  1600     d->iostat = status;
       
  1601 }
       
  1602 
       
  1603 /*!
       
  1604     Sets the picture format to \a format for the picture to be read or
       
  1605     written.
       
  1606 
       
  1607     It is necessary to specify a format before writing an picture, but
       
  1608     it is not necessary to specify a format before reading an picture.
       
  1609 
       
  1610     If no format has been set, Qt guesses the picture format before
       
  1611     reading it. If a format is set the picture will only be read if it
       
  1612     has that format.
       
  1613 
       
  1614     \sa read() write() format()
       
  1615 */
       
  1616 void QPictureIO::setFormat(const char *format)
       
  1617 {
       
  1618     d->frmt = format;
       
  1619 }
       
  1620 
       
  1621 /*!
       
  1622     Sets the IO device to be used for reading or writing an picture.
       
  1623 
       
  1624     Setting the IO device allows pictures to be read/written to any
       
  1625     block-oriented QIODevice.
       
  1626 
       
  1627     If \a ioDevice is not null, this IO device will override file name
       
  1628     settings.
       
  1629 
       
  1630     \sa setFileName()
       
  1631 */
       
  1632 void QPictureIO::setIODevice(QIODevice *ioDevice)
       
  1633 {
       
  1634     d->iodev = ioDevice;
       
  1635 }
       
  1636 
       
  1637 /*!
       
  1638     Sets the name of the file to read or write an picture from to \a
       
  1639     fileName.
       
  1640 
       
  1641     \sa setIODevice()
       
  1642 */
       
  1643 void QPictureIO::setFileName(const QString &fileName)
       
  1644 {
       
  1645     d->fname = fileName;
       
  1646 }
       
  1647 
       
  1648 /*!
       
  1649     Returns the quality of the written picture, related to the
       
  1650     compression ratio.
       
  1651 
       
  1652     \sa setQuality() QPicture::save()
       
  1653 */
       
  1654 int QPictureIO::quality() const
       
  1655 {
       
  1656     return d->quality;
       
  1657 }
       
  1658 
       
  1659 /*!
       
  1660     Sets the quality of the written picture to \a q, related to the
       
  1661     compression ratio.
       
  1662 
       
  1663     \a q must be in the range -1..100. Specify 0 to obtain small
       
  1664     compressed files, 100 for large uncompressed files. (-1 signifies
       
  1665     the default compression.)
       
  1666 
       
  1667     \sa quality() QPicture::save()
       
  1668 */
       
  1669 
       
  1670 void QPictureIO::setQuality(int q)
       
  1671 {
       
  1672     d->quality = q;
       
  1673 }
       
  1674 
       
  1675 /*!
       
  1676     Returns the picture's parameters string.
       
  1677 
       
  1678     \sa setParameters()
       
  1679 */
       
  1680 
       
  1681 const char *QPictureIO::parameters() const
       
  1682 {
       
  1683     return d->parameters;
       
  1684 }
       
  1685 
       
  1686 /*!
       
  1687     Sets the picture's parameter string to \a parameters. This is for
       
  1688     picture handlers that require special parameters.
       
  1689 
       
  1690     Although the current picture formats supported by Qt ignore the
       
  1691     parameters string, it may be used in future extensions or by
       
  1692     contributions (for example, JPEG).
       
  1693 
       
  1694     \sa parameters()
       
  1695 */
       
  1696 
       
  1697 void QPictureIO::setParameters(const char *parameters)
       
  1698 {
       
  1699     if (d->parameters)
       
  1700         delete [] (char*)d->parameters;
       
  1701     d->parameters = qstrdup(parameters);
       
  1702 }
       
  1703 
       
  1704 /*!
       
  1705     Sets the gamma value at which the picture will be viewed to \a
       
  1706     gamma. If the picture format stores a gamma value for which the
       
  1707     picture is intended to be used, then this setting will be used to
       
  1708     modify the picture. Setting to 0.0 will disable gamma correction
       
  1709     (i.e. any specification in the file will be ignored).
       
  1710 
       
  1711     The default value is 0.0.
       
  1712 
       
  1713     \sa gamma()
       
  1714 */
       
  1715 void QPictureIO::setGamma(float gamma)
       
  1716 {
       
  1717     d->gamma=gamma;
       
  1718 }
       
  1719 
       
  1720 /*!
       
  1721     Returns the gamma value at which the picture will be viewed.
       
  1722 
       
  1723     \sa setGamma()
       
  1724 */
       
  1725 float QPictureIO::gamma() const
       
  1726 {
       
  1727     return d->gamma;
       
  1728 }
       
  1729 
       
  1730 /*!
       
  1731     Sets the picture description string for picture handlers that support
       
  1732     picture descriptions to \a description.
       
  1733 
       
  1734     Currently, no picture format supported by Qt uses the description
       
  1735     string.
       
  1736 */
       
  1737 
       
  1738 void QPictureIO::setDescription(const QString &description)
       
  1739 {
       
  1740     d->descr = description;
       
  1741 }
       
  1742 
       
  1743 
       
  1744 /*!
       
  1745     Returns a string that specifies the picture format of the file \a
       
  1746     fileName, or null if the file cannot be read or if the format is
       
  1747     not recognized.
       
  1748 */
       
  1749 
       
  1750 QByteArray QPictureIO::pictureFormat(const QString &fileName)
       
  1751 {
       
  1752     QFile file(fileName);
       
  1753     QByteArray format;
       
  1754     if (!file.open(QIODevice::ReadOnly))
       
  1755         return format;
       
  1756     format = pictureFormat(&file);
       
  1757     file.close();
       
  1758     return format;
       
  1759 }
       
  1760 
       
  1761 /*!
       
  1762     \overload
       
  1763 
       
  1764     Returns a string that specifies the picture format of the picture read
       
  1765     from IO device \a d, or 0 if the device cannot be read or if the
       
  1766     format is not recognized.
       
  1767 
       
  1768     Make sure that \a d is at the right position in the device (for
       
  1769     example, at the beginning of the file).
       
  1770 
       
  1771     \sa QIODevice::at()
       
  1772 */
       
  1773 
       
  1774 QByteArray QPictureIO::pictureFormat(QIODevice *d)
       
  1775 {
       
  1776     // if you change this change the documentation for defineIOHandler()
       
  1777     const int buflen = 14;
       
  1778 
       
  1779     char buf[buflen];
       
  1780     char buf2[buflen];
       
  1781     qt_init_picture_handlers();
       
  1782     qt_init_picture_plugins();
       
  1783     int pos = d->pos();                      // save position
       
  1784     int rdlen = d->read(buf, buflen);        // read a few bytes
       
  1785 
       
  1786     QByteArray format;
       
  1787     if (rdlen != buflen)
       
  1788         return format;
       
  1789 
       
  1790     memcpy(buf2, buf, buflen);
       
  1791 
       
  1792     for (int n = 0; n < rdlen; n++)
       
  1793         if (buf[n] == '\0')
       
  1794             buf[n] = '\001';
       
  1795     if (rdlen > 0) {
       
  1796         buf[rdlen - 1] = '\0';
       
  1797         QString bufStr = QString::fromLatin1(buf);
       
  1798         if (QPHList *list = pictureHandlers()) {
       
  1799             for (int i = 0; i < list->size(); ++i) {
       
  1800                 if (list->at(i)->header.indexIn(bufStr) != -1) { // try match with headers
       
  1801                     format = list->at(i)->format;
       
  1802                     break;
       
  1803                 }
       
  1804             }
       
  1805         }
       
  1806     }
       
  1807     d->seek(pos);                                // restore position
       
  1808     return format;
       
  1809 }
       
  1810 
       
  1811 /*!
       
  1812     Returns a sorted list of picture formats that are supported for
       
  1813     picture input.
       
  1814 */
       
  1815 QList<QByteArray> QPictureIO::inputFormats()
       
  1816 {
       
  1817     QList<QByteArray> result;
       
  1818 
       
  1819     qt_init_picture_handlers();
       
  1820     qt_init_picture_plugins();
       
  1821 
       
  1822     if (QPHList *list = pictureHandlers()) {
       
  1823         for (int i = 0; i < list->size(); ++i) {
       
  1824             QPictureHandler *p = list->at(i);
       
  1825             if (p->read_picture && !p->obsolete  && !result.contains(p->format))
       
  1826                 result.append(p->format);
       
  1827         }
       
  1828     }
       
  1829     qSort(result);
       
  1830 
       
  1831     return result;
       
  1832 }
       
  1833 
       
  1834 /*!
       
  1835     Returns a sorted list of picture formats that are supported for
       
  1836     picture output.
       
  1837 */
       
  1838 QList<QByteArray> QPictureIO::outputFormats()
       
  1839 {
       
  1840     qt_init_picture_handlers();
       
  1841     qt_init_picture_plugins();
       
  1842 
       
  1843     QList<QByteArray> result;
       
  1844     if (QPHList *list = pictureHandlers()) {
       
  1845         for (int i = 0; i < list->size(); ++i) {
       
  1846             QPictureHandler *p = list->at(i);
       
  1847             if (p->write_picture && !p->obsolete && !result.contains(p->format))
       
  1848                 result.append(p->format);
       
  1849         }
       
  1850     }
       
  1851     return result;
       
  1852 }
       
  1853 
       
  1854 
       
  1855 
       
  1856 /*!
       
  1857     Reads an picture into memory and returns true if the picture was
       
  1858     successfully read; otherwise returns false.
       
  1859 
       
  1860     Before reading an picture you must set an IO device or a file name.
       
  1861     If both an IO device and a file name have been set, the IO device
       
  1862     will be used.
       
  1863 
       
  1864     Setting the picture file format string is optional.
       
  1865 
       
  1866     Note that this function does \e not set the \link format()
       
  1867     format\endlink used to read the picture. If you need that
       
  1868     information, use the pictureFormat() static functions.
       
  1869 
       
  1870     Example:
       
  1871 
       
  1872     \snippet doc/src/snippets/picture/picture.cpp 4
       
  1873 
       
  1874     \sa setIODevice() setFileName() setFormat() write() QPixmap::load()
       
  1875 */
       
  1876 bool QPictureIO::read()
       
  1877 {
       
  1878     QFile           file;
       
  1879     const char          *picture_format;
       
  1880     QPictureHandler *h;
       
  1881 
       
  1882     if (d->iodev) {                                // read from io device
       
  1883         // ok, already open
       
  1884     } else if (!d->fname.isEmpty()) {                // read from file
       
  1885         file.setFileName(d->fname);
       
  1886         if (!file.open(QIODevice::ReadOnly))
       
  1887             return false;                        // cannot open file
       
  1888         d->iodev = &file;
       
  1889     } else {                                        // no file name or io device
       
  1890         return false;
       
  1891     }
       
  1892     if (d->frmt.isEmpty()) {
       
  1893         // Try to guess format
       
  1894         picture_format = pictureFormat(d->iodev);        // get picture format
       
  1895         if (!picture_format) {
       
  1896             if (file.isOpen()) {                        // unknown format
       
  1897                 file.close();
       
  1898                 d->iodev = 0;
       
  1899             }
       
  1900             return false;
       
  1901         }
       
  1902     } else {
       
  1903         picture_format = d->frmt;
       
  1904     }
       
  1905 
       
  1906     h = get_picture_handler(picture_format);
       
  1907     if (file.isOpen()) {
       
  1908 #if !defined(Q_OS_UNIX)
       
  1909         if (h && h->text_mode) {                // reopen in translated mode
       
  1910             file.close();
       
  1911             file.open(QIODevice::ReadOnly | QIODevice::Text);
       
  1912         }
       
  1913         else
       
  1914 #endif
       
  1915             file.seek(0);                        // position to start
       
  1916     }
       
  1917     d->iostat = 1;                                        // assume error
       
  1918 
       
  1919     if (h && h->read_picture)
       
  1920         (*h->read_picture)(this);
       
  1921 
       
  1922     if (file.isOpen()) {                        // picture was read using file
       
  1923         file.close();
       
  1924         d->iodev = 0;
       
  1925     }
       
  1926     return d->iostat == 0;                                // picture successfully read?
       
  1927 }
       
  1928 
       
  1929 
       
  1930 /*!
       
  1931     Writes an picture to an IO device and returns true if the picture was
       
  1932     successfully written; otherwise returns false.
       
  1933 
       
  1934     Before writing an picture you must set an IO device or a file name.
       
  1935     If both an IO device and a file name have been set, the IO device
       
  1936     will be used.
       
  1937 
       
  1938     The picture will be written using the specified picture format.
       
  1939 
       
  1940     Example:
       
  1941     \snippet doc/src/snippets/picture/picture.cpp 5
       
  1942 
       
  1943     \sa setIODevice() setFileName() setFormat() read() QPixmap::save()
       
  1944 */
       
  1945 bool QPictureIO::write()
       
  1946 {
       
  1947     if (d->frmt.isEmpty())
       
  1948         return false;
       
  1949     QPictureHandler *h = get_picture_handler(d->frmt);
       
  1950     if (!h || !h->write_picture) {
       
  1951         qWarning("QPictureIO::write: No such picture format handler: %s",
       
  1952                  format());
       
  1953         return false;
       
  1954     }
       
  1955     QFile file;
       
  1956     if (!d->iodev && !d->fname.isEmpty()) {
       
  1957         file.setFileName(d->fname);
       
  1958         bool translate = h->text_mode==QPictureHandler::TranslateInOut;
       
  1959         QIODevice::OpenMode fmode = translate ? QIODevice::WriteOnly | QIODevice::Text : QIODevice::OpenMode(QIODevice::WriteOnly);
       
  1960         if (!file.open(fmode))                // couldn't create file
       
  1961             return false;
       
  1962         d->iodev = &file;
       
  1963     }
       
  1964     d->iostat = 1;
       
  1965     (*h->write_picture)(this);
       
  1966     if (file.isOpen()) {                        // picture was written using file
       
  1967         file.close();
       
  1968         d->iodev = 0;
       
  1969     }
       
  1970     return d->iostat == 0;                                // picture successfully written?
       
  1971 }
       
  1972 #endif //QT_NO_PICTUREIO
       
  1973 
       
  1974 /*!
       
  1975     \fn QPicture QPicture::copy() const
       
  1976 
       
  1977     Use simple assignment instead.
       
  1978 */
       
  1979 
       
  1980 QT_END_NAMESPACE
       
  1981 
       
  1982 #endif // QT_NO_PICTURE
       
  1983 
       
  1984 /*!
       
  1985     \typedef QPicture::DataPtr
       
  1986     \internal
       
  1987 */
       
  1988 
       
  1989 /*!
       
  1990     \fn DataPtr &QPicture::data_ptr()
       
  1991     \internal
       
  1992 */