⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qpixmap_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        *dst++ = pixel >> 16;                        *dst++ = pixel >> 24;                    }                    )                    break;            default:                qFatal("Logic error 2");            }        }        xi->data = (char *)newbits;    }    if (d == 8 && !trucol) {                        // 8 bit pixmap        int  pop[256];                                // pixel popularity        if (image.numColors() == 0)            image.setNumColors(1);        const QImage &cimage = image;        memset(pop, 0, sizeof(int)*256);        // reset popularity array        for (int i = 0; i < h; i++) {                        // for each scanline...            const uchar* p = cimage.scanLine(i);            const uchar *end = p + w;            while (p < end)                        // compute popularity                pop[*p++]++;        }        newbits = (uchar *)malloc(nbytes);        // copy image into newbits        Q_CHECK_PTR(newbits);        if (!newbits)                                // no memory            return QPixmap();        uchar* p = newbits;        memcpy(p, cimage.bits(), nbytes);        // copy image data into newbits        /*         * The code below picks the most important colors. It is based on the         * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.         */        struct PIX {                                // pixel sort element            uchar r,g,b,n;                        // color + pad            int          use;                                // popularity            int          index;                        // index in colormap            int          mindist;        };        int ncols = 0;        for (int i=0; i< cimage.numColors(); i++) { // compute number of colors            if (pop[i] > 0)                ncols++;        }        for (int i = cimage.numColors(); i < 256; i++) // ignore out-of-range pixels            pop[i] = 0;        // works since we make sure above to have at least        // one color in the image        if (ncols == 0)            ncols = 1;        PIX pixarr[256];                        // pixel array        PIX pixarr_sorted[256];                        // pixel array (sorted)        memset(pixarr, 0, ncols*sizeof(PIX));        PIX *px                   = &pixarr[0];        int  maxpop = 0;        int  maxpix = 0;        uint j = 0;        QVector<QRgb> ctable = cimage.colorTable();        for (int i = 0; i < 256; i++) {                // init pixel array            if (pop[i] > 0) {                px->r = qRed  (ctable[i]);                px->g = qGreen(ctable[i]);                px->b = qBlue (ctable[i]);                px->n = 0;                px->use = pop[i];                if (pop[i] > maxpop) {        // select most popular entry                    maxpop = pop[i];                    maxpix = j;                }                px->index = i;                px->mindist = 1000000;                px++;                j++;            }        }        pixarr_sorted[0] = pixarr[maxpix];        pixarr[maxpix].use = 0;        for (int i = 1; i < ncols; i++) {                // sort pixels            int minpix = -1, mindist = -1;            px = &pixarr_sorted[i-1];            int r = px->r;            int g = px->g;            int b = px->b;            int dist;            if ((i & 1) || i<10) {                // sort on max distance                for (int j=0; j<ncols; j++) {                    px = &pixarr[j];                    if (px->use) {                        dist = (px->r - r)*(px->r - r) +                               (px->g - g)*(px->g - g) +                               (px->b - b)*(px->b - b);                        if (px->mindist > dist)                            px->mindist = dist;                        if (px->mindist > mindist) {                            mindist = px->mindist;                            minpix = j;                        }                    }                }            } else {                                // sort on max popularity                for (int j=0; j<ncols; j++) {                    px = &pixarr[j];                    if (px->use) {                        dist = (px->r - r)*(px->r - r) +                               (px->g - g)*(px->g - g) +                               (px->b - b)*(px->b - b);                        if (px->mindist > dist)                            px->mindist = dist;                        if (px->use > mindist) {                            mindist = px->use;                            minpix = j;                        }                    }                }            }            pixarr_sorted[i] = pixarr[minpix];            pixarr[minpix].use = 0;        }        QColormap cmap = QColormap::instance(pixmap.data->xinfo.screen());        uint pix[256];                                // pixel translation table        px = &pixarr_sorted[0];        for (int i = 0; i < ncols; i++) {                // allocate colors            QColor c(px->r, px->g, px->b);            pix[px->index] = cmap.pixel(c);            px++;        }        p = newbits;        for (int i = 0; i < nbytes; i++) {                // translate pixels            *p = pix[*p];            p++;        }    }    if (!xi) {                                // X image not created        xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);        if (xi->bits_per_pixel == 16) {        // convert 8 bpp ==> 16 bpp            ushort *p2;            int            p2inc = xi->bytes_per_line/sizeof(ushort);            ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h);            Q_CHECK_PTR(newerbits);            if (!newerbits)                                // no memory                return QPixmap();            uchar* p = newbits;            for (int y = 0; y < h; y++) {                // OOPS: Do right byte order!!                p2 = newerbits + p2inc*y;                for (int x = 0; x < w; x++)                    *p2++ = *p++;            }            free(newbits);            newbits = (uchar *)newerbits;        } else if (xi->bits_per_pixel != 8) {            qWarning("QPixmap::convertFromImage: Display not supported "                     "(bpp=%d)", xi->bits_per_pixel);        }        xi->data = (char *)newbits;    }    pixmap.data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,                                                RootWindow(X11->display, pixmap.data->xinfo.screen()),                                                w, h, dd);    GC gc = XCreateGC(dpy, pixmap.data->hd, 0, 0);    XPutImage(dpy, pixmap.data->hd, gc, xi, 0, 0, 0, 0, w, h);    XFreeGC(dpy, gc);    qSafeXDestroyImage(xi);    pixmap.data->w = w;    pixmap.data->h = h;    pixmap.data->d = dd;#ifndef QT_NO_XRENDER    if (X11->use_xrender) {        XRenderPictFormat *format = pixmap.data->d == 1                                    ? XRenderFindStandardFormat(X11->display, PictStandardA1)                                    : XRenderFindVisualFormat(X11->display, (Visual *) pixmap.data->xinfo.visual());        pixmap.data->picture = XRenderCreatePicture(X11->display, pixmap.data->hd, format, 0, 0);    }#endif    if (image.hasAlphaChannel()) {        QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));        pixmap.setMask(m);    }    return pixmap;}/*!    \fn QPixmap QPixmap::grabWindow(WId window, int x, int y, int    width, int height)    Creates and returns a pixmap constructed by grabbing the contents    of the given \a window restricted by QRect(\a x, \a y, \a width,    \a height).    The arguments (\a{x}, \a{y}) specify the offset in the window,    whereas (\a{width}, \a{height}) specify the area to be copied.  If    \a width is negative, the function copies everything to the right    border of the window. If \a height is negative, the function    copies everything to the bottom of the window.    The window system identifier (\c WId) can be retrieved using the    QWidget::WId() function. The rationale for using a window    identifier and not a QWidget, is to enable grabbing of windows    that are not part of the application, window system frames, and so    on.    The grabWindow() function grabs pixels from the screen, not from    the window, i.e. if there is another window partially or entirely    over the one you grab, you get pixels from the overlying window,    too. The mouse cursor is generally not grabbed.    Note on X11that if the given \a window doesn't have the same depth    as the root window, and another window partially or entirely    obscures the one you grab, you will \e not get pixels from the    overlying window.  The contents of the obscured areas in the    pixmap will be undefined and uninitialized.    \warning In general, grabbing an area outside the screen is not    safe. This depends on the underlying window system.    \sa grabWidget()*/QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h){    if (w == 0 || h == 0)        return QPixmap();    Display *dpy = X11->display;    XWindowAttributes window_attr;    if (! XGetWindowAttributes(dpy, window, &window_attr))        return QPixmap();    if (w < 0)        w = window_attr.width - x;    if (h < 0)        h = window_attr.height - y;    // determine the screen    int scr;    for (scr = 0; scr < ScreenCount(dpy); ++scr) {        if (window_attr.root == RootWindow(dpy, scr))        // found it            break;    }    if (scr >= ScreenCount(dpy))                // sanity check        return QPixmap();    // get the depth of the root window    XWindowAttributes root_attr;    if (! XGetWindowAttributes(dpy, window_attr.root, &root_attr))        return QPixmap();    if (window_attr.depth == root_attr.depth) {        // if the depth of the specified window and the root window are the        // same, grab pixels from the root window (so that we get the any        // overlapping windows and window manager frames)        // map x and y to the root window        WId unused;        if (! XTranslateCoordinates(dpy, window, window_attr.root, x, y,                                    &x, &y, &unused))            return QPixmap();        window = window_attr.root;        window_attr = root_attr;    }    QPixmap pm(w, h);    pm.data->uninit = false;    pm.x11SetScreen(scr);#ifndef QT_NO_XRENDER    if (pm.data->picture) {        XRenderPictFormat *format = XRenderFindVisualFormat(dpy, window_attr.visual);        XRenderPictureAttributes pattr;        pattr.subwindow_mode = IncludeInferiors;        Picture src_pict = XRenderCreatePicture(dpy, window, format, CPSubwindowMode, &pattr);        Picture dst_pict = pm.x11PictureHandle();        XRenderComposite(dpy, PictOpSrc, src_pict, 0, dst_pict, x, y, x, y, 0, 0, w, h);        XRenderFreePicture(dpy, src_pict);    } else#endif        {            GC gc = XCreateGC(dpy, pm.handle(), 0, 0);            XSetSubwindowMode(dpy, gc, IncludeInferiors);            XCopyArea(dpy, window, pm.handle(), gc, x, y, w, h, 0, 0);            XFreeGC(dpy, gc);        }    return pm;}/*!    Returns a copy of the pixmap that is transformed using the given    transformation \a matrix and transformation \a mode. The original    pixmap is not changed.    The transformation \a matrix is internally adjusted to compensate    for unwanted translation; i.e. the pixmap produced is the smallest    pixmap that contains all the transformed points of the original    pixmap. Use the trueMatrix() function to retrieve the actual    matrix used for transforming the pixmap.    This function is slow because it involves transformation to a    QImage, non-trivial computations and a transformation back to a    QPixmap.    \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap    Transformations}*/QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) const{    int           w = 0;    int           h = 0;                                // size of target pixmap    int           ws, hs;                                // size of source pixmap    uchar *dptr;                                // data in target pixmap    int           dbpl, dbytes;                        // bytes per line/bytes total    uchar *sptr;                                // data in original pixmap    int           sbpl;                                // bytes per line in original    int           bpp;                                        // bits per pixel    bool   depth1 = depth() == 1;    Display *dpy = X11->display;    if (isNull())                                // this is a null pixmap        return copy();    ws = width();    hs = height();    QMatrix mat(matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(), 0., 0.);    bool complex_xform = false;    if (mat.m12() == 0.0F && mat.m21() == 0.0F) {        if (mat.m11() == 1.0F && mat.m22() == 1.0F) // identity matrix            return *this;        h = int(qAbs(mat.m22()) * hs + 0.9999);        w = int(qAbs(mat.m11()) * ws + 0.9999);        h = qAbs(h);        w = qAbs(w);    } else {                                        // rotation or shearing        QPolygonF a(QRectF(0, 0, ws+1, hs+1));        a = mat.map(a);        QRectF r = a.boundingRect().normalized();        w = int(r.width() + 0.9999);        h = int(r.height() + 0.9999);        complex_xform = true;    }    mat = trueMatrix(mat, ws, hs); // true matrix    bool invertible;    mat = mat.inverted(&invertibl

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -