Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/dvi/mdvi-lib/t1.c
diff options
context:
space:
mode:
Diffstat (limited to 'dvi/mdvi-lib/t1.c')
-rw-r--r--dvi/mdvi-lib/t1.c638
1 files changed, 0 insertions, 638 deletions
diff --git a/dvi/mdvi-lib/t1.c b/dvi/mdvi-lib/t1.c
deleted file mode 100644
index acbfa23..0000000
--- a/dvi/mdvi-lib/t1.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * 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
- */
-
-/*
- * Type1 font support for MDVI
- *
- * We use T1lib only as a rasterizer, not to draw glyphs.
- */
-
-#include "mdvi.h"
-
-#ifdef WITH_TYPE1_FONTS
-
-#include <stdio.h>
-#include <t1lib.h>
-#include "private.h"
-
-static int t1lib_initialized = 0;
-
-typedef struct t1info {
- struct t1info *next;
- struct t1info *prev;
- char *fontname; /* (short) name of this font */
- int t1id; /* T1lib's id for this font */
- int hasmetrics; /* have we processed this font? */
- TFMInfo *tfminfo; /* TFM data is shared */
- DviFontMapInfo mapinfo;
- DviEncoding *encoding;
-} T1Info;
-
-static void t1_font_remove __PROTO((T1Info *));
-static int t1_load_font __PROTO((DviParams *, DviFont *));
-static int t1_font_get_glyph __PROTO((DviParams *, DviFont *, int));
-static void t1_font_shrink_glyph
- __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *));
-static void t1_free_data __PROTO((DviFont *));
-static void t1_reset_font __PROTO((DviFont *));
-static char *t1_lookup_font __PROTO((const char *, Ushort *, Ushort *));
-
-/* only symbol exported by this file */
-DviFontInfo t1_font_info = {
- "Type1",
- 1, /* scaling supported by format */
- t1_load_font,
- t1_font_get_glyph,
- t1_font_shrink_glyph,
- mdvi_shrink_glyph_grey,
- t1_free_data,
- t1_reset_font,
- t1_lookup_font, /* lookup */
- kpse_type1_format,
- NULL
-};
-
-/* this seems good enough for most DVI files */
-#define T1_HASH_SIZE 31
-
-/* If these parameters change, we must delete all size information
- * in all fonts, and reset the device resolutions in T1lib */
-static int t1lib_xdpi = -1;
-static int t1lib_ydpi = -1;
-
-static ListHead t1fonts = {NULL, NULL, 0};
-static DviHashTable t1hash;
-
-/* Type1 fonts need their own `lookup' function. Here is how it works:
- * First we try to find the font by its given name. If that fails, we
- * query the font maps. A typical font map entry may contain the line
- *
- * ptmr8rn Times-Roman ".82 ExtendFont TeXBase1Encoding ReEncodeFont" <8r.enc <ptmr
- *
- * which means: If you're looking for the font `ptmr8rn' load `Times-Roman'
- * which is in `ptmr' instead, and extend it by 0.82 points, then reencode
- * it with the vector TeXBase1Encoding from the file `8r.enc'. This will
- * fail if the entry looks like this:
- *
- * ptmr8rn Times-Roman ".82 ExtendFont TeXBase1Encoding ReEncodeFont" <8r.enc
- *
- * because to deal with this we would need to be able to locate the font file
- * for the `Times-Roman' font ourselves, and that's beyond the scope of mdvi.
- * But hey, we tried hard.
- */
-char *t1_lookup_font(const char *name, Ushort *hdpi, Ushort *vdpi)
-{
- char *filename;
- char *newname;
- const char *ext;
- DviFontMapInfo info;
-
- DEBUG((DBG_TYPE1, "(t1) looking for `%s'\n", name));
-
- /* first let's try the font we were asked for */
- filename = kpse_find_file(name, kpse_type1_format, 1);
- if(filename != NULL) {
- /* we got it */
- return filename;
- }
-
- DEBUG((DBG_TYPE1, "(t1) %s: not found, querying font maps\n", name));
- /* now query the fontmap */
- if(mdvi_query_fontmap(&info, name) < 0) {
- /* it's not there either */
- return NULL;
- }
-
- /* check what we got */
- if(info.fullfile) {
- DEBUG((DBG_TYPE1, "(t1) %s: found `%s' (cached)\n",
- name, info.fullfile));
- /* this is a cached lookup */
- return mdvi_strdup(info.fullfile);
- }
-
- /* no file associated to this font? */
- if(info.fontfile == NULL)
- return info.psname ? mdvi_ps_find_font(info.psname) : NULL;
-
- /* let's extract the extension */
- ext = file_extension(info.fontfile);
- if(ext && !STREQ(ext, "pfa") && !STREQ(ext, "pfb")) {
- DEBUG((DBG_TYPE1,
- "(t1) %s: associated name `%s' is not Type1\n",
- name, info.fontfile));
- /* it's not a Type1 font */
- return NULL;
- }
-
- /* get the `base' name */
- if(ext) {
- newname = mdvi_strdup(name);
- newname[ext - info.fontfile - 1] = 0;
- } else
- newname = (char *)name; /* we don't modify this */
-
- /* look it up */
- DEBUG((DBG_TYPE1, "(t1) looking for `%s' on behalf of `%s'\n",
- newname, name));
- filename = kpse_find_file(newname, kpse_type1_format, 1);
-
- /* we don't need this anymore */
- if(newname != name)
- mdvi_free(newname);
- if(filename == NULL) {
- DEBUG((DBG_TYPE1, "(t1) %s: not found\n", name));
- return NULL;
- }
-
- DEBUG((DBG_TYPE1, "(t1) %s: found as `%s'\n", name, filename));
- /* got it! let's remember this */
- mdvi_add_fontmap_file(name, filename);
- return filename;
-}
-
-static void t1_reset_resolution(int xdpi, int ydpi)
-{
- int i;
- int nfonts;
-
- DEBUG((DBG_TYPE1, "(t1) resetting device resolution (current: (%d,%d))\n",
- t1lib_xdpi, t1lib_ydpi));
-#if T1LIB_VERSION < 5
- nfonts = T1_Get_no_fonts();
-#else
- nfonts = T1_GetNoFonts();
-#endif
-
- for(i = 0; i < nfonts; i++)
- T1_DeleteAllSizes(i);
- /* reset device resolutions */
- if(T1_SetDeviceResolutions((float)xdpi, (float)ydpi) < 0)
- warning(_("(t1) failed to reset device resolution\n"));
- else
- DEBUG((DBG_TYPE1,
- "(t1) reset successful, new resolution is (%d, %d)\n",
- xdpi, ydpi));
- t1lib_xdpi = xdpi;
- t1lib_ydpi = ydpi;
-}
-
-static void t1_reset_font(DviFont *font)
-{
- T1Info *info = (T1Info *)font->private;
-
- if(info == NULL)
- return;
- DEBUG((DBG_FONTS, "(t1) resetting font `%s'\n", font->fontname));
- /* just mark the font as not having metric info. It will be reset
- * automatically later */
- info->hasmetrics = 0;
-}
-
-static void t1_transform_font(T1Info *info)
-{
- if(!info->hasmetrics && info->encoding != NULL) {
- DEBUG((DBG_TYPE1, "(t1) %s: encoding with vector `%s'\n",
- info->fontname, info->encoding->name));
- T1_DeleteAllSizes(info->t1id);
- if(T1_ReencodeFont(info->t1id, info->encoding->vector) < 0)
- warning(_("%s: could not encode font\n"), info->fontname);
- }
- if(info->mapinfo.slant) {
- DEBUG((DBG_TYPE1, "(t1) %s: slanting by %.3f\n",
- info->fontname,
- MDVI_FMAP_SLANT(&info->mapinfo)));
- T1_SlantFont(info->t1id,
- MDVI_FMAP_SLANT(&info->mapinfo));
- }
- if(info->mapinfo.extend) {
- DEBUG((DBG_TYPE1, "(t1) %s: extending by %.3f\n",
- info->fontname,
- MDVI_FMAP_EXTEND(&info->mapinfo)));
- T1_ExtendFont(info->t1id,
- MDVI_FMAP_EXTEND(&info->mapinfo));
- }
-}
-
-/* if this function is called, we really need this font */
-static int t1_really_load_font(DviParams *params, DviFont *font, T1Info *info)
-{
- int i;
- T1Info *old;
- int t1id;
- int copied;
- int status;
-
- DEBUG((DBG_TYPE1, "(t1) really_load_font(%s)\n", info->fontname));
-
- /* if the parameters changed, reset T1lib */
- if(t1lib_xdpi != params->dpi || t1lib_ydpi != params->vdpi)
- t1_reset_resolution(params->dpi, params->vdpi);
-
- /* if we already have a T1lib id, do nothing */
- if(info->t1id != -1) {
- info->hasmetrics = 1;
- /* apply slant and extend again */
- t1_transform_font(info);
- return 0;
- }
-
- /* before we even attempt to load the font, make sure we have metric
- * data for it */
- info->tfminfo = mdvi_ps_get_metrics(info->fontname);
- if(info->tfminfo == NULL) {
- DEBUG((DBG_FONTS,
- "(t1) %s: no metric data, font ignored\n",
- info->fontname));
- goto t1_error;
- }
- /* fix this */
- font->design = info->tfminfo->design;
-
- /* check if we have a font with this name (maybe at a different size) */
- old = (T1Info *)mdvi_hash_lookup(&t1hash, (unsigned char *)info->fontname);
- if(old == info) {
- /* let's avoid confusion */
- old = NULL;
- }
- if(old && old->t1id != -1) {
- /* let's take advantage of T1lib's font sharing */
- t1id = T1_CopyFont(old->t1id);
- DEBUG((DBG_TYPE1, "(t1) %s -> %d (CopyFont)\n",
- info->fontname, t1id));
- copied = 1;
- } else {
- t1id = T1_AddFont(font->filename);
- DEBUG((DBG_TYPE1, "(t1) %s -> %d (AddFont)\n",
- info->fontname, t1id));
- copied = 0;
- }
- if(t1id < 0)
- goto t1_error;
- info->t1id = t1id;
-
- /*
- * a minor optimization: If the old font in the hash table has
- * not been loaded yet, replace it by this one, so we can use
- * CopyFont later.
- */
- if(old && old->t1id == -1) {
- DEBUG((DBG_TYPE1, "(t1) font `%s' exchanged in hash table\n",
- info->fontname));
- mdvi_hash_remove(&t1hash, (unsigned char *)old->fontname);
- mdvi_hash_add(&t1hash, (unsigned char *)info->fontname,
- info, MDVI_HASH_UNCHECKED);
- }
-
- /* now let T1lib load it */
- if(!copied && T1_LoadFont(info->t1id) < 0) {
- DEBUG((DBG_TYPE1, "(t1) T1_LoadFont(%d) failed with error %d\n",
- info->t1id, T1_errno));
- goto t1_error;
- }
- DEBUG((DBG_TYPE1, "(t1) T1_LoadFont(%d) -> Ok\n", info->t1id));
-
- /* get information from the fontmap */
- status = mdvi_query_fontmap(&info->mapinfo, info->fontname);
- if(!status && info->mapinfo.encoding)
- info->encoding = mdvi_request_encoding(info->mapinfo.encoding);
- t1_transform_font(info);
-
- i = info->tfminfo->hic - info->tfminfo->loc + 1;
- if(i != font->hic - font->loc + 1) {
- /* reset to optimal size */
- font->chars = mdvi_realloc(font->chars, i * sizeof(DviFontChar));
- }
-
- /* get the scaled characters metrics */
- get_tfm_chars(params, font, info->tfminfo, 0);
- info->hasmetrics = 1;
-
- DEBUG((DBG_TYPE1, "(t1) font `%s' really-loaded\n", info->fontname));
- return 0;
-
-t1_error:
- /* some error does not allows us to use this font. We need to reset
- * the font structure, so the font system can try to read this
- * font in a different class */
-
- /* first destroy the private data */
- t1_font_remove(info);
- /* now reset all chars -- this is the important part */
- mdvi_free(font->chars);
- font->chars = NULL;
- font->loc = font->hic = 0;
- return -1;
-}
-
-static int init_t1lib(DviParams *params)
-{
- int t1flags;
-
-#ifdef WORD_LITTLE_ENDIAN
- /* try making T1lib use bitmaps in our format, but if this
- * fails we'll convert the bitmap ourselves */
- T1_SetBitmapPad(BITMAP_BITS);
-#endif
- T1_SetDeviceResolutions((float)params->dpi, (float)params->vdpi);
- t1flags = IGNORE_CONFIGFILE|IGNORE_FONTDATABASE|T1_NO_AFM;
- if(DEBUGGING(TYPE1))
- t1flags |= LOGFILE;
- if(T1_InitLib(t1flags) == NULL)
- return (t1lib_initialized = -1);
- if(DEBUGGING(TYPE1)) {
- DEBUG((DBG_TYPE1, "T1lib debugging output saved in t1lib.log\n"));
- T1_SetLogLevel(T1LOG_DEBUG);
- }
- /* initialize our hash table, but don't allocate memory for it
- * until we use it */
- mdvi_hash_init(&t1hash);
- DEBUG((DBG_TYPE1, "(t1) t1lib %s initialized -- resolution is (%d, %d), pad is %d bits\n",
- T1_GetLibIdent(), params->dpi, params->vdpi, T1_GetBitmapPad()));
- t1lib_initialized = 1;
- t1lib_xdpi = params->dpi;
- t1lib_ydpi = params->vdpi;
- return 0;
-}
-
-static int t1_load_font(DviParams *params, DviFont *font)
-{
- T1Info *info;
- int i;
-
- if(t1lib_initialized < 0)
- return -1;
- else if(t1lib_initialized == 0 && init_t1lib(params) < 0)
- return -1;
-
- if(font->in != NULL) {
- /* we don't need this */
- fclose(font->in);
- font->in = NULL;
- }
-
- info = xalloc(T1Info);
-
- /*
- * mark the font as `unregistered' with T1lib. It will
- * be added when we actually use it
- */
- info->t1id = -1;
-
- /* add the font to our list */
- info->fontname = font->fontname;
- info->hasmetrics = 0;
- info->encoding = NULL;
- info->mapinfo.psname = NULL;
- info->mapinfo.encoding = NULL;
- info->mapinfo.fontfile = NULL;
- info->mapinfo.extend = 0;
- info->mapinfo.slant = 0;
- info->encoding = NULL;
-
- /* create the hash table if we have not done so yet */
- if(t1hash.nbucks == 0)
- mdvi_hash_create(&t1hash, T1_HASH_SIZE);
- mdvi_hash_add(&t1hash, (unsigned char *) info->fontname, info, MDVI_HASH_UNIQUE);
- listh_append(&t1fonts, LIST(info));
-
- font->private = info;
-
- /* reset everything */
- font->chars = xnalloc(DviFontChar, 256);
- font->loc = 0;
- font->hic = 255;
- for(i = 0; i < 256; i++) {
- font->chars[i].code = i;
- font->chars[i].offset = 1;
- font->chars[i].loaded = 0;
- font->chars[i].glyph.data = NULL;
- font->chars[i].shrunk.data = NULL;
- font->chars[i].grey.data = NULL;
- }
-
- return 0;
-}
-
-#define GLYPH_WIDTH(g) \
- ((g)->metrics.rightSideBearing - (g)->metrics.leftSideBearing)
-#define GLYPH_HEIGHT(g) \
- ((g)->metrics.ascent - (g)->metrics.descent)
-
-static inline BITMAP *t1_glyph_bitmap(GLYPH *glyph)
-{
- BITMAP *bm;
- int w, h;
-
- w = GLYPH_WIDTH(glyph);
- h = GLYPH_HEIGHT(glyph);
-
- if(!w || !h)
- return MDVI_GLYPH_EMPTY;
- switch(glyph->bpp << 3) {
- case 8:
- bm = bitmap_convert_lsb8((unsigned char *)glyph->bits, w, h);
- break;
- default:
- warning(_("(t1) unsupported bitmap pad size %d\n"),
- glyph->bpp);
- bm = MDVI_GLYPH_EMPTY;
- break;
- }
- return bm;
-}
-
-static void t1_font_shrink_glyph(DviContext *dvi, DviFont *font, DviFontChar *ch, DviGlyph *dest)
-{
- double size;
- GLYPH *glyph;
- T1Info *info;
- T1_TMATRIX matrix;
-
- info = (T1Info *)font->private;
- ASSERT(info != NULL);
-
- DEBUG((DBG_TYPE1, "(t1) shrinking glyph for character %d in `%s' (%d,%d)\n",
- ch->code, font->fontname, ch->width, ch->height));
- size = (double)font->scale / (dvi->params.tfm_conv * 0x100000);
- size = 72.0 * size / 72.27;
- matrix.cxx = 1.0/(double)dvi->params.hshrink;
- matrix.cyy = 1.0/(double)dvi->params.vshrink;
- matrix.cxy = 0.0;
- matrix.cyx = 0.0;
- glyph = T1_SetChar(info->t1id, ch->code, (float)size, &matrix);
-
- dest->data = t1_glyph_bitmap(glyph);
- dest->x = -glyph->metrics.leftSideBearing;
- dest->y = glyph->metrics.ascent;
- dest->w = GLYPH_WIDTH(glyph);
- dest->h = GLYPH_HEIGHT(glyph);
-
-#ifndef NODEBUG
- if(DEBUGGING(BITMAP_DATA)) {
- DEBUG((DBG_BITMAP_DATA,
- "(t1) %s: t1_shrink_glyph(%d): (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
- ch->glyph.w, ch->glyph.h, ch->glyph.x, ch->glyph.y,
- dest->w, dest->h, dest->x, dest->y));
- bitmap_print(stderr, (BITMAP *)dest->data);
- }
-#endif
- /* transform the glyph - we could do this with t1lib, but we do
- * it ourselves for now */
- font_transform_glyph(dvi->params.orientation, dest);
-}
-
-static int t1_font_get_glyph(DviParams *params, DviFont *font, int code)
-{
- T1Info *info = (T1Info *)font->private;
- GLYPH *glyph;
- DviFontChar *ch;
- double size;
- T1_TMATRIX matrix;
- int dpi;
-
- ASSERT(info != NULL);
- if(!info->hasmetrics && t1_really_load_font(params, font, info) < 0)
- return -1;
- ch = FONTCHAR(font, code);
- if(!ch || !glyph_present(ch))
- return -1;
- ch->loaded = 1;
- if(!ch->width || !ch->height) {
- ch->glyph.x = ch->x;
- ch->glyph.y = ch->y;
- ch->glyph.w = ch->width;
- ch->glyph.h = ch->height;
- ch->glyph.data = NULL;
- return 0;
- }
-
- /* load the glyph with T1lib (this is done only once for each glyph) */
-
- /* get size in TeX points (tfm_conv includes dpi and magnification) */
- size = (double)font->scale / (params->tfm_conv * 0x100000);
- /* and transform into PostScript points */
- size = 72.0 * size / 72.27;
-
- dpi = Max(font->hdpi, font->vdpi);
- /* we don't want the glyph to be cached twice (once by us, another by
- * T1lib), so we use an identity matrix to tell T1lib not to keep the
- * glyph around */
- matrix.cxx = (double)font->hdpi / dpi;
- matrix.cyy = (double)font->vdpi / dpi;
- matrix.cxy = matrix.cyx = 0.0;
- glyph = T1_SetChar(info->t1id, ch->code, (float)size, &matrix);
- if(glyph == NULL) {
- ch->glyph.x = ch->x;
- ch->glyph.y = ch->y;
- ch->glyph.w = ch->width;
- ch->glyph.h = ch->height;
- ch->glyph.data = NULL;
- ch->missing = 1;
- return 0;
- }
- /* and make it a bitmap */
- ch->glyph.data = t1_glyph_bitmap(glyph);
- ch->glyph.x = -glyph->metrics.leftSideBearing;
- ch->glyph.y = glyph->metrics.ascent;
- ch->glyph.w = GLYPH_WIDTH(glyph);
- ch->glyph.h = GLYPH_HEIGHT(glyph);
-
- /* let's also fix the glyph's origin
- * (which is not contained in the TFM) */
- ch->x = ch->glyph.x;
- ch->y = ch->glyph.y;
- /* let's fix these too */
- ch->width = ch->glyph.w;
- ch->height = ch->glyph.h;
-
- return 0;
-}
-
-static void t1_font_remove(T1Info *info)
-{
- T1Info *old;
-
- /* first remove it from our list */
- listh_remove(&t1fonts, LIST(info));
-
- /* it it's in the hash table, we may need to replace this by another font */
- old = (T1Info *)mdvi_hash_lookup(&t1hash, (unsigned char *)info->fontname);
- if(old == info) {
- mdvi_hash_remove(&t1hash, (unsigned char *) info->fontname);
- /* go through the list and see if there is another
- * font with this name */
- for(old = (T1Info *)t1fonts.head; old; old = old->next)
- if(STREQ(old->fontname, info->fontname))
- break;
- if(old != NULL)
- mdvi_hash_add(&t1hash, (unsigned char *) old->fontname, old,
- MDVI_HASH_UNCHECKED);
- }
- /* release our encoding vector */
- if(info->encoding) {
- DEBUG((DBG_TYPE1, "(t1) %s: releasing vector `%s'\n",
- info->fontname, info->encoding->name));
- mdvi_release_encoding(info->encoding, 1);
- }
-
- /* now get rid of it */
- if(info->t1id != -1) {
- DEBUG((DBG_TYPE1, "(t1) %s: T1_DeleteFont(%d)\n",
- info->fontname, info->t1id));
- T1_DeleteFont(info->t1id);
- } else
- DEBUG((DBG_TYPE1, "(t1) %s: not loaded yet, DeleteFont skipped\n",
- info->fontname));
-
- if(info->tfminfo)
- free_font_metrics(info->tfminfo);
- /*mdvi_free(info->fontname);*/
- mdvi_free(info);
-}
-
-static void t1_free_data(DviFont *font)
-{
- /* called after all the glyphs are destroyed */
-
- if(font->private == NULL) {
- /* this is perfectly normal, it just means the font has
- * not been requested by MDVI yet */
- return;
- }
-
- /* destroy this data */
-
- t1_font_remove((T1Info *)font->private);
- font->private = NULL;
-
- /*
- * if this is the last T1 font, reset the T1 library
- * It is important that we do this, because this is will be called
- * when the resolution or the magnification changes.
- */
- if(t1fonts.count == 0) {
- DEBUG((DBG_TYPE1, "(t1) last font removed -- closing T1lib\n"));
- T1_CloseLib();
- t1lib_initialized = 0;
- t1lib_xdpi = -1;
- t1lib_ydpi = -1;
- }
-}
-
-#endif /* WITH_TYPE1_FONTS */