LCOV - code coverage report
Current view: top level - include - font.h (source / functions) Hit Total Coverage
Test: GNU roff Lines: 4 4 100.0 %
Date: 2026-01-16 17:51:41 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 1989-2025 Free Software Foundation, Inc.
       2             :      Written by James Clark (jjc@jclark.com)
       3             : 
       4             : This file is part of groff, the GNU roff typesetting system.
       5             : 
       6             : groff is free software; you can redistribute it and/or modify it under
       7             : the terms of the GNU General Public License as published by the Free
       8             : Software Foundation, either version 3 of the License, or
       9             : (at your option) any later version.
      10             : 
      11             : groff is distributed in the hope that it will be useful, but WITHOUT ANY
      12             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14             : for more details.
      15             : 
      16             : You should have received a copy of the GNU General Public License
      17             : along with this program.  If not, see <http://www.gnu.org/licenses/>. */
      18             : 
      19             : #include <stdio.h> // FILE
      20             : 
      21             : // A function of this type can be registered to define the semantics of
      22             : // arbitrary commands in a font DESC file.
      23             : typedef void (*FONT_COMMAND_HANDLER)(const char *,      // command
      24             :                                      const char *,      // arg
      25             :                                      const char *,      // file
      26             :                                      int);              // lineno
      27             : 
      28             : // A glyph is represented by a font-independent 'glyph *' pointer.  The
      29             : // functions name_to_glyph and number_to_glyph return such a pointer.
      30             : //
      31             : // There are two types of glyphs:
      32             : //
      33             : //   - those with a name, and among these in particular:
      34             : //     'charNNN' denoting a single 'char' in the input character set,
      35             : //     'uXXXX' denoting a Unicode character,
      36             : //
      37             : //   - those with a number, referring to the font-dependent glyph with
      38             : //     the given number.
      39             : 
      40             : // The statically allocated information about a glyph.
      41             : //
      42             : // This is an abstract class; only its subclass 'charinfo' is
      43             : // instantiated.  'charinfo' exists in two versions: one in
      44             : // roff/troff/input.cpp for troff, and one in
      45             : // libs/libgroff/nametoindex.cpp for the preprocessors and the
      46             : // postprocessors.
      47             : struct glyph {
      48             :   int index;                    // A font-independent integer value.
      49             :   int number;                   // Glyph number or -1.
      50             :   friend class character_indexer;
      51             : };
      52             : 
      53             : #define UNDEFINED_GLYPH ((glyph *) 0)
      54             : 
      55             : // The next three functions exist in two versions: one in
      56             : // roff/troff/input.cpp for troff, and one in
      57             : // libs/libgroff/nametoindex.cpp for the preprocessors and the
      58             : // postprocessors.
      59             : extern glyph *name_to_glyph(const char *);      // Convert the glyph with
      60             :                         // the given name (arg1) to a 'glyph' object.  This
      61             :                         // has the same semantics as the groff escape sequence
      62             :                         // \C'name'.  If such a 'glyph' object does not yet
      63             :                         // exist, a new one is allocated.
      64             : extern glyph *number_to_glyph(int);     // Convert the font-dependent glyph
      65             :                         // with the given number (in the font) to a 'glyph'
      66             :                         // object.  This has the same semantics as the groff
      67             :                         // escape sequence \N'number'.  If such a 'glyph'
      68             :                         // object does not yet exist, a new one is allocated.
      69             : extern const char *glyph_to_name(glyph *);      // Convert the given
      70             :                         // glyph back to its name.  Return null pointer
      71             :                         // if the glyph doesn't have a name.
      72             : inline int glyph_to_number(glyph *);    // Convert the given glyph back to
      73             :                         // its number.  Return -1 if it does not designate
      74             :                         // a numbered character.
      75             : inline int glyph_to_index(glyph *);     // Return the unique index that is
      76             :                         // associated with the given glyph. It is >= 0.
      77             : extern int glyph_to_unicode(glyph *);   // Convert the given glyph to its
      78             :                         // Unicode codepoint.  Return -1 if it does not
      79             :                         // designate a Unicode character.
      80             : 
      81       29009 : inline int glyph_to_number(glyph *g)
      82             : {
      83       29009 :   return g->number;
      84             : }
      85             : 
      86    81287421 : inline int glyph_to_index(glyph *g)
      87             : {
      88    81287421 :   return g->index;
      89             : }
      90             : 
      91             : // Types used in non-public members of 'class font'.
      92             : struct font_kern_list;
      93             : struct font_char_metric;
      94             : struct font_widths_cache;
      95             : 
      96             : // A 'class font' instance represents the relevant information of a font of
      97             : // the given device.  This includes the set of glyphs represented by the
      98             : // font, and metrics for each glyph.
      99             : class font {
     100             : public:
     101             :   enum {                // The valid argument values of 'has_ligature'.
     102             :     LIG_ff = 1,
     103             :     LIG_fi = 2,
     104             :     LIG_fl = 4,
     105             :     LIG_ffi = 8,
     106             :     LIG_ffl = 16
     107             :   };
     108             : 
     109             :   font(const char *);   // Load font description from file name.
     110             :   virtual ~font();      // Destructor.
     111             :   bool contains(glyph *);       // This font contains the given glyph.
     112             :   bool is_special();    // This font is searched for glyphs not defined
     113             :                         // in the current font.  See section 'Special
     114             :                         // Fonts' in the groff Texinfo manual.  Used by
     115             :                         // make_glyph_node().
     116             :   int get_width(glyph *, int);  // A rectangle represents the shape of the
     117             :                         // given glyph (arg1) at the given point size
     118             :                         // (arg2).  Return the horizontal dimension of this
     119             :                         // rectangle.
     120             :   int get_height(glyph *, int); // A rectangle represents the shape of the
     121             :                         // given glyph (arg1) at the given point size
     122             :                         // (arg2).  Return the distance between the base
     123             :                         // line and the top of this rectangle.
     124             :                         // This is often also called the 'ascent' of the
     125             :                         // glyph.  If the top is above the baseline, this
     126             :                         // value is positive.
     127             :   int get_depth(glyph *, int);  // A rectangle represents the shape of the
     128             :                         // given glyph (arg1) at the given point size
     129             :                         // (arg2).  Return the distance between the base
     130             :                         // line and the bottom of this rectangle.
     131             :                         // This is often also called the 'descent' of the
     132             :                         // glyph.  If the bottom is below the baseline,
     133             :                         // this value is positive.
     134             :   int get_space_width(int);     // Return the normal width of a space at the
     135             :                         // given point size.
     136             :   int get_character_type(glyph *);      // Return a bit mask describing the
     137             :                         // shape of the given glyph.  Bit 0 is set if the
     138             :                         // character has a descender.  Bit 1 is set if the
     139             :                         // character has a tall glyph.  See groff manual,
     140             :                         // description of \w and the 'ct' register.
     141             :   int get_kern(glyph *, glyph *, int);  // Return the kerning between the
     142             :                         // given glyphs (arg1 and arg2), both at the given
     143             :                         // point size (arg3).
     144             :   int get_skew(glyph *, int, int);      // A rectangle represents the shape
     145             :                         // of the given glyph (arg1) at the given point size
     146             :                         // (arg2).  For slanted fonts like Times-Italic, the
     147             :                         // optical vertical axis is naturally slanted.  The
     148             :                         // natural slant value (measured in degrees;
     149             :                         // positive values mean aslant to the right) is
     150             :                         // specified in the font's description file (see
     151             :                         // member variable SLANT below).  In addition to
     152             :                         // this, any font can be artificially slanted.  This
     153             :                         // artificial slant value (arg3, measured in
     154             :                         // degrees; positive values mean a slant to the
     155             :                         // right) is specified with the \S escape.
     156             :                         //
     157             :                         // Return the skew value which is the horizontal
     158             :                         // distance between the upper left corner of the
     159             :                         // glyph box and the upper left corner of the glyph
     160             :                         // box thought to be slanted by the sum of the
     161             :                         // natural and artificial slant.  It basically means
     162             :                         // how much an accent must be shifted horizontally
     163             :                         // to put it on the optical axis of the glyph.
     164             :   bool has_ligature(int);       // This font has the given ligature type
     165             :                         // (one of LIG_ff, LIG_fi, ...).
     166             :   int get_italic_correction(glyph *, int);      // If the given glyph (arg1)
     167             :                         // at the given point size (arg2) is followed by an
     168             :                         // unslanted glyph, some horizontal whitespace may
     169             :                         // need to be inserted in between.  See the groff
     170             :                         // manual, description of \/.  Return the amount
     171             :                         // (width) of this whitespace.
     172             :   int get_left_italic_correction(glyph *, int); // If the given glyph (arg1)
     173             :                         // at the given point size (arg2) is preceded by an
     174             :                         // unslanted roman glyph, some horizontal white
     175             :                         // space may need to be inserted in between.  See
     176             :                         // the groff manual, description of \,.  Return the
     177             :                         // amount (width) of this whitespace.
     178             :   int get_subscript_correction(glyph *, int);   // If the given glyph (arg1)
     179             :                         // at the given point size (arg2)is followed by a
     180             :                         // subscript glyph, the horizontal position may need
     181             :                         // to be advanced by some (possibly negative)
     182             :                         // amount.  See groff manual, description of \w and
     183             :                         // the 'ssc' register.  Return this amount.
     184             :   void set_zoom(int);   // Set the font's zoom factor * 1000.  Must be a
     185             :                         // non-negative value.
     186             :   int get_zoom();       // Return the font's zoom factor * 1000.
     187             :   int get_code(glyph *);        // Return the code point in the physical
     188             :                         // font of the given glyph.
     189             :   const char *get_special_device_encoding(glyph *);     // Return
     190             :                         // special device-dependent information about
     191             :                         // the given glyph.  Return null pointer if
     192             :                         // there is no special information.
     193             :   const char *get_filename();   // Return file name containing font
     194             :                         // description.
     195             :   const char *get_internal_name();      // Return the 'internalname'
     196             :                         // attribute of this font or null pointer if it
     197             :                         // has none.
     198             :   const char *get_image_generator();    // Return the 'image_generator'
     199             :                         // attribute of this font or null pointer if it
     200             :                         // has none.
     201             :   static bool scan_papersize(const char *, const char **,
     202             :                              double *, double *); // Parse the
     203             :                         // 'papersize' directive in the DESC file name
     204             :                         // given in arg1.  Update arg2 with the name
     205             :                         // of the paper format and arg3 and arg4 with
     206             :                         // its length and width, respectively.  Return
     207             :                         // whether paper size was successfully set.
     208             :   static font *load_font(const char *, bool = false); // Load the font
     209             :                         // description file with the given name (arg1)
     210             :                         // and return a pointer to a 'font' object.  If
     211             :                         // arg2 is true, only the part of the font
     212             :                         // description file before the 'charset' and
     213             :                         // 'kernpairs' sections is loaded.  Return null
     214             :                         // pointer in case of failure.
     215             :   static void command_line_font_dir(const char *);      // Prepend given
     216             :                         // path (arg1) to the list of directories in which
     217             :                         // to look up fonts.
     218             :   static FILE *open_file(const char *, char **); // Open a font
     219             :                         // description file with the given name (arg1),
     220             :                         // searching along the current font path, and
     221             :                         // rejecting `arg1` if it contains a slash (see
     222             :                         // Savannah #61424).  If arg2 points to a string
     223             :                         // pointer, set it to the found file name (this
     224             :                         // depends on the device also).  Return the
     225             :                         // opened file's stream pointer.  If not found,
     226             :                         // arg2 is unchanged, and a null pointer is
     227             :                         // returned.
     228             :   static FILE *open_resource_file(const char *, char **); // Open an
     229             :                         // externally supplied (non-groff) file required
     230             :                         // by the output driver, possibly to embed
     231             :                         // content in the generated file.  Like
     232             :                         // `open_file()` except that it accepts slashes
     233             :                         // in `arg1`.  Examples include Type 1 fonts
     234             :                         // embedded in PostScript output.
     235             : 
     236             :   // Open the DESC file (depending on the device) and initialize some
     237             :   // static variables with info from there.
     238             :   static const char *load_desc();
     239             :   static FONT_COMMAND_HANDLER
     240             :     set_unknown_desc_command_handler(FONT_COMMAND_HANDLER);     // Register
     241             :                         // a function which defines the semantics of
     242             :                         // arbitrary commands in the font DESC file.
     243             :   // Now the variables from the DESC file, shared by all fonts.
     244             :   static int res;       // The 'res' attribute given in the DESC file.
     245             :   static int hor;       // The 'hor' attribute given in the DESC file.
     246             :   static int vert;      // The 'vert' attribute given in the DESC file.
     247             :   static int unitwidth; // The 'unitwidth' attribute given in the DESC file.
     248             :   static int paperwidth;        // The 'paperwidth' attribute given in the
     249             :                         // DESC file, or derived from the 'papersize'
     250             :                         // attribute given in the DESC file.
     251             :   static int paperlength;       // The 'paperlength' attribute given in the
     252             :                         // DESC file, or derived from the 'papersize'
     253             :                         // attribute given in the DESC file.
     254             :   static const char *papersize;
     255             :   static int biggestfont;       // The 'biggestfont' attribute given in the
     256             :                         // DESC file.
     257             :   static int spare2;
     258             :   static int sizescale; // The 'sizescale' attribute given in the DESC file.
     259             :   static bool has_tcommand;     // DESC file has 'tcommand' directive.
     260             :   static bool use_unscaled_charwidths;  // DESC file has
     261             :                         // 'unscaled_charwidths' directive.
     262             :   static bool pass_filenames;   // DESC file has 'pass_filenames'
     263             :                         // directive.
     264             :   static bool use_charnames_in_special; // DESC file has
     265             :                         // 'use_charnames_in_special' directive.
     266             :   static bool is_unicode; // DESC file has the 'unicode' directive.
     267             :   static const char *image_generator;   // The 'image_generator' attribute
     268             :                         // given in the DESC file.
     269             :   static const char **font_name_table;  // The 'fonts' attribute given
     270             :                         // in the DESC file, as a null
     271             :                         // pointer-terminated array of strings.
     272             :   static const char **style_table;      // The 'styles' attribute given
     273             :                         // in the DESC file, as a null
     274             :                         // pointer-terminated array of strings.
     275             :   static const char *family;    // The 'family' attribute given in the DESC
     276             :                         // file.
     277             :   static int *sizes;    // The 'sizes' attribute given in the DESC file, as
     278             :                         // an array of intervals of the form { lower1,
     279             :                         // upper1, ... lowerN, upperN, 0 }.
     280             : 
     281             : private:
     282             :   unsigned ligatures;   // Bit mask of available ligatures.  Used by
     283             :                         // has_ligature().
     284             :   font_kern_list **kern_hash_table;     // Hash table of kerning pairs.
     285             :                         // Used by get_kern().
     286             :   int space_width;      // The normal width of a space.  Used by
     287             :                         // get_space_width().
     288             :   bool special;         // See public is_special() above.
     289             :   char *filename;       // File name of font description.
     290             :   char *internalname;   // The 'internalname' attribute of this font, or
     291             :                         // a null pointer.  Used by get_internal_name().
     292             :   double slant;         // The natural slant angle (in degrees) of this font.
     293             :   int zoom;             // The font's magnification, multiplied by 1000.
     294             :                         // Used by scale().  A zero value means 'no zoom'.
     295             :   int *ch_index;        // Conversion table from font-independent character
     296             :                         // indices to indices for this particular font.
     297             :   int nindices;
     298             :   font_char_metric *ch; // Metrics information for every character in this
     299             :                         // font (if !is_unicode) or for just some characters
     300             :                         // (if is_unicode).  The indices of this array are
     301             :                         // font-specific, found as values in ch_index[].
     302             :   font_char_metric *wch;// Metrics for wide characters.
     303             :   int ch_used;
     304             :   int ch_size;
     305             :   font_widths_cache *widths_cache;      // A cache of scaled character
     306             :                         // widths.  Used by the get_width() function.
     307             : 
     308             :   static FONT_COMMAND_HANDLER unknown_desc_command_handler;     // A
     309             :                         // function defining the semantics of arbitrary
     310             :                         // commands in the DESC file.
     311             :   enum { KERN_HASH_TABLE_SIZE = 503 };  // Size of the hash table of kerning
     312             :                         // pairs.
     313             : 
     314             :   // These methods add new characters to the ch_index[] and ch[] arrays.
     315             :   void add_entry(glyph *,                       // glyph
     316             :                  const font_char_metric &); // metric
     317             :   void copy_entry(glyph *,                      // new_glyph
     318             :                   glyph *);                     // old_glyph
     319             :   void alloc_ch_index(int);                     // index
     320             :   void extend_ch();
     321             :   void compact();
     322             : 
     323             :   void add_kern(glyph *, glyph *, int); // Add to the kerning table a
     324             :                         // kerning amount (arg3) between two given glyphs
     325             :                         // (arg1 and arg2).
     326             :   static int hash_kern(glyph *, glyph *);       // Return a hash code for
     327             :                         // the pair of glyphs (arg1 and arg2).
     328             : 
     329             :   /* Returns w * pointsize / unitwidth, rounded to the nearest integer.  */
     330             :   int scale(int w, int pointsize);
     331             :   static bool unit_scale(double *, char); // Convert value in arg1 from
     332             :                         // the given unit (arg2; possible values are
     333             :                         // 'i', 'c', 'p', and 'P' as documented in the
     334             :                         // info file of groff, section 'Measurements')
     335             :                         // to inches.  Store result in arg1 and return
     336             :                         // whether conversion was successful.
     337             :   virtual void handle_unknown_font_command(const char *,        // command
     338             :                                            const char *,        // arg
     339             :                                            const char *,        // file
     340             :                                            int);                // lineno
     341             : 
     342             :   // Get font metric for wide characters indexed by Unicode code point.
     343             :   font_char_metric *get_font_wchar_metric(int);
     344             : 
     345             : protected:
     346             :   // Load the font description file with the name in member variable
     347             :   // `name` into this object.  If arg1 is true, only the part of the
     348             :   // font description file before the 'charset' and 'kernpairs' sections
     349             :   // is loaded.  Return success/failure status of load.
     350             :   bool load(bool = false);
     351             : };
     352             : 
     353             : // Local Variables:
     354             : // fill-column: 72
     355             : // mode: C++
     356             : // End:
     357             : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:

Generated by: LCOV version 1.14