summaryrefslogtreecommitdiff
path: root/charspace/main.c
diff options
context:
space:
mode:
authorkarl <karl>2004-04-19 22:56:26 +0000
committerkarl <karl>2004-04-19 22:56:26 +0000
commitd2ffca200655a89c5d140b66d69001e92173e3da (patch)
tree6fa1965e6e8362c5913e1554b12507a924dba7f1 /charspace/main.c
parenteb33f9ace5a3ddfe8a983866468f3352abaa6391 (diff)
downloadfontutils-d2ffca200655a89c5d140b66d69001e92173e3da.tar.gz
init
Diffstat (limited to 'charspace/main.c')
-rw-r--r--charspace/main.c330
1 files changed, 330 insertions, 0 deletions
diff --git a/charspace/main.c b/charspace/main.c
new file mode 100644
index 0000000..500c9a6
--- /dev/null
+++ b/charspace/main.c
@@ -0,0 +1,330 @@
+/* charspace -- find intercharacter spacing based on user information.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program 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 2, or (at your option)
+any later version.
+
+This program 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, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include <kpathsea/tex-file.h>
+#include <kpathsea/pathsearch.h>
+#include <kpathsea/paths.h>
+
+#include "cmdline.h"
+#include "encoding.h"
+#include "font.h"
+#include "report.h"
+
+#include "char.h"
+#include "input-cmi.h"
+#include "main.h"
+#include "output.h"
+#include "symtab.h"
+
+/* Must come after `symtab.h', since it uses `symval_type'. (It's
+ generated by Bison, so we can't fix it.) */
+#include "cmi.h"
+
+
+/* The resolution of the font we will read, in pixels per inch. We
+ don't deal with nonsquare pixels. (-dpi) */
+string dpi = "300";
+real dpi_real;
+
+/* The name of the encoding file specified by the user, and the
+ structure we parse it into. (-encoding) */
+static string encoding_name = NULL;
+encoding_info_type encoding_info;
+
+/* Whether or not there was a TFM file corresponding to `input_name'.
+ If true, `tfm_get_char' can be called -- otherwise not. */
+boolean have_tfm = false;
+
+/* The name of the bitmap font we input. */
+string input_name;
+
+/* Whether or not to output a GF file. (-no-gf) */
+boolean no_gf = false;
+
+/* Says which characters we should process. This is independent of the
+ ordering in the font file. (-range) */
+charcode_type starting_char = 0;
+charcode_type ending_char = MAX_CHARCODE;
+
+
+static string read_command_line (int, string[]);
+static encoding_info_type read_encoding_info (string);
+static string *scan_string_list (string);
+
+/* Charspace computes side bearing values to put in a font. It doesn't
+ do so automatically, unfortunately: auxiliary files have to specify
+ everything. The basic idea is due to Harry Carter as described in
+ Walter Tracy's book (see README for the citation): space a few of the
+ letters (O, H, o, n) by hand amongst themselves. Then a reasonable
+ value for most of the other side bearings can be determined
+ (independent of the typeface) as a percentage of those ``control
+ letters'' sidebearings.
+
+ The basic strategy is to first read `common.cmi', which specifies the
+ font-independent side bearing apportionments. Then we read
+ font-specific CMI files to actually define the side bearing values,
+ specify kerns, and so on.
+
+ This defines a whole bunch of things in the symbol table (see
+ `symtab.c'). We then resolve the side bearing information for all
+ the characters we will output, after all the definitions have been
+ read.
+
+ Then we output the revised GF and TFM files. We read an existing TFM
+ file and an encoding file, as well as accepting various options, to
+ get lig/kern and other TFM information. */
+
+int
+main (int argc, string argv[])
+{
+ /* This is static only because we want it to be initialized entirely
+ to NULL pointers, and it's too painful to write out 256 NULL's. */
+ static char_type *chars[MAX_CHARCODE + 1];
+ unsigned code;
+ bitmap_font_type font;
+ string font_rootname;
+ string tfm_name;
+
+ /* Get the bitmap font we're reading. */
+ input_name = read_command_line (argc, argv);
+ font = get_bitmap_font (input_name, atou (dpi));
+ font_rootname = remove_suffix (basename (input_name));
+
+ /* Make sure the output name is ok. */
+ if (output_name == NULL)
+ output_name = input_name;
+
+ if (!no_gf && find_suffix (output_name) != NULL)
+ FATAL ("You can't specify a suffix and more than one output file");
+
+ tfm_name = kpse_find_tfm (input_name);
+ if (tfm_name != NULL)
+ {
+ if (!tfm_open_input_file (tfm_name))
+ FATAL1 ("%s: Could not open TFM file", tfm_name);
+ else
+ have_tfm = true;
+ }
+
+ /* Set the numeric counterpart of `dpi', for use in lots of places. */
+ dpi_real = atof (dpi);
+
+ /* If the user didn't specify CMI files to read, then use
+ `<input_name>.<dpi>cmi'. */
+ if (cmi_names == NULL)
+ cmi_names = scan_string_list (input_name);
+
+ /* Define the designsize, so the CMI files can refer to it. */
+ {
+ real ds_points = BITMAP_FONT_DESIGN_SIZE (font);
+ real ds_pixels = POINTS_TO_REAL_PIXELS (ds_points, dpi_real);
+ symtab_define ("designsize", symtab_real_node (ds_pixels));
+ }
+
+ /* Read all the CMI information. */
+ read_cmi_file ("common.cmi", "");
+ read_cmi_file_list (cmi_names, dpi);
+
+ /* Figure out the font encoding scheme. Must be done after reading
+ the CMI files, since they can specify the codingscheme. */
+ encoding_info = read_encoding_info (encoding_name);
+
+ /* The main loop: compute each character's information. */
+ for (code = starting_char; code <= ending_char; code++)
+ {
+ do_char (code, &chars[code]);
+ }
+
+ /* Output what we've so laboriously collected. */
+ output_font (font, chars);
+
+ close_font (input_name);
+ if (have_tfm)
+ tfm_close_input_file ();
+
+ return 0;
+}
+
+/* Return the font encoding. Use
+ 1) USER_NAME (if it's non-null);
+ 2) the value of `codingscheme' in the symbol table (if it's a string);
+ 3) the codingscheme from an existing TFM file (if we have one).
+
+ Otherwise, give a fatal error. */
+
+static encoding_info_type
+read_encoding_info (string user_name)
+{
+ encoding_info_type ei;
+
+ if (user_name != NULL)
+ ei = read_encoding_file (user_name);
+ else
+ {
+ string enc_name;
+ string codingscheme = NULL;
+ symval_type *sv = symtab_lookup ("codingscheme");
+
+ if (sv == NULL)
+ codingscheme = have_tfm ? tfm_get_coding_scheme () : DEFAULT_ENCODING;
+
+ else if (SYMVAL_TAG (*sv) == symval_string)
+ codingscheme = SYMVAL_STRING (*sv);
+
+ else
+ FATAL ("codingscheme: defined (in CMI file) as a non-string");
+
+ assert (codingscheme != NULL);
+
+ enc_name = coding_scheme_to_filename (codingscheme);
+ ei = read_encoding_file (enc_name);
+ }
+
+ return ei;
+}
+
+/* Reading the options. */
+
+/* This is defined in version.c. */
+extern string version_string;
+
+#define USAGE "Options:
+<font_name> should be a filename, possibly with a resolution, e.g.,
+ `cmr10' or `cmr10.300'.\n" \
+ GETOPT_USAGE \
+"cmi-files <file1>,<file2>,...: read the CMI files
+ `<file1>.<dpi>cmi', `<file2>.<dpi>cmi', etc., after reading
+ `common.cmi'; default is `<font-name>.<dpi>cmi'. The <dpi>cmi is not
+ appended to any of the <file>s which already have a suffix.
+dpi <unsigned>: use this resolution; default is 300.
+encoding <filename>: read ligature and other encoding information
+ from <filename>.enc; there is no default. (A TFM file <font-name>.tfm
+ is also read, if it exists.)
+fontdimens <fontdimen>:<real>,<fontdimen>:<real>,...: assign <value>
+ to each <fontdimen> given, when outputting a TFM file. A <fontdimen>
+ can be either one of the standard names (in either upper or
+ lowercase), or a number between 1 and 30. Each <real> is taken to be
+ in points (except in the case of the <fontdimen> `SLANT' (parameter
+ 1), which is a dimensionless number).
+no-gf: don't output a GF file.
+output-file <filename>: write the TFM file to `<filename>.tfm' and the
+ GF file to `<filename>.<dpi>gf'; <filename> shouldn't have a suffix;
+ default is <font-name>.tfm and <font-name>.<dpi>gf, or, if those would
+ overwrite the input, those preceded by `x'.
+range <char1>-<char2>: only process characters between <char1> and
+ <char2>, inclusive.
+verbose: print brief progress reports on stdout.
+version: print the version number of this program.
+xheight-char <charcode>: use the height of this character as the
+ default x-height (for the TFM output); default is 120 (ASCII `x').
+"
+
+static string
+read_command_line (int argc, string argv[])
+{
+ int g; /* `getopt' return code. */
+ int option_index;
+ boolean explicit_dpi = false;
+ boolean printed_version = false;
+ struct option long_options[]
+ = { { "dpi", 1, 0, 0 },
+ { "cmi-files", 1, 0, 0 },
+ { "encoding", 1, 0, 0 },
+ { "fontdimens", 1, 0, 0 },
+ { "help", 0, 0, 0 },
+ { "no-gf", 0, (int *) &no_gf, 1 },
+ { "output-file", 1, 0, 0 },
+ { "range", 1, 0, 0 },
+ { "verbose", 0, (int *) &verbose, 1 },
+ { "version", 0, (int *) &printed_version, 1 },
+ { "xheight-char", 1, 0, 0 },
+ { 0, 0, 0, 0 } };
+
+ while (true)
+ {
+ g = getopt_long_only (argc, argv, "", long_options, &option_index);
+
+ if (g == EOF)
+ break;
+
+ if (g == '?')
+ continue; /* Unknown option. */
+
+ assert (g == 0); /* We have no short option names. */
+
+ if (ARGUMENT_IS ("cmi-files"))
+ cmi_names = scan_string_list (optarg);
+
+ else if (ARGUMENT_IS ("dpi"))
+ dpi = optarg;
+
+ else if (ARGUMENT_IS ("encoding"))
+ encoding_name = optarg;
+
+ else if (ARGUMENT_IS ("fontdimens"))
+ fontdimens = optarg;
+
+ else if (ARGUMENT_IS ("help"))
+ {
+ fprintf (stderr, "Usage: %s [options] <font_name>.\n", argv[0]);
+ fprintf (stderr, USAGE);
+ exit (0);
+ }
+
+ else if (ARGUMENT_IS ("output-file"))
+ output_name = optarg;
+
+ else if (ARGUMENT_IS ("range"))
+ GET_RANGE (optarg, starting_char, ending_char);
+
+ else if (ARGUMENT_IS ("version"))
+ printf ("%s.\n", version_string);
+
+ else if (ARGUMENT_IS ("xheight-char"))
+ xheight_char = xparse_charcode (optarg);
+
+ /* Else it was just a flag; getopt has already done the assignment. */
+ }
+
+ FINISH_COMMAND_LINE ();
+}
+
+
+/* Take a string L consisting of unsigned strings separated by commas
+ and return a vector of the strings, as pointers.
+ Append an element to the vector. */
+
+static string *
+scan_string_list (string l)
+{
+ string map;
+ unsigned length = 1;
+ string *vector = xmalloc (sizeof (string));
+
+ for (map = strtok (l, ","); map != NULL; map = strtok (NULL, ","))
+ {
+ length++;
+ vector = xrealloc (vector, length * sizeof (string));
+ vector[length - 2] = map;
+ }
+
+ vector[length - 1] = NULL;
+ return vector;
+}