fbtrap.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. *
  3. * Copyright © 2004 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 "picturestr.h"
  28. #include "mipict.h"
  29. #include "renderedge.h"
  30. #include "fbpict.h"
  31. void
  32. fbAddTraps(PicturePtr pPicture,
  33. INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
  34. {
  35. FbBits *buf;
  36. int bpp;
  37. int width;
  38. int stride;
  39. int height;
  40. int pxoff, pyoff;
  41. xFixed x_off_fixed;
  42. xFixed y_off_fixed;
  43. RenderEdge l, r;
  44. xFixed t, b;
  45. fbGetDrawable(pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
  46. width = pPicture->pDrawable->width;
  47. height = pPicture->pDrawable->height;
  48. x_off += pxoff;
  49. y_off += pyoff;
  50. x_off_fixed = IntToxFixed(x_off);
  51. y_off_fixed = IntToxFixed(y_off);
  52. while (ntrap--) {
  53. t = traps->top.y + y_off_fixed;
  54. if (t < 0)
  55. t = 0;
  56. t = RenderSampleCeilY(t, bpp);
  57. b = traps->bot.y + y_off_fixed;
  58. if (xFixedToInt(b) >= height)
  59. b = IntToxFixed(height) - 1;
  60. b = RenderSampleFloorY(b, bpp);
  61. if (b >= t) {
  62. /* initialize edge walkers */
  63. RenderEdgeInit(&l, bpp, t,
  64. traps->top.l + x_off_fixed,
  65. traps->top.y + y_off_fixed,
  66. traps->bot.l + x_off_fixed,
  67. traps->bot.y + y_off_fixed);
  68. RenderEdgeInit(&r, bpp, t,
  69. traps->top.r + x_off_fixed,
  70. traps->top.y + y_off_fixed,
  71. traps->bot.r + x_off_fixed,
  72. traps->bot.y + y_off_fixed);
  73. fbRasterizeEdges(buf, bpp, width, stride, &l, &r, t, b);
  74. }
  75. traps++;
  76. }
  77. }
  78. void
  79. fbRasterizeTrapezoid(PicturePtr pPicture,
  80. xTrapezoid * trap, int x_off, int y_off)
  81. {
  82. FbBits *buf;
  83. int bpp;
  84. int width;
  85. int stride;
  86. int height;
  87. int pxoff, pyoff;
  88. xFixed x_off_fixed _X_UNUSED;
  89. xFixed y_off_fixed;
  90. RenderEdge l, r;
  91. xFixed t, b;
  92. fbGetDrawable(pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
  93. width = pPicture->pDrawable->width;
  94. height = pPicture->pDrawable->height;
  95. x_off += pxoff;
  96. y_off += pyoff;
  97. x_off_fixed = IntToxFixed(x_off);
  98. y_off_fixed = IntToxFixed(y_off);
  99. t = trap->top + y_off_fixed;
  100. if (t < 0)
  101. t = 0;
  102. t = RenderSampleCeilY(t, bpp);
  103. b = trap->bottom + y_off_fixed;
  104. if (xFixedToInt(b) >= height)
  105. b = IntToxFixed(height) - 1;
  106. b = RenderSampleFloorY(b, bpp);
  107. if (b >= t) {
  108. /* initialize edge walkers */
  109. RenderLineFixedEdgeInit(&l, bpp, t, &trap->left, x_off, y_off);
  110. RenderLineFixedEdgeInit(&r, bpp, t, &trap->right, x_off, y_off);
  111. fbRasterizeEdges(buf, bpp, width, stride, &l, &r, t, b);
  112. }
  113. }
  114. static int
  115. _GreaterY(xPointFixed * a, xPointFixed * b)
  116. {
  117. if (a->y == b->y)
  118. return a->x > b->x;
  119. return a->y > b->y;
  120. }
  121. /*
  122. * Note that the definition of this function is a bit odd because
  123. * of the X coordinate space (y increasing downwards).
  124. */
  125. static int
  126. _Clockwise(xPointFixed * ref, xPointFixed * a, xPointFixed * b)
  127. {
  128. xPointFixed ad, bd;
  129. ad.x = a->x - ref->x;
  130. ad.y = a->y - ref->y;
  131. bd.x = b->x - ref->x;
  132. bd.y = b->y - ref->y;
  133. return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0;
  134. }
  135. /* FIXME -- this could be made more efficient */
  136. void
  137. fbAddTriangles(PicturePtr pPicture,
  138. INT16 x_off, INT16 y_off, int ntri, xTriangle * tris)
  139. {
  140. xPointFixed *top, *left, *right, *tmp;
  141. xTrapezoid trap;
  142. for (; ntri; ntri--, tris++) {
  143. top = &tris->p1;
  144. left = &tris->p2;
  145. right = &tris->p3;
  146. if (_GreaterY(top, left)) {
  147. tmp = left;
  148. left = top;
  149. top = tmp;
  150. }
  151. if (_GreaterY(top, right)) {
  152. tmp = right;
  153. right = top;
  154. top = tmp;
  155. }
  156. if (_Clockwise(top, right, left)) {
  157. tmp = right;
  158. right = left;
  159. left = tmp;
  160. }
  161. /*
  162. * Two cases:
  163. *
  164. * + +
  165. * / \ / \
  166. * / \ / \
  167. * / + + \
  168. * / -- -- \
  169. * / -- -- \
  170. * / --- --- \
  171. * +-- --+
  172. */
  173. trap.top = top->y;
  174. trap.left.p1 = *top;
  175. trap.left.p2 = *left;
  176. trap.right.p1 = *top;
  177. trap.right.p2 = *right;
  178. if (right->y < left->y)
  179. trap.bottom = right->y;
  180. else
  181. trap.bottom = left->y;
  182. fbRasterizeTrapezoid(pPicture, &trap, x_off, y_off);
  183. if (right->y < left->y) {
  184. trap.top = right->y;
  185. trap.bottom = left->y;
  186. trap.right.p1 = *right;
  187. trap.right.p2 = *left;
  188. }
  189. else {
  190. trap.top = left->y;
  191. trap.bottom = right->y;
  192. trap.left.p1 = *left;
  193. trap.left.p2 = *right;
  194. }
  195. fbRasterizeTrapezoid(pPicture, &trap, x_off, y_off);
  196. }
  197. }