예제 #1
0
/* 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;
}
예제 #2
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 && 
           !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;
}
예제 #3
0
파일: vf_drawtext.c 프로젝트: mark4o/FFmpeg
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;
}
예제 #4
0
파일: vf_drawtext.c 프로젝트: mark4o/FFmpeg
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;
}