📄 qpixmap_x11.cpp
字号:
XRenderFreePicture(X11->display, picture); picture = 0; }#endif // QT_NO_XRENDER if (hd2) { XFreePixmap(xinfo.display(), hd2); hd2 = 0; } XFreePixmap(xinfo.display(), hd); hd = 0; } delete paintEngine;}typedef void (*_qt_pixmap_cleanup_hook_64)(qint64);extern _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64;/*! Detaches the pixmap from shared pixmap data. A pixmap is automatically detached by Qt whenever its contents are about to change. This is done in almost all QPixmap member functions that modify the pixmap (fill(), fromImage(), load(), etc.), and in QPainter::begin() on a pixmap. There are two exceptions in which detach() must be called explicitly, that is when calling the handle() or the x11PictureHandle() function (only available on X11). Otherwise, any modifications done using system calls, will be performed on the shared data. The detach() function returns immediately if there is just a single reference or if the pixmap has not been initialized yet.*/void QPixmap::detach(){ if (qt_pixmap_cleanup_hook_64 && data->count == 1) qt_pixmap_cleanup_hook_64(cacheKey()); if (data->count != 1) *this = copy(); ++data->detach_no; data->uninit = false; // reset the cache data if (data->hd2) { XFreePixmap(X11->display, data->hd2); data->hd2 = 0; }}/*! Returns the default pixmap depth used by the application. \sa depth(), {QPixmap#Pixmap Information}{Pixmap Information}*/int QPixmap::defaultDepth(){ return QX11Info::appDepth();}/*! Fills the pixmap with the given \a fillColor. \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations}*/void QPixmap::fill(const QColor &fillColor){ if (isNull()) return; if (fillColor.alpha() != 255) {#ifndef QT_NO_XRENDER if (data->picture && data->d == 32) { detach(); ::Picture src = X11->getSolidFill(data->xinfo.screen(), fillColor); XRenderComposite(X11->display, PictOpSrc, src, 0, data->picture, 0, 0, width(), height(), 0, 0, width(), height()); } else#endif { QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied); im.fill(PREMUL(fillColor.rgba())); *this = QPixmap::fromImage(im); } return; } else { detach(); } GC gc = XCreateGC(X11->display, data->hd, 0, 0); if (depth() == 1) { XSetForeground(X11->display, gc, qGray(fillColor.rgb()) > 127 ? 0 : 1); } else if (X11->use_xrender && data->d >= 24) { XSetForeground(X11->display, gc, fillColor.rgba()); } else { XSetForeground(X11->display, gc, QColormap::instance(data->xinfo.screen()).pixel(fillColor)); } XFillRectangle(X11->display, data->hd, gc, 0, 0, width(), height()); XFreeGC(X11->display, gc);}/*! Returns the alpha channel of the pixmap as a new grayscale QPixmap in which each pixel's red, green, and blue values are given the alpha value of the original pixmap. The color depth of the returned pixmap is the system depth on X11 and 8-bit on Windows and Mac OS X. You can use this function while debugging to get a visible image of the alpha channel. If the pixmap doesn't have an alpha channel, i.e., the alpha channel's value for all pixels equals 0xff), a null pixmap is returned. You can check this with the \c isNull() function. We show an example: \quotefromfile snippets/alphachannel.cpp \skipto /pixmap =/ \printuntil /update/ \image alphachannelimage.png The pixmap and channelImage QPixmaps \sa setAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap Information}*/QPixmap QPixmap::alphaChannel() const{ if (!hasAlphaChannel()) return QPixmap(); QImage im(toImage()); return fromImage(im.alphaChannel(), Qt::OrderedDither);}/*! \fn void QPixmap::setAlphaChannel(const QPixmap &alphaChannel) Sets the alpha channel of this pixmap to the given \a alphaChannel by converting the \a alphaChannel into 32 bit and using the intensity of the RGB pixel values. The effect of this function is undefined when the pixmap is being painted on. \sa alphaChannel(), {QPixmap#Pixmap Transformations}{Pixmap Transformations} */void QPixmap::setAlphaChannel(const QPixmap &alpha){ if (paintingActive()) { qWarning("QPixmap::setAlphaChannel: Should not set alpha channel while pixmap is being painted on"); } if (alpha.isNull()) return; if (width() != alpha.width() && height() != alpha.height()) { qWarning("QPixmap::setAlphaChannel: The pixmap and the alpha channel pixmap must have the same size"); return; } QImage im(toImage()); im.setAlphaChannel(alpha.toImage()); *this = fromImage(im, Qt::OrderedDither | Qt::OrderedAlphaDither);}/*! \fn QBitmap QPixmap::mask() const Returns the mask, or a null bitmap if no mask has been set. \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}*/QBitmap QPixmap::mask() const{ QBitmap mask;#ifndef QT_NO_XRENDER if (data->picture && data->d == 32) { // #### slow - there must be a better way.. mask = QBitmap::fromImage(toImage().createAlphaMask()); } else#endif if (depth() == 1) { mask = *this; } else { mask = data->mask_to_bitmap(data->xinfo.screen()); } return mask;}/*! Sets a mask bitmap. The \a newmask bitmap defines the clip mask for this pixmap. Every pixel in \a newmask corresponds to a pixel in this pixmap. Pixel value 1 means opaque and pixel value 0 means transparent. The mask must have the same size as this pixmap. \warning Setting the mask on a pixmap will cause any alpha channel data to be cleared. For example: \quotefromfile snippets/image/image.cpp \skipto MASK \skipto QPixmap \printuntil setMask Now, alpha and alphacopy are visually different. Setting a null mask resets the mask. The effect of this function is undefined when the pixmap is being painted on. \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap Transformations}, QBitmap*/void QPixmap::setMask(const QBitmap &newmask){ if (paintingActive()) { qWarning("QPixmap::setMask: Should not set mask while pixmap is being painted on"); } if (data == newmask.data) // trying to selfmask return; if (newmask.isNull()) { // clear mask detach();#ifndef QT_NO_XRENDER if (data->picture && data->d == 32) { QPixmap pixmap; if (data->type == QPixmap::BitmapType) pixmap = QBitmap(data->w, data->h); else pixmap = QPixmap(data->w, data->h); pixmap.fill(Qt::black); XRenderComposite(X11->display, PictOpOver, data->picture, 0, pixmap.data->picture, 0, 0, 0, 0, 0, 0, data->w, data->h); *this = pixmap; } else#endif if (data->x11_mask) {#ifndef QT_NO_XRENDER if (data->picture) { XRenderPictureAttributes attrs; attrs.alpha_map = 0; XRenderChangePicture(X11->display, data->picture, CPAlphaMap, &attrs); } if (data->mask_picture) XRenderFreePicture(X11->display, data->mask_picture); data->mask_picture = 0;#endif XFreePixmap(X11->display, data->x11_mask); data->x11_mask = 0; } return; } if (newmask.width() != width() || newmask.height() != height()) { qWarning("QPixmap::setMask: The pixmap and the mask must have the same size"); return; } detach();#ifndef QT_NO_XRENDER if (data->picture && data->d == 32) { XRenderComposite(X11->display, PictOpSrc, data->picture, newmask.x11PictureHandle(), data->picture, 0, 0, 0, 0, 0, 0, data->w, data->h); } else#endif if (depth() == 1) { XGCValues vals; vals.function = GXand; GC gc = XCreateGC(X11->display, data->hd, GCFunction, &vals); XCopyArea(X11->display, newmask.handle(), data->hd, gc, 0, 0, width(), height(), 0, 0); XFreeGC(X11->display, gc); } else { // ##### should or the masks together if (data->x11_mask) { XFreePixmap(X11->display, data->x11_mask);#ifndef QT_NO_XRENDER if (data->mask_picture) XRenderFreePicture(X11->display, data->mask_picture);#endif } data->x11_mask = QPixmapData::bitmap_to_mask(newmask, data->xinfo.screen());#ifndef QT_NO_XRENDER if (data->picture) { data->mask_picture = XRenderCreatePicture(X11->display, data->x11_mask, XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0); XRenderPictureAttributes attrs; attrs.alpha_map = data->mask_picture; XRenderChangePicture(X11->display, data->picture, CPAlphaMap, &attrs); }#endif }}/*! \reimp*/int QPixmap::metric(PaintDeviceMetric m) const{ int val; if (m == PdmWidth) val = width(); else if (m == PdmHeight) { val = height(); } else { Display *dpy = X11->display; int scr = data->xinfo.screen(); switch (m) { case PdmDpiX: case PdmPhysicalDpiX: val = QX11Info::appDpiX(scr); break; case PdmDpiY: case PdmPhysicalDpiY: val = QX11Info::appDpiY(scr); break; case PdmWidthMM: val = (DisplayWidthMM(dpy,scr)*width())/ DisplayWidth(dpy,scr); break; case PdmHeightMM: val = (DisplayHeightMM(dpy,scr)*height())/ DisplayHeight(dpy,scr); break; case PdmNumColors: val = 1 << depth(); break; case PdmDepth: val = depth(); break; default: val = 0; qWarning("QPixmap::metric: Invalid metric command"); } } return val;}/*! Converts the pixmap to a QImage. Returns a null image if the conversion fails. If the pixmap has 1-bit depth, the returned image will also be 1 bit deep. If the pixmap has 2- to 8-bit depth, the returned image has 8-bit depth. If the pixmap has greater than 8-bit depth, the returned image has 32-bit depth. Note that for the moment, alpha masks on monochrome images are ignored. \sa fromImage(), {QImage#Image Formats}{Image Formats}*/QImage QPixmap::toImage() const{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -