rasops_putchar_width.h revision 1.8 1 /* $NetBSD: rasops_putchar_width.h,v 1.8 2019/07/29 17:22:19 rin Exp $ */
2
3 /* NetBSD: rasops8.c,v 1.41 2019/07/25 03:02:44 rin Exp */
4 /*-
5 * Copyright (c) 1999 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Andrew Doran.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
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
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #if RASOPS_DEPTH != 2 && RASOPS_DEPTH != 4 && RASOPS_DEPTH != 8 && \
34 RASOPS_DEPTH != 15 && RASOPS_DEPTH != 24 && RASOPS_DEPTH != 32
35 #error "Depth not supported"
36 #endif
37
38 #if RASOPS_WIDTH != 8 && RASOPS_WIDTH != 12 && RASOPS_WIDTH != 16
39 #error "Width not supported"
40 #endif
41
42 #define PUTCHAR_WIDTH1(depth, width) rasops ## depth ## _putchar ## width
43 #define PUTCHAR_WIDTH(depth, width) PUTCHAR_WIDTH1(depth, width)
44
45 #define PUTCHAR1(depth) rasops ## depth ## _putchar
46 #define PUTCHAR(depth) PUTCHAR1(depth)
47
48 #define MAKESTAMP1(depth) rasops ## depth ## _makestamp
49 #define MAKESTAMP(depth) MAKESTAMP1(depth)
50
51 #if RASOPS_DEPTH == 2
52 #define STAMP_TYPE uint8_t
53 #elif RASOPS_DEPTH == 4
54 #define STAMP_TYPE uint16_t
55 #else
56 #define STAMP_TYPE uint32_t
57 #endif
58
59 #if RASOPS_DEPTH <= 8
60 #define FILLED_STAMP 15
61 #elif RASOPS_DEPTH == 15
62 #define FILLED_STAMP 30
63 #else
64 #define FILLED_STAMP 60
65 #endif
66
67 /* ################################################################### */
68
69 #if RASOPS_DEPTH <= 8
70
71 #define SUBST_STAMP1(p, off, base) \
72 (p)[(off) * 1 + 0] = stamp[base]
73
74 #define SUBST_GLYPH1(index, nibble, off) \
75 do { \
76 int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK; \
77 rp[(off) * 1 + 0] = STAMP_READ(so); \
78 if (ri->ri_hwbits) { \
79 hrp[(off) * 1 + 0] = STAMP_READ(so); \
80 } \
81 } while (0 /* CONSTCOND */)
82
83 #endif /* RASOPS_DEPTH <= 8 */
84
85 /* ################################################################### */
86
87 #if RASOPS_DEPTH == 15
88
89 #define SUBST_STAMP1(p, off, base) \
90 (p)[(off) * 2 + 0] = (p)[(off) * 2 + 1] = stamp[base]
91
92 #define SUBST_GLYPH1(index, nibble, off) \
93 do { \
94 int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK; \
95 rp[(off) * 2 + 0] = STAMP_READ(so); \
96 rp[(off) * 2 + 1] = STAMP_READ(so + 4); \
97 if (ri->ri_hwbits) { \
98 hrp[(off) * 2 + 0] = STAMP_READ(so); \
99 hrp[(off) * 2 + 1] = STAMP_READ(so + 4); \
100 } \
101 } while (0 /* CONSTCOND */)
102
103 #endif /* RASOPS_DEPTH == 15 */
104
105 /* ################################################################### */
106
107 #if RASOPS_DEPTH == 24
108
109 #define SUBST_STAMP1(p, off, base) \
110 do { \
111 (p)[(off) * 3 + 0] = stamp[(base) + 0]; \
112 (p)[(off) * 3 + 1] = stamp[(base) + 1]; \
113 (p)[(off) * 3 + 2] = stamp[(base) + 2]; \
114 } while (0 /* CONSTCOND */)
115
116 #define SUBST_GLYPH1(index, nibble, off) \
117 do { \
118 int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK; \
119 rp[(off) * 3 + 0] = STAMP_READ(so); \
120 rp[(off) * 3 + 1] = STAMP_READ(so + 4); \
121 rp[(off) * 3 + 2] = STAMP_READ(so + 8); \
122 if (ri->ri_hwbits) { \
123 hrp[(off) * 3 + 0] = STAMP_READ(so); \
124 hrp[(off) * 3 + 1] = STAMP_READ(so + 4); \
125 hrp[(off) * 3 + 2] = STAMP_READ(so + 8); \
126 } \
127 } while (0 /* CONSTCOND */)
128
129 #endif /* RASOPS_DEPTH == 24 */
130
131 /* ################################################################### */
132
133 #if RASOPS_DEPTH == 32
134
135 #define SUBST_STAMP1(p, off, base) \
136 (p)[(off) * 4 + 0] = (p)[(off) * 4 + 1] = \
137 (p)[(off) * 4 + 2] = (p)[(off) * 4 + 3] = stamp[base]
138
139 #define SUBST_GLYPH1(index, nibble, off) \
140 do { \
141 int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK; \
142 rp[(off) * 4 + 0] = STAMP_READ(so); \
143 rp[(off) * 4 + 1] = STAMP_READ(so + 4); \
144 rp[(off) * 4 + 2] = STAMP_READ(so + 8); \
145 rp[(off) * 4 + 3] = STAMP_READ(so + 12); \
146 if (ri->ri_hwbits) { \
147 hrp[(off) * 4 + 0] = STAMP_READ(so); \
148 hrp[(off) * 4 + 1] = STAMP_READ(so + 4); \
149 hrp[(off) * 4 + 2] = STAMP_READ(so + 8); \
150 hrp[(off) * 4 + 3] = STAMP_READ(so + 12); \
151 } \
152 } while (0 /* CONSTCOND */)
153
154 #endif /* RASOPS_DEPTH == 32 */
155
156 /* ################################################################### */
157
158 #if RASOPS_WIDTH == 8
159 #define SUBST_STAMP(p, base) \
160 do { \
161 SUBST_STAMP1(p, 0, base); \
162 SUBST_STAMP1(p, 1, base); \
163 } while (0 /* CONSTCOND */)
164 #elif RASOPS_WIDTH == 12
165 #define SUBST_STAMP(p, base) \
166 do { \
167 SUBST_STAMP1(p, 0, base); \
168 SUBST_STAMP1(p, 1, base); \
169 SUBST_STAMP1(p, 2, base); \
170 } while (0 /* CONSTCOND */)
171 #elif RASOPS_WIDTH == 16
172 #define SUBST_STAMP(p, base) \
173 do { \
174 SUBST_STAMP1(p, 0, base); \
175 SUBST_STAMP1(p, 1, base); \
176 SUBST_STAMP1(p, 2, base); \
177 SUBST_STAMP1(p, 3, base); \
178 } while (0 /* CONSTCOND */)
179 #endif
180
181 #if RASOPS_WIDTH == 8
182 #define SUBST_GLYPH \
183 do { \
184 SUBST_GLYPH1(0, 1, 0); \
185 SUBST_GLYPH1(0, 0, 1); \
186 } while (0 /* CONSTCOND */)
187 #elif RASOPS_WIDTH == 12
188 #define SUBST_GLYPH \
189 do { \
190 SUBST_GLYPH1(0, 1, 0); \
191 SUBST_GLYPH1(0, 0, 1); \
192 SUBST_GLYPH1(1, 1, 2); \
193 } while (0 /* CONSTCOND */)
194 #elif RASOPS_WIDTH == 16
195 #define SUBST_GLYPH \
196 do { \
197 SUBST_GLYPH1(0, 1, 0); \
198 SUBST_GLYPH1(0, 0, 1); \
199 SUBST_GLYPH1(1, 1, 2); \
200 SUBST_GLYPH1(1, 0, 3); \
201 } while (0 /* CONSTCOND */)
202 #endif
203
204 /*
205 * Width-optimized putchar function.
206 */
207 static void
208 PUTCHAR_WIDTH(RASOPS_DEPTH, RASOPS_WIDTH)(void *cookie, int row, int col,
209 u_int uc, long attr)
210 {
211 struct rasops_info *ri = (struct rasops_info *)cookie;
212 struct wsdisplay_font *font = PICK_FONT(ri, uc);
213 int height, fs;
214 STAMP_TYPE *rp, *hrp;
215 uint8_t *fr;
216
217 hrp = NULL; /* XXX GCC */
218
219 #ifdef RASOPS_CLIPPING
220 /* Catches 'row < 0' case too */
221 if ((unsigned)row >= (unsigned)ri->ri_rows)
222 return;
223
224 if ((unsigned)col >= (unsigned)ri->ri_cols)
225 return;
226 #endif
227
228 /* check if character fits into font limits */
229 if (!CHAR_IN_FONT(uc, font))
230 return;
231
232 /* Can't risk remaking the stamp if it's already in use */
233 if (stamp_mutex++) {
234 stamp_mutex--;
235 PUTCHAR(RASOPS_DEPTH)(cookie, row, col, uc, attr);
236 return;
237 }
238
239 /* Recompute stamp? */
240 if (attr != stamp_attr)
241 MAKESTAMP(RASOPS_DEPTH)(ri, attr);
242
243 rp = (STAMP_TYPE *)(ri->ri_bits + row * ri->ri_yscale +
244 col * ri->ri_xscale);
245 if (ri->ri_hwbits)
246 hrp = (STAMP_TYPE *)(ri->ri_hwbits + row * ri->ri_yscale +
247 col * ri->ri_xscale);
248
249 height = font->fontheight;
250
251 if (uc == ' ') {
252 while (height--) {
253 SUBST_STAMP(rp, 0);
254 DELTA(rp, ri->ri_stride, STAMP_TYPE *);
255 if (ri->ri_hwbits) {
256 SUBST_STAMP(hrp, 0);
257 DELTA(hrp, ri->ri_stride, STAMP_TYPE *);
258 }
259 }
260 } else {
261 fr = FONT_GLYPH(uc, font, ri);
262 fs = font->stride;
263
264 while (height--) {
265 SUBST_GLYPH;
266
267 fr += fs;
268 DELTA(rp, ri->ri_stride, STAMP_TYPE *);
269 if (ri->ri_hwbits)
270 DELTA(hrp, ri->ri_stride, STAMP_TYPE *);
271 }
272 }
273
274 /* Do underline */
275 if ((attr & WSATTR_UNDERLINE) != 0) {
276 DELTA(rp, -(ri->ri_stride << 1), STAMP_TYPE *);
277 SUBST_STAMP(rp, FILLED_STAMP);
278 if (ri->ri_hwbits) {
279 DELTA(hrp, -(ri->ri_stride << 1), STAMP_TYPE *);
280 SUBST_STAMP(hrp, FILLED_STAMP);
281 }
282 }
283
284 stamp_mutex--;
285 }
286
287 #undef STAMP_TYPE
288
289 #undef FILLED_STAMP
290
291 #undef PUTCHAR_WIDTH1
292 #undef PUTCHAR_WIDTH
293
294 #undef PUTCHAR1
295 #undef PUTCHAR
296
297 #undef MAKESTAMP1
298 #undef MAKESTAMP
299
300 #undef SUBST_STAMP1
301 #undef SUBST_STAMP
302
303 #undef SUBST_GLYPH1
304 #undef SUBST_GLYPH
305