| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: rasops_putchar_aa.h,v 1.1 2019/07/29 10:55:56 rin Exp $ */ | | 1 | /* $NetBSD: rasops_putchar_aa.h,v 1.2 2019/07/29 14:06:32 rin Exp $ */ |
2 | | | 2 | |
3 | /* NetBSD: rasops8.c,v 1.43 2019/07/28 12:06:10 rin Exp */ | | 3 | /* NetBSD: rasops8.c,v 1.43 2019/07/28 12:06:10 rin Exp */ |
4 | /*- | | 4 | /*- |
5 | * Copyright (c) 1999 The NetBSD Foundation, Inc. | | 5 | * Copyright (c) 1999 The NetBSD Foundation, Inc. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * This code is derived from software contributed to The NetBSD Foundation | | 8 | * This code is derived from software contributed to The NetBSD Foundation |
9 | * by Andrew Doran. | | 9 | * by Andrew Doran. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -20,61 +20,91 @@ | | | @@ -20,61 +20,91 @@ |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | * POSSIBILITY OF SUCH DAMAGE. | | 30 | * POSSIBILITY OF SUCH DAMAGE. |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #if RASOPS_DEPTH != 8 && RASOPS_DEPTH != 15 && /* RASOPS_DEPTH != 24 && */ \ | | 33 | #if RASOPS_DEPTH != 8 && RASOPS_DEPTH != 15 && RASOPS_DEPTH != 24 && \ |
34 | RASOPS_DEPTH != 32 | | 34 | RASOPS_DEPTH != 32 |
35 | #error "Depth not supported" | | 35 | #error "Depth not supported" |
36 | #endif | | 36 | #endif |
37 | | | 37 | |
38 | #define PUTCHAR_AA(depth) PUTCHAR_AA1(depth) | | 38 | #define PUTCHAR_AA(depth) PUTCHAR_AA1(depth) |
39 | #define PUTCHAR_AA1(depth) rasops ## depth ## _putchar_aa | | 39 | #define PUTCHAR_AA1(depth) rasops ## depth ## _putchar_aa |
40 | | | 40 | |
| | | 41 | #define MAX_WIDTH 64 /* XXX */ |
| | | 42 | |
41 | #if RASOPS_DEPTH == 8 | | 43 | #if RASOPS_DEPTH == 8 |
42 | #define PIXEL_TYPE uint8_t | | 44 | #define PIXEL_TYPE uint8_t |
43 | #define PIXEL_BITS 8 | | | |
44 | #elif RASOPS_DEPTH == 15 | | 45 | #elif RASOPS_DEPTH == 15 |
45 | #define PIXEL_TYPE uint16_t | | 46 | #define PIXEL_TYPE uint16_t |
46 | #define PIXEL_BITS 16 | | 47 | #elif RASOPS_DEPTH == 24 |
| | | 48 | #define PIXEL_TYPE uint8_t |
47 | #elif RASOPS_DEPTH == 32 | | 49 | #elif RASOPS_DEPTH == 32 |
48 | #define PIXEL_TYPE uint32_t | | 50 | #define PIXEL_TYPE uint32_t |
49 | #define PIXEL_BITS 32 | | | |
50 | #endif | | 51 | #endif |
51 | | | 52 | |
52 | #define MAX_WIDTH 64 /* XXX */ | | 53 | #if RASOPS_DEPTH != 24 |
| | | 54 | #define PIXEL_LEN sizeof(PIXEL_TYPE) |
| | | 55 | #define BUF_LEN MAX_WIDTH |
| | | 56 | #define SET_PIXEL(x, c) buf[x] = clr[c] |
| | | 57 | #endif /* RASOPS_DEPTH != 24 */ |
| | | 58 | |
| | | 59 | #if RASOPS_DEPTH == 24 |
| | | 60 | #define PIXEL_LEN 3 |
| | | 61 | #define BUF_LEN (MAX_WIDTH * 3) |
| | | 62 | # if BYTE_ORDER == LITTLE_ENDIAN |
| | | 63 | #define ROFF (ri->ri_rpos / 8) |
| | | 64 | #define GOFF (ri->ri_gpos / 8) |
| | | 65 | #define BOFF (ri->ri_bpos / 8) |
| | | 66 | # else /* BIG_ENDIAN XXX not tested */ |
| | | 67 | #define ROFF (2 - ri->ri_rpos / 8) |
| | | 68 | #define GOFF (2 - ri->ri_gpos / 8) |
| | | 69 | #define BOFF (2 - ri->ri_bpos / 8) |
| | | 70 | # endif |
| | | 71 | #define SET_PIXEL(x, c) \ |
| | | 72 | do { \ |
| | | 73 | buf[3 * x + ROFF] = r[c]; \ |
| | | 74 | buf[3 * x + GOFF] = g[c]; \ |
| | | 75 | buf[3 * x + BOFF] = b[c]; \ |
| | | 76 | } while (0 /* CONSTCOND */) |
| | | 77 | #endif /* RASOPS_DEPTH == 24 */ |
| | | 78 | |
| | | 79 | #if RASOPS_DEPTH != 8 |
| | | 80 | #define SET_BUF(c) for (x = 0; x < width; x++) { SET_PIXEL(x, c); } |
| | | 81 | #else |
| | | 82 | #define SET_BUF(c) memset(buf, clr[c], width) |
| | | 83 | #endif |
53 | | | 84 | |
54 | static void | | 85 | static void |
55 | PUTCHAR_AA(RASOPS_DEPTH)(void *cookie, int row, int col, u_int uc, long attr) | | 86 | PUTCHAR_AA(RASOPS_DEPTH)(void *cookie, int row, int col, u_int uc, long attr) |
56 | { | | 87 | { |
57 | struct rasops_info *ri = (struct rasops_info *)cookie; | | 88 | struct rasops_info *ri = (struct rasops_info *)cookie; |
58 | struct wsdisplay_font *font = PICK_FONT(ri, uc); | | 89 | struct wsdisplay_font *font = PICK_FONT(ri, uc); |
59 | int height, width, bgo, fgo, x, y; | | 90 | int height, width, x, y, off[2]; |
60 | uint8_t *fr, r0, r1, g0, g1, b0, b1, aval; | | 91 | uint16_t r[2], g[2], b[2]; |
61 | #if RASOPS_DEPTH == 8 | | 92 | uint8_t *fr, aval; |
62 | uint16_t r, g, b; | | 93 | PIXEL_TYPE *rp, *hp, R, G, B; |
63 | #else | | 94 | PIXEL_TYPE buf[BUF_LEN] __attribute__ ((aligned(8))); /* XXX */ |
64 | PIXEL_TYPE r, g, b; | | 95 | #if RASOPS_DEPTH != 24 |
| | | 96 | PIXEL_TYPE clr[2]; |
65 | #endif | | 97 | #endif |
66 | PIXEL_TYPE *rp, *hp, bg, fg, pixel; | | | |
67 | PIXEL_TYPE buf[MAX_WIDTH] __attribute__ ((aligned(8))); /* XXX */ | | | |
68 | | | 98 | |
69 | hp = NULL; /* XXX GCC */ | | 99 | hp = NULL; /* XXX GCC */ |
70 | | | 100 | |
71 | if (!CHAR_IN_FONT(uc, font)) | | 101 | if (!CHAR_IN_FONT(uc, font)) |
72 | return; | | 102 | return; |
73 | | | 103 | |
74 | #ifdef RASOPS_CLIPPING | | 104 | #ifdef RASOPS_CLIPPING |
75 | /* Catches 'row < 0' case too */ | | 105 | /* Catches 'row < 0' case too */ |
76 | if ((unsigned)row >= (unsigned)ri->ri_rows) | | 106 | if ((unsigned)row >= (unsigned)ri->ri_rows) |
77 | return; | | 107 | return; |
78 | | | 108 | |
79 | if ((unsigned)col >= (unsigned)ri->ri_cols) | | 109 | if ((unsigned)col >= (unsigned)ri->ri_cols) |
80 | return; | | 110 | return; |
| @@ -83,98 +113,110 @@ PUTCHAR_AA(RASOPS_DEPTH)(void *cookie, i | | | @@ -83,98 +113,110 @@ PUTCHAR_AA(RASOPS_DEPTH)(void *cookie, i |
83 | rp = (PIXEL_TYPE *)(ri->ri_bits + row * ri->ri_yscale + | | 113 | rp = (PIXEL_TYPE *)(ri->ri_bits + row * ri->ri_yscale + |
84 | col * ri->ri_xscale); | | 114 | col * ri->ri_xscale); |
85 | if (ri->ri_hwbits) | | 115 | if (ri->ri_hwbits) |
86 | hp = (PIXEL_TYPE *)(ri->ri_hwbits + row * ri->ri_yscale + | | 116 | hp = (PIXEL_TYPE *)(ri->ri_hwbits + row * ri->ri_yscale + |
87 | col * ri->ri_xscale); | | 117 | col * ri->ri_xscale); |
88 | | | 118 | |
89 | height = font->fontheight; | | 119 | height = font->fontheight; |
90 | | | 120 | |
91 | /* XXX */ | | 121 | /* XXX */ |
92 | width = font->fontwidth; | | 122 | width = font->fontwidth; |
93 | if (__predict_false(width > MAX_WIDTH)) | | 123 | if (__predict_false(width > MAX_WIDTH)) |
94 | width = MAX_WIDTH; | | 124 | width = MAX_WIDTH; |
95 | | | 125 | |
96 | bg = (PIXEL_TYPE)ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf]; | | 126 | #if RASOPS_DEPTH != 24 |
97 | fg = (PIXEL_TYPE)ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf]; | | 127 | clr[0] = (PIXEL_TYPE)ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf]; |
| | | 128 | clr[1] = (PIXEL_TYPE)ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf]; |
| | | 129 | #endif |
| | | 130 | |
| | | 131 | /* |
| | | 132 | * This is independent to positions/lengths of RGB in pixel. |
| | | 133 | */ |
| | | 134 | off[0] = (((uint32_t)attr >> 16) & 0xf) * 3; |
| | | 135 | off[1] = (((uint32_t)attr >> 24) & 0xf) * 3; |
| | | 136 | |
| | | 137 | r[0] = rasops_cmap[off[0]]; |
| | | 138 | r[1] = rasops_cmap[off[1]]; |
| | | 139 | g[0] = rasops_cmap[off[0] + 1]; |
| | | 140 | g[1] = rasops_cmap[off[1] + 1]; |
| | | 141 | b[0] = rasops_cmap[off[0] + 2]; |
| | | 142 | b[1] = rasops_cmap[off[1] + 2]; |
98 | | | 143 | |
99 | if (uc == ' ') { | | 144 | if (uc == ' ') { |
100 | #if RASOPS_DEPTH == 8 | | 145 | SET_BUF(0); |
101 | memset(buf, bg, width); | | | |
102 | #else | | | |
103 | for (x = 0; x < width; x++) | | | |
104 | buf[x] = bg; | | | |
105 | #endif | | | |
106 | while (height--) { | | 146 | while (height--) { |
107 | memcpy(rp, buf, width * sizeof(PIXEL_TYPE)); | | 147 | memcpy(rp, buf, width * PIXEL_LEN); |
108 | DELTA(rp, ri->ri_stride, PIXEL_TYPE *); | | 148 | DELTA(rp, ri->ri_stride, PIXEL_TYPE *); |
109 | if (ri->ri_hwbits) { | | 149 | if (ri->ri_hwbits) { |
110 | memcpy(hp, buf, width * sizeof(PIXEL_TYPE)); | | 150 | memcpy(hp, buf, width * PIXEL_LEN); |
111 | DELTA(hp, ri->ri_stride, PIXEL_TYPE *); | | 151 | DELTA(hp, ri->ri_stride, PIXEL_TYPE *); |
112 | } | | 152 | } |
113 | } | | 153 | } |
114 | } else { | | 154 | } else { |
115 | fr = FONT_GLYPH(uc, font, ri); | | 155 | fr = FONT_GLYPH(uc, font, ri); |
116 | | | 156 | |
117 | /* | | | |
118 | * This is independent to positions/lengths of RGB in pixel. | | | |
119 | */ | | | |
120 | bgo = (((uint32_t)attr >> 16) & 0xf) * 3; | | | |
121 | fgo = (((uint32_t)attr >> 24) & 0xf) * 3; | | | |
122 | | | | |
123 | r0 = rasops_cmap[bgo]; | | | |
124 | r1 = rasops_cmap[fgo]; | | | |
125 | g0 = rasops_cmap[bgo + 1]; | | | |
126 | g1 = rasops_cmap[fgo + 1]; | | | |
127 | b0 = rasops_cmap[bgo + 2]; | | | |
128 | b1 = rasops_cmap[fgo + 2]; | | | |
129 | | | | |
130 | for (y = 0; y < height; y++) { | | 157 | for (y = 0; y < height; y++) { |
131 | for (x = 0; x < width; x++) { | | 158 | for (x = 0; x < width; x++) { |
132 | aval = *fr; | | 159 | aval = *fr; |
133 | fr++; | | 160 | fr++; |
134 | if (aval == 0) { | | 161 | if (aval == 0) |
135 | pixel = bg; | | 162 | SET_PIXEL(x, 0); |
136 | } else if (aval == 255) { | | 163 | else if (aval == 255) |
137 | pixel = fg; | | 164 | SET_PIXEL(x, 1); |
138 | } else { | | 165 | else { |
139 | r = aval * r1 + (0xff - aval) * r0; | | 166 | #define AVERAGE(p, w) ((w * p[1] + (0xff - w) * p[0]) >> 8) |
140 | g = aval * g1 + (0xff - aval) * g0; | | 167 | R = AVERAGE(r, aval); |
141 | b = aval * b1 + (0xff - aval) * b0; | | 168 | G = AVERAGE(g, aval); |
142 | #define RGB2PIXEL(r, g, b) \ | | 169 | B = AVERAGE(b, aval); |
143 | ((((r) & 0xff00) >> (8 + 8 - ri->ri_rnum)) << ri->ri_rpos) | \ | | 170 | #undef AVERAGE |
144 | ((((g) & 0xff00) >> (8 + 8 - ri->ri_gnum)) << ri->ri_gpos) | \ | | 171 | |
145 | ((((b) & 0xff00) >> (8 + 8 - ri->ri_bnum)) << ri->ri_bpos) | | 172 | #if RASOPS_DEPTH != 24 |
146 | pixel = RGB2PIXEL(r, g, b); | | 173 | #define RGB2PIXEL(_r, _g, _b) \ |
| | | 174 | (((_r) >> (8 - ri->ri_rnum)) << ri->ri_rpos) | \ |
| | | 175 | (((_g) >> (8 - ri->ri_gnum)) << ri->ri_gpos) | \ |
| | | 176 | (((_b) >> (8 - ri->ri_bnum)) << ri->ri_bpos) |
| | | 177 | buf[x] = RGB2PIXEL(R, G, B); |
147 | #undef RGB2PIXEL | | 178 | #undef RGB2PIXEL |
| | | 179 | #endif |
| | | 180 | |
| | | 181 | #if RASOPS_DEPTH == 24 |
| | | 182 | buf[3 * x + ROFF] = R; |
| | | 183 | buf[3 * x + GOFF] = G; |
| | | 184 | buf[3 * x + BOFF] = B; |
| | | 185 | #endif |
148 | } | | 186 | } |
149 | buf[x] = pixel; | | | |
150 | } | | 187 | } |
151 | memcpy(rp, buf, width * sizeof(PIXEL_TYPE)); | | 188 | memcpy(rp, buf, width * PIXEL_LEN); |
152 | DELTA(rp, ri->ri_stride, PIXEL_TYPE *); | | 189 | DELTA(rp, ri->ri_stride, PIXEL_TYPE *); |
153 | if (ri->ri_hwbits) { | | 190 | if (ri->ri_hwbits) { |
154 | memcpy(hp, buf, width * sizeof(PIXEL_TYPE)); | | 191 | memcpy(hp, buf, width * PIXEL_LEN); |
155 | DELTA(hp, ri->ri_stride, PIXEL_TYPE *); | | 192 | DELTA(hp, ri->ri_stride, PIXEL_TYPE *); |
156 | } | | 193 | } |
157 | } | | 194 | } |
158 | } | | 195 | } |
159 | | | 196 | |
160 | /* Do underline */ | | 197 | /* Do underline */ |
161 | if ((attr & WSATTR_UNDERLINE) != 0) { | | 198 | if ((attr & WSATTR_UNDERLINE) != 0) { |
| | | 199 | SET_BUF(1); |
162 | DELTA(rp, -(ri->ri_stride << 1), PIXEL_TYPE *); | | 200 | DELTA(rp, -(ri->ri_stride << 1), PIXEL_TYPE *); |
163 | if (ri->ri_hwbits) { | | 201 | if (ri->ri_hwbits) |
164 | DELTA(hp, -(ri->ri_stride << 1), PIXEL_TYPE *); | | 202 | DELTA(hp, -(ri->ri_stride << 1), PIXEL_TYPE *); |
165 | } | | 203 | memcpy(rp, buf, width * PIXEL_LEN); |
166 | while (width--) { | | 204 | if (ri->ri_hwbits) |
167 | *rp++ = fg; | | 205 | memcpy(hp, buf, width * PIXEL_LEN); |
168 | if (ri->ri_hwbits) | | | |
169 | *hp++ = fg; | | | |
170 | } | | | |
171 | } | | 206 | } |
172 | } | | 207 | } |
173 | | | 208 | |
174 | #undef PUTCHAR_AA | | 209 | #undef PUTCHAR_AA |
175 | #undef PUTCHAR_AA1 | | 210 | #undef PUTCHAR_AA1 |
176 | | | 211 | |
| | | 212 | #undef MAX_WIDTH |
| | | 213 | |
177 | #undef PIXEL_TYPE | | 214 | #undef PIXEL_TYPE |
178 | #undef PIXEL_BITS | | 215 | #undef PIXEL_LEN |
| | | 216 | #undef SET_PIXEL |
179 | | | 217 | |
180 | #undef MAX_WIDTH | | 218 | #undef ROFF |
| | | 219 | #undef GOFF |
| | | 220 | #undef BOFF |
| | | 221 | |
| | | 222 | #undef SET_BUF |