1/*
2 * Copyright © 1998 Keith Packard
3 * Copyright © 2012 Intel Corporation
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Keith Packard not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission.  Keith Packard makes no
12 * representations about the suitability of this software for any purpose.  It
13 * is provided "as is" without express or implied warranty.
14 *
15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 */
23
24#include "fb.h"
25#include "fbclip.h"
26
27inline static void
28fbFillSpan(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *data)
29{
30	DBG(("%s (%d,%d)+%d\n", __FUNCTION__, b->x1, b->y1, b->x2-b->x1));
31	fbFill(drawable, gc, b->x1, b->y1, b->x2 - b->x1, 1);
32}
33
34void
35fbFillSpans(DrawablePtr drawable, GCPtr gc,
36	    int n, DDXPointPtr pt, int *width, int fSorted)
37{
38	DBG(("%s x %d\n", __FUNCTION__, n));
39	while (n--) {
40		BoxRec box;
41
42		*(DDXPointPtr)&box = *pt++;
43		box.x2 = box.x1 + *width++;
44		box.y2 = box.y1 + 1;
45
46		/* XXX fSorted */
47		fbDrawableRun(drawable, gc, &box, fbFillSpan, NULL);
48	}
49}
50
51struct fbSetSpan {
52	char *src;
53	DDXPointRec pt;
54	FbStride stride;
55	FbBits *dst;
56	int dx, dy;
57};
58
59inline static void
60fbSetSpan(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data)
61{
62	struct fbSetSpan *data = _data;
63	int xoff, bpp;
64
65	xoff = (int) (((long)data->src) & (FB_MASK >> 3));
66	bpp = drawable->bitsPerPixel;
67
68	fbBlt((FbBits *)(data->src - xoff), 0,
69	      (b->x1 - data->pt.x) * bpp + (xoff << 3),
70	      data->dst + (b->y1 + data->dy) * data->stride, data->stride,
71	      (b->x1 + data->dx) * bpp,
72	      (b->x2 - b->x1) * bpp, 1,
73	      gc->alu, fb_gc(gc)->pm, bpp,
74	      FALSE, FALSE);
75}
76
77void
78fbSetSpans(DrawablePtr drawable, GCPtr gc,
79           char *src, DDXPointPtr pt, int *width, int n, int fSorted)
80{
81	struct fbSetSpan data;
82	PixmapPtr pixmap;
83
84	DBG(("%s x %d\n", __FUNCTION__, n));
85
86	fbGetDrawablePixmap(drawable, pixmap, data.dx, data.dy);
87	data.dst = pixmap->devPrivate.ptr;
88	data.stride = pixmap->devKind / sizeof(FbStip);
89
90	data.src = src;
91	while (n--) {
92		BoxRec box;
93
94		*(DDXPointPtr)&box = data.pt = *pt;
95		box.x2 = box.x1 + *width;
96		box.y2 = box.y1 + 1;
97
98		fbDrawableRun(drawable, gc, &box, fbSetSpan, &data);
99
100		data.src += PixmapBytePad(*width, drawable->depth);
101		width++;
102		pt++;
103	}
104}
105
106void
107fbGetSpans(DrawablePtr drawable, int wMax,
108           DDXPointPtr pt, int *width, int n, char *dst)
109{
110	FbBits *src, *d;
111	FbStride srcStride;
112	int srcBpp;
113	int srcXoff, srcYoff;
114	int xoff;
115
116	fbGetDrawable(drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
117
118	DBG(("%s x %d\n", __FUNCTION__, n));
119	while (n--) {
120		xoff = (int) (((long) dst) & (FB_MASK >> 3));
121		d = (FbBits *) (dst - xoff);
122		fbBlt(src + (pt->y + srcYoff) * srcStride, srcStride,
123		      (pt->x + srcXoff) * srcBpp,
124		      d, 1, xoff << 3, *width * srcBpp,
125		      1, GXcopy, FB_ALLONES, srcBpp,
126		      FALSE, FALSE);
127		dst += PixmapBytePad(*width, drawable->depth);
128		pt++;
129		width++;
130	}
131}
132