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