~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/image/qbitmap.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the painting module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qbitmap.h"
 
30
#include "qpixmap_p.h"
 
31
#include "qimage.h"
 
32
#include "qvariant.h"
 
33
#include <qpainter.h>
 
34
#if defined(Q_WS_X11)
 
35
#include <private/qt_x11_p.h>
 
36
#endif
 
37
 
 
38
/*!
 
39
    \class QBitmap qbitmap.h
 
40
    \brief The QBitmap class provides monochrome (1-bit depth) pixmaps.
 
41
 
 
42
    \ingroup multimedia
 
43
 
 
44
    The QBitmap class is a monochrome off-screen paint device used mainly for
 
45
    creating custom QCursor and QBrush objects, settings masks for \link
 
46
    QPixmap::setMask() pixmaps \endlink and \link QWidget::setMask() widgets
 
47
    \endlink, and for QRegion.
 
48
 
 
49
    A QBitmap is a QPixmap with a \link QPixmap::depth() depth\endlink
 
50
    of 1. If a pixmap with a depth greater than 1 is assigned to a
 
51
    bitmap, the bitmap will be dithered automatically. A QBitmap is
 
52
    guaranteed to always have the depth 1, unless it is
 
53
    \link QPixmap::isNull() null \endlink since null pixmaps have depth 0.
 
54
 
 
55
    When drawing in a QBitmap (or QPixmap with depth 1), we recommend
 
56
    using the QColor objects Qt::color0 and Qt::color1.
 
57
    Painting with Qt::color0 sets the bitmap bits to 0, and painting
 
58
    with Qt::color1 sets the bits to 1. For a bitmap, 0-bits indicate
 
59
    background (or transparent pixels) and 1-bits indicate foreground (or
 
60
    opaque pixels). Using the Qt::black and Qt::white colors make no
 
61
    sense because the QColor::pixel() value is not necessarily 0 for
 
62
    black and 1 for white.
 
63
 
 
64
    The QBitmap can be transformed (translated, scaled, sheared, and
 
65
    rotated) using transform().
 
66
 
 
67
    Just like the QPixmap class, QBitmap is optimized by the use of
 
68
    \link shclass.html implicit sharing\endlink, so it is very
 
69
    efficient to pass QBitmap objects as arguments.
 
70
 
 
71
    \sa QPixmap, QPainter::drawPixmap(), bitBlt(), \link shclass.html Shared Classes\endlink
 
72
*/
 
73
 
 
74
 
 
75
/*!
 
76
    Constructs a null bitmap.
 
77
 
 
78
    \sa QPixmap::isNull()
 
79
*/
 
80
 
 
81
QBitmap::QBitmap()
 
82
    : QPixmap(QSize(0, 0), BitmapType)
 
83
{
 
84
}
 
85
 
 
86
/*!
 
87
    \fn QBitmap::QBitmap(int width, int height)
 
88
 
 
89
    Constructs a bitmap with the given \a width and \a height. The pixels
 
90
    inside are uninitialized.
 
91
 
 
92
*/
 
93
 
 
94
QBitmap::QBitmap(int w, int h)
 
95
    : QPixmap(QSize(w, h), BitmapType)
 
96
{
 
97
}
 
98
 
 
99
/*!
 
100
    \fn QBitmap::clear()
 
101
 
 
102
    Clear the bitmap to Qt::color0.
 
103
*/
 
104
 
 
105
/*!
 
106
    \overload
 
107
 
 
108
    Constructs a bitmap with the given \a size.
 
109
 
 
110
    The pixels in the bitmap are uninitialized.
 
111
*/
 
112
 
 
113
QBitmap::QBitmap(const QSize &size)
 
114
    : QPixmap(size, BitmapType)
 
115
{
 
116
}
 
117
 
 
118
/*!
 
119
    Constructs a bitmap that is a copy of the \a pixmap given.
 
120
 
 
121
    Dithering will be performed if the pixmap has a QPixmap::depth()
 
122
    greater than 1.
 
123
*/
 
124
 
 
125
QBitmap::QBitmap(const QPixmap &pixmap)
 
126
{
 
127
    QBitmap::operator=(pixmap);
 
128
}
 
129
 
 
130
/*!
 
131
  \fn QBitmap::QBitmap(const QImage &image)
 
132
 
 
133
    Constructs a bitmap that is a copy of the \a image given.
 
134
 
 
135
    Dithering will be performed if the image has a QImage::depth()
 
136
    greater than 1.
 
137
*/
 
138
 
 
139
#ifndef QT_NO_IMAGEIO
 
140
/*!
 
141
    Constructs a bitmap from the file referred to by \a fileName. If the
 
142
    file does not exist, or is of an unknown format, the bitmap becomes a
 
143
    null bitmap.
 
144
 
 
145
    The parameters \a fileName and \a format are passed on to
 
146
    QPixmap::load(). Dithering will be performed if the file format
 
147
    uses more than 1 bit per pixel.
 
148
 
 
149
    \sa QPixmap::isNull(), QPixmap::load(), QPixmap::loadFromData(),
 
150
    QPixmap::save(), QImageReader::imageFormat()
 
151
*/
 
152
 
 
153
QBitmap::QBitmap(const QString& fileName, const char *format)
 
154
    : QPixmap(QSize(0, 0), BitmapType)
 
155
{
 
156
    load(fileName, format, Qt::MonoOnly);
 
157
}
 
158
#endif
 
159
 
 
160
/*!
 
161
    \overload
 
162
 
 
163
    Assigns the \a pixmap to this bitmap and returns a
 
164
    reference to it.
 
165
 
 
166
    Dithering will be performed if the pixmap has a QPixmap::depth()
 
167
    greater than 1.
 
168
*/
 
169
 
 
170
QBitmap &QBitmap::operator=(const QPixmap &pixmap)
 
171
{
 
172
    if (pixmap.isNull()) {                        // a null pixmap
 
173
        QBitmap bm(0, 0);
 
174
        QBitmap::operator=(bm);
 
175
    } else if (pixmap.depth() == 1) {                // 1-bit pixmap
 
176
        QPixmap::operator=(pixmap);                // shallow assignment
 
177
    } else {                                        // n-bit depth pixmap
 
178
        QImage image;
 
179
        image = pixmap.toImage();                                // convert pixmap to image
 
180
        *this = fromImage(image);                                // will dither image
 
181
    }
 
182
    return *this;
 
183
}
 
184
 
 
185
 
 
186
#ifdef QT3_SUPPORT
 
187
QBitmap::QBitmap(int w, int h, const uchar *bits, bool isXbitmap)
 
188
{
 
189
    *this = fromData(QSize(w, h), bits, isXbitmap ? QImage::Format_MonoLSB : QImage::Format_Mono);
 
190
}
 
191
 
 
192
 
 
193
QBitmap::QBitmap(const QSize &size, const uchar *bits, bool isXbitmap)
 
194
{
 
195
    *this = fromData(size, bits, isXbitmap ? QImage::Format_MonoLSB : QImage::Format_Mono);
 
196
}
 
197
#endif
 
198
 
 
199
/*!
 
200
  Destroys the bitmap.
 
201
*/
 
202
QBitmap::~QBitmap()
 
203
{
 
204
}
 
205
 
 
206
/*!
 
207
   Returns the bitmap as a QVariant.
 
208
*/
 
209
QBitmap::operator QVariant() const
 
210
{
 
211
    return QVariant(QVariant::Bitmap, this);
 
212
}
 
213
 
 
214
/*!
 
215
  \fn QBitmap &QBitmap::operator=(const QImage &image)
 
216
 
 
217
    \overload
 
218
 
 
219
    Converts the image \a image to a bitmap, and assigns the result to
 
220
    this bitmap. Returns a reference to the bitmap.
 
221
 
 
222
    Dithering will be performed if the image has a QImage::depth()
 
223
    greater than 1.
 
224
*/
 
225
 
 
226
/*!
 
227
    Returns a copy of the given \a image converted to a bitmap using the
 
228
    image conversion flags specified by \a flags.
 
229
*/
 
230
QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
 
231
{
 
232
    if (image.isNull())
 
233
        return QBitmap();
 
234
    QImage img = image.convertToFormat(QImage::Format_MonoLSB, flags);
 
235
#if defined (Q_WS_WIN) || defined (Q_WS_QWS)
 
236
    QBitmap bm;
 
237
    bm.data->image = img;
 
238
 
 
239
    // Swap colors to match so that default config draws more correctly.
 
240
    // black bits -> black pen in QPainter
 
241
    if (image.numColors() == 2 && qGray(image.color(0)) < qGray(image.color(1))) {
 
242
        QRgb color0 = image.color(0);
 
243
        QRgb color1 = image.color(1);
 
244
        bm.data->image.setColor(0, color1);
 
245
        bm.data->image.setColor(1, color0);
 
246
        bm.data->image.invertPixels();
 
247
    }
 
248
    return bm;
 
249
#elif defined(Q_WS_X11)
 
250
    QBitmap bm;
 
251
    // make sure image.color(0) == Qt::color0 (white) and image.color(1) == Qt::color1 (black)
 
252
    const QRgb c0 = QColor(Qt::black).rgb();
 
253
    const QRgb c1 = QColor(Qt::white).rgb();
 
254
    if (img.color(0) == c0 && img.color(1) == c1) {
 
255
        img.invertPixels();
 
256
        img.setColor(0, c1);
 
257
        img.setColor(1, c0);
 
258
    }
 
259
 
 
260
    char  *bits;
 
261
    uchar *tmp_bits;
 
262
    int w = img.width();
 
263
    int h = img.height();
 
264
    int bpl = (w+7)/8;
 
265
    int ibpl = img.bytesPerLine();
 
266
    if (bpl != ibpl) {
 
267
        tmp_bits = new uchar[bpl*h];
 
268
        bits = (char *)tmp_bits;
 
269
        uchar *p, *b;
 
270
        int y;
 
271
        b = tmp_bits;
 
272
        p = img.scanLine(0);
 
273
        for (y = 0; y < h; y++) {
 
274
            memcpy(b, p, bpl);
 
275
            b += bpl;
 
276
            p += ibpl;
 
277
        }
 
278
    } else {
 
279
        bits = (char *)img.bits();
 
280
        tmp_bits = 0;
 
281
    }
 
282
    bm.data->hd = (Qt::HANDLE)XCreateBitmapFromData(bm.data->xinfo.display(),
 
283
                                                    RootWindow(bm.data->xinfo.display(), bm.data->xinfo.screen()),
 
284
                                                    bits, w, h);
 
285
 
 
286
#ifndef QT_NO_XRENDER
 
287
    if (X11->use_xrender)
 
288
        bm.data->picture = XRenderCreatePicture(X11->display, bm.data->hd,
 
289
                                                XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
 
290
#endif // QT_NO_XRENDER
 
291
 
 
292
    if (tmp_bits)                                // Avoid purify complaint
 
293
        delete [] tmp_bits;
 
294
    bm.data->w = w;  bm.data->h = h;  bm.data->d = 1;
 
295
 
 
296
    return bm;
 
297
#else
 
298
    return QBitmap(QPixmap::fromImage(img, flags|Qt::MonoOnly));
 
299
#endif
 
300
}
 
301
 
 
302
/*!
 
303
    Constructs a bitmap with the given \a size, and sets the contents to
 
304
    the \a bits supplied.
 
305
 
 
306
    The bitmap data has to be byte aligned and provided in in the bit
 
307
    order specified by \a monoFormat. The mono format must be either
 
308
    QImage::Mono or QImage::MonoLSB.
 
309
 
 
310
    Use QImage::Mono to specify data on the XBM format.
 
311
 
 
312
*/
 
313
QBitmap QBitmap::fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat)
 
314
{
 
315
    Q_ASSERT(monoFormat == QImage::Format_Mono || monoFormat == QImage::Format_MonoLSB);
 
316
 
 
317
    QImage image(size, monoFormat);
 
318
    image.setColor(0, Qt::color0);
 
319
    image.setColor(1, Qt::color1);
 
320
 
 
321
    // Need to memcpy each line separatly since QImage is 32bit aligned and
 
322
    // this data is only byte aligned...
 
323
    int bytesPerLine = (size.width() + 7) / 8;
 
324
    for (int y = 0; y < size.height(); ++y)
 
325
        memcpy(image.scanLine(y), bits + bytesPerLine * y, bytesPerLine);
 
326
    return QBitmap::fromImage(image);
 
327
}
 
328
 
 
329
 
 
330
#ifndef QT_NO_PIXMAP_TRANSFORMATION
 
331
/*!
 
332
    Returns a transformed copy of this bitmap using the \a matrix given.
 
333
 
 
334
    This function does exactly the same as QPixmap::transform(), except
 
335
    that it returns a QBitmap instead of a QPixmap.
 
336
 
 
337
    \sa QPixmap::transformed()
 
338
*/
 
339
 
 
340
QBitmap QBitmap::transformed(const QMatrix &matrix) const
 
341
{
 
342
    QBitmap bm = QPixmap::transformed(matrix);
 
343
    return bm;
 
344
}
 
345
#endif // QT_NO_TRANSFORMATIONS
 
346
 
 
347
#ifdef QT3_SUPPORT
 
348
/*!
 
349
    \fn QBitmap QBitmap::xForm(const QMatrix &matrix) const
 
350
 
 
351
    Use transform(\a matrix) instead.
 
352
*/
 
353
 
 
354
/*!
 
355
    \fn QBitmap::QBitmap(const QSize &size, bool clear)
 
356
 
 
357
    Use the QBitmap(\a size) constructor. If \a clear is true, call
 
358
    clear() afterward.
 
359
 
 
360
    \sa clear()
 
361
*/
 
362
 
 
363
/*!
 
364
    \fn QBitmap::QBitmap(int w, int h, bool clear)
 
365
 
 
366
    Use the QBitmap(\a w, \a h) constructor. If \a clear is true, call
 
367
    clear() afterward.
 
368
 
 
369
    \sa clear()
 
370
*/
 
371
 
 
372
/*!
 
373
    \fn QBitmap::QBitmap(int width, int height, const uchar *bits, bool isXbitmap)
 
374
 
 
375
    Constructs a bitmap with the given \a width and \a height,
 
376
    and sets the contents to the \a bits supplied.
 
377
 
 
378
    The \a isXbitmap flag should be true if \a bits was generated by
 
379
    the X11 bitmap program. The X bitmap bit order is little endian.
 
380
    The QImage documentation discusses bit order of monochrome
 
381
    images. Opposed to QImage, the data has to be byte aligned.
 
382
 
 
383
    Example (creates an arrow bitmap):
 
384
    \code
 
385
        uchar arrow_bits[] = { 0x3f, 0x1f, 0x0f, 0x1f, 0x3b, 0x71, 0xe0, 0xc0 };
 
386
        QBitmap bm(8, 8, arrow_bits, true);
 
387
    \endcode
 
388
*/
 
389
 
 
390
 
 
391
/*!
 
392
  \fn QBitmap::QBitmap(const QSize &size, const uchar *bits, bool isXbitmap)
 
393
 
 
394
    \overload
 
395
 
 
396
    Constructs a bitmap with the given \a size, and sets the contents to
 
397
    the \a bits supplied.
 
398
 
 
399
    The \a isXbitmap flag should be true if \a bits was generated by
 
400
    the X11 bitmap program. The X bitmap bit order is little endian.
 
401
    The QImage documentation discusses bit order of monochrome images.
 
402
*/
 
403
#endif