2 * Copyright © 2004 David Reveman
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * David Reveman not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * David Reveman makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
15 * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: David Reveman <davidr@novell.com>
31 xglFill (DrawablePtr pDrawable
,
33 xglGeometryPtr pGeometry
,
43 switch (pGC
->fillStyle
) {
45 if (xglSolid (pDrawable
,
46 pGCPriv
->op
, pGCPriv
->fg
,
54 case FillOpaqueStippled
:
57 if (xglTile (pDrawable
,
58 pGCPriv
->op
, pGC
->tile
.pixmap
,
59 -(pGC
->patOrg
.x
+ pDrawable
->x
),
60 -(pGC
->patOrg
.y
+ pDrawable
->y
),
73 xglFillBox (DrawablePtr pDrawable
,
85 if (!xglFill (pDrawable
, pGC
, NULL
, x
, y
, width
, height
, pBox
, nBox
))
89 XGL_DRAWABLE_PIXMAP (pDrawable
);
90 XGL_PIXMAP_PRIV (pPixmap
);
92 if (!xglMapPixmapBits (pPixmap
))
93 FatalError (XGL_SW_FAILURE_STRING
);
95 switch (pGC
->fillStyle
) {
99 case FillOpaqueStippled
:
100 if (!xglSyncBits (&pGC
->stipple
->drawable
, NullBox
))
101 FatalError (XGL_SW_FAILURE_STRING
);
104 if (!xglSyncBits (&pGC
->tile
.pixmap
->drawable
, NullBox
))
105 FatalError (XGL_SW_FAILURE_STRING
);
109 pPixmapPriv
->damageBox
= miEmptyBox
;
113 fbFill (pDrawable
, pGC
,
115 pBox
->x2
- pBox
->x1
, pBox
->y2
- pBox
->y1
);
117 REGION_INIT (pDrawable
->pScreen
, ®ion
, pBox
, 1);
118 xglAddSurfaceDamage (pDrawable
, ®ion
);
119 REGION_UNINIT (pDrawable
->pScreen
, ®ion
);
124 xglAddCurrentBitDamage (pDrawable
);
127 #define N_STACK_BOX 1024
130 xglMoreBoxes (BoxPtr stackBox
,
134 Bool stack
= !heapBox
;
136 heapBox
= xrealloc (heapBox
, sizeof (BoxRec
) * nBoxes
);
141 memcpy (heapBox
, stackBox
, sizeof (BoxRec
) * N_STACK_BOX
);
146 #define ADD_BOX(pBox, nBox, stackBox, heapBox, size, box) \
148 if ((nBox) == (size)) \
151 (heapBox) = xglMoreBoxes (stackBox, heapBox, size); \
154 (pBox) = (heapBox) + (nBox); \
167 xglFillRect (DrawablePtr pDrawable
,
172 RegionPtr pClip
= pGC
->pCompositeClip
;
174 BoxPtr pExtent
= REGION_EXTENTS (pGC
->pScreen
, pClip
);
176 BoxPtr heapBox
= NULL
;
177 BoxRec stackBox
[N_STACK_BOX
];
178 int size
= N_STACK_BOX
;
179 BoxPtr pBox
= stackBox
;
184 full
.x1
= prect
->x
+ pDrawable
->x
;
185 full
.y1
= prect
->y
+ pDrawable
->y
;
186 full
.x2
= full
.x1
+ (int) prect
->width
;
187 full
.y2
= full
.y1
+ (int) prect
->height
;
191 if (full
.x1
< pExtent
->x1
)
192 full
.x1
= pExtent
->x1
;
193 if (full
.y1
< pExtent
->y1
)
194 full
.y1
= pExtent
->y1
;
195 if (full
.x2
> pExtent
->x2
)
196 full
.x2
= pExtent
->x2
;
197 if (full
.y2
> pExtent
->y2
)
198 full
.y2
= pExtent
->y2
;
200 if (full
.x1
>= full
.x2
|| full
.y1
>= full
.y2
)
203 nClip
= REGION_NUM_RECTS (pClip
);
206 ADD_BOX (pBox
, nBox
, stackBox
, heapBox
, size
, full
);
210 pClipBox
= REGION_RECTS (pClip
);
215 if (part
.x1
< full
.x1
)
217 if (part
.y1
< full
.y1
)
219 if (part
.x2
> full
.x2
)
221 if (part
.y2
> full
.y2
)
224 if (part
.x1
< part
.x2
&& part
.y1
< part
.y2
)
225 ADD_BOX (pBox
, nBox
, stackBox
, heapBox
, size
, part
);
230 xglFillBox (pDrawable
, pGC
,
231 pExtent
->x1
, pExtent
->y1
,
232 pExtent
->x2
- pExtent
->x1
, pExtent
->y2
- pExtent
->y1
,
233 (heapBox
) ? heapBox
: stackBox
, nBox
);
240 xglFillSpan (DrawablePtr pDrawable
,
246 RegionPtr pClip
= pGC
->pCompositeClip
;
248 BoxPtr pExtent
= REGION_EXTENTS (pGC
->pScreen
, pClip
);
250 BoxPtr heapBox
= NULL
;
251 BoxRec stackBox
[N_STACK_BOX
];
252 int size
= N_STACK_BOX
;
253 BoxPtr pBox
= stackBox
;
260 full
.x2
= full
.x1
+ *pwidth
;
261 full
.y2
= full
.y1
+ 1;
266 if (full
.x1
< pExtent
->x1
)
267 full
.x1
= pExtent
->x1
;
268 if (full
.y1
< pExtent
->y1
)
269 full
.y1
= pExtent
->y1
;
270 if (full
.x2
> pExtent
->x2
)
271 full
.x2
= pExtent
->x2
;
272 if (full
.y2
> pExtent
->y2
)
273 full
.y2
= pExtent
->y2
;
275 if (full
.x1
>= full
.x2
|| full
.y1
>= full
.y2
)
278 nClip
= REGION_NUM_RECTS (pClip
);
281 ADD_BOX (pBox
, nBox
, stackBox
, heapBox
, size
, full
);
285 pClipBox
= REGION_RECTS (pClip
);
290 if (part
.x1
< full
.x1
)
292 if (part
.y1
< full
.y1
)
294 if (part
.x2
> full
.x2
)
296 if (part
.y2
> full
.y2
)
299 if (part
.x1
< part
.x2
&& part
.y1
< part
.y2
)
300 ADD_BOX (pBox
, nBox
, stackBox
, heapBox
, size
, part
);
305 xglFillBox (pDrawable
, pGC
,
306 pExtent
->x1
, pExtent
->y1
,
307 pExtent
->x2
- pExtent
->x1
, pExtent
->y2
- pExtent
->y1
,
308 (heapBox
) ? heapBox
: stackBox
, nBox
);
315 xglFillLine (DrawablePtr pDrawable
,
321 RegionPtr pClip
= pGC
->pCompositeClip
;
322 BoxPtr pExtent
= REGION_EXTENTS (pGC
->pScreen
, pClip
);
323 Bool coincidentEndpoints
= FALSE
;
324 Bool horizontalAndVertical
= TRUE
;
328 xglGeometryPtr pGeometry
;
330 XGL_SCREEN_PRIV (pGC
->pScreen
);
340 if (mode
== CoordModePrevious
)
344 if (pptTmp
->x
&& pptTmp
->y
)
345 horizontalAndVertical
= FALSE
;
353 if (pt
.x
== ppt
->x
&& pt
.y
== ppt
->y
)
354 coincidentEndpoints
= TRUE
;
360 if (pptTmp
->x
!= pt
.x
&& pptTmp
->y
!= pt
.y
)
362 horizontalAndVertical
= FALSE
;
369 if (ppt
[npt
- 1].x
== ppt
->x
&& ppt
[npt
- 1].y
== ppt
->y
)
370 coincidentEndpoints
= TRUE
;
373 if (horizontalAndVertical
)
377 BoxPtr heapBox
= NULL
;
378 BoxRec stackBox
[N_STACK_BOX
];
379 int size
= N_STACK_BOX
;
380 BoxPtr pBox
= stackBox
;
391 if (mode
== CoordModePrevious
)
406 full
.x1
= pt
.x
+ pDrawable
->x
;
408 if (npt
|| coincidentEndpoints
)
409 full
.x2
= full
.x1
+ dx
;
411 full
.x2
= full
.x1
+ dx
+ 1;
415 full
.x2
= pt
.x
+ pDrawable
->x
+ 1;
417 if (npt
|| coincidentEndpoints
)
418 full
.x1
= full
.x2
+ dx
;
420 full
.x1
= full
.x2
+ dx
- 1;
423 full
.y1
= pt
.y
+ pDrawable
->y
;
424 full
.y2
= full
.y1
+ 1;
430 full
.y1
= pt
.y
+ pDrawable
->y
;
432 if (npt
|| coincidentEndpoints
)
433 full
.y2
= full
.y1
+ dy
;
435 full
.y2
= full
.y1
+ dy
+ 1;
439 full
.y2
= pt
.y
+ pDrawable
->y
+ 1;
441 if (npt
|| coincidentEndpoints
)
442 full
.y1
= full
.y2
+ dy
;
444 full
.y1
= full
.y2
+ dy
- 1;
447 full
.x1
= pt
.x
+ pDrawable
->x
;
448 full
.x2
= full
.x1
+ 1;
456 if (full
.x1
< pExtent
->x1
)
457 full
.x1
= pExtent
->x1
;
458 if (full
.y1
< pExtent
->y1
)
459 full
.y1
= pExtent
->y1
;
460 if (full
.x2
> pExtent
->x2
)
461 full
.x2
= pExtent
->x2
;
462 if (full
.y2
> pExtent
->y2
)
463 full
.y2
= pExtent
->y2
;
465 if (full
.x1
>= full
.x2
|| full
.y1
>= full
.y2
)
468 nClip
= REGION_NUM_RECTS (pClip
);
471 ADD_BOX (pBox
, nBox
, stackBox
, heapBox
, size
, full
);
475 pClipBox
= REGION_RECTS (pClip
);
480 if (part
.x1
< full
.x1
)
482 if (part
.y1
< full
.y1
)
484 if (part
.x2
> full
.x2
)
486 if (part
.y2
> full
.y2
)
489 if (part
.x1
< part
.x2
&& part
.y1
< part
.y2
)
490 ADD_BOX (pBox
, nBox
, stackBox
, heapBox
, size
, part
);
495 xglFillBox (pDrawable
, pGC
,
496 pExtent
->x1
, pExtent
->y1
,
497 pExtent
->x2
- pExtent
->x1
, pExtent
->y2
- pExtent
->y1
,
498 (heapBox
) ? heapBox
: stackBox
, nBox
);
506 if (!pScreenPriv
->lines
)
509 if (coincidentEndpoints
)
512 pGeometry
= xglGetScratchVertexGeometry (pGC
->pScreen
, npt
);
514 GEOMETRY_ADD_LINE (pGC
->pScreen
, pGeometry
,
515 coincidentEndpoints
, mode
, npt
, ppt
);
517 if (coincidentEndpoints
)
518 GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry
, GLITZ_PRIMITIVE_LINE_LOOP
);
520 GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry
, GLITZ_PRIMITIVE_LINE_STRIP
);
522 /* Lines need a 0.5 translate */
523 GEOMETRY_TRANSLATE_FIXED (pGeometry
, 1 << 15, 1 << 15);
525 GEOMETRY_TRANSLATE (pGeometry
, pDrawable
->x
, pDrawable
->y
);
527 pExtent
= REGION_EXTENTS (pDrawable
->pScreen
, pGC
->pCompositeClip
);
529 if (xglFill (pDrawable
, pGC
, pGeometry
,
530 pExtent
->x1
, pExtent
->y1
,
531 pExtent
->x2
- pExtent
->x1
, pExtent
->y2
- pExtent
->y1
,
532 REGION_RECTS (pGC
->pCompositeClip
),
533 REGION_NUM_RECTS (pGC
->pCompositeClip
)))
535 xglAddCurrentBitDamage (pDrawable
);
543 xglFillSegment (DrawablePtr pDrawable
,
548 RegionPtr pClip
= pGC
->pCompositeClip
;
549 BoxPtr pExtent
= REGION_EXTENTS (pGC
->pScreen
, pClip
);
550 Bool horizontalAndVertical
= TRUE
;
551 xglGeometryPtr pGeometry
;
555 XGL_SCREEN_PRIV (pGC
->pScreen
);
564 if (pSeg
->x1
!= pSeg
->x2
&& pSeg
->y1
!= pSeg
->y2
)
565 horizontalAndVertical
= FALSE
;
570 if (horizontalAndVertical
)
574 BoxPtr heapBox
= NULL
;
575 BoxRec stackBox
[N_STACK_BOX
];
576 int size
= N_STACK_BOX
;
577 BoxPtr pBox
= stackBox
;
582 if (pSegInit
->x1
!= pSegInit
->x2
)
584 if (pSegInit
->x1
< pSegInit
->x2
)
586 full
.x1
= pSegInit
->x1
;
587 full
.x2
= pSegInit
->x2
;
591 full
.x1
= pSegInit
->x2
;
592 full
.x2
= pSegInit
->x1
;
595 full
.x1
+= pDrawable
->x
;
596 full
.x2
+= pDrawable
->x
+ 1;
597 full
.y1
= pSegInit
->y1
+ pDrawable
->y
;
598 full
.y2
= full
.y1
+ 1;
602 if (pSegInit
->y1
< pSegInit
->y2
)
604 full
.y1
= pSegInit
->y1
;
605 full
.y2
= pSegInit
->y2
;
609 full
.y1
= pSegInit
->y2
;
610 full
.y2
= pSegInit
->y1
;
613 full
.y1
+= pDrawable
->y
;
614 full
.y2
+= pDrawable
->y
+ 1;
615 full
.x1
= pSegInit
->x1
+ pDrawable
->x
;
616 full
.x2
= full
.x1
+ 1;
621 if (full
.x1
< pExtent
->x1
)
622 full
.x1
= pExtent
->x1
;
623 if (full
.y1
< pExtent
->y1
)
624 full
.y1
= pExtent
->y1
;
625 if (full
.x2
> pExtent
->x2
)
626 full
.x2
= pExtent
->x2
;
627 if (full
.y2
> pExtent
->y2
)
628 full
.y2
= pExtent
->y2
;
630 if (full
.x1
>= full
.x2
|| full
.y1
>= full
.y2
)
633 nClip
= REGION_NUM_RECTS (pClip
);
636 ADD_BOX (pBox
, nBox
, stackBox
, heapBox
, size
, full
);
640 pClipBox
= REGION_RECTS (pClip
);
645 if (part
.x1
< full
.x1
)
647 if (part
.y1
< full
.y1
)
649 if (part
.x2
> full
.x2
)
651 if (part
.y2
> full
.y2
)
654 if (part
.x1
< part
.x2
&& part
.y1
< part
.y2
)
655 ADD_BOX (pBox
, nBox
, stackBox
, heapBox
, size
, part
);
660 xglFillBox (pDrawable
, pGC
,
661 pExtent
->x1
, pExtent
->y1
,
662 pExtent
->x2
- pExtent
->x1
, pExtent
->y2
- pExtent
->y1
,
663 (heapBox
) ? heapBox
: stackBox
, nBox
);
671 if (!pScreenPriv
->lines
)
674 pGeometry
= xglGetScratchVertexGeometry (pGC
->pScreen
, 2 * nSegInit
);
676 GEOMETRY_ADD_SEGMENT (pGC
->pScreen
, pGeometry
, nSegInit
, pSegInit
);
678 /* Line segments need 0.5 translate */
679 GEOMETRY_TRANSLATE_FIXED (pGeometry
, 1 << 15, 1 << 15);
680 GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry
, GLITZ_PRIMITIVE_LINES
);
682 GEOMETRY_TRANSLATE (pGeometry
, pDrawable
->x
, pDrawable
->y
);
684 if (xglFill (pDrawable
, pGC
, pGeometry
,
685 pExtent
->x1
, pExtent
->y1
,
686 pExtent
->x2
- pExtent
->x1
, pExtent
->y2
- pExtent
->y1
,
687 REGION_RECTS (pGC
->pCompositeClip
),
688 REGION_NUM_RECTS (pGC
->pCompositeClip
)))
690 xglAddCurrentBitDamage (pDrawable
);
698 xglFillGlyph (DrawablePtr pDrawable
,
707 xglGeometryRec geometry
;
712 pExtent
= REGION_EXTENTS (pDrawable
->pScreen
, pGC
->pCompositeClip
);
717 GEOMETRY_INIT (pDrawable
->pScreen
, &geometry
,
718 GLITZ_GEOMETRY_TYPE_BITMAP
,
719 GEOMETRY_USAGE_SYSMEM
, 0);
721 GEOMETRY_FOR_GLYPH (pDrawable
->pScreen
,
727 GEOMETRY_TRANSLATE (&geometry
, x
, y
);
729 if (xglFill (pDrawable
, pGC
, &geometry
,
730 pExtent
->x1
, pExtent
->y1
,
731 pExtent
->x2
- pExtent
->x1
, pExtent
->y2
- pExtent
->y1
,
732 REGION_RECTS (pGC
->pCompositeClip
),
733 REGION_NUM_RECTS (pGC
->pCompositeClip
)))
735 GEOMETRY_UNINIT (&geometry
);
736 xglAddCurrentBitDamage (pDrawable
);
740 GEOMETRY_UNINIT (&geometry
);