/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include "fb.h" #include "fbclip.h" struct fbPutZImage { FbStip *src, *dst; FbStride src_stride, dst_stride; int dst_x, dst_y; int x0, y0; }; inline static void _fbPutZImage(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { struct fbPutZImage *data = _data; int bpp = drawable->bitsPerPixel; fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, (b->x1 - data->x0) * bpp, data->dst + (b->y1 + data->dst_y) * data->dst_stride, data->dst_stride, (b->x1 + data->dst_x) * bpp, (b->x2 - b->x1) * bpp, (b->y2 - b->y1), gc->alu, fb_gc(gc)->pm, bpp); } static void fbPutZImage(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height, FbStip *src, FbStride srcStride) { PixmapPtr pixmap; struct fbPutZImage data; BoxRec box; box.x1 = data.x0 = x; box.y1 = data.y0 = y; box.x2 = x + width; box.y2 = y + height; data.src = src; data.src_stride = srcStride; fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y); data.dst = pixmap->devPrivate.ptr; data.dst_stride = pixmap->devKind / sizeof(FbStip); fbDrawableRun(drawable, gc, &box, _fbPutZImage, &data); } struct fbPutXYImage { FbStip *src, *dst; FbStride src_stride, dst_stride; int dst_x, dst_y, src_x; int x0, y0; int alu, pm; FbBits fgand, fgxor, bgand, bgxor; }; inline static void _fbPutXYImage1(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { struct fbPutXYImage *data = _data; int bpp = drawable->bitsPerPixel; fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, (b->x1 - data->x0) + data->src_x, (FbStip *) (data->dst + (b->y1 + data->dst_y) * data->dst_stride), data->dst_stride, (b->x1 + data->dst_x) * bpp, (b->x2 - b->x1) * bpp, (b->y2 - b->y1), data->alu, data->pm, bpp); } inline static void _fbPutXYImageN(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { struct fbPutXYImage *data = _data; int bpp = drawable->bitsPerPixel; fbBltOne(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, (b->x1 - data->x0) + data->src_x, data->dst + (b->y1 + data->dst_y) * data->dst_stride, data->dst_stride, (b->x1 + data->dst_x) * bpp, bpp, (b->x2 - b->x1) * bpp, (b->y2 - b->y1), data->fgand, data->fgxor, data->bgand, data->bgxor); } void fbPutXYImage(DrawablePtr drawable, GCPtr gc, FbBits fg, FbBits bg, FbBits pm, int alu, Bool opaque, int x, int y, int width, int height, FbStip *src, FbStride srcStride, int srcX) { PixmapPtr pixmap; struct fbPutXYImage data; BoxRec box; box.x1 = data.x0 = x; box.y1 = data.y0 = y; box.x2 = x + width; box.y2 = y + height; data.src = src; data.src_stride = srcStride; data.src_x = srcX; fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y); data.dst = pixmap->devPrivate.ptr; data.dst_stride = pixmap->devKind / sizeof(FbStip); if (drawable->bitsPerPixel == 1) { if (opaque) data.alu = FbOpaqueStipple1Rop(alu, fg, bg); else data.alu = FbStipple1Rop(alu, fg); data.pm = pm; fbDrawableRun(drawable, gc, &box, _fbPutXYImage1, &data); } else { data.fgand = fbAnd(alu, fg, pm); data.fgxor = fbXor(alu, fg, pm); if (opaque) { data.bgand = fbAnd(alu, bg, pm); data.bgxor = fbXor(alu, bg, pm); } else { data.bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); data.bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); } fbDrawableRun(drawable, gc, &box, _fbPutXYImageN, &data); } } void fbPutImage(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *image) { FbGCPrivPtr pgc = fb_gc(gc); unsigned long i; FbStride srcStride; FbStip *src = (FbStip *)image; DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); x += drawable->x; y += drawable->y; switch (format) { case XYBitmap: srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); fbPutXYImage(drawable, gc, pgc->fg, pgc->bg, pgc->pm, gc->alu, TRUE, x, y, w, h, src, srcStride, leftPad); break; case XYPixmap: srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); for (i = (unsigned long) 1 << (drawable->depth - 1); i; i >>= 1) { if (i & gc->planemask) { fbPutXYImage(drawable, gc, FB_ALLONES, 0, fbReplicatePixel(i, drawable->bitsPerPixel), gc->alu, TRUE, x, y, w, h, src, srcStride, leftPad); src += srcStride * h; } } break; case ZPixmap: srcStride = PixmapBytePad(w, drawable->depth) / sizeof(FbStip); fbPutZImage(drawable, gc, x, y, w, h, src, srcStride); } } void fbGetImage(DrawablePtr drawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbStip *dst; FbStride dstStride; DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); fbGetDrawable(drawable, src, srcStride, srcBpp, srcXoff, srcYoff); x += drawable->x; y += drawable->y; dst = (FbStip *) d; if (format == ZPixmap || srcBpp == 1) { FbBits pm; pm = fbReplicatePixel(planeMask, srcBpp); dstStride = PixmapBytePad(w, drawable->depth); dstStride /= sizeof(FbStip); fbBltStip((FbStip *)(src + (y + srcYoff) * srcStride), srcStride, (x + srcXoff) * srcBpp, dst, dstStride, 0, w * srcBpp, h, GXcopy, FB_ALLONES, srcBpp); if (pm != FB_ALLONES) { int i = dstStride * h; while (i--) *dst++ &= pm; } } else { dstStride = BitmapBytePad(w) / sizeof(FbStip); fbBltPlane(src + (y + srcYoff) * srcStride, srcStride, (x + srcXoff) * srcBpp, srcBpp, dst, dstStride, 0, w * srcBpp, h, fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), fbAndStip(GXcopy, 0, FB_STIP_ALLONES), fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask); } }