Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / xf4bpp / ppcSetSp.c
blob7659384e784306ccddf183b1721bab6acf83956d
1 /*
2 * Copyright IBM Corporation 1987,1988,1989
4 * All Rights Reserved
6 * Permission to use, copy, modify, and distribute this software and its
7 * documentation for any purpose and without fee is hereby granted,
8 * provided that the above copyright notice appear in all copies and that
9 * both that copyright notice and this permission notice appear in
10 * supporting documentation, and that the name of IBM not be
11 * used in advertising or publicity pertaining to distribution of the
12 * software without specific, written prior permission.
14 * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16 * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20 * SOFTWARE.
24 /***********************************************************
26 Copyright (c) 1987 X Consortium
28 Permission is hereby granted, free of charge, to any person obtaining a copy
29 of this software and associated documentation files (the "Software"), to deal
30 in the Software without restriction, including without limitation the rights
31 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32 copies of the Software, and to permit persons to whom the Software is
33 furnished to do so, subject to the following conditions:
35 The above copyright notice and this permission notice shall be included in
36 all copies or substantial portions of the Software.
38 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
42 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
43 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45 Except as contained in this notice, the name of the X Consortium shall not be
46 used in advertising or otherwise to promote the sale, use or other dealings
47 in this Software without prior written authorization from the X Consortium.
50 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
52 All Rights Reserved
54 Permission to use, copy, modify, and distribute this software and its
55 documentation for any purpose and without fee is hereby granted,
56 provided that the above copyright notice appear in all copies and that
57 both that copyright notice and this permission notice appear in
58 supporting documentation, and that the name of Digital not be
59 used in advertising or publicity pertaining to distribution of the
60 software without specific, written prior permission.
62 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
63 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
64 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
65 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
66 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
67 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
68 SOFTWARE.
70 ******************************************************************/
72 #ifdef HAVE_XORG_CONFIG_H
73 #include <xorg-config.h>
74 #endif
76 #include <stdlib.h>
78 #include "xf4bpp.h"
79 #include "OScompiler.h"
80 #include "mfbmap.h"
81 #include "mfb.h"
82 #include "servermd.h"
84 /* SetScanline -- copies the bits from psrc to the drawable starting at
85 * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc
86 * starts on the scanline. (I.e., if this scanline passes through multiple
87 * boxes, we may not want to start grabbing bits at psrc but at some offset
88 * further on.)
90 static void
91 ppcSetScanline
93 register int pixCount, /* width of scanline in bits */
94 register char *psrc,
95 register unsigned char *pdst, /* where to put the bits */
96 register int pm, /* plane mask */
97 const int alu /* raster op */
100 register int npm = ~pm ; /* inverted plane mask */
101 register char tmpx ;
103 pm &= 0x0F; npm &= 0x0F; /* GJA */
105 switch ( alu ) {
106 case GXclear: /* 0x0 Zero 0 */
107 while ( pixCount-- )
108 *pdst++ &= npm ;
109 break ;
110 case GXand: /* 0x1 src AND dst */
111 while ( pixCount-- )
112 *pdst++ &= *psrc++ | npm ;
113 break ;
114 case GXandReverse: /* 0x2 src AND NOT dst */
115 for ( ; pixCount-- ; pdst++, psrc++ ) {
116 tmpx = *pdst;
117 *pdst = ( tmpx & npm ) | ( pm & *psrc & ~tmpx ) ;
119 break ;
120 case GXcopy: /* 0x3 src */
121 for ( ; pixCount-- ; pdst++, psrc++ )
122 *pdst = ( *pdst & npm ) | ( pm & *psrc ) ;
123 break ;
124 case GXandInverted: /* 0x4 NOT src AND dst */
125 while ( pixCount-- )
126 *pdst++ &= npm | ~*psrc++ ;
127 break ;
128 case GXnoop: /* 0x5 dst */
129 break ;
130 case GXxor: /* 0x6 src XOR dst */
131 while ( pixCount-- )
132 *pdst++ ^= pm & *psrc++ ;
133 break ;
134 case GXor: /* 0x7 src OR dst */
135 while ( pixCount-- )
136 *pdst++ |= *psrc++ & pm ;
137 break ;
138 case GXnor: /* 0x8 NOT src AND NOT dst */
139 for ( ; pixCount-- ; pdst++, psrc++ ) {
140 tmpx = *pdst;
141 *pdst = ( tmpx & npm ) | ( pm & ~( tmpx | *psrc ) ) ;
143 break ;
144 case GXequiv: /* 0x9 NOT src XOR dst */
145 while ( pixCount-- )
146 *pdst++ ^= pm & ~ *psrc++ ;
147 break ;
148 case GXorReverse: /* 0xb src OR NOT dst */
149 for ( ; pixCount-- ; pdst++, psrc++ ) {
150 tmpx = *pdst;
151 *pdst = ( tmpx & npm ) | ( pm & ( *psrc | ~tmpx ) ) ;
153 break ;
154 case GXinvert: /* 0xa NOT dst */
155 while ( pixCount-- )
156 *pdst++ ^= pm ;
157 break ;
158 case GXcopyInverted: /* 0xc NOT src */
159 for ( ; pixCount-- ; pdst++, psrc++ )
160 *pdst = ( *pdst & npm ) | ( pm & ~ *psrc ) ;
161 break ;
162 case GXorInverted: /* 0xd NOT src OR dst */
163 while ( pixCount-- )
164 *pdst++ |= pm & ~ *psrc++ ;
165 break ;
166 case GXnand: /* 0xe NOT src OR NOT dst */
167 for ( ; pixCount-- ; pdst++, psrc++ ) {
168 tmpx = *pdst;
169 *pdst = ( tmpx & npm ) | ( pm & ~( tmpx & *psrc ) ) ;
171 break ;
172 case GXset: /* 0xf 1 */
173 while ( pixCount-- )
174 *pdst++ |= pm ;
175 break ;
176 default:
177 ErrorF( "ppcSetScanLine: bad alu value == 0x%02X\n", alu ) ;
178 break ;
181 return ;
184 /* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
185 * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines
186 * are in increasing Y order.
187 * Source bit lines are server scanline padded so that they always begin
188 * on a word boundary.
190 void
191 xf4bppSetSpans( pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted )
192 register DrawablePtr pDrawable ;
193 GCPtr pGC ;
194 char *psrc ;
195 register DDXPointPtr ppt ;
196 int *pwidth ;
197 int nspans ;
198 int fSorted ;
200 unsigned char *pdstBase = NULL; /* start of dst bitmap */
201 int widthDst = 0; /* width of bitmap in words */
202 register BoxPtr pbox, pboxLast, pboxTest ;
203 register DDXPointPtr pptLast ;
204 RegionPtr prgnDst ;
205 register int width ;
206 int xStart, xEnd ;
207 int yMax ;
208 int alu ;
209 int pm ;
211 /* allow for 1-deep windows on nfb machines (eg apa8, aed) */
212 if ( ( pDrawable->depth == 1 ) && ( pDrawable->type == DRAWABLE_PIXMAP ) ) {
213 mfbSetSpans( pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted ) ;
214 return ;
217 if ( !( pm = pGC->planemask & ~( (~0) << pDrawable->depth ) )
218 || ( ( alu = pGC->alu ) == GXnoop ) )
219 return ;
221 prgnDst = pGC->pCompositeClip ;
223 if ( ! REGION_NUM_RECTS(prgnDst))
224 return ;
226 pboxLast = ( pbox = REGION_RECTS(prgnDst) ) + REGION_NUM_RECTS(prgnDst);
227 pptLast = ppt + nspans ;
229 if ( pDrawable->type == DRAWABLE_WINDOW ) {
230 yMax = (int) pDrawable->height + pDrawable->y ;
232 else {
233 pdstBase = (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr ;
234 widthDst = (int) ( (PixmapPtr) pDrawable )->devKind ;
235 yMax = pDrawable->height ;
238 if ( fSorted ) {
239 /* scan lines sorted in ascending order. Because they are sorted, we
240 * don't have to check each scanline against each clip box. We can be
241 * sure that this scanline only has to be clipped to boxes at or after the
242 * beginning of this y-band
244 for ( pboxTest = pbox ;
245 ( ppt < pptLast ) && ( ppt->y < yMax ) ;
246 ppt++, pwidth++,
247 psrc += PixmapBytePad( width, pDrawable->depth ) ) {
248 width = *pwidth ;
249 for ( pbox = pboxTest ;
250 pbox < pboxLast ;
251 pbox++ ) {
252 if ( pbox->y2 <= ppt->y ) {
253 /* clip box is before scanline */
254 pboxTest = pbox + 1 ;
256 else if ( ( pbox->y1 > ppt->y )
257 || ( pbox->x1 > ppt->x + width ) )
258 break ; /* scanline before clip box or left of clip box */
259 else if ( pbox->x2 > ppt->x ) {
260 /* some of the scanline is in the current clip box */
261 xStart = MAX( pbox->x1, ppt->x ) ;
262 xEnd = MIN( ppt->x + width, pbox->x2 ) ;
263 if ( pDrawable->type == DRAWABLE_PIXMAP )
264 ppcSetScanline( xEnd - xStart,
265 psrc + ( xStart - ppt->x ),
266 pdstBase + xStart
267 + ( ppt->y * widthDst ),
268 pm, alu ) ;
269 else
270 xf4bppDrawColorImage( (WindowPtr)pDrawable,
271 xStart, ppt->y, xEnd - xStart, 1,
272 (unsigned char *)psrc + ( xStart - ppt->x ),
273 xEnd - xStart, alu, pm ) ;
274 if ( ppt->x + width <= pbox->x2 )
275 break ; /* End of the line, as it were */
278 /* We've tried this line against every box ; it must be outside them
279 * all. move on to the next point */
282 else {
283 /* scan lines not sorted. We must clip each line against all the boxes */
284 for ( ;
285 ppt < pptLast ;
286 ppt++, pwidth++,
287 psrc += PixmapBytePad( width, pDrawable->depth ) ) {
288 width = *pwidth ;
289 if ( ppt->y >= 0 && ppt->y < yMax ) {
290 for ( pbox = REGION_RECTS(prgnDst) ; pbox < pboxLast ; pbox++ ) {
291 if ( pbox->y1 > ppt->y )
292 break ; /* rest of clip region is above this scanline */
293 else if ( ( pbox->y2 > ppt->y )
294 && ( pbox->x1 <= ppt->x + width )
295 && ( pbox->x2 > ppt->x ) ) {
296 xStart = MAX( pbox->x1, ppt->x ) ;
297 xEnd = MIN( pbox->x2, ppt->x + width ) ;
298 if ( pDrawable->type == DRAWABLE_PIXMAP )
299 ppcSetScanline( xEnd - xStart,
300 psrc + ( xStart - ppt->x ),
301 /* ^ GJA */
302 ( ( pdstBase
303 + ( ppt->y * widthDst ) )
304 + xStart ),
305 pm, alu ) ;
306 else /* pDrawable->type == DRAWABLE_WINDOW */
307 xf4bppDrawColorImage( (WindowPtr)pDrawable,
308 xStart, ppt->y, xEnd - xStart, 1,
309 (unsigned char *)psrc + ( xStart - ppt->x ),
310 /* GJA ^ */
311 xEnd - xStart, alu, pm ) ;
318 return ;