1706f2543Smrg
2706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
3706f2543Smrg#include <xorg-config.h>
4706f2543Smrg#endif
5706f2543Smrg
6706f2543Smrg#include "misc.h"
7706f2543Smrg#include "xf86.h"
8706f2543Smrg#include "xf86_OSproc.h"
9706f2543Smrg
10706f2543Smrg#include <X11/X.h>
11706f2543Smrg#include "scrnintstr.h"
12706f2543Smrg#include "miline.h"
13706f2543Smrg#include "xf86str.h"
14706f2543Smrg#include "xaa.h"
15706f2543Smrg#include "xaalocal.h"
16706f2543Smrg
17706f2543Smrg
18706f2543Smrgvoid
19706f2543SmrgXAASolidHorVertLineAsRects(
20706f2543Smrg   ScrnInfoPtr pScrn,
21706f2543Smrg   int x, int y, int len, int dir
22706f2543Smrg){
23706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
24706f2543Smrg
25706f2543Smrg    if(dir == DEGREES_0)
26706f2543Smrg	(*infoRec->SubsequentSolidFillRect)(pScrn, x, y, len, 1);
27706f2543Smrg    else
28706f2543Smrg	(*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, len);
29706f2543Smrg}
30706f2543Smrg
31706f2543Smrg
32706f2543Smrgvoid
33706f2543SmrgXAASolidHorVertLineAsTwoPoint(
34706f2543Smrg   ScrnInfoPtr pScrn,
35706f2543Smrg   int x, int y, int len, int dir
36706f2543Smrg){
37706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
38706f2543Smrg
39706f2543Smrg    len--;
40706f2543Smrg
41706f2543Smrg    if(dir == DEGREES_0)
42706f2543Smrg	(*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x + len, y, 0);
43706f2543Smrg    else
44706f2543Smrg	(*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x, y + len, 0);
45706f2543Smrg}
46706f2543Smrg
47706f2543Smrgvoid
48706f2543SmrgXAASolidHorVertLineAsBresenham(
49706f2543Smrg   ScrnInfoPtr pScrn,
50706f2543Smrg   int x, int y, int len, int dir
51706f2543Smrg){
52706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
53706f2543Smrg
54706f2543Smrg    if(dir == DEGREES_0)
55706f2543Smrg	(*infoRec->SubsequentSolidBresenhamLine)(
56706f2543Smrg		pScrn, x, y, len << 1, 0, -len, len, 0);
57706f2543Smrg    else
58706f2543Smrg	(*infoRec->SubsequentSolidBresenhamLine)(
59706f2543Smrg		pScrn, x, y, len << 1, 0, -len, len, YMAJOR);
60706f2543Smrg}
61706f2543Smrg
62706f2543Smrg
63706f2543Smrgvoid
64706f2543SmrgXAAComputeDash(GCPtr pGC)
65706f2543Smrg{
66706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
67706f2543Smrg    XAAGCPtr   pGCPriv = (XAAGCPtr)dixLookupPrivate(&pGC->devPrivates,
68706f2543Smrg						    XAAGetGCKey());
69706f2543Smrg    Bool EvenDash = (pGC->numInDashList & 0x01) ? FALSE : TRUE;
70706f2543Smrg    int PatternLength = 0;
71706f2543Smrg    unsigned char* DashPtr = (unsigned char*)pGC->dash;
72706f2543Smrg    CARD32 *ptr;
73706f2543Smrg    int count = pGC->numInDashList;
74706f2543Smrg    int shift, value, direction;
75706f2543Smrg    Bool set;
76706f2543Smrg
77706f2543Smrg    free(pGCPriv->DashPattern);
78706f2543Smrg
79706f2543Smrg    pGCPriv->DashPattern = NULL;
80706f2543Smrg    pGCPriv->DashLength = 0;
81706f2543Smrg
82706f2543Smrg    while(count--)
83706f2543Smrg	PatternLength += *(DashPtr++);
84706f2543Smrg
85706f2543Smrg    if(!EvenDash)
86706f2543Smrg	PatternLength <<= 1;
87706f2543Smrg
88706f2543Smrg    if(PatternLength > infoRec->DashPatternMaxLength)
89706f2543Smrg	return;
90706f2543Smrg
91706f2543Smrg    if((infoRec->DashedLineFlags & LINE_PATTERN_POWER_OF_2_ONLY) &&
92706f2543Smrg				(PatternLength & (PatternLength - 1)))
93706f2543Smrg	return;
94706f2543Smrg
95706f2543Smrg    pGCPriv->DashPattern = calloc((PatternLength + 31) >> 5, 4);
96706f2543Smrg    if(!pGCPriv->DashPattern) return;
97706f2543Smrg    pGCPriv->DashLength = PatternLength;
98706f2543Smrg
99706f2543Smrg    if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
100706f2543Smrg 	 	 		   LINE_PATTERN_LSBFIRST_LSBJUSTIFIED)) {
101706f2543Smrg	direction = 1;
102706f2543Smrg	set = TRUE;
103706f2543Smrg	DashPtr = (unsigned char*)pGC->dash;
104706f2543Smrg    } else {
105706f2543Smrg	direction = -1;
106706f2543Smrg	set = FALSE;
107706f2543Smrg	DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList - 1;
108706f2543Smrg    }
109706f2543Smrg
110706f2543Smrg    if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
111706f2543Smrg 	 	 		   LINE_PATTERN_MSBFIRST_MSBJUSTIFIED))
112706f2543Smrg	shift = 32 - (PatternLength & 31);
113706f2543Smrg    else
114706f2543Smrg	shift = 0;
115706f2543Smrg
116706f2543Smrg    ptr = (CARD32*)(pGCPriv->DashPattern);
117706f2543Smrg
118706f2543SmrgCONCATENATE:
119706f2543Smrg
120706f2543Smrg    count = pGC->numInDashList;
121706f2543Smrg
122706f2543Smrg    while(count--) {
123706f2543Smrg	value = *DashPtr;
124706f2543Smrg	DashPtr += direction;
125706f2543Smrg	while(value) {
126706f2543Smrg	    if(value < (32 - shift)) {
127706f2543Smrg		if(set) *ptr |= XAAShiftMasks[value] << shift;
128706f2543Smrg		shift += value;
129706f2543Smrg		break;
130706f2543Smrg	     } else {
131706f2543Smrg		if(set) *ptr |= ~0L << shift;
132706f2543Smrg		value -= (32 - shift);
133706f2543Smrg		shift = 0;
134706f2543Smrg		ptr++;
135706f2543Smrg	     }
136706f2543Smrg	}
137706f2543Smrg	if(set) set = FALSE;
138706f2543Smrg	else set = TRUE;
139706f2543Smrg    }
140706f2543Smrg
141706f2543Smrg    if(!EvenDash) {
142706f2543Smrg	EvenDash = TRUE;
143706f2543Smrg	if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
144706f2543Smrg				       LINE_PATTERN_LSBFIRST_LSBJUSTIFIED))
145706f2543Smrg	   DashPtr = (unsigned char*)pGC->dash;
146706f2543Smrg	else
147706f2543Smrg	   DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList;
148706f2543Smrg	goto CONCATENATE;
149706f2543Smrg    }
150706f2543Smrg}
151