rasops1.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /* $OpenBSD: rasops1.c,v 1.9 2014/12/19 22:44:58 guenther Exp $ */
  2. /* $NetBSD: rasops1.c,v 1.11 2000/04/12 14:22:29 pk Exp $ */
  3. /*-
  4. * Copyright (c) 1999 The NetBSD Foundation, Inc.
  5. * All rights reserved.
  6. *
  7. * This code is derived from software contributed to The NetBSD Foundation
  8. * by Andrew Doran.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  21. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  23. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include <sys/param.h>
  32. #include <sys/systm.h>
  33. #include <sys/time.h>
  34. #include <sys/endian.h>
  35. #include <dev/wscons/wsdisplayvar.h>
  36. #include <dev/wscons/wsconsio.h>
  37. #include <dev/rasops/rasops.h>
  38. #include <dev/rasops/rasops_masks.h>
  39. int rasops1_copycols(void *, int, int, int, int);
  40. int rasops1_erasecols(void *, int, int, int, long);
  41. int rasops1_do_cursor(struct rasops_info *);
  42. int rasops1_putchar(void *, int, int col, u_int, long);
  43. #ifndef RASOPS_SMALL
  44. int rasops1_putchar8(void *, int, int col, u_int, long);
  45. int rasops1_putchar16(void *, int, int col, u_int, long);
  46. #endif
  47. /*
  48. * Initialize rasops_info struct for this colordepth.
  49. */
  50. void
  51. rasops1_init(struct rasops_info *ri)
  52. {
  53. rasops_masks_init();
  54. switch (ri->ri_font->fontwidth) {
  55. #ifndef RASOPS_SMALL
  56. case 8:
  57. ri->ri_ops.putchar = rasops1_putchar8;
  58. break;
  59. case 16:
  60. ri->ri_ops.putchar = rasops1_putchar16;
  61. break;
  62. #endif
  63. default:
  64. ri->ri_ops.putchar = rasops1_putchar;
  65. break;
  66. }
  67. if ((ri->ri_font->fontwidth & 7) != 0) {
  68. ri->ri_ops.erasecols = rasops1_erasecols;
  69. ri->ri_ops.copycols = rasops1_copycols;
  70. ri->ri_do_cursor = rasops1_do_cursor;
  71. }
  72. }
  73. /*
  74. * Paint a single character. This is the generic version, this is ugly.
  75. */
  76. int
  77. rasops1_putchar(void *cookie, int row, int col, u_int uc, long attr)
  78. {
  79. u_int fs, rs, fb, bg, fg, lmask, rmask;
  80. u_int32_t height, width;
  81. struct rasops_info *ri;
  82. int32_t *rp;
  83. u_char *fr;
  84. ri = (struct rasops_info *)cookie;
  85. #ifdef RASOPS_CLIPPING
  86. /* Catches 'row < 0' case too */
  87. if ((unsigned)row >= (unsigned)ri->ri_rows)
  88. return 0;
  89. if ((unsigned)col >= (unsigned)ri->ri_cols)
  90. return 0;
  91. #endif
  92. col *= ri->ri_font->fontwidth;
  93. rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
  94. height = ri->ri_font->fontheight;
  95. width = ri->ri_font->fontwidth;
  96. col = col & 31;
  97. rs = ri->ri_stride;
  98. bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
  99. fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
  100. /* If fg and bg match this becomes a space character */
  101. if (fg == bg || uc == ' ') {
  102. uc = (u_int)-1;
  103. fr = 0; /* shutup gcc */
  104. fs = 0; /* shutup gcc */
  105. } else {
  106. uc -= ri->ri_font->firstchar;
  107. fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  108. fs = ri->ri_font->stride;
  109. }
  110. /* Single word, one mask */
  111. if ((col + width) <= 32) {
  112. rmask = rasops_pmask[col][width];
  113. lmask = ~rmask;
  114. if (uc == (u_int)-1) {
  115. bg &= rmask;
  116. while (height--) {
  117. *rp = (*rp & lmask) | bg;
  118. DELTA(rp, rs, int32_t *);
  119. }
  120. } else {
  121. /* NOT fontbits if bg is white */
  122. if (bg) {
  123. while (height--) {
  124. fb = ~(fr[3] | (fr[2] << 8) |
  125. (fr[1] << 16) | (fr[0] << 24));
  126. *rp = (*rp & lmask)
  127. | (MBE(fb >> col) & rmask);
  128. fr += fs;
  129. DELTA(rp, rs, int32_t *);
  130. }
  131. } else {
  132. while (height--) {
  133. fb = (fr[3] | (fr[2] << 8) |
  134. (fr[1] << 16) | (fr[0] << 24));
  135. *rp = (*rp & lmask)
  136. | (MBE(fb >> col) & rmask);
  137. fr += fs;
  138. DELTA(rp, rs, int32_t *);
  139. }
  140. }
  141. }
  142. /* Do underline */
  143. if ((attr & 1) != 0) {
  144. DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  145. *rp = (*rp & lmask) | (fg & rmask);
  146. }
  147. } else {
  148. lmask = ~rasops_lmask[col];
  149. rmask = ~rasops_rmask[(col + width) & 31];
  150. if (uc == (u_int)-1) {
  151. width = bg & ~rmask;
  152. bg = bg & ~lmask;
  153. while (height--) {
  154. rp[0] = (rp[0] & lmask) | bg;
  155. rp[1] = (rp[1] & rmask) | width;
  156. DELTA(rp, rs, int32_t *);
  157. }
  158. } else {
  159. width = 32 - col;
  160. /* NOT fontbits if bg is white */
  161. if (bg) {
  162. while (height--) {
  163. fb = ~(fr[3] | (fr[2] << 8) |
  164. (fr[1] << 16) | (fr[0] << 24));
  165. rp[0] = (rp[0] & lmask)
  166. | MBE((u_int)fb >> col);
  167. rp[1] = (rp[1] & rmask)
  168. | (MBE((u_int)fb << width) & ~rmask);
  169. fr += fs;
  170. DELTA(rp, rs, int32_t *);
  171. }
  172. } else {
  173. while (height--) {
  174. fb = (fr[3] | (fr[2] << 8) |
  175. (fr[1] << 16) | (fr[0] << 24));
  176. rp[0] = (rp[0] & lmask)
  177. | MBE(fb >> col);
  178. rp[1] = (rp[1] & rmask)
  179. | (MBE(fb << width) & ~rmask);
  180. fr += fs;
  181. DELTA(rp, rs, int32_t *);
  182. }
  183. }
  184. }
  185. /* Do underline */
  186. if ((attr & 1) != 0) {
  187. DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  188. rp[0] = (rp[0] & lmask) | (fg & ~lmask);
  189. rp[1] = (rp[1] & rmask) | (fg & ~rmask);
  190. }
  191. }
  192. return 0;
  193. }
  194. #ifndef RASOPS_SMALL
  195. /*
  196. * Paint a single character. This is for 8-pixel wide fonts.
  197. */
  198. int
  199. rasops1_putchar8(void *cookie, int row, int col, u_int uc, long attr)
  200. {
  201. int height, fs, rs, bg, fg;
  202. struct rasops_info *ri;
  203. u_char *fr, *rp;
  204. ri = (struct rasops_info *)cookie;
  205. #ifdef RASOPS_CLIPPING
  206. /* Catches 'row < 0' case too */
  207. if ((unsigned)row >= (unsigned)ri->ri_rows)
  208. return 0;
  209. if ((unsigned)col >= (unsigned)ri->ri_cols)
  210. return 0;
  211. #endif
  212. rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  213. height = ri->ri_font->fontheight;
  214. rs = ri->ri_stride;
  215. bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
  216. fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
  217. /* If fg and bg match this becomes a space character */
  218. if (fg == bg || uc == ' ') {
  219. while (height--) {
  220. *rp = bg;
  221. rp += rs;
  222. }
  223. } else {
  224. uc -= ri->ri_font->firstchar;
  225. fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  226. fs = ri->ri_font->stride;
  227. /* NOT fontbits if bg is white */
  228. if (bg) {
  229. while (height--) {
  230. *rp = ~*fr;
  231. fr += fs;
  232. rp += rs;
  233. }
  234. } else {
  235. while (height--) {
  236. *rp = *fr;
  237. fr += fs;
  238. rp += rs;
  239. }
  240. }
  241. }
  242. /* Do underline */
  243. if ((attr & 1) != 0)
  244. rp[-(ri->ri_stride << 1)] = fg;
  245. return 0;
  246. }
  247. /*
  248. * Paint a single character. This is for 16-pixel wide fonts.
  249. */
  250. int
  251. rasops1_putchar16(void *cookie, int row, int col, u_int uc, long attr)
  252. {
  253. int height, fs, rs, bg, fg;
  254. struct rasops_info *ri;
  255. u_char *fr, *rp;
  256. ri = (struct rasops_info *)cookie;
  257. #ifdef RASOPS_CLIPPING
  258. /* Catches 'row < 0' case too */
  259. if ((unsigned)row >= (unsigned)ri->ri_rows)
  260. return 0;
  261. if ((unsigned)col >= (unsigned)ri->ri_cols)
  262. return 0;
  263. #endif
  264. rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  265. height = ri->ri_font->fontheight;
  266. rs = ri->ri_stride;
  267. bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
  268. fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
  269. /* If fg and bg match this becomes a space character */
  270. if (fg == bg || uc == ' ') {
  271. while (height--) {
  272. *(int16_t *)rp = bg;
  273. rp += rs;
  274. }
  275. } else {
  276. uc -= ri->ri_font->firstchar;
  277. fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  278. fs = ri->ri_font->stride;
  279. /* NOT fontbits if bg is white */
  280. if (bg) {
  281. while (height--) {
  282. rp[0] = ~fr[0];
  283. rp[1] = ~fr[1];
  284. fr += fs;
  285. rp += rs;
  286. }
  287. } else {
  288. while (height--) {
  289. rp[0] = fr[0];
  290. rp[1] = fr[1];
  291. fr += fs;
  292. rp += rs;
  293. }
  294. }
  295. }
  296. /* Do underline */
  297. if ((attr & 1) != 0)
  298. *(int16_t *)(rp - (ri->ri_stride << 1)) = fg;
  299. return 0;
  300. }
  301. #endif /* !RASOPS_SMALL */
  302. /*
  303. * Grab routines common to depths where (bpp < 8)
  304. */
  305. #define NAME(ident) rasops1_##ident
  306. #define PIXEL_SHIFT 0
  307. #include <dev/rasops/rasops_bitops.h>