"""Font metrics base class.

This module provides the interface for accurate font metrics generated
from the Adobe AFM files.  The generation script is a simple C program
that uses Adobe's AFM conversion library parseAFM.c, available from
ftp.adobe.com.  You can get Adobe's AFM files from the same ftp site.
See the comments at the tail of this file for the little C wrapper I
wrote to generate the PSFont_*.py files.

This module has its origins in code contributed by Fredrik Lundh
<Fredrik_Lundh@ivab.se> who contributed the framework for the Grail
0.2 release.  Thanks Fredrik!

"""

import string
import array

class PSFont:
    def __init__(self, fontname, fullname, metrics):
	self._fontname = fontname
	self._fullname = fullname
	self._metrics = metrics

    def fontname(self): return self._fontname
    def fullname(self): return self._fullname

    def text_width(self, fontsize, str):
	"""Quickly calculate the width in points of the given string
	in the current font, at the given font size.
	"""
	width = 0
	metrics = self._metrics
	for ci in map(ord, str):
	    width = width + metrics[ci]
	return width * fontsize / 1000


if __name__ == '__main__':
    import PSFont_Times_Roman
    font = PSFont_Times_Roman.font

    print 'Font Name:', font.fontname()
    print 'Full Name:', font.fullname()
    print 'Width of "Hello World" in 12.0:', \
	  font.text_width(12.0, 'Hello World')


##/* Main program to extract character width font metrics from an
## * Adobe AFM file.  This basically uses the parseAFM.h interface.
## *
## * Usage: dumpafm <afmfile>
## *
## * <afmfile> is the filename of the file to dump.  character width metrics
## * get printed to stdout, one character per line.
## */
##
###include <stdio.h>
###include "parseAFM.h"
##
###define min(a, b) ((a) < (b) ? (a) : (b))
###define PY_TRANSLATE_MAX 256
##
###define FORMAT "%4d,%s"
###define PERLINE 10
##
##void writearray(FILE* outfp, int* array, int count)
##{
##  int lim = min(PY_TRANSLATE_MAX, count);
##  int c;
##
##  for( c=0; c < lim; c++ ) {
##    char* sep = (c+1) % PERLINE ? " " : "\n ";
##    fprintf(outfp, FORMAT, array[c], sep);
##  }
##      /* the Python layer expects exactly 256 elements in the list */
##  for( ; c < PY_TRANSLATE_MAX; c++ ) {
##    char* sep = (c+1) % PERLINE ? " " : "\n ";
##    fprintf(outfp, FORMAT, 0, sep);
##  }
##}
##
##int dofile( char* infilename )
##{
##      /* N.B.: I know we're leaking FontInfo data for each file we parse.
##       * The library doesn't have a call to free the data, which is IMHO a
##       * bug, and I've looked at their sample code for freeing the
##       * structure -- it's gross.  I doubt we'll parse so many files that
##       * we'll run out of memory, so I'm not worrying about it.
##       */
##  FILE* infp = NULL;
##  FILE* outfp = NULL;
##  FontInfo* fi = NULL;
##      /* We want Global Font Info and character widths.  The Global Font
##       * Info will give us the font's full name.
##       */
##  FLAGS flags = P_GW;
##  char outfilename[1024];
##  int status;
##  int c;
##
##  if( NULL == (infp=fopen(infilename, "r")) ) {
##    fprintf(stderr, "Cannot open AFM input file: %s\n", infilename);
##    return 1;
##  }
##
##  status = parseFile(infp, &fi, flags);
##  if( status != ok ) {
##    fprintf(stderr, "Error %d occurred while parsing AFM file.", status);
##    return 1;
##  }
##
##      /* Open the file for writing based on the font name.  PostScript uses
##       * dashes in the name, but Python uses underscores in module names.
##       * Also, prefix the file name with `PSFont_'.  And yes, we should
##       * probably be safer about copying the font name into this buffer,
##       * but oh well.
##       */
##  sprintf(outfilename, "PSFont_%s.py", fi->gfi->fontName);
##  for( c=0; c < strlen(outfilename); c++ )
##    if( outfilename[c] == '-' )
##      outfilename[c] = '_';
##
##  if( NULL == (outfp=fopen(outfilename, "w")) ) {
##    fprintf(stderr, "Cannot open Python output file: %s\n", outfilename);
##    return 1;
##  }
##
##      /* dump font info to stdout, in Python format */
##  fprintf(outfp, "# Character width information for PostScript font `%s'\n",
##          fi->gfi->fullName);
##  fprintf(outfp, "# Generated by wrapper script using Adobe's parseAFM.c\n");
##  fprintf(outfp, "# library, from the Adobe font file `%s'\n", infilename);
##  fprintf(outfp, "#\n");
##  fprintf(outfp, "import PSFont\n");
##  fprintf(outfp, "font = PSFont.PSFont(");
##  fprintf(outfp, "'%s', '%s',\n", fi->gfi->fontName, fi->gfi->fullName);
##  fprintf(outfp, "[");
##  writearray(outfp, fi->cwi, fi->numOfChars);
##  fprintf(outfp, "])\n");
##
##  close(infp);
##  close(outfp);
##  return 0;
##}
##
##
##int main( int argc, char** argv )
##{
##  int argvi;
##
##  for( argvi=1; argvi < argc; argvi++ )
##    dofile(argv[argvi]);
##
##  return 0;
##}
