summaryrefslogtreecommitdiffstats
path: root/src/include/font.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/font.h')
-rw-r--r--src/include/font.h343
1 files changed, 343 insertions, 0 deletions
diff --git a/src/include/font.h b/src/include/font.h
new file mode 100644
index 0000000..68a82fa
--- /dev/null
+++ b/src/include/font.h
@@ -0,0 +1,343 @@
+// -*- C++ -*-
+/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+ Written by James Clark (jjc@jclark.com)
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+// A function of this type can be registered to define the semantics of
+// arbitrary commands in a font DESC file.
+typedef void (*FONT_COMMAND_HANDLER)(const char *, // command
+ const char *, // arg
+ const char *, // file
+ int); // lineno
+
+// A glyph is represented by a font-independent 'glyph *' pointer. The
+// functions name_to_glyph and number_to_glyph return such a pointer.
+//
+// There are two types of glyphs:
+//
+// - those with a name, and among these in particular:
+// 'charNNN' denoting a single 'char' in the input character set,
+// 'uXXXX' denoting a Unicode character,
+//
+// - those with a number, referring to the font-dependent glyph with
+// the given number.
+
+// The statically allocated information about a glyph.
+//
+// This is an abstract class; only its subclass 'charinfo' is
+// instantiated. 'charinfo' exists in two versions: one in
+// roff/troff/input.cpp for troff, and one in
+// libs/libgroff/nametoindex.cpp for the preprocessors and the
+// postprocessors.
+struct glyph {
+ int index; // A font-independent integer value.
+ int number; // Glyph number or -1.
+ friend class character_indexer;
+};
+
+#define UNDEFINED_GLYPH ((glyph *) 0)
+
+// The next three functions exist in two versions: one in
+// roff/troff/input.cpp for troff, and one in
+// libs/libgroff/nametoindex.cpp for the preprocessors and the
+// postprocessors.
+extern glyph *name_to_glyph(const char *); // Convert the glyph with
+ // the given name (arg1) to a 'glyph' object. This
+ // has the same semantics as the groff escape sequence
+ // \C'name'. If such a 'glyph' object does not yet
+ // exist, a new one is allocated.
+extern glyph *number_to_glyph(int); // Convert the font-dependent glyph
+ // with the given number (in the font) to a 'glyph'
+ // object. This has the same semantics as the groff
+ // escape sequence \N'number'. If such a 'glyph'
+ // object does not yet exist, a new one is allocated.
+extern const char *glyph_to_name(glyph *); // Convert the given
+ // glyph back to its name. Return null pointer
+ // if the glyph doesn't have a name.
+inline int glyph_to_number(glyph *); // Convert the given glyph back to
+ // its number. Return -1 if it does not designate
+ // a numbered character.
+inline int glyph_to_index(glyph *); // Return the unique index that is
+ // associated with the given glyph. It is >= 0.
+extern int glyph_to_unicode(glyph *); // Convert the given glyph to its
+ // Unicode codepoint. Return -1 if it does not
+ // designate a Unicode character.
+
+inline int glyph_to_number(glyph *g)
+{
+ return g->number;
+}
+
+inline int glyph_to_index(glyph *g)
+{
+ return g->index;
+}
+
+// Types used in non-public members of 'class font'.
+struct font_kern_list;
+struct font_char_metric;
+struct font_widths_cache;
+
+// A 'class font' instance represents the relevant information of a font of
+// the given device. This includes the set of glyphs represented by the
+// font, and metrics for each glyph.
+class font {
+public:
+ enum { // The valid argument values of 'has_ligature'.
+ LIG_ff = 1,
+ LIG_fi = 2,
+ LIG_fl = 4,
+ LIG_ffi = 8,
+ LIG_ffl = 16
+ };
+
+ virtual ~font(); // Destructor.
+ bool contains(glyph *); // This font contains the given glyph.
+ bool is_special(); // This font is searched for glyphs not defined
+ // in the current font. See section 'Special
+ // Fonts' in the groff Texinfo manual. Used by
+ // make_glyph_node().
+ int get_width(glyph *, int); // A rectangle represents the shape of the
+ // given glyph (arg1) at the given point size
+ // (arg2). Return the horizontal dimension of this
+ // rectangle.
+ int get_height(glyph *, int); // A rectangle represents the shape of the
+ // given glyph (arg1) at the given point size
+ // (arg2). Return the distance between the base
+ // line and the top of this rectangle.
+ // This is often also called the 'ascent' of the
+ // glyph. If the top is above the baseline, this
+ // value is positive.
+ int get_depth(glyph *, int); // A rectangle represents the shape of the
+ // given glyph (arg1) at the given point size
+ // (arg2). Return the distance between the base
+ // line and the bottom of this rectangle.
+ // This is often also called the 'descent' of the
+ // glyph. If the bottom is below the baseline,
+ // this value is positive.
+ int get_space_width(int); // Return the normal width of a space at the
+ // given point size.
+ int get_character_type(glyph *); // Return a bit mask describing the
+ // shape of the given glyph. Bit 0 is set if the
+ // character has a descender. Bit 1 is set if the
+ // character has a tall glyph. See groff manual,
+ // description of \w and the 'ct' register.
+ int get_kern(glyph *, glyph *, int); // Return the kerning between the
+ // given glyphs (arg1 and arg2), both at the given
+ // point size (arg3).
+ int get_skew(glyph *, int, int); // A rectangle represents the shape
+ // of the given glyph (arg1) at the given point size
+ // (arg2). For slanted fonts like Times-Italic, the
+ // optical vertical axis is naturally slanted. The
+ // natural slant value (measured in degrees;
+ // positive values mean aslant to the right) is
+ // specified in the font's description file (see
+ // member variable SLANT below). In addition to
+ // this, any font can be artificially slanted. This
+ // artificial slant value (arg3, measured in
+ // degrees; positive values mean a slant to the
+ // right) is specified with the \S escape.
+ //
+ // Return the skew value which is the horizontal
+ // distance between the upper left corner of the
+ // glyph box and the upper left corner of the glyph
+ // box thought to be slanted by the sum of the
+ // natural and artificial slant. It basically means
+ // how much an accent must be shifted horizontally
+ // to put it on the optical axis of the glyph.
+ bool has_ligature(int); // This font has the given ligature type
+ // (one of LIG_ff, LIG_fi, ...).
+ int get_italic_correction(glyph *, int); // If the given glyph (arg1)
+ // at the given point size (arg2) is followed by an
+ // unslanted glyph, some horizontal white space may
+ // need to be inserted in between. See the groff
+ // manual, description of \/. Return the amount
+ // (width) of this white space.
+ int get_left_italic_correction(glyph *, int); // If the given glyph (arg1)
+ // at the given point size (arg2) is preceded by an
+ // unslanted roman glyph, some horizontal white
+ // space may need to be inserted in between. See
+ // the groff manual, description of \,. Return the
+ // amount (width) of this white space.
+ int get_subscript_correction(glyph *, int); // If the given glyph (arg1)
+ // at the given point size (arg2)is followed by a
+ // subscript glyph, the horizontal position may need
+ // to be advanced by some (possibly negative)
+ // amount. See groff manual, description of \w and
+ // the 'ssc' register. Return this amount.
+ void set_zoom(int); // Set the font's zoom factor * 1000. Must be a
+ // non-negative value.
+ int get_zoom(); // Return the font's zoom factor * 1000.
+ int get_code(glyph *); // Return the code point in the physical
+ // font of the given glyph.
+ const char *get_special_device_encoding(glyph *); // Return
+ // special device-dependent information about
+ // the given glyph. Return null pointer if
+ // there is no special information.
+ const char *get_name(); // Return the name of this font.
+ const char *get_internal_name(); // Return the 'internalname'
+ // attribute of this font or null pointer if it
+ // has none.
+ const char *get_image_generator(); // Return the 'image_generator'
+ // attribute of this font or null pointer if it
+ // has none.
+ static bool scan_papersize(const char *, const char **,
+ double *, double *); // Parse the
+ // 'papersize' directive in the DESC file name
+ // given in arg1. Update arg2 with the name
+ // of the paper format and arg3 and arg4 with
+ // its length and width, respectively. Return
+ // whether paper size was successfully set.
+ static font *load_font(const char *, bool = false); // Load the font
+ // description file with the given name (arg1)
+ // and return a pointer to a 'font' object. If
+ // arg2 is true, only the part of the font
+ // description file before the 'charset' and
+ // 'kernpairs' sections is loaded. Return null
+ // pointer in case of failure.
+ static void command_line_font_dir(const char *); // Prepend given
+ // path (arg1) to the list of directories in which
+ // to look up fonts.
+ static FILE *open_file(const char *, char **); // Open
+ // a font file with the given name (arg1),
+ // searching along the current font path. If
+ // arg2 points to a string pointer, set it to
+ // the found file name (this depends on the
+ // device also). Return the opened file. If
+ // not found, arg2 is unchanged, and a null
+ // pointer is returned.
+
+ // Open the DESC file (depending on the device) and initialize some
+ // static variables with info from there.
+ static const char *load_desc();
+ static FONT_COMMAND_HANDLER
+ set_unknown_desc_command_handler(FONT_COMMAND_HANDLER); // Register
+ // a function which defines the semantics of
+ // arbitrary commands in the font DESC file.
+ // Now the variables from the DESC file, shared by all fonts.
+ static int res; // The 'res' attribute given in the DESC file.
+ static int hor; // The 'hor' attribute given in the DESC file.
+ static int vert; // The 'vert' attribute given in the DESC file.
+ static int unitwidth; // The 'unitwidth' attribute given in the DESC file.
+ static int paperwidth; // The 'paperwidth' attribute given in the
+ // DESC file, or derived from the 'papersize'
+ // attribute given in the DESC file.
+ static int paperlength; // The 'paperlength' attribute given in the
+ // DESC file, or derived from the 'papersize'
+ // attribute given in the DESC file.
+ static const char *papersize;
+ static int biggestfont; // The 'biggestfont' attribute given in the
+ // DESC file.
+ static int spare2;
+ static int sizescale; // The 'sizescale' attribute given in the DESC file.
+ static bool has_tcommand; // DESC file has 'tcommand' directive.
+ static bool use_unscaled_charwidths; // DESC file has
+ // 'unscaled_charwidths' directive.
+ static bool pass_filenames; // DESC file has 'pass_filenames'
+ // directive.
+ static bool use_charnames_in_special; // DESC file has
+ // 'use_charnames_in_special' directive.
+ static bool is_unicode; // DESC file has the 'unicode' directive.
+ static const char *image_generator; // The 'image_generator' attribute
+ // given in the DESC file.
+ static const char **font_name_table; // The 'fonts' attribute given
+ // in the DESC file, as a null
+ // pointer-terminated array of strings.
+ static const char **style_table; // The 'styles' attribute given
+ // in the DESC file, as a null
+ // pointer-terminated array of strings.
+ static const char *family; // The 'family' attribute given in the DESC
+ // file.
+ static int *sizes; // The 'sizes' attribute given in the DESC file, as
+ // an array of intervals of the form { lower1,
+ // upper1, ... lowerN, upperN, 0 }.
+
+private:
+ unsigned ligatures; // Bit mask of available ligatures. Used by
+ // has_ligature().
+ font_kern_list **kern_hash_table; // Hash table of kerning pairs.
+ // Used by get_kern().
+ int space_width; // The normal width of a space. Used by
+ // get_space_width().
+ bool special; // See public is_special() above.
+ char *name; // The name of this font. Used by get_name().
+ char *internalname; // The 'internalname' attribute of this font, or
+ // a null pointer. Used by get_internal_name().
+ double slant; // The natural slant angle (in degrees) of this font.
+ int zoom; // The font's magnification, multiplied by 1000.
+ // Used by scale(). A zero value means 'no zoom'.
+ int *ch_index; // Conversion table from font-independent character
+ // indices to indices for this particular font.
+ int nindices;
+ font_char_metric *ch; // Metrics information for every character in this
+ // font (if !is_unicode) or for just some characters
+ // (if is_unicode). The indices of this array are
+ // font-specific, found as values in ch_index[].
+ int ch_used;
+ int ch_size;
+ font_widths_cache *widths_cache; // A cache of scaled character
+ // widths. Used by the get_width() function.
+
+ static FONT_COMMAND_HANDLER unknown_desc_command_handler; // A
+ // function defining the semantics of arbitrary
+ // commands in the DESC file.
+ enum { KERN_HASH_TABLE_SIZE = 503 }; // Size of the hash table of kerning
+ // pairs.
+
+ // These methods add new characters to the ch_index[] and ch[] arrays.
+ void add_entry(glyph *, // glyph
+ const font_char_metric &); // metric
+ void copy_entry(glyph *, // new_glyph
+ glyph *); // old_glyph
+ void alloc_ch_index(int); // index
+ void extend_ch();
+ void compact();
+
+ void add_kern(glyph *, glyph *, int); // Add to the kerning table a
+ // kerning amount (arg3) between two given glyphs
+ // (arg1 and arg2).
+ static int hash_kern(glyph *, glyph *); // Return a hash code for
+ // the pair of glyphs (arg1 and arg2).
+
+ /* Returns w * pointsize / unitwidth, rounded to the nearest integer. */
+ int scale(int w, int pointsize);
+ static bool unit_scale(double *, char); // Convert value in arg1 from
+ // the given unit (arg2; possible values are
+ // 'i', 'c', 'p', and 'P' as documented in the
+ // info file of groff, section 'Measurements')
+ // to inches. Store result in arg1 and return
+ // whether conversion was successful.
+ virtual void handle_unknown_font_command(const char *, // command
+ const char *, // arg
+ const char *, // file
+ int); // lineno
+
+protected:
+ font(const char *); // Initialize a font with the given name.
+
+ // Load the font description file with the name in member variable
+ // `name` into this object. If arg1 is true, only the part of the
+ // font description file before the 'charset' and 'kernpairs' sections
+ // is loaded. Return success/failure status of load.
+ bool load(bool = false);
+};
+
+// Local Variables:
+// fill-column: 72
+// mode: C++
+// End:
+// vim: set cindent noexpandtab shiftwidth=2 textwidth=72: