"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 */