Example #1
0
integer myatodim(char **s)
{
   register long w, num, den, sc ;
   register const char *q ;
   char *p ;
   int negative = 0, i ;

   p = *s ;
   if (**s == '-') {
      p++ ;
      negative = 1 ;
   }
   w = myatol(&p) ;
   if (w < 0) {
      pdftex_warn("number too large; 1000 used") ;
      w = 1000 ;
   }
   num = 0 ;
   den = 1 ;
   if (*p == '.') {
      p++ ;
      while ('0' <= *p && *p <= '9') {
         if (den <= 1000) {
            den *= 10 ;
            num = num * 10 + *p - '0' ;
         } else if (den == 10000) {
            den *= 2 ;
            num = num * 2 + (*p - '0') / 5 ;
         }
         p++ ;
      }
   }
   skip(p, ' ');
   true_dimen = false;
   if (strncmp(p, "true", strlen("true")) == 0) {
     true_dimen = true;
     p += strlen("true");
     skip(p, ' ');
   }
   for (i=0, q=scalenames; ; i++, q += 2)
      if (*q == 0) {
         pdftex_warn("expected units in %s, assuming inches.", *s);
         sc = scalevals[8] ;
         break ;
      } else if (*p == *q && p[1] == q[1]) {
         sc = scalevals[i] ;
         p += 2 ;
         break ;
      }
   w = scale(w, num, den, sc) ;
   *s = p ;
   return(negative?-w:w) ;
}
Example #2
0
void fm_read_info()
{
    if (tfm_tree == NULL)
        create_avl_trees();
    if (mitem->line == NULL)    /* nothing to do */
        return;
    mitem->lineno = 1;
    switch (mitem->type) {
    case MAPFILE:
        set_cur_file_name(mitem->line);
        if (!fm_open()) {
            pdftex_warn("cannot open font map file");
        } else {
            cur_file_name = (char *) nameoffile + 1;
            tex_printf("{%s", cur_file_name);
            while (!fm_eof()) {
                fm_scan_line();
                mitem->lineno++;
            }
            fm_close();
            tex_printf("}");
            fm_file = NULL;
        }
        break;
    case MAPLINE:
        cur_file_name = NULL;   /* makes pdftex_warn() shorter */
        fm_scan_line();
        break;
    default:
        assert(0);
    }
    mitem->line = NULL;         /* done with this line */
    cur_file_name = NULL;
    return;
}
Example #3
0
/*
 *   Convert a sequence of digits into a long; return -1 if no digits.
 *   Advance the passed pointer as well.
 */
integer myatol(char **s)
{
   register char *p ;
   register long result ;

   result = 0 ;
   p = *s ;
   while ('0' <= *p && *p <= '9') {
      if (result > 100000000)
         pdftex_warn("arithmetic overflow in parameter") ;
      result = 10 * result + *p++ - '0' ;
   }
   if (p == *s) {
      pdftex_warn("expected number in %s returning 10", *s) ;
      return 10 ;
   } else {
      *s = p ;
      return(result) ;
   }
}
Example #4
0
static long scale(long whole, long num, long den, long sf)
{
   long v ;

   v = whole * sf + num * (sf / den) ;
   if (v / sf != whole || v < 0 || v > 0x40000000L)
      pdftex_warn("arithmetic overflow in parameter") ;
   sf = sf % den ;
   v += (sf * num * 2 + den) / (2 * den) ;
   return(v) ;
}
Example #5
0
static void fix_fontmetrics(fd_entry * fd)
{
    intparm *p = (intparm *) fd->font_dim;
    if (!p[FONTBBOX1_CODE].set || !p[FONTBBOX2_CODE].set ||
        !p[FONTBBOX3_CODE].set || !p[FONTBBOX4_CODE].set) {
        pdftex_warn("font `%s' doesn't have a BoundingBox", fd->fm->ff_name);
        return;
    }
    if (!p[ASCENT_CODE].set) {
        p[ASCENT_CODE].val = p[FONTBBOX4_CODE].val;
        p[ASCENT_CODE].set = true;
    }
    if (!p[DESCENT_CODE].set) {
        p[DESCENT_CODE].val = p[FONTBBOX2_CODE].val;
        p[DESCENT_CODE].set = true;
    }
    if (!p[CAPHEIGHT_CODE].set) {
        p[CAPHEIGHT_CODE].val = p[FONTBBOX4_CODE].val;
        p[CAPHEIGHT_CODE].set = true;
    }
}
Example #6
0
void deftounicode(strnumber glyph, strnumber unistr)
{
    char buf[SMALL_BUF_SIZE], *p;
    char buf2[SMALL_BUF_SIZE], *q;
    int valid_unistr;           /* 0: invalid; 1: unicode value; 2: string */
    int i, l;
    glyph_unicode_entry *gu, t;
    void **aa;

    p = makecstring(glyph);
    assert(strlen(p) < SMALL_BUF_SIZE);
    strcpy(buf, p);             /* copy the result to buf before next call of makecstring() */
    p = makecstring(unistr);
    while (*p == ' ')
        p++;                    /* ignore leading spaces */
    l = strlen(p);
    while (l > 0 && p[l - 1] == ' ')
        l--;                    /* ignore traling spaces */
    valid_unistr = 1;           /* a unicode value is the most common case */
    for (i = 0; i < l; i++) {
        if (p[i] == ' ')
            valid_unistr = 2;   /* if a space occurs we treat this entry as a string */
        else if (!isXdigit(p[i])) {
            valid_unistr = 0;
            break;
        }
    }
    if (l == 0 || valid_unistr == 0 || strlen(buf) == 0
        || strcmp(buf, notdef) == 0) {
        pdftex_warn("ToUnicode: invalid parameter(s): `%s' => `%s'", buf, p);
        return;
    }
    if (glyph_unicode_tree == NULL) {
        glyph_unicode_tree =
            avl_create(comp_glyph_unicode_entry, NULL, &avl_xallocator);
        assert(glyph_unicode_tree != NULL);
    }
    t.name = buf;
    /* allow overriding existing entries */
    if ((gu = (glyph_unicode_entry *) avl_find(glyph_unicode_tree, &t)) != NULL) {
        if (gu->code == UNI_STRING) {
            assert(gu->unicode_seq != NULL);
            xfree(gu->unicode_seq);
        }
    } else {                    /* make new entry */
        gu = new_glyph_unicode_entry();
        gu->name = xstrdup(buf);
    }
    if (valid_unistr == 2) {    /* a string with space(s) */
        /* copy p to buf2, ignoring spaces */
        for (q = buf2; *p != 0; p++)
            if (*p != ' ')
                *q++ = *p;
        *q = 0;
        gu->code = UNI_STRING;
        gu->unicode_seq = xstrdup(buf2);
    } else {
        i = sscanf(p, "%lX", &(gu->code));
        assert(i == 1);
    }
    aa = avl_probe(glyph_unicode_tree, gu);
    assert(aa != NULL);
}
Example #7
0
integer write_tounicode(char **glyph_names, char *name)
{
    char buf[SMALL_BUF_SIZE], *p;
    static char builtin_suffix[] = "-builtin";
    short range_size[257];
    glyph_unicode_entry gtab[257];
    integer objnum;
    int i, j;
    int bfchar_count, bfrange_count, subrange_count;
    assert(strlen(name) + strlen(builtin_suffix) < SMALL_BUF_SIZE);
    if (glyph_unicode_tree == NULL) {
        pdftex_warn("no GlyphToUnicode entry has been inserted yet!");
        fixedgentounicode = 0;
        return 0;
    }
    strcpy(buf, name);
    if ((p = strrchr(buf, '.')) != NULL && strcmp(p, ".enc") == 0)
        *p = 0;                 /* strip ".enc" from encoding name */
    else
        strcat(buf, builtin_suffix);    /* ".enc" not present, this is a builtin
                                           encoding so the name is eg "cmr10-builtin" */
    objnum = pdfnewobjnum();
    pdfbegindict(objnum, 0);
    pdfbeginstream();
    pdf_printf("%%!PS-Adobe-3.0 Resource-CMap\n"
               "%%%%DocumentNeededResources: ProcSet (CIDInit)\n"
               "%%%%IncludeResource: ProcSet (CIDInit)\n"
               "%%%%BeginResource: CMap (TeX-%s-0)\n"
               "%%%%Title: (TeX-%s-0 TeX %s 0)\n"
               "%%%%Version: 1.000\n"
               "%%%%EndComments\n"
               "/CIDInit /ProcSet findresource begin\n"
               "12 dict begin\n"
               "begincmap\n"
               "/CIDSystemInfo\n"
               "<< /Registry (TeX)\n"
               "/Ordering (%s)\n"
               "/Supplement 0\n"
               ">> def\n"
               "/CMapName /TeX-%s-0 def\n"
               "/CMapType 2 def\n"
               "1 begincodespacerange\n"
               "<00> <FF>\n" "endcodespacerange\n", buf, buf, buf, buf, buf);

    /* set gtab */
    for (i = 0; i < 256; ++i) {
        gtab[i].code = UNI_UNDEF;
        set_glyph_unicode(glyph_names[i], &gtab[i]);
    }
    gtab[256].code = UNI_UNDEF;

    /* set range_size */
    for (i = 0; i < 256;) {
        if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) {
            range_size[i] = 1;  /* single entry */
            i++;
        } else if (gtab[i].code == UNI_UNDEF) {
            range_size[i] = 0;  /* no entry */
            i++;
        } else {                /* gtab[i].code >= 0 */
            j = i;
            while (i < 256 && gtab[i + 1].code >= 0 &&
                   gtab[i].code + 1 == gtab[i + 1].code)
                i++;
            /* at this point i is the last entry of the subrange */
            i++;                /* move i to the next entry */
            range_size[j] = i - j;
        }
    }

    /* calculate bfrange_count and bfchar_count */
    bfrange_count = 0;
    bfchar_count = 0;
    for (i = 0; i < 256;) {
        if (range_size[i] == 1) {
            bfchar_count++;
            i++;
        } else if (range_size[i] > 1) {
            bfrange_count++;
            i += range_size[i];
        } else
            i++;
    }

    /* write out bfrange */
    i = 0;
  write_bfrange:
    if (bfrange_count > 100)
        subrange_count = 100;
    else
        subrange_count = bfrange_count;
    bfrange_count -= subrange_count;
    pdf_printf("%i beginbfrange\n", subrange_count);
    for (j = 0; j < subrange_count; j++) {
        while (range_size[i] <= 1 && i < 256)
            i++;
        assert(i < 256);
        pdf_printf("<%02X> <%02X> <%s>\n", i, i + range_size[i] - 1,
                   utf16be_str(gtab[i].code));
        i += range_size[i];
    }
    pdf_printf("endbfrange\n");
    if (bfrange_count > 0)
        goto write_bfrange;

    /* write out bfchar */
    i = 0;
  write_bfchar:
    if (bfchar_count > 100)
        subrange_count = 100;
    else
        subrange_count = bfchar_count;
    bfchar_count -= subrange_count;
    pdf_printf("%i beginbfchar\n", subrange_count);
    for (j = 0; j < subrange_count; j++) {
        while (i < 256) {
            if (range_size[i] > 1)
                i += range_size[i];
            else if (range_size[i] == 0)
                i++;
            else                /* range_size[i] == 1 */
                break;
        }
        assert(i < 256 && gtab[i].code != UNI_UNDEF);
        if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) {
            assert(gtab[i].unicode_seq != NULL);
            pdf_printf("<%02X> <%s>\n", i, gtab[i].unicode_seq);
        } else
            pdf_printf("<%02X> <%s>\n", i, utf16be_str(gtab[i].code));
        i++;
    }
    pdf_printf("endbfchar\n");
    if (bfchar_count > 0)
        goto write_bfchar;

    /* free strings allocated by set_glyph_unicode() */
    for (i = 0; i < 256; ++i) {
        if (gtab[i].code == UNI_EXTRA_STRING)
            xfree(gtab[i].unicode_seq);
    }

    pdf_printf("endcmap\n"
               "CMapName currentdict /CMap defineresource pop\n"
               "end\n" "end\n" "%%%%EndResource\n" "%%%%EOF\n");
    pdfendstream();
    return objnum;
}
Example #8
0
static sfd_entry *read_sfd (char *sfd_name)
{
    void **aa;
    sfd_entry *sfd, tmp_sfd;
    subfont_entry *sf;
	char *ftemp = NULL;
    char buf[SMALL_BUF_SIZE], *p;
    long int i, j, k;
    int n;
    int callback_id=0;
    int file_opened=0;
    /* check whether this sfd has been read */
    tmp_sfd.name = sfd_name;
    if (sfd_tree == NULL) {
        sfd_tree = avl_create (comp_sfd_entry, NULL, &avl_xallocator);
        assert (sfd_tree != NULL);
    }
    sfd = (sfd_entry *) avl_find (sfd_tree, &tmp_sfd);
    if (sfd != NULL)
        return sfd;
    set_cur_file_name (sfd_name);
    if (sfd_buffer!=NULL) {
      xfree(sfd_buffer);
      sfd_buffer=NULL;
    }
    sfd_curbyte=0;
    sfd_size=0;

	callback_id=callback_defined(find_sfd_file_callback);
	if (callback_id>0) {
	  if(run_callback(callback_id,"S->S",cur_file_name,&ftemp)) {
		if(ftemp!=NULL&&strlen(ftemp)) {
		  if (cur_file_name)
			free(cur_file_name);
		  cur_file_name = xstrdup(ftemp);
		  free(ftemp);
		}
	  }
	}
    callback_id=callback_defined(read_sfd_file_callback);
    if (callback_id>0) {
      if(! (run_callback(callback_id,"S->bSd",cur_file_name,
		       &file_opened, &sfd_buffer,&sfd_size) &&
	    file_opened && 
	    sfd_size>0 ) ) {
	pdftex_warn ("cannot open SFD file for reading");
	cur_file_name = NULL;
	return NULL;      
      }
      sfd_read_file();
      sfd_close();
    }
    tex_printf ("{");
    tex_printf (cur_file_name);
    sfd = new_sfd_entry ();
    sfd->name = xstrdup (sfd_name);
    while (!sfd_eof ()) {
        sfd_getline (true);
        if (*sfd_line == 10)    /* empty line indicating eof */
            break;
        sf = new_subfont_entry ();
        sf->next = sfd->subfont;
        sfd->subfont = sf;
        sscanf (sfd_line, "%s %n", buf, &n);
        sf->infix = xstrdup (buf);
        p = sfd_line + n;       /* skip to the next word */
        k = 0;
      read_ranges:
        for (;;) {
            if (*p == '\\') {   /* continue on next line */
                sfd_getline (false);
                p = sfd_line;
                goto read_ranges;
            } else if (*p == 0) /* end of subfont */
                break;
            if (sscanf (p, " %li %n", &i, &n) == 0)
                pdftex_fail ("invalid token:\n%s", p);
            p += n;
            if (*p == ':') {    /* offset */
                k = i;
                p++;
            } else if (*p == '_') {     /* range */
                if (sscanf (p + 1, " %li %n", &j, &n) == 0)
                    pdftex_fail ("invalid token:\n%s", p);
                if (i > j || k + (j - i) > 255)
                    pdftex_fail ("invalid range:\n%s", p);
                while (i <= j)
                    sf->charcodes[k++] = i++;
                p += n + 1;
            } else              /* codepoint */
                sf->charcodes[k++] = i;
        }
    }
    tex_printf ("}");
    aa = avl_probe (sfd_tree, sfd);
    assert (aa != NULL);
    return sfd;
}
Example #9
0
void fm_read_info ()
{
    int callback_id;
    int file_opened = 0;
	char *ftemp = NULL;
    if (tfm_tree == NULL)
        create_avl_trees ();
    if (mitem->line == NULL)    /* nothing to do */
        return;
    mitem->lineno = 1;
    switch (mitem->type) {
    case MAPFILE:
        set_cur_file_name (mitem->line);
		if (fm_buffer!=NULL) {
		  xfree(fm_buffer);
		  fm_buffer=NULL;
		}
		fm_curbyte=0;
		fm_size=0;
		callback_id=callback_defined(find_map_file_callback);
		if (callback_id>0) {
		  if(run_callback(callback_id,"S->S",(char *)(nameoffile+1),&ftemp)) {
			if(ftemp!=NULL&&strlen(ftemp)) {
			  free(nameoffile);
			  namelength = strlen(ftemp);
			  nameoffile = xmalloc(namelength+2);
			  strcpy((char *)(nameoffile+1),ftemp);
			  free(ftemp);
			}			
		  }
		}
		callback_id=callback_defined(read_map_file_callback);
		if (callback_id>0) {
		  if(run_callback(callback_id,"S->bSd",(char *)(nameoffile+1),
						 &file_opened, &fm_buffer,&fm_size)) {
			if(file_opened) {
			  if (fm_size>0) {
				cur_file_name = (char *) nameoffile + 1;
				if (tracefilenames)
				  tex_printf ("{%s", cur_file_name);
				while (!fm_eof ()) {
				  fm_scan_line ();
				  mitem->lineno++;
				}
				if (tracefilenames)
				  tex_printf ("}");
				fm_file = NULL;
			  }
			} else {
			  pdftex_warn ("cannot open font map file");
			}
		  } else {
			pdftex_warn ("cannot open font map file");
		  }
		} else {
		  if (!fm_open ()) {
			pdftex_warn ("cannot open font map file");
		  } else {
			fm_read_file();
			cur_file_name = (char *) nameoffile + 1;
			tex_printf ("{%s", cur_file_name);
			while (!fm_eof ()) {
			  fm_scan_line ();
			  mitem->lineno++;
			}
			fm_close ();
			tex_printf ("}");
			fm_file = NULL;
		  }
		}
		break;
    case MAPLINE:
	  cur_file_name = NULL;   /* makes pdftex_warn() shorter */
	  fm_scan_line ();
	  break;
    default:
	  assert (0);
    }
    mitem->line = NULL;         /* done with this line */
    cur_file_name = NULL;
    return;
}
Example #10
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);
}
Example #11
0
int check_fm_entry(fm_entry * fm, boolean warn)
{
    int a = 0;
    assert(fm != NULL);

    if (is_fontfile(fm) && !is_included(fm)) {
        if (warn)
            pdftex_warn
                ("ambiguous entry for `%s': font file present but not included, "
                 "will be treated as font file not present", fm->tfm_name);
        xfree(fm->ff_name);
        /* do not set variable |a| as this entry will be still accepted */
    }

    /* if both ps_name and font file are missing, drop this entry */
    if (fm->ps_name == NULL && !is_fontfile(fm)) {
        if (warn)
            pdftex_warn
                ("invalid entry for `%s': both ps_name and font file missing",
                 fm->tfm_name);
        a += 1;
    }

    /* TrueType fonts cannot be reencoded without subsetting */
    if (is_truetype(fm) && is_reencoded(fm) && !is_subsetted(fm)) {
        if (warn)
            pdftex_warn
                ("invalid entry for `%s': only subsetted TrueType font can be reencoded",
                 fm->tfm_name);
        a += 2;
    }

    /* SlantFont and ExtendFont can be used only with Type1 fonts */
    if ((fm->slant != 0 || fm->extend != 0)
        && !(is_t1fontfile(fm) && is_included(fm))) {
        if (warn)
            pdftex_warn
                ("invalid entry for `%s': SlantFont/ExtendFont can be used only with embedded Type1 fonts",
                 fm->tfm_name);
        a += 4;
    }

    /* the value of SlantFont and ExtendFont must be reasonable */
    if (abs(fm->slant) > 1000) {
        if (warn)
            pdftex_warn
                ("invalid entry for `%s': too big value of SlantFont (%g)",
                 fm->tfm_name, fm->slant / 1000.0);
        a += 8;
    }
    if (abs(fm->extend) > 2000) {
        if (warn)
            pdftex_warn
                ("invalid entry for `%s': too big value of ExtendFont (%g)",
                 fm->tfm_name, fm->extend / 1000.0);
        a += 16;
    }

    /* subfonts must be used with subsetted non-reencoded TrueType fonts */
    if (fm->pid != -1 &&
        !(is_truetype(fm) && is_subsetted(fm) && !is_reencoded(fm))) {
        if (warn)
            pdftex_warn
                ("invalid entry for `%s': PidEid can be used only with subsetted non-reencoded TrueType fonts",
                 fm->tfm_name);
        a += 32;
    }

    return a;
}
Example #12
0
int avl_do_entry(fm_entry * fm, int mode)
{
    fm_entry *p;
    void *a;
    void **aa;

    /* handle tfm_name link */

    if (strcmp(fm->tfm_name, nontfm)) {
        p = (fm_entry *) avl_find(tfm_tree, fm);
        if (p != NULL) {
            switch (mode) {
            case FM_DUPIGNORE:
                pdftex_warn
                    ("fontmap entry for `%s' already exists, duplicates ignored",
                     fm->tfm_name);
                goto exit;
                break;
            case FM_REPLACE:
            case FM_DELETE:
                if (p->in_use) {
                    pdftex_warn
                        ("fontmap entry for `%s' has been used, replace/delete not allowed",
                         fm->tfm_name);
                    goto exit;
                }
                a = avl_delete(tfm_tree, p);
                assert(a != NULL);
                unset_tfmlink(p);
                if (!has_pslink(p))
                    delete_fm_entry(p);
                break;
            default:
                assert(0);
            }
        }
        if (mode != FM_DELETE) {
            aa = avl_probe(tfm_tree, fm);
            assert(aa != NULL);
            set_tfmlink(fm);
        }
    }

    /* handle ps_name link */

    if (fm->ps_name != NULL) {
        p = (fm_entry *) avl_find(ps_tree, fm);
        if (p != NULL) {
            switch (mode) {
            case FM_DUPIGNORE:
                goto exit;
                break;
            case FM_REPLACE:
            case FM_DELETE:
                if (p->in_use)
                    goto exit;
                a = avl_delete(ps_tree, p);
                assert(a != NULL);
                unset_pslink(p);
                if (!has_tfmlink(p))
                    delete_fm_entry(p);
                break;
            default:
                assert(0);
            }
        }
        if (mode != FM_DELETE && is_t1fontfile(fm) && is_included(fm)) {
            aa = avl_probe(ps_tree, fm);
            assert(aa != NULL);
            set_pslink(fm);
        }
    }
  exit:
    if (!has_tfmlink(fm) && !has_pslink(fm))    /* e. g. after FM_DELETE */
        return 1;               /* deallocation of fm_entry structure required */
    else
        return 0;
}