summaryrefslogtreecommitdiffstats
path: root/contrib/groff/hpftodit/hpftodit.cc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/groff/hpftodit/hpftodit.cc')
-rw-r--r--contrib/groff/hpftodit/hpftodit.cc812
1 files changed, 0 insertions, 812 deletions
diff --git a/contrib/groff/hpftodit/hpftodit.cc b/contrib/groff/hpftodit/hpftodit.cc
deleted file mode 100644
index 2e5978c..0000000
--- a/contrib/groff/hpftodit/hpftodit.cc
+++ /dev/null
@@ -1,812 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1994 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 2, 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 groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/*
-TODO
-put human readable font name in device file
-devise new names for useful characters
-use --- for unnamed characters
-option to specify symbol sets to look in
-make it work with TrueType fonts
-put filename in error messages (or fix lib)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <errno.h>
-#include "assert.h"
-#include "lib.h"
-#include "posix.h"
-#include "errarg.h"
-#include "error.h"
-#include "cset.h"
-#include "nonposix.h"
-
-#define SIZEOF(v) (sizeof(v)/sizeof(v[0]))
-
-const int MULTIPLIER = 3;
-
-inline
-int scale(int n)
-{
- return n * MULTIPLIER;
-}
-
-// tags in TFM file
-
-enum tag_type {
- min_tag = 400,
- type_tag = 400,
- symbol_set_tag = 404,
- msl_tag = 403,
- inches_per_point_tag = 406,
- design_units_per_em_tag = 408,
- posture_tag = 409,
- stroke_weight_tag = 411,
- spacing_tag = 412,
- slant_tag = 413,
- appearance_width_tag = 414,
- word_spacing_tag = 421,
- x_height_tag = 424,
- lower_ascent_tag = 427,
- lower_descent_tag = 428,
- width_tag = 433,
- left_extent_tag = 435,
- right_extent_tag = 436,
- ascent_tag = 437,
- descent_tag = 438,
- pair_kern_tag = 439,
- typeface_tag = 442,
- max_tag = 443
- };
-
-// types in TFM file
-
-enum {
- ENUM_TYPE = 1,
- BYTE_TYPE = 2,
- USHORT_TYPE = 3,
- FLOAT_TYPE = 5,
- SIGNED_SHORT_TYPE = 17
- };
-
-
-typedef unsigned char byte;
-typedef unsigned short uint16;
-typedef short int16;
-typedef unsigned int uint32;
-
-class File {
-public:
- File(const char *);
- void skip(int n);
- byte get_byte();
- uint16 get_uint16();
- uint32 get_uint32();
- void seek(uint32 n);
-private:
- unsigned char *buf_;
- const unsigned char *ptr_;
- const unsigned char *end_;
-};
-
-struct entry {
- char present;
- uint16 type;
- uint32 count;
- uint32 value;
- entry() : present(0) { }
-};
-
-struct char_info {
- uint16 msl;
- uint16 width;
- uint16 ascent;
- int16 descent;
- int16 left_extent;
- uint16 right_extent;
- uint16 symbol_set;
- unsigned char code;
-};
-
-const uint16 NO_SYMBOL_SET = 0;
-
-struct name_list {
- char *name;
- name_list *next;
- name_list(const char *s, name_list *p) : name(strsave(s)), next(p) { }
- ~name_list() { a_delete name; }
-};
-
-struct symbol_set {
- uint16 select;
- uint16 index[256];
-};
-
-#define SYMBOL_SET(n, c) ((n) * 32 + ((c) - 64))
-
-uint16 text_symbol_sets[] = {
- SYMBOL_SET(0, 'N'), // Latin 1
- SYMBOL_SET(6, 'J'), // Microsoft Publishing
- SYMBOL_SET(2, 'N'), // Latin 2
- 0
- };
-
-uint16 special_symbol_sets[] = {
- SYMBOL_SET(8, 'M'),
- SYMBOL_SET(5, 'M'),
- SYMBOL_SET(15, 'U'),
- 0
- };
-
-entry tags[max_tag + 1 - min_tag];
-
-char_info *char_table;
-uint32 nchars;
-
-int msl_name_table_size = 0;
-name_list **msl_name_table = 0;
-
-int n_symbol_sets;
-symbol_set *symbol_set_table;
-
-static int special_flag = 0;
-static int italic_flag = 0;
-static int italic_sep;
-
-static void usage();
-static const char *xbasename(const char *);
-static void read_tags(File &);
-static void check_type();
-static void check_units(File &);
-static int read_map(const char *);
-static void require_tag(tag_type);
-static void dump_tags(File &f);
-static void output_spacewidth();
-static void output_pclweight();
-static void output_pclproportional();
-static void read_and_output_pcltypeface(File &);
-static void output_pclstyle();
-static void output_slant();
-static void output_ligatures();
-static void read_symbol_sets(File &);
-static void read_and_output_kernpairs(File &);
-static void output_charset();
-static void read_char_table(File &f);
-
-inline
-entry &tag_info(tag_type t)
-{
- return tags[t - min_tag];
-}
-
-int main(int argc, char **argv)
-{
- program_name = argv[0];
-
- int opt;
- int debug_flag = 0;
-
- while ((opt = getopt(argc, argv, "dsvi:")) != EOF) {
- switch (opt) {
- case 'd':
- debug_flag = 1;
- break;
- case 's':
- special_flag = 1;
- break;
- case 'i':
- italic_flag = 1;
- italic_sep = atoi(optarg);
- break;
- case 'v':
- {
- extern const char *Version_string;
- fprintf(stderr, "hpftodit version %s\n", Version_string);
- fflush(stderr);
- break;
- }
- break;
- case '?':
- usage();
- default:
- assert(0);
- }
- }
- if (argc - optind != 3)
- usage();
- File f(argv[optind]);
- if (!read_map(argv[optind + 1]))
- exit(1);
- current_filename = 0;
- current_lineno = -1; // no line numbers
- if (freopen(argv[optind + 2], "w", stdout) == 0)
- fatal("cannot open `%1': %2", argv[optind + 2], strerror(errno));
- current_filename = argv[optind];
- printf("name %s\n", xbasename(argv[optind + 2]));
- if (special_flag)
- printf("special\n");
- read_tags(f);
- check_type();
- check_units(f);
- if (debug_flag)
- dump_tags(f);
- read_char_table(f);
- output_spacewidth();
- output_slant();
- read_and_output_pcltypeface(f);
- output_pclproportional();
- output_pclweight();
- output_pclstyle();
- read_symbol_sets(f);
- output_ligatures();
- read_and_output_kernpairs(f);
- output_charset();
- return 0;
-}
-
-static
-void usage()
-{
- fprintf(stderr, "usage: %s [-s] [-i n] tfm_file map_file output_font\n",
- program_name);
- exit(1);
-}
-
-File::File(const char *s)
-{
- // We need to read the file in binary mode because hpftodit relies
- // on byte counts.
- int fd = open(s, O_RDONLY | O_BINARY);
- if (fd < 0)
- fatal("cannot open `%1': %2", s, strerror(errno));
- current_filename = s;
- struct stat sb;
- if (fstat(fd, &sb) < 0)
- fatal("cannot stat: %1", strerror(errno));
- if (!S_ISREG(sb.st_mode))
- fatal("not a regular file");
- buf_ = new unsigned char[sb.st_size];
- long nread = read(fd, buf_, sb.st_size);
- if (nread < 0)
- fatal("read error: %1", strerror(errno));
- if (nread != sb.st_size)
- fatal("read unexpected number of bytes");
- ptr_ = buf_;
- end_ = buf_ + sb.st_size;
- // These are actually text files, so we must get rid of the `\r'
- // characters. This is also enabled for Posix systems, in case the
- // input came from Windows...
- unsigned char *p = buf_, *q = buf_;
- while (q < end_)
- {
- if (*q == '\r')
- {
- if (*++q != '\n')
- *p++ = '\r';
- }
-#if defined(__MSDOS__) || defined(_MSC_VER)
- if (*q == '\032') // ^Z means ``software EOF''
- break;
-#endif
- *p++ = *q++;
- }
- end_ = p;
-}
-
-void File::skip(int n)
-{
- if (end_ - ptr_ < n)
- fatal("unexpected end of file");
- ptr_ += n;
-}
-
-void File::seek(uint32 n)
-{
- if (end_ - buf_ < n)
- fatal("unexpected end of file");
- ptr_ = buf_ + n;
-}
-
-byte File::get_byte()
-{
- if (ptr_ >= end_)
- fatal("unexpected end of file");
- return *ptr_++;
-}
-
-uint16 File::get_uint16()
-{
- if (end_ - ptr_ < 2)
- fatal("unexpected end of file");
- uint16 n = *ptr_++;
- return n + (*ptr_++ << 8);
-}
-
-uint32 File::get_uint32()
-{
- if (end_ - ptr_ < 4)
- fatal("unexpected end of file");
- uint32 n = *ptr_++;
- for (int i = 0; i < 3; i++)
- n += *ptr_++ << (i + 1)*8;
- return n;
-}
-
-static
-void read_tags(File &f)
-{
- if (f.get_byte() != 'I' || f.get_byte() != 'I')
- fatal("not an Intel format TFM file");
- f.skip(6);
- uint16 ntags = f.get_uint16();
- entry dummy;
- for (uint16 i = 0; i < ntags; i++) {
- uint16 tag = f.get_uint16();
- entry *p;
- if (min_tag <= tag && tag <= max_tag)
- p = tags + (tag - min_tag);
- else
- p = &dummy;
- p->present = 1;
- p->type = f.get_uint16();
- p->count = f.get_uint32();
- p->value = f.get_uint32();
- }
-}
-
-static
-void check_type()
-{
- require_tag(type_tag);
- if (tag_info(type_tag).value != 0) {
- if (tag_info(type_tag).value == 2)
- fatal("cannot handle TrueType tfm files");
- fatal("unknown type tag %1", int(tag_info(type_tag).value));
- }
-}
-
-static
-void check_units(File &f)
-{
- require_tag(design_units_per_em_tag);
- f.seek(tag_info(design_units_per_em_tag).value);
- uint32 num = f.get_uint32();
- uint32 den = f.get_uint32();
- if (num != 8782 || den != 1)
- fatal("design units per em != 8782/1");
- require_tag(inches_per_point_tag);
- f.seek(tag_info(inches_per_point_tag).value);
- num = f.get_uint32();
- den = f.get_uint32();
- if (num != 100 || den != 7231)
- fatal("inches per point not 100/7231");
-}
-
-static
-void require_tag(tag_type t)
-{
- if (!tag_info(t).present)
- fatal("tag %1 missing", int(t));
-}
-
-static
-void output_spacewidth()
-{
- require_tag(word_spacing_tag);
- printf("spacewidth %d\n", scale(tag_info(word_spacing_tag).value));
-}
-
-static
-void read_symbol_sets(File &f)
-{
- uint32 symbol_set_dir_length = tag_info(symbol_set_tag).count;
- n_symbol_sets = symbol_set_dir_length/14;
- symbol_set_table = new symbol_set[n_symbol_sets];
- int i;
- for (i = 0; i < n_symbol_sets; i++) {
- f.seek(tag_info(symbol_set_tag).value + i*14);
- (void)f.get_uint32();
- uint32 off1 = f.get_uint32();
- uint32 off2 = f.get_uint32();
- (void)f.get_uint16(); // what's this for?
- f.seek(off1);
- int j;
- uint16 kind = 0;
- for (j = 0; j < off2 - off1; j++) {
- unsigned char c = f.get_byte();
- if ('0' <= c && c <= '9')
- kind = kind*10 + (c - '0');
- else if ('A' <= c && c <= 'Z')
- kind = kind*32 + (c - 64);
- }
- symbol_set_table[i].select = kind;
- for (j = 0; j < 256; j++)
- symbol_set_table[i].index[j] = f.get_uint16();
- }
- for (i = 0; i < nchars; i++)
- char_table[i].symbol_set = NO_SYMBOL_SET;
-
- uint16 *symbol_set_selectors = (special_flag
- ? special_symbol_sets
- : text_symbol_sets);
- for (i = 0; symbol_set_selectors[i] != 0; i++) {
- int j;
- for (j = 0; j < n_symbol_sets; j++)
- if (symbol_set_table[j].select == symbol_set_selectors[i])
- break;
- if (j < n_symbol_sets) {
- for (int k = 0; k < 256; k++) {
- uint16 index = symbol_set_table[j].index[k];
- if (index != 0xffff
- && char_table[index].symbol_set == NO_SYMBOL_SET) {
- char_table[index].symbol_set = symbol_set_table[j].select;
- char_table[index].code = k;
- }
- }
- }
- }
-}
-
-static
-void read_char_table(File &f)
-{
- require_tag(msl_tag);
- nchars = tag_info(msl_tag).count;
- char_table = new char_info[nchars];
-
- f.seek(tag_info(msl_tag).value);
- uint32 i;
- for (i = 0; i < nchars; i++)
- char_table[i].msl = f.get_uint16();
-
- require_tag(width_tag);
- f.seek(tag_info(width_tag).value);
- for (i = 0; i < nchars; i++)
- char_table[i].width = f.get_uint16();
-
- require_tag(ascent_tag);
- f.seek(tag_info(ascent_tag).value);
- for (i = 0; i < nchars; i++) {
- char_table[i].ascent = f.get_uint16();
- }
-
- require_tag(descent_tag);
- f.seek(tag_info(descent_tag).value);
- for (i = 0; i < nchars; i++) {
- char_table[i].descent = f.get_uint16();
- if (char_table[i].descent > 0)
- char_table[i].descent = 0;
- }
-
- require_tag(left_extent_tag);
- f.seek(tag_info(left_extent_tag).value);
- for (i = 0; i < nchars; i++)
- char_table[i].left_extent = int16(f.get_uint16());
-
- require_tag(right_extent_tag);
- f.seek(tag_info(right_extent_tag).value);
- for (i = 0; i < nchars; i++)
- char_table[i].right_extent = f.get_uint16();
-}
-
-static
-void output_pclweight()
-{
- require_tag(stroke_weight_tag);
- int stroke_weight = tag_info(stroke_weight_tag).value;
- int pcl_stroke_weight;
- if (stroke_weight < 128)
- pcl_stroke_weight = -3;
- else if (stroke_weight == 128)
- pcl_stroke_weight = 0;
- else if (stroke_weight <= 145)
- pcl_stroke_weight = 1;
- else if (stroke_weight <= 179)
- pcl_stroke_weight = 3;
- else
- pcl_stroke_weight = 4;
- printf("pclweight %d\n", pcl_stroke_weight);
-}
-
-static
-void output_pclproportional()
-{
- require_tag(spacing_tag);
- printf("pclproportional %d\n", tag_info(spacing_tag).value == 0);
-}
-
-static
-void read_and_output_pcltypeface(File &f)
-{
- printf("pcltypeface ");
- require_tag(typeface_tag);
- f.seek(tag_info(typeface_tag).value);
- for (uint32 i = 0; i < tag_info(typeface_tag).count; i++) {
- unsigned char c = f.get_byte();
- if (c == '\0')
- break;
- putchar(c);
- }
- printf("\n");
-}
-
-static
-void output_pclstyle()
-{
- unsigned pcl_style = 0;
- // older tfms don't have the posture tag
- if (tag_info(posture_tag).present) {
- if (tag_info(posture_tag).value)
- pcl_style |= 1;
- }
- else {
- require_tag(slant_tag);
- if (tag_info(slant_tag).value != 0)
- pcl_style |= 1;
- }
- require_tag(appearance_width_tag);
- if (tag_info(appearance_width_tag).value < 100) // guess
- pcl_style |= 4;
- printf("pclstyle %d\n", pcl_style);
-}
-
-static
-void output_slant()
-{
- require_tag(slant_tag);
- int slant = int16(tag_info(slant_tag).value);
- if (slant != 0)
- printf("slant %f\n", slant/100.0);
-}
-
-static
-void output_ligatures()
-{
- // don't use ligatures for fixed space font
- require_tag(spacing_tag);
- if (tag_info(spacing_tag).value != 0)
- return;
- static const char *ligature_names[] = {
- "fi", "fl", "ff", "ffi", "ffl"
- };
-
- static const char *ligature_chars[] = {
- "fi", "fl", "ff", "Fi", "Fl"
- };
-
- unsigned ligature_mask = 0;
- int i;
- for (i = 0; i < nchars; i++) {
- uint16 msl = char_table[i].msl;
- if (msl < msl_name_table_size
- && char_table[i].symbol_set != NO_SYMBOL_SET) {
- for (name_list *p = msl_name_table[msl]; p; p = p->next)
- for (int j = 0; j < SIZEOF(ligature_chars); j++)
- if (strcmp(p->name, ligature_chars[j]) == 0) {
- ligature_mask |= 1 << j;
- break;
- }
- }
- }
- if (ligature_mask) {
- printf("ligatures");
- for (i = 0; i < SIZEOF(ligature_names); i++)
- if (ligature_mask & (1 << i))
- printf(" %s", ligature_names[i]);
- printf(" 0\n");
- }
-}
-
-static
-void read_and_output_kernpairs(File &f)
-{
- if (tag_info(pair_kern_tag).present) {
- printf("kernpairs\n");
- f.seek(tag_info(pair_kern_tag).value);
- uint16 n_pairs = f.get_uint16();
- for (int i = 0; i < n_pairs; i++) {
- uint16 i1 = f.get_uint16();
- uint16 i2 = f.get_uint16();
- int16 val = int16(f.get_uint16());
- if (char_table[i1].symbol_set != NO_SYMBOL_SET
- && char_table[i2].symbol_set != NO_SYMBOL_SET
- && char_table[i1].msl < msl_name_table_size
- && char_table[i2].msl < msl_name_table_size) {
- for (name_list *p = msl_name_table[char_table[i1].msl];
- p;
- p = p->next)
- for (name_list *q = msl_name_table[char_table[i2].msl];
- q;
- q = q->next)
- printf("%s %s %d\n", p->name, q->name, scale(val));
- }
- }
- }
-}
-
-static
-void output_charset()
-{
- require_tag(slant_tag);
- double slant_angle = int16(tag_info(slant_tag).value)*PI/18000.0;
- double slant = sin(slant_angle)/cos(slant_angle);
-
- require_tag(x_height_tag);
- require_tag(lower_ascent_tag);
- require_tag(lower_descent_tag);
-
- printf("charset\n");
- int i;
- for (i = 0; i < nchars; i++) {
- uint16 msl = char_table[i].msl;
- if (msl < msl_name_table_size
- && msl_name_table[msl]) {
- if (char_table[i].symbol_set != NO_SYMBOL_SET) {
- printf("%s\t%d,%d",
- msl_name_table[msl]->name,
- scale(char_table[i].width),
- scale(char_table[i].ascent));
- int depth = scale(- char_table[i].descent);
- if (depth < 0)
- depth = 0;
- int italic_correction = 0;
- int left_italic_correction = 0;
- int subscript_correction = 0;
- if (italic_flag) {
- italic_correction = scale(char_table[i].right_extent
- - char_table[i].width
- + italic_sep);
- if (italic_correction < 0)
- italic_correction = 0;
- subscript_correction = int((tag_info(x_height_tag).value
- * slant * .8) + .5);
- if (subscript_correction > italic_correction)
- subscript_correction = italic_correction;
- left_italic_correction = scale(italic_sep
- - char_table[i].left_extent);
- }
- if (subscript_correction != 0)
- printf(",%d,%d,%d,%d",
- depth, italic_correction, left_italic_correction,
- subscript_correction);
- else if (left_italic_correction != 0)
- printf(",%d,%d,%d", depth, italic_correction, left_italic_correction);
- else if (italic_correction != 0)
- printf(",%d,%d", depth, italic_correction);
- else if (depth != 0)
- printf(",%d", depth);
- // This is fairly arbitrary. Fortunately it doesn't much matter.
- unsigned type = 0;
- if (char_table[i].ascent > (tag_info(lower_ascent_tag).value*9)/10)
- type |= 2;
- if (char_table[i].descent < (int16(tag_info(lower_descent_tag).value)*9)/10)
- type |= 1;
- printf("\t%d\t%d\n",
- type,
- char_table[i].symbol_set*256 + char_table[i].code);
- for (name_list *p = msl_name_table[msl]->next; p; p = p->next)
- printf("%s\t\"\n", p->name);
- }
- else
- warning("MSL %1 not in any of the searched symbol sets", msl);
- }
- }
-}
-
-static
-void dump_tags(File &f)
-{
- int i;
- for (i = min_tag; i <= max_tag; i++) {
- enum tag_type t = tag_type(i);
- if (tag_info(t).present) {
- fprintf(stderr,
- "%d %d %d %d\n", i, tag_info(t).type, tag_info(t).count,
- tag_info(t).value);
- if (tag_info(t).type == FLOAT_TYPE
- && tag_info(t).count == 1) {
- f.seek(tag_info(t).value);
- uint32 num = f.get_uint32();
- uint32 den = f.get_uint32();
- fprintf(stderr, "(%u/%u = %g)\n", num, den, (double)num/den);
- }
- }
- }
-}
-
-static
-int read_map(const char *file)
-{
- errno = 0;
- FILE *fp = fopen(file, "r");
- if (!fp) {
- error("can't open `%1': %2", file, strerror(errno));
- return 0;
- }
- current_filename = file;
- char buf[512];
- current_lineno = 0;
- while (fgets(buf, int(sizeof(buf)), fp)) {
- current_lineno++;
- char *ptr = buf;
- while (csspace(*ptr))
- ptr++;
- if (*ptr == '\0' || *ptr == '#')
- continue;
- ptr = strtok(ptr, " \n\t");
- if (!ptr)
- continue;
- int n;
- if (sscanf(ptr, "%d", &n) != 1) {
- error("bad map file");
- fclose(fp);
- return 0;
- }
- if (n < 0) {
- error("negative code");
- fclose(fp);
- return 0;
- }
- if (n >= msl_name_table_size) {
- size_t old_size = msl_name_table_size;
- name_list **old_table = msl_name_table;
- msl_name_table_size = n + 256;
- msl_name_table = new name_list *[msl_name_table_size];
- if (old_table) {
- memcpy(msl_name_table, old_table, old_size*sizeof(name_list *));
- a_delete old_table;
- }
- for (size_t i = old_size; i < msl_name_table_size; i++)
- msl_name_table[i] = 0;
- }
- ptr = strtok(0, " \n\t");
- if (!ptr) {
- error("missing names");
- fclose(fp);
- return 0;
- }
- for (; ptr; ptr = strtok(0, " \n\t"))
- msl_name_table[n] = new name_list(ptr, msl_name_table[n]);
- }
- fclose(fp);
- return 1;
-}
-
-static
-const char *xbasename(const char *s)
-{
- // DIR_SEPS[] are possible directory separator characters, see
- // nonposix.h. We want the rightmost separator of all possible
- // ones. Example: d:/foo\\bar.
- const char *b = strrchr(s, DIR_SEPS[0]), *b1;
- const char *sep = &DIR_SEPS[1];
-
- while (*sep)
- {
- b1 = strrchr(s, *sep);
- if (b1 && (!b || b1 > b))
- b = b1;
- sep++;
- }
- return b ? b + 1 : s;
-}
OpenPOWER on IntegriCloud