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:
|