summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipng/tfm.c
blob: 81b89d0f7d160c909ad045126466cb80b6727442 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/* tfm.c */

/************************************************************************

  Part of the dvipng distribution

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation, either version 3 of the
  License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this program. If not, see
  <http://www.gnu.org/licenses/>.

  Copyright (C) 2002-2008 Jan-Åke Larsson

************************************************************************/

#include "dvipng.h"
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif

bool ReadTFM(struct font_entry * tfontp, char* tfmname)
{
  struct filemmap fmmap;
  struct char_entry *tcharptr;  
  unsigned char *position; 
  int lh,bc,ec,nw, c;
  dviunits* width;

  DEBUG_PRINT((DEBUG_DVI|DEBUG_FT|DEBUG_TFM),
	      ("\n  OPEN METRICS:\t'%s'", tfmname));
  if (MmapFile(tfmname,&fmmap)) return(false);
  position=(unsigned char*)fmmap.data;
  lh = UNumRead(position+2,2);
  bc = UNumRead(position+4,2);
  ec = UNumRead(position+6,2);
  nw = UNumRead(position+8,2);
  DEBUG_PRINT(DEBUG_TFM,(" %d %d %d %d",lh,bc,ec,nw));
  width=alloca(nw*sizeof(dviunits));  
  c=0;
  position=position+24+(lh+ec-bc+1)*4;
  while( c < nw ) {
    width[c] = SNumRead(position,4);
    c++;
    position += 4; 
  }
  
  /* Read char widths */
  c=bc;
  position=(unsigned char*)fmmap.data+24+lh*4;
  while(c <= ec) {
    DEBUG_PRINT(DEBUG_TFM,("\n@%ld TFM METRICS:\t", 
			   (long)position - (long)fmmap.data));
    tcharptr=xmalloc(sizeof(struct char_entry));
    tcharptr->data=NULL;
    tcharptr->tfmw=width[*position];
    DEBUG_PRINT(DEBUG_TFM,("%d [%d] %d",c,*position,tcharptr->tfmw));
    tcharptr->tfmw = (dviunits) 
      ((int64_t) tcharptr->tfmw * tfontp->s / (1 << 20));
    DEBUG_PRINT(DEBUG_TFM,(" (%d)",tcharptr->tfmw));
    if (c >= NFNTCHARS) /* Only positive for now */
      Fatal("tfm file %s exceeds char numbering limit",tfmname);
    tfontp->chr[c] = tcharptr;
    c++;
    position += 4;
  }
  UnMmapFile(&fmmap);
  return(true);
}