diff options
author | karl <karl> | 2004-04-19 22:56:26 +0000 |
---|---|---|
committer | karl <karl> | 2004-04-19 22:56:26 +0000 |
commit | d2ffca200655a89c5d140b66d69001e92173e3da (patch) | |
tree | 6fa1965e6e8362c5913e1554b12507a924dba7f1 /charspace/main.c | |
parent | eb33f9ace5a3ddfe8a983866468f3352abaa6391 (diff) | |
download | fontutils-d2ffca200655a89c5d140b66d69001e92173e3da.tar.gz |
init
Diffstat (limited to 'charspace/main.c')
-rw-r--r-- | charspace/main.c | 330 |
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; +} |