1428d7b3dSmrg/*
2428d7b3dSmrg * Copyright © 1998 Keith Packard
3428d7b3dSmrg * Copyright © 2012 Intel Corporation
4428d7b3dSmrg *
5428d7b3dSmrg * Permission to use, copy, modify, distribute, and sell this software and its
6428d7b3dSmrg * documentation for any purpose is hereby granted without fee, provided that
7428d7b3dSmrg * the above copyright notice appear in all copies and that both that
8428d7b3dSmrg * copyright notice and this permission notice appear in supporting
9428d7b3dSmrg * documentation, and that the name of Keith Packard not be used in
10428d7b3dSmrg * advertising or publicity pertaining to distribution of the software without
11428d7b3dSmrg * specific, written prior permission.  Keith Packard makes no
12428d7b3dSmrg * representations about the suitability of this software for any purpose.  It
13428d7b3dSmrg * is provided "as is" without express or implied warranty.
14428d7b3dSmrg *
15428d7b3dSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16428d7b3dSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17428d7b3dSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18428d7b3dSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19428d7b3dSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20428d7b3dSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21428d7b3dSmrg * PERFORMANCE OF THIS SOFTWARE.
22428d7b3dSmrg */
23428d7b3dSmrg
24428d7b3dSmrg#include "fb.h"
25428d7b3dSmrg#include "fbclip.h"
26428d7b3dSmrg
27428d7b3dSmrginline static void
28428d7b3dSmrgfbFillSpan(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *data)
29428d7b3dSmrg{
30428d7b3dSmrg	DBG(("%s (%d,%d)+%d\n", __FUNCTION__, b->x1, b->y1, b->x2-b->x1));
31428d7b3dSmrg	fbFill(drawable, gc, b->x1, b->y1, b->x2 - b->x1, 1);
32428d7b3dSmrg}
33428d7b3dSmrg
34428d7b3dSmrgvoid
35428d7b3dSmrgfbFillSpans(DrawablePtr drawable, GCPtr gc,
36428d7b3dSmrg	    int n, DDXPointPtr pt, int *width, int fSorted)
37428d7b3dSmrg{
38428d7b3dSmrg	DBG(("%s x %d\n", __FUNCTION__, n));
39428d7b3dSmrg	while (n--) {
40428d7b3dSmrg		BoxRec box;
41428d7b3dSmrg
42428d7b3dSmrg		*(DDXPointPtr)&box = *pt++;
43428d7b3dSmrg		box.x2 = box.x1 + *width++;
44428d7b3dSmrg		box.y2 = box.y1 + 1;
45428d7b3dSmrg
46428d7b3dSmrg		/* XXX fSorted */
47428d7b3dSmrg		fbDrawableRun(drawable, gc, &box, fbFillSpan, NULL);
48428d7b3dSmrg	}
49428d7b3dSmrg}
50428d7b3dSmrg
51428d7b3dSmrgstruct fbSetSpan {
52428d7b3dSmrg	char *src;
53428d7b3dSmrg	DDXPointRec pt;
54428d7b3dSmrg	FbStride stride;
55428d7b3dSmrg	FbBits *dst;
56428d7b3dSmrg	int dx, dy;
57428d7b3dSmrg};
58428d7b3dSmrg
59428d7b3dSmrginline static void
60428d7b3dSmrgfbSetSpan(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data)
61428d7b3dSmrg{
62428d7b3dSmrg	struct fbSetSpan *data = _data;
63428d7b3dSmrg	int xoff, bpp;
64428d7b3dSmrg
65428d7b3dSmrg	xoff = (int) (((long)data->src) & (FB_MASK >> 3));
66428d7b3dSmrg	bpp = drawable->bitsPerPixel;
67428d7b3dSmrg
68428d7b3dSmrg	fbBlt((FbBits *)(data->src - xoff), 0,
69428d7b3dSmrg	      (b->x1 - data->pt.x) * bpp + (xoff << 3),
70428d7b3dSmrg	      data->dst + (b->y1 + data->dy) * data->stride, data->stride,
71428d7b3dSmrg	      (b->x1 + data->dx) * bpp,
72428d7b3dSmrg	      (b->x2 - b->x1) * bpp, 1,
73428d7b3dSmrg	      gc->alu, fb_gc(gc)->pm, bpp,
74428d7b3dSmrg	      FALSE, FALSE);
75428d7b3dSmrg}
76428d7b3dSmrg
77428d7b3dSmrgvoid
78428d7b3dSmrgfbSetSpans(DrawablePtr drawable, GCPtr gc,
79428d7b3dSmrg           char *src, DDXPointPtr pt, int *width, int n, int fSorted)
80428d7b3dSmrg{
81428d7b3dSmrg	struct fbSetSpan data;
82428d7b3dSmrg	PixmapPtr pixmap;
83428d7b3dSmrg
84428d7b3dSmrg	DBG(("%s x %d\n", __FUNCTION__, n));
85428d7b3dSmrg
86428d7b3dSmrg	fbGetDrawablePixmap(drawable, pixmap, data.dx, data.dy);
87428d7b3dSmrg	data.dst = pixmap->devPrivate.ptr;
88428d7b3dSmrg	data.stride = pixmap->devKind / sizeof(FbStip);
89428d7b3dSmrg
90428d7b3dSmrg	data.src = src;
91428d7b3dSmrg	while (n--) {
92428d7b3dSmrg		BoxRec box;
93428d7b3dSmrg
94428d7b3dSmrg		*(DDXPointPtr)&box = data.pt = *pt;
95428d7b3dSmrg		box.x2 = box.x1 + *width;
96428d7b3dSmrg		box.y2 = box.y1 + 1;
97428d7b3dSmrg
98428d7b3dSmrg		fbDrawableRun(drawable, gc, &box, fbSetSpan, &data);
99428d7b3dSmrg
100428d7b3dSmrg		data.src += PixmapBytePad(*width, drawable->depth);
101428d7b3dSmrg		width++;
102428d7b3dSmrg		pt++;
103428d7b3dSmrg	}
104428d7b3dSmrg}
105428d7b3dSmrg
106428d7b3dSmrgvoid
107428d7b3dSmrgfbGetSpans(DrawablePtr drawable, int wMax,
108428d7b3dSmrg           DDXPointPtr pt, int *width, int n, char *dst)
109428d7b3dSmrg{
110428d7b3dSmrg	FbBits *src, *d;
111428d7b3dSmrg	FbStride srcStride;
112428d7b3dSmrg	int srcBpp;
113428d7b3dSmrg	int srcXoff, srcYoff;
114428d7b3dSmrg	int xoff;
115428d7b3dSmrg
116428d7b3dSmrg	fbGetDrawable(drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
117428d7b3dSmrg
118428d7b3dSmrg	DBG(("%s x %d\n", __FUNCTION__, n));
119428d7b3dSmrg	while (n--) {
120428d7b3dSmrg		xoff = (int) (((long) dst) & (FB_MASK >> 3));
121428d7b3dSmrg		d = (FbBits *) (dst - xoff);
122428d7b3dSmrg		fbBlt(src + (pt->y + srcYoff) * srcStride, srcStride,
123428d7b3dSmrg		      (pt->x + srcXoff) * srcBpp,
124428d7b3dSmrg		      d, 1, xoff << 3, *width * srcBpp,
125428d7b3dSmrg		      1, GXcopy, FB_ALLONES, srcBpp,
126428d7b3dSmrg		      FALSE, FALSE);
127428d7b3dSmrg		dst += PixmapBytePad(*width, drawable->depth);
128428d7b3dSmrg		pt++;
129428d7b3dSmrg		width++;
130428d7b3dSmrg	}
131428d7b3dSmrg}
132