fbarc.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Copyright © 1998 Keith Packard
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that
  7. * copyright notice and this permission notice appear in supporting
  8. * documentation, and that the name of Keith Packard not be used in
  9. * advertising or publicity pertaining to distribution of the software without
  10. * specific, written prior permission. Keith Packard makes no
  11. * representations about the suitability of this software for any purpose. It
  12. * is provided "as is" without express or implied warranty.
  13. *
  14. * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16. * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  20. * PERFORMANCE OF THIS SOFTWARE.
  21. */
  22. #ifdef HAVE_DIX_CONFIG_H
  23. #include <dix-config.h>
  24. #endif
  25. #include "fb.h"
  26. #include "mizerarc.h"
  27. #include <limits.h>
  28. typedef void (*FbArc) (FbBits * dst,
  29. FbStride dstStride,
  30. int dstBpp,
  31. xArc * arc, int dx, int dy, FbBits and, FbBits xor);
  32. void
  33. fbPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs)
  34. {
  35. FbArc arc;
  36. if (pGC->lineWidth == 0) {
  37. arc = 0;
  38. if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid) {
  39. switch (pDrawable->bitsPerPixel) {
  40. case 8:
  41. arc = fbArc8;
  42. break;
  43. case 16:
  44. arc = fbArc16;
  45. break;
  46. case 24:
  47. arc = fbArc24;
  48. break;
  49. case 32:
  50. arc = fbArc32;
  51. break;
  52. }
  53. }
  54. if (arc) {
  55. FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
  56. FbBits *dst;
  57. FbStride dstStride;
  58. int dstBpp;
  59. int dstXoff, dstYoff;
  60. BoxRec box;
  61. int x2, y2;
  62. RegionPtr cclip;
  63. #ifdef FB_ACCESS_WRAPPER
  64. int wrapped = 1;
  65. #endif
  66. cclip = fbGetCompositeClip(pGC);
  67. fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
  68. while (narcs--) {
  69. if (miCanZeroArc(parcs)) {
  70. box.x1 = parcs->x + pDrawable->x;
  71. box.y1 = parcs->y + pDrawable->y;
  72. /*
  73. * Because box.x2 and box.y2 get truncated to 16 bits, and the
  74. * RECT_IN_REGION test treats the resulting number as a signed
  75. * integer, the RECT_IN_REGION test alone can go the wrong way.
  76. * This can result in a server crash because the rendering
  77. * routines in this file deal directly with cpu addresses
  78. * of pixels to be stored, and do not clip or otherwise check
  79. * that all such addresses are within their respective pixmaps.
  80. * So we only allow the RECT_IN_REGION test to be used for
  81. * values that can be expressed correctly in a signed short.
  82. */
  83. x2 = box.x1 + (int) parcs->width + 1;
  84. box.x2 = x2;
  85. y2 = box.y1 + (int) parcs->height + 1;
  86. box.y2 = y2;
  87. if ((x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
  88. (RegionContainsRect(cclip, &box) == rgnIN)) {
  89. #ifdef FB_ACCESS_WRAPPER
  90. if (!wrapped) {
  91. fbPrepareAccess(pDrawable);
  92. wrapped = 1;
  93. }
  94. #endif
  95. (*arc) (dst, dstStride, dstBpp,
  96. parcs, pDrawable->x + dstXoff,
  97. pDrawable->y + dstYoff, pPriv->and, pPriv->xor);
  98. }
  99. else {
  100. #ifdef FB_ACCESS_WRAPPER
  101. if (wrapped) {
  102. fbFinishAccess(pDrawable);
  103. wrapped = 0;
  104. }
  105. #endif
  106. miZeroPolyArc(pDrawable, pGC, 1, parcs);
  107. }
  108. }
  109. else {
  110. #ifdef FB_ACCESS_WRAPPER
  111. if (wrapped) {
  112. fbFinishAccess(pDrawable);
  113. wrapped = 0;
  114. }
  115. #endif
  116. miPolyArc(pDrawable, pGC, 1, parcs);
  117. }
  118. parcs++;
  119. }
  120. #ifdef FB_ACCESS_WRAPPER
  121. if (wrapped) {
  122. fbFinishAccess(pDrawable);
  123. wrapped = 0;
  124. }
  125. #endif
  126. }
  127. else
  128. miZeroPolyArc(pDrawable, pGC, narcs, parcs);
  129. }
  130. else
  131. miPolyArc(pDrawable, pGC, narcs, parcs);
  132. }