void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels) { GuiLock __; Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, cx, cy, 24); XPicture picture = XRenderCreatePicture( Xdisplay, pixmap, XRenderFindStandardFormat(Xdisplay, PictStandardRGB24), 0, 0 ); XImage ximg; sInitXImage(ximg, Size(cx, cy)); ximg.bitmap_pad = 32; ximg.bytes_per_line = 4 * cx; ximg.bits_per_pixel = 32; ximg.blue_mask = 0x00ff0000; ximg.green_mask = 0x0000ff00; ximg.red_mask = 0x000000ff; ximg.bitmap_unit = 32; ximg.depth = 24; ximg.data = (char *)pixels; XInitImage(&ximg); GC gc = XCreateGC(Xdisplay, pixmap, 0, 0); XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, cx, cy); XFreeGC(Xdisplay, gc); XFreePixmap(Xdisplay, pixmap); XRenderComposite(Xdisplay, PictOpOver, picture, 0, XftDrawPicture(w.GetXftDraw()), 0, 0, 0, 0, x, y, cx, cy); XRenderFreePicture(Xdisplay, picture); }
void ImageSysData::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c) { GuiLock __; x += w.GetOffset().x; y += w.GetOffset().y; Size sz = img.GetSize(); int len = sz.cx * sz.cy; Rect sr = src & sz; Size ssz = sr.Size(); if(sr.IsEmpty()) return; int kind = img.GetKind(); if(kind == IMAGE_EMPTY) return; if(kind == IMAGE_OPAQUE && !IsNull(c)) { w.DrawRect(x, y, sz.cx, sz.cy, c); return; } if(kind == IMAGE_OPAQUE && paintcount == 0 && sr == Rect(sz)) { SetSurface(w, x, y, sz.cx, sz.cy, ~img); paintcount++; return; } if(IsNull(c)) { if(!picture) { bool opaque = kind == IMAGE_OPAQUE; Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, opaque ? 24 : 32); picture = XRenderCreatePicture( Xdisplay, pixmap, XRenderFindStandardFormat(Xdisplay, opaque ? PictStandardRGB24 : PictStandardARGB32), 0, 0 ); XImage ximg; sInitXImage(ximg, sz); ximg.bitmap_pad = 32; ximg.bytes_per_line = 4 * sz.cx; ximg.bits_per_pixel = 32; ximg.blue_mask = 0x00ff0000; ximg.green_mask = 0x0000ff00; ximg.red_mask = 0x000000ff; ximg.bitmap_unit = 32; ximg.data = (char *)~img; ximg.depth = opaque ? 24 : 32; XInitImage(&ximg); GC gc = XCreateGC(Xdisplay, pixmap, 0, 0); XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, sz.cx, sz.cy); XFreeGC(Xdisplay, gc); XFreePixmap(Xdisplay, pixmap); SysImageRealized(img); } XRenderComposite(Xdisplay, PictOpOver, picture, 0, XftDrawPicture(w.GetXftDraw()), sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy); } else { if(!picture8) { Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, 8); picture8 = XRenderCreatePicture(Xdisplay, pixmap, XRenderFindStandardFormat(Xdisplay, PictStandardA8), 0, 0); Buffer<byte> ab(len); byte *t = ab; const RGBA *s = ~img; const RGBA *e = s + len; while(s < e) *t++ = (s++)->a; XImage ximg; sInitXImage(ximg, sz); ximg.data = (char *)~ab; ximg.bitmap_unit = 8; ximg.bitmap_pad = 8; ximg.depth = 8; ximg.bytes_per_line = sz.cx; ximg.bits_per_pixel = 8; XInitImage(&ximg); GC gc = XCreateGC(Xdisplay, pixmap, 0, 0); XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, sz.cx, sz.cy); XFreeGC(Xdisplay, gc); XFreePixmap(Xdisplay, pixmap); } XRenderComposite(Xdisplay, PictOpOver, sGetSolidFill(c), picture8, XftDrawPicture(w.GetXftDraw()), sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy); } }