Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/dvi/mdvi-lib/tfmfile.c
diff options
context:
space:
mode:
authorNickolay V. Shmyrev <nshmyrev@yandex.ru>2007-01-08 12:25:31 (GMT)
committer Nickolay V. Shmyrev <nshmyrev@src.gnome.org>2007-01-08 12:25:31 (GMT)
commit13a06349251874bd35d2f03c3fc93217cee749a2 (patch)
treea681279b008acb19f686ee265aaed2be0da8d9e8 /dvi/mdvi-lib/tfmfile.c
parentafb550ab779e00918d8fe24742abee3a81ebfe93 (diff)
Reorganize source tree.
2007-01-08 Nickolay V. Shmyrev <nshmyrev@yandex.ru> * Makefile.am: * backend/Makefile.am: * backend/comics/Makefile.am: * backend/djvu/Makefile.am: * backend/dvi/Makefile.am: * backend/ev-async-renderer.c: * backend/ev-async-renderer.h: * backend/ev-attachment.c: * backend/ev-attachment.h: * backend/ev-backend-marshal.c: * backend/ev-document-factory.c: * backend/ev-document-factory.h: * backend/ev-document-find.c: * backend/ev-document-find.h: * backend/ev-document-fonts.c: * backend/ev-document-fonts.h: * backend/ev-document-images.c: * backend/ev-document-images.h: * backend/ev-document-info.h: * backend/ev-document-links.c: * backend/ev-document-links.h: * backend/ev-document-misc.c: * backend/ev-document-misc.h: * backend/ev-document-security.c: * backend/ev-document-security.h: * backend/ev-document-thumbnails.c: * backend/ev-document-thumbnails.h: * backend/ev-document-transition.c: * backend/ev-document-transition.h: * backend/ev-document.c: * backend/ev-document.h: * backend/ev-file-exporter.c: * backend/ev-file-exporter.h: * backend/ev-image.c: * backend/ev-image.h: * backend/ev-link-action.c: * backend/ev-link-action.h: * backend/ev-link-dest.c: * backend/ev-link-dest.h: * backend/ev-link.c: * backend/ev-link.h: * backend/ev-render-context.c: * backend/ev-render-context.h: * backend/ev-selection.c: * backend/ev-selection.h: * backend/impress/Makefile.am: * backend/pdf/Makefile.am: * backend/pixbuf/Makefile.am: * backend/ps/Makefile.am: * backend/ps/ps-document.c: (push_pixbuf), (interpreter_failed), (ps_document_widget_event), (setup_pixmap), (setup_page), (input), (start_interpreter), (stop_interpreter), (document_load), (ps_document_next_page), (render_page): * backend/tiff/Makefile.am: * comics/Makefile.am: * comics/comics-document.c: * comics/comics-document.h: * configure.ac: * cut-n-paste/zoom-control/ephy-zoom-control.c: * djvu/Makefile.am: * djvu/djvu-document-private.h: * djvu/djvu-document.c: * djvu/djvu-document.h: * djvu/djvu-links.c: * djvu/djvu-links.h: * djvu/djvu-text-page.c: * djvu/djvu-text-page.h: * djvu/djvu-text.c: * djvu/djvu-text.h: * dvi/Makefile.am: * dvi/dvi-document.c: * dvi/dvi-document.h: * dvi/fonts.c: * dvi/fonts.h: * dvi/mdvi-lib/Makefile.am: * dvi/mdvi-lib/afmparse.c: * dvi/mdvi-lib/afmparse.h: * dvi/mdvi-lib/bitmap.c: * dvi/mdvi-lib/bitmap.h: * dvi/mdvi-lib/color.c: * dvi/mdvi-lib/color.h: * dvi/mdvi-lib/common.c: * dvi/mdvi-lib/common.h: * dvi/mdvi-lib/defaults.h: * dvi/mdvi-lib/dvimisc.c: * dvi/mdvi-lib/dviopcodes.h: * dvi/mdvi-lib/dviread.c: * dvi/mdvi-lib/files.c: * dvi/mdvi-lib/font.c: * dvi/mdvi-lib/fontmap.c: * dvi/mdvi-lib/fontmap.h: * dvi/mdvi-lib/fontsrch.c: * dvi/mdvi-lib/gf.c: * dvi/mdvi-lib/hash.c: * dvi/mdvi-lib/hash.h: * dvi/mdvi-lib/list.c: * dvi/mdvi-lib/mdvi.h: * dvi/mdvi-lib/pagesel.c: * dvi/mdvi-lib/paper.c: * dvi/mdvi-lib/paper.h: * dvi/mdvi-lib/pk.c: * dvi/mdvi-lib/private.h: * dvi/mdvi-lib/setup.c: * dvi/mdvi-lib/sp-epsf.c: * dvi/mdvi-lib/special.c: * dvi/mdvi-lib/sysdeps.h: * dvi/mdvi-lib/t1.c: * dvi/mdvi-lib/tfm.c: * dvi/mdvi-lib/tfmfile.c: * dvi/mdvi-lib/tt.c: * dvi/mdvi-lib/util.c: * dvi/mdvi-lib/vf.c: * dvi/pixbuf-device.c: * dvi/pixbuf-device.h: * impress/Makefile.am: * impress/common.h: * impress/document.c: * impress/f_oasis.c: * impress/f_oo13.c: * impress/iksemel.c: * impress/iksemel.h: * impress/imposter.h: * impress/impress-document.c: * impress/impress-document.h: * impress/internal.h: * impress/r_back.c: * impress/r_draw.c: * impress/r_geometry.c: * impress/r_gradient.c: * impress/r_style.c: * impress/r_text.c: * impress/render.c: * impress/render.h: * impress/zip.c: * impress/zip.h: * lib/Makefile.am: * lib/ev-debug.c: * lib/ev-debug.h: * lib/ev-file-helpers.c: * lib/ev-file-helpers.h: * lib/ev-gui.c: * lib/ev-gui.h: * lib/ev-tooltip.c: * lib/ev-tooltip.h: * libdocument/Makefile.am: * libdocument/ev-file-helpers.c: * pdf/Makefile.am: * pdf/ev-poppler.cc: * pdf/ev-poppler.h: * pixbuf/Makefile.am: * pixbuf/pixbuf-document.c: * pixbuf/pixbuf-document.h: * properties/Makefile.am: * ps/Makefile.am: * ps/gsdefaults.c: * ps/gsdefaults.h: * ps/gsio.c: * ps/gsio.h: * ps/gstypes.h: * ps/ps-document.c: * ps/ps-document.h: * ps/ps.c: * ps/ps.h: * shell/Makefile.am: * shell/ev-application.h: * shell/ev-sidebar-links.c: * shell/ev-sidebar-links.h: * shell/ev-utils.c: (ev_gui_sanitise_popup_position), (ev_gui_menu_position_tree_selection): * shell/ev-utils.h: * shell/ev-view.c: (ev_view_finalize): * shell/ev-window.c: * shell/main.c: (main): * thumbnailer/Makefile.am: * tiff/Makefile.am: * tiff/tiff-document.c: * tiff/tiff-document.h: * tiff/tiff2ps.c: * tiff/tiff2ps.h: Reorganize source tree. svn path=/trunk/; revision=2197
Diffstat (limited to 'dvi/mdvi-lib/tfmfile.c')
-rw-r--r--dvi/mdvi-lib/tfmfile.c746
1 files changed, 0 insertions, 746 deletions
diff --git a/dvi/mdvi-lib/tfmfile.c b/dvi/mdvi-lib/tfmfile.c
deleted file mode 100644
index 1ea1b13..0000000
--- a/dvi/mdvi-lib/tfmfile.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/* tfmfile.c -- readers for TFM, AFM, OTFM-0 and OTFM-1 files */
-/*
- * Copyright (C) 2000, Matias Atria
- *
- * 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdio.h> /* tex-file.h needs this */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "mdvi.h"
-#include "private.h"
-
-#ifdef WITH_AFM_FILES
-#undef TRUE
-#undef FALSE
-#include "afmparse.h"
-#endif
-
-typedef struct tfmpool {
- struct tfmpool *next;
- struct tfmpool *prev;
- char *short_name;
- int links;
- TFMInfo tfminfo;
-} TFMPool;
-
-static ListHead tfmpool = {NULL, NULL, 0};
-static DviHashTable tfmhash;
-
-#define TFM_HASH_SIZE 31
-
-#ifdef WORD_LITTLE_ENDIAN
-static inline void swap_array(Uint32 *ptr, int n)
-{
- Uint32 i;
-
- while(n-- > 0) {
- i = *ptr;
- *ptr++ = ((i & 0xff000000) >> 24)
- | ((i & 0x00ff0000) >> 8)
- | ((i & 0x0000ff00) << 8)
- | ((i & 0x000000ff) << 24);
- }
-}
-#endif
-
-#ifdef WITH_AFM_FILES
-
-static int __PROTO(ofm_load_file(const char *filename, TFMInfo *info));
-
-/* reading of AFM files */
-/* macro to convert between AFM and TFM units */
-#define AFM2TFM(x) FROUND((double)(x) * 0x100000 / 1000)
-int afm_load_file(const char *filename, TFMInfo *info)
-{
- /* the information we want is:
- * - tfmwidth
- * - width and heights
- * - character origins
- */
- FontInfo *fi = NULL;
- int status;
- CharMetricInfo *cm;
- FILE *in;
-
- in = fopen(filename, "r");
- if(in == NULL)
- return -1;
- status = afm_parse_file(in, &fi, P_GM);
- fclose(in);
-
- if(status != ok) {
- error(_("%s: Error reading AFM data\n"), filename);
- return -1;
- }
-
- /* aim high */
- info->chars = xnalloc(TFMChar, 256);
- info->loc = 256;
- info->hic = 0;
- info->design = 0xa00000; /* fake -- 10pt */
- info->checksum = 0; /* no checksum */
- info->type = DviFontAFM;
- mdvi_strncpy(info->coding, fi->gfi->encodingScheme, 63);
- mdvi_strncpy(info->family, fi->gfi->familyName, 63);
-
- /* now get the data */
- for(cm = fi->cmi; cm < fi->cmi + fi->numOfChars; cm++) {
- int code;
- TFMChar *ch;
-
- code = cm->code;
- if(code < 0 || code > 255)
- continue; /* ignore it */
- ch = &info->chars[code];
- ch->present = 1;
- if(code < info->loc)
- info->loc = code;
- if(code > info->hic)
- info->hic = code;
- ch->advance = AFM2TFM(cm->wx);
- /* this is the `leftSideBearing' */
- ch->left = AFM2TFM(cm->charBBox.llx);
- /* this is the height (ascent - descent) -- the sign is to follow
- * TeX conventions, as opposed to Adobe's ones */
- ch->depth = -AFM2TFM(cm->charBBox.lly);
- /* this is the width (rightSideBearing - leftSideBearing) */
- ch->right = AFM2TFM(cm->charBBox.urx);
- /* this is the `ascent' */
- ch->height = AFM2TFM(cm->charBBox.ury);
- }
-
- /* we don't need this anymore */
- afm_free_fontinfo(fi);
-
- /* optimize storage */
- if(info->loc > 0 || info->hic < 256) {
- memmove(&info->chars[0],
- &info->chars[info->loc],
- (info->hic - info->loc + 1) * sizeof(TFMChar));
- info->chars = mdvi_realloc(info->chars,
- (info->hic - info->loc + 1) * sizeof(TFMChar));
- }
-
- /* we're done */
- return 0;
-}
-
-#endif /* WITH_AFM_FILES */
-
-int tfm_load_file(const char *filename, TFMInfo *info)
-{
- int lf, lh, bc, ec, nw, nh, nd, ne;
- int i, n;
- Uchar *tfm;
- Uchar *ptr;
- struct stat st;
- int size;
- FILE *in;
- Int32 *cb;
- Int32 *charinfo;
- Int32 *widths;
- Int32 *heights;
- Int32 *depths;
- Uint32 checksum;
-
- in = fopen(filename, "r");
- if(in == NULL)
- return -1;
- tfm = NULL;
-
- DEBUG((DBG_FONTS, "(mt) reading TFM file `%s'\n",
- filename));
- /* We read the entire TFM file into core */
- if(fstat(fileno(in), &st) < 0)
- return -1;
- if(st.st_size == 0)
- goto bad_tfm;
-
- /* allocate a word-aligned buffer to hold the file */
- size = 4 * ROUND(st.st_size, 4);
- if(size != st.st_size)
- warning(_("Warning: TFM file `%s' has suspicious size\n"),
- filename);
- tfm = (Uchar *)mdvi_malloc(size);
- if(fread(tfm, st.st_size, 1, in) != 1)
- goto error;
- /* we don't need this anymore */
- fclose(in);
- in = NULL;
-
- /* not a checksum, but serves a similar purpose */
- checksum = 0;
-
- ptr = tfm;
- /* get the counters */
- lf = muget2(ptr);
- lh = muget2(ptr); checksum += 6 + lh;
- bc = muget2(ptr);
- ec = muget2(ptr); checksum += ec - bc + 1;
- nw = muget2(ptr); checksum += nw;
- nh = muget2(ptr); checksum += nh;
- nd = muget2(ptr); checksum += nd;
- checksum += muget2(ptr); /* skip italics correction count */
- checksum += muget2(ptr); /* skip lig/kern table size */
- checksum += muget2(ptr); /* skip kern table size */
- ne = muget2(ptr); checksum += ne;
- checksum += muget2(ptr); /* skip # of font parameters */
-
- size = ec - bc + 1;
- cb = (Int32 *)tfm; cb += 6 + lh;
- charinfo = cb; cb += size;
- widths = cb; cb += nw;
- heights = cb; cb += nh;
- depths = cb;
-
- if(widths[0] || heights[0] || depths[0] ||
- checksum != lf || bc - 1 > ec || ec > 255 || ne > 256)
- goto bad_tfm;
-
- /* from this point on, no error checking is done */
-
- /* now we're at the header */
- /* get the checksum */
- info->checksum = muget4(ptr);
- /* get the design size */
- info->design = muget4(ptr);
- /* get the coding scheme */
- if(lh > 2) {
- /* get the coding scheme */
- i = n = msget1(ptr);
- if(n < 0 || n > 39) {
- warning(_("%s: font coding scheme truncated to 40 bytes\n"),
- filename);
- n = 39;
- }
- memcpy(info->coding, ptr, n);
- info->coding[n] = 0;
- ptr += i;
- } else
- strcpy(info->coding, "FontSpecific");
- /* get the font family */
- if(lh > 12) {
- n = msget1(ptr);
- if(n > 0) {
- i = Max(n, 63);
- memcpy(info->family, ptr, i);
- info->family[i] = 0;
- } else
- strcpy(info->family, "unspecified");
- ptr += n;
- }
- /* now we don't read from `ptr' anymore */
-
- info->loc = bc;
- info->hic = ec;
- info->type = DviFontTFM;
-
- /* allocate characters */
- info->chars = xnalloc(TFMChar, size);
-
-
-#ifdef WORD_LITTLE_ENDIAN
- /* byte-swap the three arrays at once (they are consecutive in memory) */
- swap_array((Uint32 *)widths, nw + nh + nd);
-#endif
-
- /* get the relevant data */
- ptr = (Uchar *)charinfo;
- for(i = bc; i <= ec; ptr += 3, i++) {
- int ndx;
-
- ndx = (int)*ptr; ptr++;
- info->chars[i-bc].advance = widths[ndx];
- /* TFM files lack this information */
- info->chars[i-bc].left = 0;
- info->chars[i-bc].right = widths[ndx];
- info->chars[i-bc].present = (ndx != 0);
- if(ndx) {
- ndx = ((*ptr >> 4) & 0xf);
- info->chars[i-bc].height = heights[ndx];
- ndx = (*ptr & 0xf);
- info->chars[i-bc].depth = depths[ndx];
- }
- }
-
- /* free everything */
- mdvi_free(tfm);
-
- return 0;
-
-bad_tfm:
- error(_("%s: File corrupted, or not a TFM file\n"), filename);
-error:
- if(tfm) mdvi_free(tfm);
- if(in) fclose(in);
- return -1;
-}
-
-static int ofm1_load_file(FILE *in, TFMInfo *info)
-{
- int lf, lh, bc, ec, nw, nh, nd;
- int nco, ncw, npc;
- int i;
- int n;
- int size;
- Int32 *tfm;
- Int32 *widths;
- Int32 *heights;
- Int32 *depths;
- TFMChar *tch;
- TFMChar *end;
-
- lf = fuget4(in);
- lh = fuget4(in);
- bc = fuget4(in);
- ec = fuget4(in);
- nw = fuget4(in);
- nh = fuget4(in);
- nd = fuget4(in);
- fuget4(in); /* italics */
- fuget4(in); /* lig-kern */
- fuget4(in); /* kern */
- fuget4(in); /* extensible recipe */
- fuget4(in); /* parameters */
- fuget4(in); /* direction */
- nco = fuget4(in);
- ncw = fuget4(in);
- npc = fuget4(in);
-
- /* get the checksum */
- info->checksum = fuget4(in);
- /* the design size */
- info->design = fuget4(in);
- /* get the coding scheme */
- if(lh > 2) {
- /* get the coding scheme */
- i = n = fsget1(in);
- if(n < 0 || n > 39)
- n = 39;
- fread(info->coding, 39, 1, in);
- info->coding[n] = 0;
- } else
- strcpy(info->coding, "FontSpecific");
- /* get the font family */
- if(lh > 12) {
- n = fsget1(in);
- if(n > 0) {
- i = Max(n, 63);
- fread(info->family, i, 1, in);
- info->family[i] = 0;
- } else
- strcpy(info->family, "unspecified");
- }
- tfm = NULL;
-
- /* jump to the beginning of the char-info table */
- fseek(in, 4L*nco, SEEK_SET);
-
- size = ec - bc + 1;
- info->loc = bc;
- info->hic = ec;
- info->chars = xnalloc(TFMChar, size);
- end = info->chars + size;
-
- for(tch = info->chars, i = 0; i < ncw; i++) {
- TFMChar ch;
- int nr;
-
- /* in the characters we store the actual indices */
- ch.advance = fuget2(in);
- ch.height = fuget1(in);
- ch.depth = fuget1(in);
- /* skip 2nd word */
- fuget4(in);
- /* get # of repeats */
- nr = fuget2(in);
- /* skip parameters */
- fseek(in, (long)npc * 2, SEEK_CUR);
- /* if npc is odd, skip padding */
- if(npc & 1) fuget2(in);
-
- /* now repeat the character */
- while(nr-- >= 0 && tch < end)
- memcpy(tch++, &ch, sizeof(TFMChar));
- if(tch == end)
- goto bad_tfm;
- }
-
- /* I wish we were done, but we aren't */
-
- /* get the widths, heights and depths */
- size = nw + nh + nd;
- tfm = xnalloc(Int32, size);
- /* read them in one sweep */
- if(fread(tfm, 4, size, in) != size) {
- mdvi_free(tfm);
- goto bad_tfm;
- }
-
- /* byte-swap things if necessary */
-#ifdef WORD_LITTLE_ENDIAN
- swap_array((Uint32 *)tfm, size);
-#endif
- widths = tfm;
- heights = widths + nw;
- depths = heights + nh;
-
- if(widths[0] || heights[0] || depths[0])
- goto bad_tfm;
-
- /* now fix the characters */
- size = ec - bc + 1;
- for(tch = info->chars; tch < end; tch++) {
- tch->present = (tch->advance != 0);
- tch->advance = widths[tch->advance];
- tch->height = heights[tch->height];
- tch->depth = depths[tch->depth];
- tch->left = 0;
- tch->right = tch->advance;
- }
-
- /* NOW we're done */
- mdvi_free(tfm);
- return 0;
-
-bad_tfm:
- if(tfm) mdvi_free(tfm);
- return -1;
-}
-
-/* we don't read OFM files into memory, because they can potentially be large */
-static int ofm_load_file(const char *filename, TFMInfo *info)
-{
- int lf, lh, bc, ec, nw, nh, nd;
- int i, n;
- Int32 *tfm;
- Uchar *ptr;
- int size;
- FILE *in;
- Int32 *cb;
- Int32 *charinfo;
- Int32 *widths;
- Int32 *heights;
- Int32 *depths;
- Uint32 checksum;
- int olevel;
- int nwords;
-
- in = fopen(filename, "r");
- if(in == NULL)
- return -1;
-
- /* not a checksum, but serves a similar purpose */
- checksum = 0;
-
- /* get the counters */
- /* get file level */
- olevel = fsget2(in);
- if(olevel != 0)
- goto bad_tfm;
- olevel = fsget2(in);
- if(olevel != 0) {
- DEBUG((DBG_FONTS, "(mt) reading Level-1 OFM file `%s'\n",
- filename));
- /* we handle level-1 files separately */
- if(ofm1_load_file(in, info) < 0)
- goto bad_tfm;
- return 0;
- }
-
- DEBUG((DBG_FONTS, "(mt) reading Level-0 OFM file `%s'\n", filename));
- nwords = 14;
- lf = fuget4(in); checksum = nwords;
- lh = fuget4(in); checksum += lh;
- bc = fuget4(in);
- ec = fuget4(in); checksum += 2 * (ec - bc + 1);
- nw = fuget4(in); checksum += nw;
- nh = fuget4(in); checksum += nh;
- nd = fuget4(in); checksum += nd;
- checksum += fuget4(in); /* skip italics correction count */
- checksum += 2*fuget4(in); /* skip lig/kern table size */
- checksum += fuget4(in); /* skip kern table size */
- checksum += 2*fuget4(in); /* skip extensible recipe count */
- checksum += fuget4(in); /* skip # of font parameters */
-
- /* I have found several .ofm files that seem to have the
- * font-direction word missing, so we try to detect that here */
- if(checksum == lf + 1) {
- DEBUG((DBG_FONTS, "(mt) font direction missing in `%s'\n",
- filename));
- checksum--;
- nwords--;
- } else {
- /* skip font direction */
- fuget4(in);
- }
-
- if(checksum != lf || bc > ec + 1 || ec > 65535)
- goto bad_tfm;
-
- /* now we're at the header */
-
- /* get the checksum */
- info->checksum = fuget4(in);
- /* get the design size */
- info->design = fuget4(in);
-
- /* get the coding scheme */
- if(lh > 2) {
- /* get the coding scheme */
- i = n = fsget1(in);
- if(n < 0 || n > 39) {
- warning(_("%s: font coding scheme truncated to 40 bytes\n"),
- filename);
- n = 39;
- }
- fread(info->coding, 39, 1, in);
- info->coding[n] = 0;
- } else
- strcpy(info->coding, "FontSpecific");
- /* get the font family */
- if(lh > 12) {
- n = fsget1(in);
- if(n > 0) {
- i = Max(n, 63);
- fread(info->family, i, 1, in);
- info->family[i] = 0;
- } else
- strcpy(info->family, "unspecified");
- }
-
- /* now skip anything else in the header */
- fseek(in, 4L*(nwords + lh), SEEK_SET);
- /* and read everything at once */
- size = 2*(ec - bc + 1) + nw + nh + nd;
- tfm = xnalloc(Int32, size * sizeof(Int32));
- if(fread(tfm, 4, size, in) != size) {
- mdvi_free(tfm);
- goto bad_tfm;
- }
- /* byte-swap all the tables at once */
-#ifdef WORD_LITTLE_ENDIAN
- swap_array((Uint32 *)tfm, size);
-#endif
- cb = tfm;
- charinfo = cb; cb += 2*(ec - bc + 1);
- widths = cb; cb += nw;
- heights = cb; cb += nh;
- depths = cb;
-
- if(widths[0] || heights[0] || depths[0]) {
- mdvi_free(tfm);
- goto bad_tfm;
- }
-
- /* from this point on, no error checking is done */
-
- /* we don't need this anymore */
- fclose(in);
-
- /* now we don't read from `ptr' anymore */
-
- info->loc = bc;
- info->hic = ec;
- info->type = DviFontTFM;
-
- /* allocate characters */
- info->chars = xnalloc(TFMChar, size);
-
- /* get the relevant data */
- ptr = (Uchar *)charinfo;
- for(i = bc; i <= ec; ptr += 4, i++) {
- int ndx;
-
- ndx = muget2(ptr);
- info->chars[i-bc].advance = widths[ndx];
- /* TFM files lack this information */
- info->chars[i-bc].left = 0;
- info->chars[i-bc].right = widths[ndx];
- info->chars[i-bc].present = (ndx != 0);
- ndx = muget1(ptr);
- info->chars[i-bc].height = heights[ndx];
- ndx = muget1(ptr);
- info->chars[i-bc].depth = depths[ndx];
- }
-
- mdvi_free(tfm);
- return 0;
-
-bad_tfm:
- error(_("%s: File corrupted, or not a TFM file\n"), filename);
- fclose(in);
- return -1;
-}
-
-char *lookup_font_metrics(const char *name, int *type)
-{
- char *file;
-
- switch(*type) {
-#ifndef WITH_AFM_FILES
- case DviFontAny:
-#endif
- case DviFontTFM:
- file = kpse_find_tfm(name);
- *type = DviFontTFM;
- break;
- case DviFontOFM: {
- file = kpse_find_ofm(name);
- /* we may have gotten a TFM back */
- if(file != NULL) {
- const char *ext = file_extension(file);
- if(ext && STREQ(ext, "tfm"))
- *type = DviFontTFM;
- }
- break;
- }
-#ifdef WITH_AFM_FILES
- case DviFontAFM:
- file = kpse_find_file(name, kpse_afm_format, 0);
- break;
- case DviFontAny:
- file = kpse_find_file(name, kpse_afm_format, 0);
- *type = DviFontAFM;
- if(file == NULL) {
- file = kpse_find_tfm(name);
- *type = DviFontTFM;
- }
- break;
-#endif
- default:
- return NULL;
- }
-
- return file;
-}
-
-/*
- * The next two functions are just wrappers for the font metric loaders,
- * and use the pool of TFM data
- */
-
-/* this is how we interpret arguments:
- * - if filename is NULL, we look for files of the given type,
- * unless type is DviFontAny, in which case we try all the
- * types we know of.
- * - if filename is not NULL, we look at `type' to decide
- * how to read the file. If type is DviFontAny, we just
- * return an error.
- */
-TFMInfo *get_font_metrics(const char *short_name, int type, const char *filename)
-{
- TFMPool *tfm = NULL;
- int status;
- char *file;
-
- if(tfmpool.count) {
- tfm = (TFMPool *)mdvi_hash_lookup(&tfmhash,
- MDVI_KEY(short_name));
- if(tfm != NULL) {
- DEBUG((DBG_FONTS, "(mt) reusing metric file `%s' (%d links)\n",
- short_name, tfm->links));
- tfm->links++;
- return &tfm->tfminfo;
- }
- }
-
- file = filename ? (char *)filename : lookup_font_metrics(short_name, &type);
- if(file == NULL)
- return NULL;
-
- tfm = xalloc(TFMPool);
- DEBUG((DBG_FONTS, "(mt) loading font metric data from `%s'\n", file, file));
- switch(type) {
- case DviFontTFM:
- status = tfm_load_file(file, &tfm->tfminfo);
- break;
- case DviFontOFM:
- status = ofm_load_file(file, &tfm->tfminfo);
- break;
-#ifdef WITH_AFM_FILES
- case DviFontAFM:
- status = afm_load_file(file, &tfm->tfminfo);
- break;
-#endif
- default:
- status = -1;
- break;
- }
- if(file != filename)
- mdvi_free(file);
- if(status < 0) {
- mdvi_free(tfm);
- return NULL;
- }
- tfm->short_name = mdvi_strdup(short_name);
-
- /* add it to the pool */
- if(tfmpool.count == 0)
- mdvi_hash_create(&tfmhash, TFM_HASH_SIZE);
- mdvi_hash_add(&tfmhash, MDVI_KEY(tfm->short_name),
- tfm, MDVI_HASH_UNCHECKED);
- listh_prepend(&tfmpool, LIST(tfm));
- tfm->links = 1;
-
- return &tfm->tfminfo;
-}
-
-void free_font_metrics(TFMInfo *info)
-{
- TFMPool *tfm;
-
- if(tfmpool.count == 0)
- return;
- /* get the entry -- can't use the hash table for this, because
- * we don't have the short name */
- for(tfm = (TFMPool *)tfmpool.head; tfm; tfm = tfm->next)
- if(info == &tfm->tfminfo)
- break;
- if(tfm == NULL)
- return;
- if(--tfm->links > 0) {
- DEBUG((DBG_FONTS, "(mt) %s not removed, still in use\n",
- tfm->short_name));
- return;
- }
- mdvi_hash_remove_ptr(&tfmhash, MDVI_KEY(tfm->short_name));
-
- DEBUG((DBG_FONTS, "(mt) removing unused TFM data for `%s'\n", tfm->short_name));
- listh_remove(&tfmpool, LIST(tfm));
- mdvi_free(tfm->short_name);
- mdvi_free(tfm->tfminfo.chars);
- mdvi_free(tfm);
-}
-
-void flush_font_metrics(void)
-{
- TFMPool *ptr;
-
- for(; (ptr = (TFMPool *)tfmpool.head); ) {
- tfmpool.head = LIST(ptr->next);
-
- mdvi_free(ptr->short_name);
- mdvi_free(ptr->tfminfo.chars);
- mdvi_free(ptr);
- }
- mdvi_hash_reset(&tfmhash, 0);
-}