fbstipple.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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. /*
  28. * This is a slight abuse of the preprocessor to generate repetitive
  29. * code, the idea is to generate code for each case of a copy-mode
  30. * transparent stipple
  31. */
  32. #define LaneCases1(c,a) case c: \
  33. while (n--) { (void)FbLaneCase(c,a); a++; } \
  34. break
  35. #define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a)
  36. #define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a)
  37. #define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a)
  38. #define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a)
  39. #define LaneCases32(c,a) LaneCases16(c,a); LaneCases16(c+16,a)
  40. #define LaneCases64(c,a) LaneCases32(c,a); LaneCases32(c+32,a)
  41. #define LaneCases128(c,a) LaneCases64(c,a); LaneCases64(c+64,a)
  42. #define LaneCases256(c,a) LaneCases128(c,a); LaneCases128(c+128,a)
  43. #if FB_SHIFT == 6
  44. #define LaneCases(a) LaneCases256(0,a)
  45. #endif
  46. #if FB_SHIFT == 5
  47. #define LaneCases(a) LaneCases16(0,a)
  48. #endif
  49. /*
  50. * Repeat a transparent stipple across a scanline n times
  51. */
  52. void
  53. fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n)
  54. {
  55. FbStip s;
  56. s = ((FbStip) (stip) & 0x01);
  57. s |= ((FbStip) (stip >> 8) & 0x02);
  58. s |= ((FbStip) (stip >> 16) & 0x04);
  59. s |= ((FbStip) (stip >> 24) & 0x08);
  60. #if FB_SHIFT > 5
  61. s |= ((FbStip) (stip >> 32) & 0x10);
  62. s |= ((FbStip) (stip >> 40) & 0x20);
  63. s |= ((FbStip) (stip >> 48) & 0x40);
  64. s |= ((FbStip) (stip >> 56) & 0x80);
  65. #endif
  66. switch (s) {
  67. LaneCases(dst);
  68. }
  69. }
  70. void
  71. fbEvenStipple(FbBits * dst,
  72. FbStride dstStride,
  73. int dstX,
  74. int dstBpp,
  75. int width,
  76. int height,
  77. FbStip * stip,
  78. FbStride stipStride,
  79. int stipHeight,
  80. FbBits fgand,
  81. FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
  82. {
  83. FbBits startmask, endmask;
  84. FbBits mask, and, xor;
  85. int nmiddle, n;
  86. FbStip *s, *stipEnd, bits;
  87. int rot, stipX, stipY;
  88. int pixelsPerDst;
  89. const FbBits *fbBits;
  90. Bool transparent;
  91. int startbyte, endbyte;
  92. /*
  93. * Check for a transparent stipple (stencil)
  94. */
  95. transparent = FALSE;
  96. if (dstBpp >= 8 && fgand == 0 && bgand == FB_ALLONES && bgxor == 0)
  97. transparent = TRUE;
  98. pixelsPerDst = FB_UNIT / dstBpp;
  99. /*
  100. * Adjust dest pointers
  101. */
  102. dst += dstX >> FB_SHIFT;
  103. dstX &= FB_MASK;
  104. FbMaskBitsBytes(dstX, width, fgand == 0 && bgand == 0,
  105. startmask, startbyte, nmiddle, endmask, endbyte);
  106. if (startmask)
  107. dstStride--;
  108. dstStride -= nmiddle;
  109. xRot *= dstBpp;
  110. /*
  111. * Compute stip start scanline and rotation parameters
  112. */
  113. stipEnd = stip + stipStride * stipHeight;
  114. modulus(-yRot, stipHeight, stipY);
  115. s = stip + stipStride * stipY;
  116. modulus(-xRot, FB_UNIT, stipX);
  117. rot = stipX;
  118. /*
  119. * Get pointer to stipple mask array for this depth
  120. */
  121. /* fbStippleTable covers all valid bpp (4,8,16,32) */
  122. fbBits = fbStippleTable[pixelsPerDst];
  123. while (height--) {
  124. /*
  125. * Extract stipple bits for this scanline;
  126. */
  127. bits = *s;
  128. s += stipStride;
  129. if (s == stipEnd)
  130. s = stip;
  131. #if FB_UNIT > 32
  132. if (pixelsPerDst == 16)
  133. mask = FbStipple16Bits(FbLeftStipBits(bits, 16));
  134. else
  135. #endif
  136. mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
  137. /*
  138. * Rotate into position and compute reduced rop values
  139. */
  140. mask = FbRotLeft(mask, rot);
  141. and = (fgand & mask) | (bgand & ~mask);
  142. xor = (fgxor & mask) | (bgxor & ~mask);
  143. if (transparent) {
  144. if (startmask) {
  145. fbTransparentSpan(dst, mask & startmask, fgxor, 1);
  146. dst++;
  147. }
  148. fbTransparentSpan(dst, mask, fgxor, nmiddle);
  149. dst += nmiddle;
  150. if (endmask)
  151. fbTransparentSpan(dst, mask & endmask, fgxor, 1);
  152. }
  153. else
  154. {
  155. /*
  156. * Fill scanline
  157. */
  158. if (startmask) {
  159. FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
  160. dst++;
  161. }
  162. n = nmiddle;
  163. if (!and)
  164. while (n--)
  165. *dst++ = xor;
  166. else {
  167. while (n--) {
  168. *dst = FbDoRRop(*dst, and, xor);
  169. dst++;
  170. }
  171. }
  172. if (endmask)
  173. FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
  174. }
  175. dst += dstStride;
  176. }
  177. }
  178. void
  179. fbOddStipple(FbBits * dst,
  180. FbStride dstStride,
  181. int dstX,
  182. int dstBpp,
  183. int width,
  184. int height,
  185. FbStip * stip,
  186. FbStride stipStride,
  187. int stipWidth,
  188. int stipHeight,
  189. FbBits fgand,
  190. FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
  191. {
  192. int stipX, stipY, sx;
  193. int widthTmp;
  194. int h, w;
  195. int x, y;
  196. modulus(-yRot, stipHeight, stipY);
  197. modulus(dstX / dstBpp - xRot, stipWidth, stipX);
  198. y = 0;
  199. while (height) {
  200. h = stipHeight - stipY;
  201. if (h > height)
  202. h = height;
  203. height -= h;
  204. widthTmp = width;
  205. x = dstX;
  206. sx = stipX;
  207. while (widthTmp) {
  208. w = (stipWidth - sx) * dstBpp;
  209. if (w > widthTmp)
  210. w = widthTmp;
  211. widthTmp -= w;
  212. fbBltOne(stip + stipY * stipStride,
  213. stipStride,
  214. sx,
  215. dst + y * dstStride,
  216. dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor);
  217. x += w;
  218. sx = 0;
  219. }
  220. y += h;
  221. stipY = 0;
  222. }
  223. }
  224. void
  225. fbStipple(FbBits * dst,
  226. FbStride dstStride,
  227. int dstX,
  228. int dstBpp,
  229. int width,
  230. int height,
  231. FbStip * stip,
  232. FbStride stipStride,
  233. int stipWidth,
  234. int stipHeight,
  235. Bool even,
  236. FbBits fgand,
  237. FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
  238. {
  239. if (even)
  240. fbEvenStipple(dst, dstStride, dstX, dstBpp, width, height,
  241. stip, stipStride, stipHeight,
  242. fgand, fgxor, bgand, bgxor, xRot, yRot);
  243. else
  244. fbOddStipple(dst, dstStride, dstX, dstBpp, width, height,
  245. stip, stipStride, stipWidth, stipHeight,
  246. fgand, fgxor, bgand, bgxor, xRot, yRot);
  247. }