/* ttfr.c */
/* rename the given true type file to it fullname */
/* removes spaces from name */
/* by James S Perrin Time-stamp: <Sunday 12/11/00 13:38:09 nobody> */

/* v1.1 replaced dosman problem symbols <>":/ with . */

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

/*#define DEBUG*/

typedef struct {
  unsigned int scalarType;
  unsigned short numTables;
  unsigned short searchRange;
  unsigned short entrySelector;
  unsigned short rangeShift;
} SubTable;

typedef struct {
  unsigned int tag;
  unsigned int checkSum;
  unsigned int offset;
  unsigned int length;  
} TableDirectory;

typedef struct {
  unsigned short platformID;
  unsigned short platformSpecificID;
  unsigned short languageID;
  unsigned short nameID;
  unsigned short length;
  unsigned short offset;
} NameRecord;

typedef struct {
  unsigned short format;
  unsigned short count;
  unsigned short stringOffset;
  char *names;
} NameTable;

int main(int argc, char *argv[])
{
  int i=1, j, skip, spaces=0;
  char *tagptr, *fullname;
  FILE *fin;
  
  SubTable subTable;
  TableDirectory tableDir;
  NameTable nameTable;
  NameRecord nameRecord;

#ifdef DEBUG
  printf("sizeof(SubTable) = %d\n", sizeof(SubTable));
  printf("sizeof(TableDirectory) = %d\n", sizeof(TableDirectory));
  printf("sizeof(NameTable) = %d\n", sizeof(NameTable));
  printf("sizeof(NameRecord) = %d\n", sizeof(NameRecord));
#endif

  if(argc<2)
  {
    printf("%s <files...>\n", argv[0]);
    exit(1);
  }


	if(!strcmp(argv[1], "-s"))
	{
		spaces = 1;
		i = 2;
	}
	
  for(; i<argc; i++)
  {
    if(fin=fopen(argv[i], "rb"))
    {
      /* read subTable */
      fread(&subTable, sizeof(SubTable), 1, fin);

#ifdef DEBUG
      printf("Num of Tables %d\n", subTable.numTables);
#endif

      /* search for name table */
      for(j=0; j<subTable.numTables; j++)
      {
	fread(&tableDir, sizeof(TableDirectory), 1, fin);
	tagptr = (char *)&tableDir.tag;
	
#ifdef DEBUG
      printf("TableDir %d tag %c%c%c%c\n", j, tagptr[0], tagptr[1],tagptr[2],tagptr[3]);
#endif

	if(*(tagptr++)=='n' && *(tagptr++)=='a' &&
	   *(tagptr++)=='m' && *(tagptr++)=='e')
	  break;
      }

      /* jump to name table in file */
      fseek(fin, tableDir.offset, SEEK_SET);

      /* get name table */
      fread(&nameTable.format, sizeof(unsigned short), 1, fin); 
      fread(&nameTable.count, sizeof(unsigned short), 1, fin);
      fread(&nameTable.stringOffset, sizeof(unsigned short), 1, fin);

#ifdef DEBUG
      printf("Number of NameRecords %d\n", nameTable.count);
      printf("Strings Offset %d\n", nameTable.stringOffset);
#endif
      
      /* find full name record */
      for(j=0; j<nameTable.count; j++)
      {
	fread(&nameRecord, sizeof(NameRecord), 1, fin);
	
#ifdef DEBUG
      printf("NameRecord %d nameID %d\n", j, nameRecord.nameID);
#endif

	if(nameRecord.nameID == 4)
	  break;
      }

      /* skip remaining records */
      fseek(fin, (nameTable.count-j-1) * sizeof(NameRecord), SEEK_CUR);

      /* go get fullname string */
      fseek(fin, nameRecord.offset, SEEK_CUR);
      
      fullname = malloc(nameRecord.length+5); /* .ttf\0 */
      
#ifdef DEBUG
      printf("NameRecord %d length %d\n", j, nameRecord.length);
      printf("NameRecord %d offset %d\n", j, nameRecord.offset);
      printf("NameRecord %d platfornID %d\n", j, nameRecord.platformID);
#endif

      /* bodge 16bit unicode strings */
      if(nameRecord.platformID == 0)
	skip = 2;
      else
	skip = 1;
      
      for(j=0; j<nameRecord.length/skip; j++)
      {
	if(skip == 2) getc(fin);
	fullname[j] = (char)getc(fin);
      }
      
      fullname[j]='\0';

      /* Remove spaces */
      for(j=0; j<nameRecord.length && fullname[j] != '\0'; j++)
      {
	if(!spaces && fullname[j] == ' ')
	  strcpy(&fullname[j], &fullname[j+1]);
	
	if(fullname[j] == ':' || fullname[j] == '/' || fullname[j] == '<' || fullname[j] == '>' || fullname[j] == '"')
	  fullname[j] = '.'; 
      }

      /* add extension */
      strcat(fullname, ".ttf");

      /* rename original file */
      printf("Renaming %s to %s\n", argv[i], fullname);
      fclose(fin);
      rename(argv[i], fullname);

      /* clean up */
      free(fullname);
    }
    else
     printf("Can't open file %s\n",argv[i]);

  }

  exit(0);
}
