Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/dvi/mdvi-lib/font.c
diff options
context:
space:
mode:
Diffstat (limited to 'dvi/mdvi-lib/font.c')
-rw-r--r--dvi/mdvi-lib/font.c516
1 files changed, 0 insertions, 516 deletions
diff --git a/dvi/mdvi-lib/font.c b/dvi/mdvi-lib/font.c
deleted file mode 100644
index fedb7e7..0000000
--- a/dvi/mdvi-lib/font.c
+++ /dev/null
@@ -1,516 +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
- */
-
-#include <stdlib.h>
-
-#include "mdvi.h"
-#include "private.h"
-
-static ListHead fontlist;
-
-extern char *_mdvi_fallback_font;
-
-extern void vf_free_macros(DviFont *);
-
-#define finfo search.info
-#define TYPENAME(font) \
- ((font)->finfo ? (font)->finfo->name : "none")
-
-int font_reopen(DviFont *font)
-{
- if(font->in)
- fseek(font->in, (long)0, SEEK_SET);
- else if((font->in = fopen(font->filename, "r")) == NULL) {
- DEBUG((DBG_FILES, "reopen(%s) -> Error\n", font->filename));
- return -1;
- }
- DEBUG((DBG_FILES, "reopen(%s) -> Ok.\n", font->filename));
- return 0;
-}
-
-/* used from context: params and device */
-static int load_font_file(DviParams *params, DviFont *font)
-{
- int status;
-
- if(SEARCH_DONE(font->search))
- return -1;
- if(font->in == NULL && font_reopen(font) < 0)
- return -1;
- DEBUG((DBG_FONTS, "%s: loading %s font from `%s'\n",
- font->fontname,
- font->finfo->name, font->filename));
- do {
- status = font->finfo->load(params, font);
- } while(status < 0 && mdvi_font_retry(params, font) == 0);
- if(status < 0)
- return -1;
- if(font->in) {
- fclose(font->in);
- font->in = NULL;
- }
- DEBUG((DBG_FONTS, "reload_font(%s) -> %s\n",
- font->fontname, status < 0 ? "Error" : "Ok"));
- return 0;
-}
-
-void font_drop_one(DviFontRef *ref)
-{
- DviFont *font;
-
- font = ref->ref;
- mdvi_free(ref);
- /* drop all children */
- for(ref = font->subfonts; ref; ref = ref->next) {
- /* just adjust the reference counts */
- ref->ref->links--;
- }
- if(--font->links == 0) {
- /*
- * this font doesn't have any more references, but
- * we still keep it around in case a virtual font
- * requests it.
- */
- if(font->in) {
- fclose(font->in);
- font->in = NULL;
- }
- if(LIST(font) != fontlist.tail) {
- /* move it to the end of the list */
- listh_remove(&fontlist, LIST(font));
- listh_append(&fontlist, LIST(font));
- }
- }
- DEBUG((DBG_FONTS, "%s: reference dropped, %d more left\n",
- font->fontname, font->links));
-}
-
-void font_drop_chain(DviFontRef *head)
-{
- DviFontRef *ptr;
-
- for(; (ptr = head); ) {
- head = ptr->next;
- font_drop_one(ptr);
- }
-}
-
-int font_free_unused(DviDevice *dev)
-{
- DviFont *font, *next;
- int count = 0;
-
- DEBUG((DBG_FONTS, "destroying unused fonts\n"));
- for(font = (DviFont *)fontlist.head; font; font = next) {
- DviFontRef *ref;
-
- next = font->next;
- if(font->links)
- continue;
- count++;
- DEBUG((DBG_FONTS, "removing unused %s font `%s'\n",
- TYPENAME(font), font->fontname));
- listh_remove(&fontlist, LIST(font));
- if(font->in)
- fclose(font->in);
- /* get rid of subfonts (but can't use `drop_chain' here) */
- for(; (ref = font->subfonts); ) {
- font->subfonts = ref->next;
- mdvi_free(ref);
- }
- /* remove this font */
- font_reset_font_glyphs(dev, font, MDVI_FONTSEL_GLYPH);
- /* let the font destroy its private data */
- if(font->finfo->freedata)
- font->finfo->freedata(font);
- /* destroy characters */
- if(font->chars)
- mdvi_free(font->chars);
- mdvi_free(font->fontname);
- mdvi_free(font->filename);
- mdvi_free(font);
- }
- DEBUG((DBG_FONTS, "%d unused fonts removed\n", count));
- return count;
-}
-
-/* used from context: params and device */
-DviFontRef *
-font_reference(
- DviParams *params, /* rendering parameters */
- Int32 id, /* external id number */
- const char *name, /* font name */
- Int32 sum, /* checksum (from DVI of VF) */
- int hdpi, /* resolution */
- int vdpi,
- Int32 scale) /* scaling factor (from DVI or VF) */
-{
- DviFont *font;
- DviFontRef *ref;
- DviFontRef *subfont_ref;
-
- /* see if there is a font with the same characteristics */
- for(font = (DviFont *)fontlist.head; font; font = font->next) {
- if(strcmp(name, font->fontname) == 0
- && (!sum || !font->checksum || font->checksum == sum)
- && font->hdpi == hdpi
- && font->vdpi == vdpi
- && font->scale == scale)
- break;
- }
- /* try to load the font */
- if(font == NULL) {
- font = mdvi_add_font(name, sum, hdpi, vdpi, scale);
- if(font == NULL)
- return NULL;
- listh_append(&fontlist, LIST(font));
- }
- if(!font->links && !font->chars && load_font_file(params, font) < 0) {
- DEBUG((DBG_FONTS, "font_reference(%s) -> Error\n", name));
- return NULL;
- }
- ref = xalloc(DviFontRef);
- ref->ref = font;
-
- font->links++;
- for(subfont_ref = font->subfonts; subfont_ref; subfont_ref = subfont_ref->next) {
- /* just adjust the reference counts */
- subfont_ref->ref->links++;
- }
-
- ref->fontid = id;
-
- if(LIST(font) != fontlist.head) {
- listh_remove(&fontlist, LIST(font));
- listh_prepend(&fontlist, LIST(font));
- }
-
- DEBUG((DBG_FONTS, "font_reference(%s) -> %d links\n",
- font->fontname, font->links));
- return ref;
-}
-
-void font_transform_glyph(DviOrientation orient, DviGlyph *g)
-{
- BITMAP *map;
- int x, y;
-
- map = (BITMAP *)g->data;
- if(MDVI_GLYPH_ISEMPTY(map))
- map = NULL;
-
- /* put the glyph in the right orientation */
- switch(orient) {
- case MDVI_ORIENT_TBLR:
- break;
- case MDVI_ORIENT_TBRL:
- g->x = g->w - g->x;
- if(map) bitmap_flip_horizontally(map);
- break;
- case MDVI_ORIENT_BTLR:
- g->y = g->h - g->y;
- if(map) bitmap_flip_vertically(map);
- break;
- case MDVI_ORIENT_BTRL:
- g->x = g->w - g->x;
- g->y = g->h - g->y;
- if(map) bitmap_flip_diagonally(map);
- break;
- case MDVI_ORIENT_RP90:
- if(map) bitmap_rotate_counter_clockwise(map);
- y = g->y;
- x = g->w - g->x;
- g->x = y;
- g->y = x;
- SWAPINT(g->w, g->h);
- break;
- case MDVI_ORIENT_RM90:
- if(map) bitmap_rotate_clockwise(map);
- y = g->h - g->y;
- x = g->x;
- g->x = y;
- g->y = x;
- SWAPINT(g->w, g->h);
- break;
- case MDVI_ORIENT_IRP90:
- if(map) bitmap_flip_rotate_counter_clockwise(map);
- y = g->y;
- x = g->x;
- g->x = y;
- g->y = x;
- SWAPINT(g->w, g->h);
- break;
- case MDVI_ORIENT_IRM90:
- if(map) bitmap_flip_rotate_clockwise(map);
- y = g->h - g->y;
- x = g->w - g->x;
- g->x = y;
- g->y = x;
- SWAPINT(g->w, g->h);
- break;
- }
-}
-
-static int load_one_glyph(DviContext *dvi, DviFont *font, int code)
-{
- BITMAP *map;
- DviFontChar *ch;
- int status;
-
-#ifndef NODEBUG
- ch = FONTCHAR(font, code);
- DEBUG((DBG_GLYPHS, "loading glyph code %d in %s (at %u)\n",
- code, font->fontname, ch->offset));
-#endif
- if(font->finfo->getglyph == NULL) {
- /* font type does not need to load glyphs (e.g. vf) */
- return 0;
- }
-
- status = font->finfo->getglyph(&dvi->params, font, code);
- if(status < 0)
- return -1;
- /* get the glyph again (font->chars may have changed) */
- ch = FONTCHAR(font, code);
-#ifndef NODEBUG
- map = (BITMAP *)ch->glyph.data;
- if(DEBUGGING(BITMAP_DATA)) {
- DEBUG((DBG_BITMAP_DATA,
- "%s: new %s bitmap for character %d:\n",
- font->fontname, TYPENAME(font), code));
- if(MDVI_GLYPH_ISEMPTY(map))
- DEBUG((DBG_BITMAP_DATA, "blank bitmap\n"));
- else
- bitmap_print(stderr, map);
- }
-#endif
- /* check if we have to scale it */
- if(!font->finfo->scalable && font->hdpi != font->vdpi) {
- int hs, vs, d;
-
- /* we scale it ourselves */
- d = Max(font->hdpi, font->vdpi);
- hs = d / font->hdpi;
- vs = d / font->vdpi;
- if(ch->width && ch->height && (hs > 1 || vs > 1)) {
- int h, v;
- DviGlyph glyph;
-
- DEBUG((DBG_FONTS,
- "%s: scaling glyph %d to resolution %dx%d\n",
- font->fontname, code, font->hdpi, font->vdpi));
- h = dvi->params.hshrink;
- v = dvi->params.vshrink;
- d = dvi->params.density;
- dvi->params.hshrink = hs;
- dvi->params.vshrink = vs;
- dvi->params.density = 50;
- /* shrink it */
- font->finfo->shrink0(dvi, font, ch, &glyph);
- /* restore parameters */
- dvi->params.hshrink = h;
- dvi->params.vshrink = v;
- dvi->params.density = d;
- /* update glyph data */
- if(!MDVI_GLYPH_ISEMPTY(ch->glyph.data))
- bitmap_destroy((BITMAP *)ch->glyph.data);
- ch->glyph.data = glyph.data;
- ch->glyph.x = glyph.x;
- ch->glyph.y = glyph.y;
- ch->glyph.w = glyph.w;
- ch->glyph.h = glyph.h;
- }
-
- }
- font_transform_glyph(dvi->params.orientation, &ch->glyph);
-
- return 0;
-}
-
-DviFontChar *font_get_glyph(DviContext *dvi, DviFont *font, int code)
-{
- DviFontChar *ch;
-
-again:
- /* if we have not loaded the font yet, do so now */
- if(!font->chars && load_font_file(&dvi->params, font) < 0)
- return NULL;
-
- /* get the unscaled glyph, maybe loading it from disk */
- ch = FONTCHAR(font, code);
- if(!ch || !glyph_present(ch))
- return NULL;
- if(!ch->loaded && load_one_glyph(dvi, font, code) == -1) {
- if(font->chars == NULL) {
- /* we need to try another font class */
- goto again;
- }
- return NULL;
- }
- /* yes, we have to do this again */
- ch = FONTCHAR(font, code);
-
- /* Got the glyph. If we also have the right scaled glyph, do no more */
- if(!ch->width || !ch->height ||
- font->finfo->getglyph == NULL ||
- (dvi->params.hshrink == 1 && dvi->params.vshrink == 1))
- return ch;
-
- /* If the glyph is empty, we just need to shrink the box */
- if(ch->missing || MDVI_GLYPH_ISEMPTY(ch->glyph.data)) {
- if(MDVI_GLYPH_UNSET(ch->shrunk.data))
- mdvi_shrink_box(dvi, font, ch, &ch->shrunk);
- return ch;
- } else if(MDVI_ENABLED(dvi, MDVI_PARAM_ANTIALIASED)) {
- if(ch->grey.data &&
- ch->fg == dvi->curr_fg &&
- ch->bg == dvi->curr_bg)
- return ch;
- if(ch->grey.data) {
- if(dvi->device.free_image)
- dvi->device.free_image(ch->grey.data);
- ch->grey.data = NULL;
- }
- font->finfo->shrink1(dvi, font, ch, &ch->grey);
- } else if(!ch->shrunk.data)
- font->finfo->shrink0(dvi, font, ch, &ch->shrunk);
-
- return ch;
-}
-
-void font_reset_one_glyph(DviDevice *dev, DviFontChar *ch, int what)
-{
- if(!glyph_present(ch))
- return;
- if(what & MDVI_FONTSEL_BITMAP) {
- if(MDVI_GLYPH_NONEMPTY(ch->shrunk.data))
- bitmap_destroy((BITMAP *)ch->shrunk.data);
- ch->shrunk.data = NULL;
- }
- if(what & MDVI_FONTSEL_GREY) {
- if(MDVI_GLYPH_NONEMPTY(ch->grey.data)) {
- if(dev->free_image)
- dev->free_image(ch->grey.data);
- }
- ch->grey.data = NULL;
- }
- if(what & MDVI_FONTSEL_GLYPH) {
- if(MDVI_GLYPH_NONEMPTY(ch->glyph.data))
- bitmap_destroy((BITMAP *)ch->glyph.data);
- ch->glyph.data = NULL;
- ch->loaded = 0;
- }
-}
-
-void font_reset_font_glyphs(DviDevice *dev, DviFont *font, int what)
-{
- int i;
- DviFontChar *ch;
-
- if(what & MDVI_FONTSEL_GLYPH)
- what |= MDVI_FONTSEL_BITMAP|MDVI_FONTSEL_GREY;
- if(font->subfonts) {
- DviFontRef *ref;
-
- for(ref = font->subfonts; ref; ref = ref->next)
- font_reset_font_glyphs(dev, ref->ref, what);
- }
- if(font->in) {
- DEBUG((DBG_FILES, "close(%s)\n", font->filename));
- fclose(font->in);
- font->in = NULL;
- }
- if(font->finfo->getglyph == NULL)
- return;
- DEBUG((DBG_FONTS, "resetting glyphs in font `%s'\n", font->fontname));
- for(ch = font->chars, i = font->loc; i <= font->hic; ch++, i++) {
- if(glyph_present(ch))
- font_reset_one_glyph(dev, ch, what);
- }
- if((what & MDVI_FONTSEL_GLYPH) && font->finfo->reset)
- font->finfo->reset(font);
-}
-
-void font_reset_chain_glyphs(DviDevice *dev, DviFontRef *head, int what)
-{
- DviFontRef *ref;
-
- for(ref = head; ref; ref = ref->next)
- font_reset_font_glyphs(dev, ref->ref, what);
-}
-
-static int compare_refs(const void *p1, const void *p2)
-{
- return ((*(DviFontRef **)p1)->fontid - (*(DviFontRef **)p2)->fontid);
-}
-
-void font_finish_definitions(DviContext *dvi)
-{
- int count;
- DviFontRef **map, *ref;
-
- /* first get rid of unused fonts */
- font_free_unused(&dvi->device);
-
- if(dvi->fonts == NULL) {
- warning(_("%s: no fonts defined\n"), dvi->filename);
- return;
- }
- map = xnalloc(DviFontRef *, dvi->nfonts);
- for(count = 0, ref = dvi->fonts; ref; ref = ref->next)
- map[count++] = ref;
- /* sort the array by font id */
- qsort(map, dvi->nfonts, sizeof(DviFontRef *), compare_refs);
- dvi->fontmap = map;
-}
-
-DviFontRef *font_find_flat(DviContext *dvi, Int32 id)
-{
- DviFontRef *ref;
-
- for(ref = dvi->fonts; ref; ref = ref->next)
- if(ref->fontid == id)
- break;
- return ref;
-}
-
-DviFontRef *font_find_mapped(DviContext *dvi, Int32 id)
-{
- int lo, hi, n;
- DviFontRef **map;
-
- /* do a binary search */
- lo = 0; hi = dvi->nfonts;
- map = dvi->fontmap;
- while(lo < hi) {
- int sign;
-
- n = (hi + lo) >> 1;
- sign = (map[n]->fontid - id);
- if(sign == 0)
- break;
- else if(sign < 0)
- lo = n;
- else
- hi = n;
- }
- if(lo >= hi)
- return NULL;
- return map[n];
-}
-