"Fossies" - the Fresh Open Source Software Archive 
Member "xterm-379/doublechr.c" (23 Oct 2022, 9301 Bytes) of package /linux/misc/xterm-379.tgz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "doublechr.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
374_vs_375.
1 /* $XTermId: doublechr.c,v 1.108 2022/10/23 14:46:14 tom Exp $ */
2
3 /*
4 * Copyright 1997-2021,2022 by Thomas E. Dickey
5 *
6 * All Rights Reserved
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Except as contained in this notice, the name(s) of the above copyright
28 * holders shall not be used in advertising or otherwise to promote the
29 * sale, use or other dealings in this Software without prior written
30 * authorization.
31 */
32
33 #include <xterm.h>
34 #include <data.h>
35 #include <fontutils.h>
36
37 #include <assert.h>
38
39 #define WhichCgsId(flag) (((flag) & BOLD) ? gcCBold : gcCNorm)
40
41 /*
42 * The first column is all that matters for double-size characters (since the
43 * controls apply to a whole line). However, it's easier to maintain the
44 * information for special fonts by writing to all cells.
45 */
46 #if OPT_DEC_CHRSET
47
48 static void
49 repaint_line(XtermWidget xw, unsigned newChrSet)
50 {
51 TScreen *screen = TScreenOf(xw);
52 LineData *ld;
53 int curcol = screen->cur_col;
54 int currow = screen->cur_row;
55 int width = MaxCols(screen);
56 unsigned len = (unsigned) width;
57
58 assert(width > 0);
59
60 /*
61 * Ignore repetition.
62 */
63 if (!IsLeftRightMode(xw)
64 && (ld = getLineData(screen, currow)) != 0) {
65 unsigned oldChrSet = GetLineDblCS(ld);
66
67 if (oldChrSet != newChrSet) {
68 TRACE(("repaint_line(%2d,%2d) (%s -> %s)\n", currow, screen->cur_col,
69 visibleDblChrset(oldChrSet),
70 visibleDblChrset(newChrSet)));
71 HideCursor(xw);
72
73 /* If switching from single-width, keep the cursor in the visible part
74 * of the line.
75 */
76 if (CSET_DOUBLE(newChrSet)) {
77 width /= 2;
78 if (curcol > width)
79 curcol = width;
80 }
81
82 /*
83 * ScrnRefresh won't paint blanks for us if we're switching between a
84 * single-size and double-size font. So we paint our own.
85 */
86 ClearCurBackground(xw,
87 currow,
88 0,
89 1,
90 len,
91 (unsigned) LineFontWidth(screen, ld));
92
93 SetLineDblCS(ld, newChrSet);
94
95 set_cur_col(screen, 0);
96 ScrnUpdate(xw, currow, 0, 1, (int) len, True);
97 set_cur_col(screen, curcol);
98 }
99 }
100 }
101 #endif
102
103 /*
104 * Set the line to double-height characters. The 'top' flag denotes whether
105 * we'll be using it for the top (true) or bottom (false) of the line.
106 */
107 void
108 xterm_DECDHL(XtermWidget xw, Bool top)
109 {
110 #if OPT_DEC_CHRSET
111 repaint_line(xw, (unsigned) (top ? CSET_DHL_TOP : CSET_DHL_BOT));
112 #else
113 (void) xw;
114 (void) top;
115 #endif
116 }
117
118 /*
119 * Set the line to single-width characters (the normal state).
120 */
121 void
122 xterm_DECSWL(XtermWidget xw)
123 {
124 #if OPT_DEC_CHRSET
125 repaint_line(xw, CSET_SWL);
126 #else
127 (void) xw;
128 #endif
129 }
130
131 /*
132 * Set the line to double-width characters
133 */
134 void
135 xterm_DECDWL(XtermWidget xw)
136 {
137 #if OPT_DEC_CHRSET
138 repaint_line(xw, CSET_DWL);
139 #else
140 (void) xw;
141 #endif
142 }
143
144 /*
145 * Reset all lines on the screen to single-width/single-height.
146 */
147 void
148 xterm_ResetDouble(XtermWidget xw)
149 {
150 #if OPT_DEC_CHRSET
151 TScreen *screen = TScreenOf(xw);
152 Boolean changed = False;
153 unsigned code;
154 int row;
155
156 for (row = 0; row < screen->max_row; ++row) {
157 LineData *ld;
158
159 if ((ld = getLineData(screen, ROW2INX(screen, row))) != 0) {
160 code = GetLineDblCS(ld);
161 if (code != CSET_SWL) {
162 SetLineDblCS(ld, CSET_SWL);
163 changed = True;
164 }
165 }
166 }
167 if (changed) {
168 xtermRepaint(xw);
169 }
170 #else
171 (void) xw;
172 #endif
173 }
174
175 #if OPT_DEC_CHRSET
176 static void
177 discard_font(XtermWidget xw, int n)
178 {
179 TScreen *screen = TScreenOf(xw);
180 XTermFonts *data = getDoubleFont(screen, n);
181
182 TRACE(("discard_font chrset=%d %s\n", data->chrset,
183 (data->fn != 0) ? data->fn : "<no-name>"));
184
185 data->chrset = 0;
186 data->flags = 0;
187 FreeAndNull(data->fn);
188 xtermCloseFont(xw, data);
189
190 screen->fonts_used -= 1;
191 while (n < screen->fonts_used) {
192 screen->double_fonts[n] = screen->double_fonts[n + 1];
193 ++n;
194 }
195 }
196
197 /* push back existing fonts and create a new entry */
198 static XTermFonts *
199 pushback_font(XtermWidget xw, XTermFonts * source)
200 {
201 TScreen *screen = TScreenOf(xw);
202 XTermFonts *data = getDoubleFont(screen, 0);
203 int n;
204
205 if (screen->fonts_used >= screen->cache_doublesize) {
206 TRACE(("pushback_font: discard oldest\n"));
207 discard_font(xw, screen->fonts_used - 1);
208 } else {
209 screen->fonts_used += 1;
210 }
211
212 for (n = screen->fonts_used; n > 0; n--)
213 data[n] = data[n - 1];
214 data[0] = *source;
215
216 TRACE(("pushback_font -> (NEW:%d)\n", screen->fonts_used));
217
218 return data;
219 }
220
221 static int
222 xterm_Double_index(XTermDraw * params)
223 {
224 XTermDraw local = *params;
225 int n;
226 int result = -1;
227 TScreen *screen = TScreenOf(local.xw);
228 XTermFonts *data = getDoubleFont(screen, 0);
229
230 local.attr_flags &= BOLD;
231 TRACE(("xterm_Double_index chrset=%#x, flags=%#x\n", local.this_chrset, local.attr_flags));
232
233 for (n = 0; n < screen->fonts_used; n++) {
234 if (data[n].chrset == (unsigned) local.this_chrset
235 && data[n].flags == local.attr_flags) {
236 if (n != 0) {
237 XTermFonts save;
238 TRACE(("...xterm_Double_index -> %d (OLD:%d)\n", n, screen->fonts_used));
239 save = data[n];
240 while (n > 0) {
241 data[n] = data[n - 1];
242 n--;
243 }
244 data[n] = save;
245 }
246 result = n;
247 break;
248 }
249 }
250
251 return result;
252 }
253
254 /*
255 * Lookup/cache a GC for the double-size character display. We save up to
256 * NUM_CHRSET values.
257 */
258 GC
259 xterm_DoubleGC(XTermDraw * params, GC old_gc, int *inxp)
260 {
261 TScreen *screen = TScreenOf(params->xw);
262 VTwin *cgsWin = WhichVWin(screen);
263 char *name;
264 GC result = 0;
265
266 if ((name = xtermSpecialFont(params))
267 != 0) {
268 CgsEnum cgsId = WhichCgsId(params->attr_flags);
269 Boolean found = False;
270 XTermFonts *data = 0;
271 int n;
272
273 if ((n = xterm_Double_index(params)) >= 0) {
274 data = getDoubleFont(screen, n);
275 if (data->fn != 0) {
276 if (!strcmp(data->fn, name)
277 && data->fs != 0) {
278 found = True;
279 FreeAndNull(name);
280 } else {
281 discard_font(params->xw, n);
282 }
283 }
284 }
285
286 if (!found && name != NULL) {
287 XTermFonts temp;
288
289 TRACE(("xterm_DoubleGC %s %d: %s\n",
290 (params->attr_flags & BOLD) ? "BOLD" : "NORM", n, name));
291
292 memset(&temp, 0, sizeof(temp));
293 temp.fn = name;
294 temp.chrset = params->this_chrset;
295 temp.flags = (params->attr_flags & BOLD);
296 temp.warn = fwResource;
297
298 if (!xtermOpenFont(params->xw, name, &temp, NULL, False)) {
299 XTermDraw local = *params;
300 char *nname;
301
302 /* Retry with * in resolutions */
303 local.draw_flags |= NORESOLUTION;
304 nname = xtermSpecialFont(&local);
305 if (nname != 0) {
306 found = (Boolean) xtermOpenFont(params->xw, nname, &temp,
307 NULL, False);
308 free(nname);
309 }
310 } else {
311 found = True;
312 }
313 free(name);
314
315 if (found) {
316 n = 0;
317 data = pushback_font(params->xw, &temp);
318 }
319
320 TRACE(("-> %s\n", found ? "OK" : "FAIL"));
321 }
322
323 if (found) {
324 setCgsCSet(params->xw, cgsWin, cgsId, params->this_chrset);
325 setCgsFont(params->xw, cgsWin, cgsId, data);
326 setCgsFore(params->xw, cgsWin, cgsId, getCgsFore(params->xw,
327 cgsWin, old_gc));
328 setCgsBack(params->xw, cgsWin, cgsId, getCgsBack(params->xw,
329 cgsWin, old_gc));
330 result = getCgsGC(params->xw, cgsWin, cgsId);
331 *inxp = n;
332 } else if (params->attr_flags & BOLD) {
333 UIntClr(params->attr_flags, BOLD);
334 result = xterm_DoubleGC(params, old_gc, inxp);
335 }
336 }
337
338 return result;
339 }
340
341 #if OPT_RENDERFONT
342 /*
343 * Like xterm_DoubleGC(), but returning an Xft font.
344 */
345 XTermXftFonts *
346 xterm_DoubleFT(XTermDraw * params, unsigned chrset, unsigned attr_flags)
347 {
348 XTermXftFonts *result;
349 TScreen *screen = TScreenOf(params->xw);
350 unsigned num = (chrset & CSET_DWL);
351
352 if ((attr_flags &= BOLD) != 0)
353 num |= 4;
354
355 result = &screen->double_xft_fonts[num];
356 if (XftFp(result) == NULL) {
357 getDoubleXftFont(params, result, chrset, attr_flags);
358 }
359 return result;
360 }
361
362 void
363 freeall_DoubleFT(XtermWidget xw)
364 {
365 TScreen *screen = TScreenOf(xw);
366 unsigned num;
367
368 for (num = 0; num < XtNumber(screen->double_xft_fonts); ++num) {
369 closeCachedXft(screen, XftFp(&screen->double_xft_fonts[num]));
370 XftFp(&screen->double_xft_fonts[num]) = NULL;
371 XftIs(&screen->double_xft_fonts[num]) = xcEmpty;
372 }
373 }
374 #endif /* OPT_RENDERFONT */
375
376 #endif /* OPT_DEC_CHRSET */