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)); }
/* 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; }
int mdvi_unregister_special(const char *prefix) { DviSpecial *sp; sp = find_special_prefix(prefix); if(sp == NULL) return -1; mdvi_free(sp->prefix); #ifdef WITH_REGEX_SPECIALS if(sp->has_reg) regfree(&sp->reg); #endif listh_remove(&specials, LIST(sp)); mdvi_free(sp); return 0; }
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; }