"Fossies" - the Fresh Open Source Software Archive

Member "netpbm-10.91.01/lib/libpbmfont0.c" (22 Jul 2020, 11084 Bytes) of package /linux/misc/netpbm-10.91.01.tar.xz:


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 "libpbmfont0.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 10.91.00_vs_10.91.01.

    1 /*
    2 **
    3 ** Font routines.
    4 **
    5 ** Wide character stuff written by Akira Urushibata in 2018 and contributed
    6 ** to the public domain.
    7 **
    8 ** Also copyright (C) 1991 by Jef Poskanzer and licensed to the public as
    9 ** follows.
   10 **
   11 ** Permission to use, copy, modify, and distribute this software and its
   12 ** documentation for any purpose and without fee is hereby granted, provided
   13 ** that the above copyright notice appear in all copies and that both that
   14 ** copyright notice and this permission notice appear in supporting
   15 ** documentation.  This software is provided "as is" without express or
   16 ** implied warranty.
   17 */
   18 
   19 #include <assert.h>
   20 #include <string.h>
   21 
   22 #include "netpbm/pm_c_util.h"
   23 #include "netpbm/mallocvar.h"
   24 #include "netpbm/nstring.h"
   25 
   26 #include "pbm.h"
   27 #include "pbmfont.h"
   28 #include "pbmfontdata.h"
   29 
   30 struct font *
   31 pbm_defaultfont(const char * const name) {
   32 /*----------------------------------------------------------------------------
   33    Generate the built-in font with name 'name'.
   34 -----------------------------------------------------------------------------*/
   35     struct font * retval;
   36 
   37     if (streq(name, "bdf"))
   38         retval = &pbm_defaultBdffont;
   39     else if (streq(name, "fixed"))
   40         retval = &pbm_defaultFixedfont;
   41     else
   42         pm_error( "built-in font name unknown, try 'bdf' or 'fixed'");
   43 
   44     return retval;
   45 }
   46 
   47 
   48 
   49 struct font2 *
   50 pbm_defaultfont2(const char * const requestedFontName) {
   51 
   52     struct font2 * font2P;
   53     struct font2 * retval = NULL; /* initial value */
   54     unsigned int i;
   55 
   56     for (i = 0; retval == NULL; ++i) {
   57         const char * longName;
   58         const char * shortName;
   59         font2P = (struct font2 * ) pbm_builtinFonts[i];
   60         if (font2P == NULL)
   61             break;
   62 
   63         longName = font2P->name;
   64         shortName = &longName[strlen("builtin ")];
   65 
   66         if (streq(shortName, requestedFontName))
   67              retval = font2P;
   68     }
   69 
   70     if (retval == NULL)
   71         pm_error("No builtin font named %s", requestedFontName);
   72 
   73     return retval;
   74 }
   75 
   76 
   77 
   78 static void
   79 selectFontType(const    char *            const filename,
   80                PM_WCHAR                   const maxmaxglyph,
   81                unsigned int               const isWide,
   82                struct font  **            const fontPP,
   83                struct font2 **            const font2PP,
   84                const struct pm_selector * const selectorP) {
   85 
   86     FILE * fileP;
   87     struct font  * fontP  = NULL; /* initial value */
   88     struct font2 * font2P = NULL; /* initial value */
   89     char line[10] = "\0\0\0\0\0\0\0\0\0\0";
   90         /* Initialize to suppress Valgrind error which is reported when file
   91            is empty or very small.
   92         */
   93 
   94     fileP = pm_openr(filename);
   95     fgets(line, 10, fileP);
   96     pm_close(fileP);
   97 
   98     if (line[0] == PBM_MAGIC1 &&
   99         (line[1] == PBM_MAGIC2 || line[1] == RPBM_MAGIC2)) {
  100         if (isWide == TRUE)
  101             font2P = pbm_loadpbmfont2(filename);
  102         else
  103             fontP  = pbm_loadpbmfont(filename);
  104         if (fontP == NULL && font2P == NULL)
  105             pm_error("could not load PBM font file");
  106 
  107     } else if (!strncmp(line, "STARTFONT", 9)) {
  108         if (isWide == TRUE)
  109             font2P = pbm_loadbdffont2select(filename, maxmaxglyph, selectorP);
  110         else
  111             fontP = pbm_loadbdffont(filename);
  112         if (fontP == NULL && font2P == NULL)
  113             pm_error("could not load BDF font file");
  114 
  115     } else {
  116         pm_error("font file not in a recognized format.  Does not start "
  117                  "with the signature of a PBM file or BDF font file");
  118         assert(false);
  119         fontP = NULL;  /* defeat compiler warning */
  120     }
  121 
  122     if (isWide)
  123         *font2PP = font2P;
  124     else
  125         *fontPP = fontP;
  126 }
  127 
  128 
  129 
  130 struct font *
  131 pbm_loadfont(const char * const filename) {
  132 /*----------------------------------------------------------------------------
  133    Load font file named 'filename'.
  134    Font file may be either a PBM sheet or BDF.
  135    Supports 8 bit codepoints.
  136 -----------------------------------------------------------------------------*/
  137     struct font  * fontP;
  138     struct font2 * font2P;
  139 
  140     selectFontType(filename, PM_FONT_MAXGLYPH, FALSE, &fontP, &font2P, NULL);
  141     return fontP;
  142 }
  143 
  144 
  145 
  146 struct font2 *
  147 pbm_loadfont2(const char * const filename,
  148               PM_WCHAR     const maxmaxglyph) {
  149 /*----------------------------------------------------------------------------
  150    Load font file named 'filename'.
  151    Font file may be either a PBM sheet or BDF.
  152    Supports codepoints above 256.
  153 -----------------------------------------------------------------------------*/
  154     struct font  * fontP;
  155     struct font2 * font2P;
  156 
  157     selectFontType(filename, maxmaxglyph, TRUE, &fontP, &font2P, NULL);
  158     return font2P;
  159 }
  160 
  161 
  162 struct font2 *
  163 pbm_loadfont2select(const  char *              const filename,
  164                     PM_WCHAR                   const maxmaxglyph,
  165                     const struct pm_selector * const selectorP) {
  166 /*----------------------------------------------------------------------------
  167    Same as pbm_loadfont2(), but load only glyphs indicated by *selectorP
  168 -----------------------------------------------------------------------------*/
  169     struct font  * fontP;
  170     struct font2 * font2P;
  171 
  172     selectFontType(filename, maxmaxglyph, TRUE, &fontP, &font2P, selectorP);
  173 
  174     return font2P;
  175 }
  176 
  177 
  178 
  179 void
  180 pbm_createbdffont2_base(struct font2 ** const font2PP,
  181                         PM_WCHAR        const maxmaxglyph) {
  182 
  183     struct font2 * font2P;
  184 
  185     MALLOCVAR(font2P);
  186     if (font2P == NULL)
  187         pm_error("no memory for font");
  188 
  189     MALLOCARRAY(font2P->glyph, maxmaxglyph + 1);
  190     if (font2P->glyph == NULL)
  191         pm_error("no memory for font glyphs");
  192 
  193     /* Initialize */
  194     font2P->size = sizeof (struct font2);
  195     font2P->len  = PBM_FONT2_STRUCT_SIZE(charset_string);
  196 
  197     /*  Caller should overwrite following fields as necessary */
  198     font2P->oldfont = NULL;
  199     font2P->fcols = font2P->frows = 0;
  200     font2P->selectorP = NULL;
  201     font2P->default_char = 0;
  202     font2P->default_char_defined = FALSE;
  203     font2P->total_chars = font2P->chars = 0;
  204     font2P->name = NULL;
  205     font2P->charset = ENCODING_UNKNOWN;
  206     font2P->charset_string = NULL;
  207 
  208     *font2PP = font2P;
  209 }
  210 
  211 
  212 
  213 static void
  214 destroyGlyphData(struct glyph **            const glyph,
  215                  PM_WCHAR                   const maxglyph,
  216                  const struct pm_selector * const selectorP) {
  217 /*----------------------------------------------------------------------------
  218   Free glyph objects and bitmap objects.
  219 
  220   This does not work when an object is "shared" through multiple pointers
  221   referencing an identical address and thus pointing to a common glyph
  222   or bitmap object.
  223 
  224   If 'selectorP' is NULL, free all glyph and bitmap objects in the range
  225   0 ... maxglyph.  If not, free only the objects which the selector
  226   indicates as present.
  227 -----------------------------------------------------------------------------*/
  228 
  229     PM_WCHAR const min = (selectorP != NULL) ? selectorP->min : 0;
  230     PM_WCHAR const max =
  231         (selectorP != NULL) ? MIN(selectorP->max, maxglyph) : maxglyph;
  232 
  233     PM_WCHAR i;
  234 
  235     for (i = min; i <= max; ++i) {
  236         if (pm_selector_is_marked(selectorP, i) && glyph[i]) {
  237             free((void *) (glyph[i]->bmap));
  238             free(glyph[i]);
  239         }
  240     }
  241 }
  242 
  243 
  244 void
  245 pbm_destroybdffont2_base(struct font2 * const font2P) {
  246 /*----------------------------------------------------------------------------
  247   Free font2 structure, but not the glyph data
  248 ---------------------------------------------------------------------------- */
  249 
  250     pm_strfree(font2P->name);
  251 
  252     pm_strfree(font2P->charset_string);
  253 
  254     free(font2P->glyph);
  255 
  256     if (font2P->oldfont)
  257        pbm_freearray(font2P->oldfont, font2P->frows);
  258 
  259     free(font2P);
  260 }
  261 
  262 
  263 
  264 void
  265 pbm_destroybdffont2(struct font2 * const font2P) {
  266 /*----------------------------------------------------------------------------
  267   Free font2 structure and glyph data
  268 
  269   Examines the 'load_fn' field to check whether the object is fixed data.
  270   Do nothing if 'load_fn' is 'FIXED_DATA'.
  271 ---------------------------------------------------------------------------- */
  272 
  273     if (font2P->load_fn != FIXED_DATA) {
  274         destroyGlyphData(font2P->glyph, font2P->maxglyph, font2P->selectorP);
  275         pbm_destroybdffont2_base(font2P);
  276     }
  277 }
  278 
  279 
  280 
  281 void
  282 pbm_destroybdffont(struct font * const fontP) {
  283 /*----------------------------------------------------------------------------
  284   Free font structure and glyph data.
  285 
  286   For freeing a structure created by pbm_loadbdffont() or pbm_loadpbmfont().
  287 ---------------------------------------------------------------------------- */
  288 
  289     destroyGlyphData(fontP->glyph, PM_FONT_MAXGLYPH, NULL);
  290 
  291     if (fontP->oldfont !=NULL)
  292        pbm_freearray(fontP->oldfont, fontP->frows);
  293 
  294     free(fontP);
  295 }
  296 
  297 
  298 
  299 struct font2 *
  300 pbm_expandbdffont(const struct font * const fontP) {
  301 /*----------------------------------------------------------------------------
  302   Convert a traditional 'font' structure into an expanded 'font2' structure.
  303 
  304   After calling this function *fontP may be freed, but not the individual
  305   glyph data: fontP->glyph[0...255] .
  306 
  307   Using this function on static data is not recommended.  Rather add
  308   the extra fields to make a font2 structure.  See file pbmfontdata1.c
  309   for an example.
  310 
  311   The returned object is in new malloc'ed storage, in many pieces.
  312 
  313   Destroy with pbm_destroybdffont2() if *fontP is read from a file.
  314 
  315   Destroy with pbm_destroybdffont2_base() if *fontP is static data
  316   and you desire to defy the above-stated recommendation.
  317 
  318   The general function for conversion in the opposite direction
  319   'font2' => 'font' is font2ToFont() in libpbmfont2.c .  It is currently
  320   declared as static.
  321  ---------------------------------------------------------------------------*/
  322     PM_WCHAR maxglyph, codePoint;
  323     unsigned int nCharacters;
  324     struct font2 * font2P;
  325 
  326     pbm_createbdffont2_base(&font2P, PM_FONT_MAXGLYPH);
  327 
  328     font2P->maxwidth  = fontP->maxwidth;
  329     font2P->maxheight = fontP->maxheight;
  330 
  331     font2P->x = fontP->x;
  332     font2P->y = fontP->y;
  333 
  334     /* Hunt for max non-NULL entry in glyph table */
  335     for (codePoint = PM_FONT_MAXGLYPH;
  336          fontP->glyph[codePoint] == NULL && codePoint > 0; --codePoint)
  337         ;
  338 
  339     maxglyph = font2P->maxglyph = codePoint;
  340     assert (0 <= maxglyph && maxglyph <= PM_FONT_MAXGLYPH);
  341 
  342     if (maxglyph == 0 && fontP->glyph[0] == NULL)
  343         pm_error("no glyphs loaded");
  344 
  345     REALLOCARRAY(font2P->glyph, font2P->maxglyph + 1);
  346 
  347     for (codePoint = 0; codePoint <= maxglyph; ++codePoint) {
  348         font2P->glyph[codePoint] = fontP->glyph[codePoint];
  349 
  350         if (font2P->glyph[codePoint] != NULL)
  351            ++nCharacters;
  352     }
  353 
  354     font2P->oldfont = fontP->oldfont;
  355     font2P->fcols = fontP->fcols;
  356     font2P->frows = fontP->frows;
  357 
  358     font2P->bit_format = PBM_FORMAT;
  359     font2P->total_chars = font2P->chars = nCharacters;
  360     font2P->load_fn = CONVERTED_TYPE1_FONT;
  361     /* Caller should overwrite the above to a more descriptive value */
  362     return font2P;
  363 }
  364 
  365 
  366