/* 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; }
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 && !MDVI_GLYPH_ISEMPTY(ch->grey.data) && ch->fg == dvi->curr_fg && ch->bg == dvi->curr_bg) return ch; if(ch->grey.data && !MDVI_GLYPH_ISEMPTY(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; }
static int load_font(AVFilterContext *ctx) { DrawTextContext *s = ctx->priv; int err; /* load the face, and set up the encoding, which is by default UTF-8 */ err = load_font_file(ctx, s->fontfile, 0); if (!err) return 0; #if CONFIG_LIBFONTCONFIG err = load_font_fontconfig(ctx); if (!err) return 0; #endif return err; }
static int load_font_fontconfig(AVFilterContext *ctx) { DrawTextContext *s = ctx->priv; FcConfig *fontconfig; FcPattern *pat, *best; FcResult result = FcResultMatch; FcChar8 *filename; int index; double size; int err = AVERROR(ENOENT); fontconfig = FcInitLoadConfigAndFonts(); if (!fontconfig) { av_log(ctx, AV_LOG_ERROR, "impossible to init fontconfig\n"); return AVERROR_UNKNOWN; } pat = FcNameParse(s->fontfile ? s->fontfile : (uint8_t *)(intptr_t)"default"); if (!pat) { av_log(ctx, AV_LOG_ERROR, "could not parse fontconfig pat"); return AVERROR(EINVAL); } FcPatternAddString(pat, FC_FAMILY, s->font); if (s->fontsize) FcPatternAddDouble(pat, FC_SIZE, (double)s->fontsize); FcDefaultSubstitute(pat); if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) { av_log(ctx, AV_LOG_ERROR, "could not substitue fontconfig options"); /* very unlikely */ FcPatternDestroy(pat); return AVERROR(ENOMEM); } best = FcFontMatch(fontconfig, pat, &result); FcPatternDestroy(pat); if (!best || result != FcResultMatch) { av_log(ctx, AV_LOG_ERROR, "Cannot find a valid font for the family %s\n", s->font); goto fail; } if ( FcPatternGetInteger(best, FC_INDEX, 0, &index ) != FcResultMatch || FcPatternGetDouble (best, FC_SIZE, 0, &size ) != FcResultMatch) { av_log(ctx, AV_LOG_ERROR, "impossible to find font information"); return AVERROR(EINVAL); } if (FcPatternGetString(best, FC_FILE, 0, &filename) != FcResultMatch) { av_log(ctx, AV_LOG_ERROR, "No file path for %s\n", s->font); goto fail; } av_log(ctx, AV_LOG_INFO, "Using \"%s\"\n", filename); if (!s->fontsize) s->fontsize = size + 0.5; err = load_font_file(ctx, filename, index); if (err) return err; FcConfigDestroy(fontconfig); fail: FcPatternDestroy(best); return err; }