fbarc.c 4.2 KB

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