rasops_putchar_width.h revision 1.10 1 /* $NetBSD: rasops_putchar_width.h,v 1.10 2019/07/31 02:04:14 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 SUBST_UNIT 1
61 #elif RASOPS_DEPTH == 15
62 #define SUBST_UNIT 2
63 #elif RASOPS_DEPTH == 24
64 #define SUBST_UNIT 3
65 #elif RASOPS_DEPTH == 32
66 #define SUBST_UNIT 4
67 #endif
68
69 #define SUBST_BYTES (SUBST_UNIT * (RASOPS_WIDTH / 4) * sizeof(STAMP_TYPE))
70
71 #if RASOPS_DEPTH <= 8
72 #define FILLED_STAMP 15
73 #elif RASOPS_DEPTH == 15
74 #define FILLED_STAMP 30
75 #else
76 #define FILLED_STAMP 60
77 #endif
78
79 /* ################################################################### */
80
81 #if RASOPS_DEPTH <= 8
82
83 #define SUBST_STAMP1(off, base) \
84 rp[(off) * 1 + 0] = stamp[base]
85
86 #define SUBST_GLYPH1(index, nibble, off) \
87 do { \
88 int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK; \
89 rp[(off) * 1 + 0] = STAMP_READ(so); \
90 } while (0 /* CONSTCOND */)
91
92 #endif /* RASOPS_DEPTH <= 8 */
93
94 /* ################################################################### */
95
96 #if RASOPS_DEPTH == 15
97
98 #define SUBST_STAMP1(off, base) \
99 rp[(off) * 2 + 0] = rp[(off) * 2 + 1] = stamp[base]
100
101 #define SUBST_GLYPH1(index, nibble, off) \
102 do { \
103 int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK; \
104 rp[(off) * 2 + 0] = STAMP_READ(so); \
105 rp[(off) * 2 + 1] = STAMP_READ(so + 4); \
106 } while (0 /* CONSTCOND */)
107
108 #endif /* RASOPS_DEPTH == 15 */
109
110 /* ################################################################### */
111
112 #if RASOPS_DEPTH == 24
113
114 #define SUBST_STAMP1(off, base) \
115 do { \
116 rp[(off) * 3 + 0] = stamp[(base) + 0]; \
117 rp[(off) * 3 + 1] = stamp[(base) + 1]; \
118 rp[(off) * 3 + 2] = stamp[(base) + 2]; \
119 } while (0 /* CONSTCOND */)
120
121 #define SUBST_GLYPH1(index, nibble, off) \
122 do { \
123 int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK; \
124 rp[(off) * 3 + 0] = STAMP_READ(so); \
125 rp[(off) * 3 + 1] = STAMP_READ(so + 4); \
126 rp[(off) * 3 + 2] = STAMP_READ(so + 8); \
127 } while (0 /* CONSTCOND */)
128
129 #endif /* RASOPS_DEPTH == 24 */
130
131 /* ################################################################### */
132
133 #if RASOPS_DEPTH == 32
134
135 #define SUBST_STAMP1(off, base) \
136 rp[(off) * 4 + 0] = rp[(off) * 4 + 1] = \
137 rp[(off) * 4 + 2] = rp[(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 } while (0 /* CONSTCOND */)
147
148 #endif /* RASOPS_DEPTH == 32 */
149
150 /* ################################################################### */
151
152 #if RASOPS_WIDTH == 8
153 #define SUBST_STAMP(base) \
154 do { \
155 SUBST_STAMP1(0, base); \
156 SUBST_STAMP1(1, base); \
157 } while (0 /* CONSTCOND */)
158 #elif RASOPS_WIDTH == 12
159 #define SUBST_STAMP(base) \
160 do { \
161 SUBST_STAMP1(0, base); \
162 SUBST_STAMP1(1, base); \
163 SUBST_STAMP1(2, base); \
164 } while (0 /* CONSTCOND */)
165 #elif RASOPS_WIDTH == 16
166 #define SUBST_STAMP(base) \
167 do { \
168 SUBST_STAMP1(0, base); \
169 SUBST_STAMP1(1, base); \
170 SUBST_STAMP1(2, base); \
171 SUBST_STAMP1(3, base); \
172 } while (0 /* CONSTCOND */)
173 #endif
174
175 #if RASOPS_WIDTH == 8
176 #define SUBST_GLYPH \
177 do { \
178 SUBST_GLYPH1(0, 1, 0); \
179 SUBST_GLYPH1(0, 0, 1); \
180 } while (0 /* CONSTCOND */)
181 #elif RASOPS_WIDTH == 12
182 #define SUBST_GLYPH \
183 do { \
184 SUBST_GLYPH1(0, 1, 0); \
185 SUBST_GLYPH1(0, 0, 1); \
186 SUBST_GLYPH1(1, 1, 2); \
187 } while (0 /* CONSTCOND */)
188 #elif RASOPS_WIDTH == 16
189 #define SUBST_GLYPH \
190 do { \
191 SUBST_GLYPH1(0, 1, 0); \
192 SUBST_GLYPH1(0, 0, 1); \
193 SUBST_GLYPH1(1, 1, 2); \
194 SUBST_GLYPH1(1, 0, 3); \
195 } while (0 /* CONSTCOND */)
196 #endif
197
198 /*
199 * Width-optimized putchar function.
200 */
201 static void
202 PUTCHAR_WIDTH(RASOPS_DEPTH, RASOPS_WIDTH)(void *cookie, int row, int col,
203 u_int uc, long attr)
204 {
205 struct rasops_info *ri = (struct rasops_info *)cookie;
206 struct wsdisplay_font *font = PICK_FONT(ri, uc);
207 STAMP_TYPE *stamp = (STAMP_TYPE *)ri->ri_stamp;
208 int height, fs;
209 uint8_t *fr;
210 STAMP_TYPE *rp, *hp;
211
212 hp = NULL; /* XXX GCC */
213
214 #ifdef RASOPS_CLIPPING
215 /* Catches 'row < 0' case too */
216 if ((unsigned)row >= (unsigned)ri->ri_rows)
217 return;
218
219 if ((unsigned)col >= (unsigned)ri->ri_cols)
220 return;
221 #endif
222
223 /* check if character fits into font limits */
224 if (!CHAR_IN_FONT(uc, font))
225 return;
226
227 /* Recompute stamp? */
228 if (attr != ri->ri_stamp_attr)
229 MAKESTAMP(RASOPS_DEPTH)(ri, attr);
230
231 rp = (STAMP_TYPE *)(ri->ri_bits + row * ri->ri_yscale +
232 col * ri->ri_xscale);
233 if (ri->ri_hwbits)
234 hp = (STAMP_TYPE *)(ri->ri_hwbits + row * ri->ri_yscale +
235 col * ri->ri_xscale);
236
237 height = font->fontheight;
238
239 if (uc == ' ') {
240 while (height--) {
241 SUBST_STAMP(0);
242 if (ri->ri_hwbits) {
243 memcpy(hp, rp, SUBST_BYTES);
244 DELTA(hp, ri->ri_stride, STAMP_TYPE *);
245 }
246 DELTA(rp, ri->ri_stride, STAMP_TYPE *);
247 }
248 } else {
249 fr = FONT_GLYPH(uc, font, ri);
250 fs = font->stride;
251
252 while (height--) {
253 SUBST_GLYPH;
254 fr += fs;
255 if (ri->ri_hwbits) {
256 memcpy(hp, rp, SUBST_BYTES);
257 DELTA(hp, ri->ri_stride, STAMP_TYPE *);
258 }
259 DELTA(rp, ri->ri_stride, STAMP_TYPE *);
260 }
261 }
262
263 /* Do underline */
264 if ((attr & WSATTR_UNDERLINE) != 0) {
265 DELTA(rp, -(ri->ri_stride << 1), STAMP_TYPE *);
266 SUBST_STAMP(FILLED_STAMP);
267 if (ri->ri_hwbits) {
268 DELTA(hp, -(ri->ri_stride << 1), STAMP_TYPE *);
269 memcpy(hp, rp, SUBST_BYTES);
270 }
271 }
272 }
273
274 #undef STAMP_TYPE
275
276 #undef SUBST_UNIT
277 #undef SUBST_BYTES
278
279 #undef FILLED_STAMP
280
281 #undef PUTCHAR_WIDTH1
282 #undef PUTCHAR_WIDTH
283
284 #undef PUTCHAR1
285 #undef PUTCHAR
286
287 #undef MAKESTAMP1
288 #undef MAKESTAMP
289
290 #undef SUBST_STAMP1
291 #undef SUBST_STAMP
292
293 #undef SUBST_GLYPH1
294 #undef SUBST_GLYPH
295