int xterm_Double_index(unsigned chrset, unsigned flags) { int n; TScreen *screen = &term->screen; XTermFonts *data = screen->double_fonts; flags &= BOLD; TRACE(("xterm_Double_index chrset=%#x, flags=%#x\n", chrset, flags)); for (n = 0; n < screen->fonts_used; n++) { if (data[n].chrset == chrset && data[n].flags == flags) { if (n != 0) { XTermFonts save; TRACE(("...xterm_Double_index -> %d (OLD:%d)\n", n, screen->fonts_used)); save = data[n]; while (n > 0) { data[n] = data[n - 1]; n--; } data[n] = save; } return n; } } /* Not, found, push back existing fonts and create a new entry */ if (screen->fonts_used >= screen->cache_doublesize) { TRACE(("...xterm_Double_index: discard oldest\n")); discard_font(screen, &(data[screen->fonts_used - 1])); } else { screen->fonts_used += 1; } for (n = screen->fonts_used; n > 0; n--) data[n] = data[n - 1]; TRACE(("...xterm_Double_index -> (NEW:%d)\n", screen->fonts_used)); data[0].chrset = chrset; data[0].flags = flags; data[0].fn = 0; data[0].fs = 0; data[0].gc = 0; return 0; }
/* * Lookup/cache a GC for the double-size character display. We save up to * NUM_CHRSET values. */ GC xterm_DoubleGC(unsigned chrset, unsigned flags, GC old_gc) { XGCValues gcv; register TScreen *screen = &term->screen; unsigned long mask = (GCForeground | GCBackground | GCFont); int n; char *name; XTermFonts *data; if ((name = xtermSpecialFont(flags, chrset)) == 0) return 0; n = xterm_Double_index(chrset, flags); data = &(screen->double_fonts[n]); if (data->fn != 0) { if (!strcmp(data->fn, name)) { if (data->fs != 0) { XCopyGC(screen->display, old_gc, ~GCFont, data->gc); return data->gc; } } discard_font(screen, data); data->chrset = chrset; data->flags = flags & BOLD; } data->fn = name; TRACE(("xterm_DoubleGC %s %d: %s\n", flags & BOLD ? "BOLD" : "NORM", n, name)); if ((data->fs = XLoadQueryFont(screen->display, name)) == 0) return 0; TRACE(("-> OK\n")); gcv.graphics_exposures = TRUE; /* default */ gcv.font = data->fs->fid; gcv.foreground = screen->foreground; gcv.background = term->core.background_pixel; data->gc = XCreateGC(screen->display, VWindow(screen), mask, &gcv); XCopyGC(screen->display, old_gc, ~GCFont, data->gc); return data->gc; }
/* push back existing fonts and create a new entry */ static XTermFonts * pushback_font(XtermWidget xw, XTermFonts * source) { TScreen *screen = TScreenOf(xw); XTermFonts *data = screen->double_fonts; int n; if (screen->fonts_used >= screen->cache_doublesize) { TRACE(("pushback_font: discard oldest\n")); discard_font(xw, screen->fonts_used - 1); } else { screen->fonts_used += 1; } for (n = screen->fonts_used; n > 0; n--) data[n] = data[n - 1]; data[0] = *source; TRACE(("pushback_font -> (NEW:%d)\n", screen->fonts_used)); return data; }
/* * Lookup/cache a GC for the double-size character display. We save up to * NUM_CHRSET values. */ GC xterm_DoubleGC(XtermWidget xw, unsigned chrset, unsigned attr_flags, unsigned draw_flags, GC old_gc, int *inxp) { TScreen *screen = TScreenOf(xw); VTwin *cgsWin = WhichVWin(screen); char *name; GC result = 0; if ((name = xtermSpecialFont(screen, attr_flags, draw_flags, chrset)) != 0) { CgsEnum cgsId = WhichCgsId(attr_flags); Boolean found = False; XTermFonts *data = 0; int n; if ((n = xterm_Double_index(xw, chrset, attr_flags)) >= 0) { data = &(screen->double_fonts[n]); if (data->fn != 0) { if (!strcmp(data->fn, name) && data->fs != 0) { found = True; free(name); } else { discard_font(xw, n); } } } if (!found) { XTermFonts temp; TRACE(("xterm_DoubleGC %s %d: %s\n", (attr_flags & BOLD) ? "BOLD" : "NORM", n, name)); memset(&temp, 0, sizeof(temp)); temp.fn = name; temp.chrset = chrset; temp.flags = (attr_flags & BOLD); if (!xtermOpenFont(xw, name, &temp, fwAlways, False)) { /* Retry with * in resolutions */ char *nname = xtermSpecialFont(screen, attr_flags, draw_flags | NORESOLUTION, chrset); if (nname != 0) { found = (Boolean) xtermOpenFont(xw, nname, &temp, fwAlways, False); free(nname); } } else { found = True; } free(name); if (found) { n = 0; data = pushback_font(xw, &temp); } TRACE(("-> %s\n", found ? "OK" : "FAIL")); } if (found) { setCgsCSet(xw, cgsWin, cgsId, chrset); setCgsFont(xw, cgsWin, cgsId, data); setCgsFore(xw, cgsWin, cgsId, getCgsFore(xw, cgsWin, old_gc)); setCgsBack(xw, cgsWin, cgsId, getCgsBack(xw, cgsWin, old_gc)); result = getCgsGC(xw, cgsWin, cgsId); *inxp = n; } else if (attr_flags & BOLD) { UIntClr(attr_flags, BOLD); result = xterm_DoubleGC(xw, chrset, attr_flags, draw_flags, old_gc, inxp); } } return result; }