2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
11 #include "xf86_OSproc.h"
13 #include "scrnintstr.h"
14 #include "pixmapstr.h"
24 DrawablePtr pDrawable
,
30 DrawablePtr pDrawable
,
32 int mode
, /* Origin or Previous */
33 int npt
, /* number of points */
37 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_GC(pGC
);
38 BoxPtr pboxInit
= REGION_RECTS(pGC
->pCompositeClip
);
39 int nboxInit
= REGION_NUM_RECTS(pGC
->pCompositeClip
);
40 unsigned int bias
= miGetZeroLineBias(pDrawable
->pScreen
);
41 int xorg
= pDrawable
->x
;
42 int yorg
= pDrawable
->y
;
48 int x1
, x2
, y1
, y2
, tmp
, len
;
53 if (infoRec
->SolidLineFlags
& LINE_LIMIT_COORDS
) {
54 int minValX
= infoRec
->SolidLineLimits
.x1
;
55 int maxValX
= infoRec
->SolidLineLimits
.x2
;
56 int minValY
= infoRec
->SolidLineLimits
.y1
;
57 int maxValY
= infoRec
->SolidLineLimits
.y2
;
69 x2
= ppt
->x
+ xorgtmp
;
70 y2
= ppt
->y
+ yorgtmp
;
84 if (mode
== CoordModePrevious
) {
88 x2
= ppt
->x
+ xorgtmp
;
89 y2
= ppt
->y
+ yorgtmp
;
91 if (x1
> maxValX
|| x1
< minValX
||
92 x2
> maxValX
|| x2
< minValX
||
93 y1
> maxValY
|| y1
< minValY
||
94 y2
> maxValY
|| y2
< minValY
) {
96 XAAFallbackOps
.PolySegment(pDrawable
, pGC
, nseg
, pSeg
);
98 XAAFallbackOps
.Polylines(pDrawable
, pGC
, mode
, npt
, pptInit
);
105 (*infoRec
->SetupForSolidLine
)(infoRec
->pScrn
, pGC
->fgPixel
,
106 pGC
->alu
, pGC
->planemask
);
121 x1
= pSeg
->x1
+ xorg
;
122 y1
= pSeg
->y1
+ yorg
;
123 x2
= pSeg
->x2
+ xorg
;
124 y2
= pSeg
->y2
+ yorg
;
130 if (mode
== CoordModePrevious
) {
138 if (x1
== x2
) { /* vertical line */
139 /* make the line go top to bottom of screen, keeping
147 if (pGC
->capStyle
!= CapNotLast
) y1
--;
151 else if (pGC
->capStyle
!= CapNotLast
) y2
++;
153 /* get to first band that might contain part of line */
154 while(nbox
&& (pbox
->y2
<= y1
)) {
159 /* stop when lower edge of box is beyond end of line */
160 while(nbox
&& (y2
>= pbox
->y1
)) {
161 if ((x1
>= pbox
->x1
) && (x1
< pbox
->x2
)) {
162 tmp
= max(y1
, pbox
->y1
);
163 len
= min(y2
, pbox
->y2
) - tmp
;
164 if (len
) (*infoRec
->SubsequentSolidHorVertLine
)(
165 infoRec
->pScrn
, x1
, tmp
, len
, DEGREES_270
);
173 } else if (y1
== y2
) { /* horizontal line */
174 /* force line from left to right, keeping endpoint semantics */
180 if (pGC
->capStyle
!= CapNotLast
) x1
--;
184 else if (pGC
->capStyle
!= CapNotLast
) x2
++;
187 /* find the correct band */
188 while(nbox
&& (pbox
->y2
<= y1
)) {
193 /* try to draw the line, if we haven't gone beyond it */
194 if (nbox
&& (pbox
->y1
<= y1
)) {
195 int orig_y
= pbox
->y1
;
196 /* when we leave this band, we're done */
197 while(nbox
&& (orig_y
== pbox
->y1
)) {
198 if (pbox
->x2
<= x1
) {
199 /* skip boxes until one might contain start point */
205 /* stop if left of box is beyond right of line */
206 if (pbox
->x1
>= x2
) {
211 tmp
= max(x1
, pbox
->x1
);
212 len
= min(x2
, pbox
->x2
) - tmp
;
213 if (len
) (*infoRec
->SubsequentSolidHorVertLine
)(
214 infoRec
->pScrn
, tmp
, y1
, len
, DEGREES_0
);
222 } else{ /* sloped line */
223 unsigned int oc1
, oc2
;
224 int dmin
, dmaj
, e
, octant
;
226 if (infoRec
->SubsequentSolidBresenhamLine
) {
227 if((dmaj
= x2
- x1
) < 0) {
229 octant
= XDECREASING
;
232 if((dmin
= y2
- y1
) < 0) {
234 octant
|= YDECREASING
;
238 tmp
= dmin
; dmin
= dmaj
; dmaj
= tmp
;
242 e
= -dmaj
- ((bias
>> octant
) & 1);
246 } else { /* Muffle compiler */
247 dmin
= dmaj
= e
= octant
= len
= 0;
252 OUTCODES(oc1
, x1
, y1
, pbox
);
253 OUTCODES(oc2
, x2
, y2
, pbox
);
254 if (!(oc1
| oc2
)) { /* unclipped */
255 if(infoRec
->SubsequentSolidTwoPointLine
) {
256 (*infoRec
->SubsequentSolidTwoPointLine
)(
257 infoRec
->pScrn
, x1
, y1
, x2
, y2
,
259 (pGC
->capStyle
!= CapNotLast
) ? 0 :
264 (*infoRec
->SubsequentSolidBresenhamLine
)(
265 infoRec
->pScrn
, x1
, y1
, dmaj
, dmin
, e
,
267 (pGC
->capStyle
!= CapNotLast
) ? (len
+1) :
272 } else if (oc1
& oc2
) { /* completely clipped */
274 } else if (infoRec
->ClippingFlags
& HARDWARE_CLIP_SOLID_LINE
) {
275 (*infoRec
->SetClippingRectangle
)(infoRec
->pScrn
,
276 pbox
->x1
, pbox
->y1
, pbox
->x2
- 1, pbox
->y2
- 1);
278 if(infoRec
->SubsequentSolidBresenhamLine
) {
279 (*infoRec
->SubsequentSolidBresenhamLine
)(
280 infoRec
->pScrn
, x1
, y1
, dmaj
, dmin
, e
,
282 (pGC
->capStyle
!= CapNotLast
) ? (len
+1) :
286 (*infoRec
->SubsequentSolidTwoPointLine
)(
287 infoRec
->pScrn
, x1
, y1
, x2
, y2
,
289 (pGC
->capStyle
!= CapNotLast
) ? 0 :
294 (*infoRec
->DisableClipping
)(infoRec
->pScrn
);
297 int new_x1
= x1
, new_y1
= y1
, new_x2
= x2
, new_y2
= y2
;
298 int clip1
= 0, clip2
= 0;
301 if(octant
& YMAJOR
) {
309 if (miZeroClipLine(pbox
->x1
, pbox
->y1
,
310 pbox
->x2
- 1, pbox
->y2
- 1,
311 &new_x1
, &new_y1
, &new_x2
, &new_y2
,
312 adx
, ady
, &clip1
, &clip2
,
313 octant
, bias
, oc1
, oc2
) == -1)
320 len
= abs(new_y2
- new_y1
);
322 len
= abs(new_x2
- new_x1
);
324 if (clip2
!= 0 || pGC
->capStyle
!= CapNotLast
)
330 int abserr
, clipdx
, clipdy
;
331 /* unwind bresenham error term to first point */
333 clipdx
= abs(new_x1
- x1
);
334 clipdy
= abs(new_y1
- y1
);
337 err
= e
+ clipdy
*dmin
- clipdx
*dmaj
;
339 err
= e
+ clipdx
*dmin
- clipdy
*dmaj
;
343 #define range infoRec->SolidBresenhamLineErrorTermBits
345 while((abserr
& range
) ||
354 (*infoRec
->SubsequentSolidBresenhamLine
)(
355 infoRec
->pScrn
, new_x1
, new_y1
,
356 dmaj
, dmin
, err
, len
, octant
);
360 } /* while (nbox--) */
362 } /* while (nline--) */
365 /* paint the last point if the end style isn't CapNotLast.
366 (Assume that a projecting, butt, or round cap that is one
367 pixel wide is the same as the single pixel of the endpoint.)
370 if ((pGC
->capStyle
!= CapNotLast
) &&
371 ((ppt
->x
+ xorg
!= pptInit
->x
+ pDrawable
->x
) ||
372 (ppt
->y
+ yorg
!= pptInit
->y
+ pDrawable
->y
) ||
373 (ppt
== pptInit
+ 1)))
379 if ((x2
>= pbox
->x1
) && (y2
>= pbox
->y1
) &&
380 (x2
< pbox
->x2
) && (y2
< pbox
->y2
))
382 (*infoRec
->SubsequentSolidHorVertLine
)(
383 infoRec
->pScrn
, x2
, y2
, 1, DEGREES_0
);
392 SET_SYNC_FLAG(infoRec
);