Esempio n. 1
0
boolean handle_subfont_fm(fm_entry * fm, int mode)
{
    size_t l;
    char *p, *q, *r;
    sfd_entry *sfd;
    subfont_entry *sf;
    fm_entry *fm2;
    char buf[SMALL_BUF_SIZE];
    assert(fm->tfm_name != NULL);

    p = fm->tfm_name;
    q = strchr(p, '@');         /* search for the first '@' */
    if (q == NULL)
        return false;
    r = strchr(q + 1, '@');     /* search for the second '@' */
    if (r == NULL)
        return false;
    if (q <= p || r <= q + 1    /* prefix or sfd name is empty */
        || r - p != strlen(p) - 1)      /* or the second '@' is not the last char yet */
        return false;
    l = r - (q + 1);            /* length of sfd name */
    strncpy(buf, q + 1, l);
    buf[l] = 0;
    check_buf(strlen(buf) + 4, SMALL_BUF_SIZE);
    strcat(buf, ".sfd");
    sfd = read_sfd(buf);
    if (sfd == NULL)
        return false;

    /* at this point we know fm is a subfont */
    set_subfont(fm);
    xfree(fm->ps_name);
    fm->ps_name = NULL;
    /* set default values for PidEid */
    if (fm->pid == -1) {
        fm->pid = 3;
        fm->eid = 1;
    }
    l = q - p;                  /* length of base tfm name (prefix) */
    for (sf = sfd->subfont; sf != NULL; sf = sf->next) {
        strncpy(buf, p, l);
        buf[l] = 0;
        strcat(buf, sf->infix);
        fm2 = new_fm_entry();
        fm2->tfm_name = xstrdup(buf);
        fm2->ff_name = xstrdup(fm->ff_name);
        fm2->type = fm->type;
        fm2->pid = fm->pid;
        fm2->eid = fm->eid;
        fm2->subfont = sf;
        if (avl_do_entry(fm2, mode) != 0)       /* try to insert the entry */
            delete_fm_entry(fm2);       /* delete it if failed */
    }
    delete_fm_entry(fm);
    return true;
}
Esempio n. 2
0
static void fm_scan_line()
{
    int a, b, c, j, u = 0, v = 0;
    float d;
    fm_entry *fm;
    char fm_line[FM_BUF_SIZE], buf[FM_BUF_SIZE];
    char *p, *q, *r, *s;
    switch (mitem->type) {
    case MAPFILE:
        p = fm_line;
        do {
	  c = fm_getchar();
	  append_char_to_buf(c, p, fm_line, FM_BUF_SIZE);
        }
        while (c != 10 && !fm_eof());
        *(--p) = '\0';
        r = fm_line;
        break;
    case MAPLINE:
        r = mitem->line;        /* work on string from makecstring() */
        break;
    default:
        assert(0);
    }
    if (*r == '\0' || is_cfg_comment(*r))
        return;
    fm = new_fm_entry();
    read_field(r, q, buf);
    set_field(tfm_name);
    if (!isdigit(*r)) {         /* 2nd field ps_name may not start with a digit */
        read_field(r, q, buf);
        set_field(ps_name);
    }
    if (isdigit(*r)) {          /* font descriptor /Flags given? */
        for (s = r; isdigit(*s); s++);
        if (*s == ' ' || *s == '"' || *s == '<' || *s == '\0') {        /* not e. g. 8r.enc */
            fm->fd_flags = atoi(r);
            while (isdigit(*r))
                r++;
        }
    }
    while (1) {                 /* loop through "specials", encoding, font file */
        skip(r, ' ');
        switch (*r) {
        case '\0':
            goto done;
        case '"':              /* opening quote */
            r++;
            u = v = 0;
            do {
                skip(r, ' ');
                if (sscanf(r, "%f %n", &d, &j) > 0) {
                    s = r + j;  /* jump behind number, eat also blanks, if any */
                    if (*(s - 1) == 'E' || *(s - 1) == 'e')
                        s--;    /* e. g. 0.5ExtendFont: %f = 0.5E */
                    if (str_prefix(s, "SlantFont")) {
                        d *= 1000.0;    /* correct rounding also for neg. numbers */
                        fm->slant = (integer) (d > 0 ? d + 0.5 : d - 0.5);
                        r = s + strlen("SlantFont");
                    } else if (str_prefix(s, "ExtendFont")) {
                        d *= 1000.0;
                        fm->extend = (integer) (d > 0 ? d + 0.5 : d - 0.5);
                        if (fm->extend == 1000)
                            fm->extend = 0;
                        r = s + strlen("ExtendFont");
                    } else {    /* unknown name */
                        for (r = s; *r != ' ' && *r != '"' && *r != '\0'; r++); /* jump over name */
                        c = *r; /* remember char for temporary end of string */
                        *r = '\0';
                        pdftex_warn
                            ("invalid entry for `%s': unknown name `%s' ignored",
                             fm->tfm_name, s);
                        *r = c;
                    }
                } else
                    for (; *r != ' ' && *r != '"' && *r != '\0'; r++);
            }
            while (*r == ' ');
            if (*r == '"')      /* closing quote */
                r++;
            else {
                pdftex_warn
                    ("invalid entry for `%s': closing quote missing",
                     fm->tfm_name);
                goto bad_line;
            }
            break;
        case 'P':              /* handle cases for subfonts like 'PidEid=3,1' */
            if (sscanf(r, "PidEid=%i, %i %n", &a, &b, &c) >= 2) {
                fm->pid = a;
                fm->eid = b;
                r += c;
                break;
            }
        default:               /* encoding or font file specification */
            a = b = 0;
            if (*r == '<') {
                a = *r++;
                if (*r == '<' || *r == '[')
                    b = *r++;
            }
            read_field(r, q, buf);
            /* encoding, formats: '8r.enc' or '<8r.enc' or '<[8r.enc' */
            if (strlen(buf) > 4 && strcasecmp(strend(buf) - 4, ".enc") == 0) {
                fm->encname = add_encname(buf);
                u = v = 0;      /* u, v used if intervening blank: "<< foo" */
            } else if (strlen(buf) > 0) {       /* file name given */
                /* font file, formats:
                 * subsetting:    '<cmr10.pfa'
                 * no subsetting: '<<cmr10.pfa'
                 * no embedding:  'cmr10.pfa'
                 */
                if (a == '<' || u == '<') {
                    set_included(fm);
                    if ((a == '<' && b == 0) || (a == 0 && v == 0))
                        set_subsetted(fm);
                    /* otherwise b == '<' (or '[') => no subsetting */
                }
                set_field(ff_name);
                u = v = 0;
            } else {
                u = a;
                v = b;
            }
        }
    }
  done:
    if (fm->ps_name != NULL && check_std_t1font(fm->ps_name))
        set_std_t1font(fm);
    if (is_fontfile(fm)) {
        if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".ttf") == 0)
            set_truetype(fm);
        else if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".otf") == 0)
            set_opentype(fm);
        else
            set_type1(fm);
    } else
        set_type1(fm);          /* assume a builtin font is Type1 */
    if (check_fm_entry(fm, true) != 0)
        goto bad_line;
    /*
       Until here the map line has been completely scanned without errors;
       fm points to a valid, freshly filled-out fm_entry structure.
       Now follows the actual work of registering/deleting.
     */
    if (handle_subfont_fm(fm, mitem->mode))     /* is this a subfont? */
        return;
    if (avl_do_entry(fm, mitem->mode) == 0)     /* if success */
        return;
  bad_line:
    delete_fm_entry(fm);
}