/*
 * disol.c
 *   --- Disassemble Vector Font Data
 *
 *  Programmed by Hirotsugu KAKUGAWA, Hiroshima University
 *  E-Mail:  kakugawa@se.hiroshima-u.ac.jp
 *
 * Edition History
 *  31 Dec 1993  
 *  20 Jan 1994  New output format
 *
 */ 

/* This file is part of VFlib
 *
 * Copyright (C) 1993,1994,1995,1996 Hirotsugu KAKUGAWA. All rights reserved.
 *
 * VFlib is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
 * to anyone for the consequences of using it or for whether it serves any
 * particular purpose or works at all, unless he says so in writing.  Refer
 * to the GNU General Public License for full details.
 *
 * Everyone is granted permission to copy, modify and redistribute
 * VFlib, but only under the conditions described in the GNU
 * General Public License.  A copy of this license is supposed to have been
 * given to you along with VFlib so you can know your rights and
 * responsibilities.  It should be in a file named COPYING.  Among other
 * things, the copyright notice and this notice must be preserved on all
 * copies.
 */


#include <stdio.h>
#include <stdlib.h>
#include <varargs.h>
#include "../src/VF.h"

#define CommentLine printf

void usage(void);
void DisVFData(long *vfdata, int fd);
void EmptyLine(void);
void PrintCCode(int n);
void PrintToken(void);
void Print(int *mp, char *str);
void Newline(void);
void PrintEnd(void);
void PrintXY(int x, int y);


int
main(argc, argv)
  int  argc;
  char **argv;
{
  int   Fd, i;
  int   CharCode, Ch, Coord;
  char  *FontName, *Vfcap;
  long  *VFData;

  FontName = "min";
  Vfcap    = NULL;
  Coord    = 0;

  Ch = argc + 2001;
  for (i = 1; i < argc; i++){
    if (argv[i][0] == '-'){
      switch (argv[i][1]){
      case 'f':
	FontName = argv[++i];
	break;
      case 'v':
	Vfcap = argv[++i];
	break;
      case 'c':
	Coord = 1;
	break;
      case 'h':
      default:
	usage();
      }
    } else {
      Ch = i;
      break;
    }
  }

  if (Ch > argc)
    usage();  /* no char codes */

  /* Init VFlib */
  if (VF_Init(Vfcap) <0){
    fprintf(stderr, "VFlib init error\n");    
    exit(1);
  }

  /* OPEN THE FONT */
  if ((Fd = VF_OpenFont(FontName)) < 0){
    fprintf(stderr, "open error; %s\n", FontName);
    exit(-1);
  }

  printf(";; OUTLINES OF FONT ENTRY %s\n\n", FontName);
  
  while (Ch < argc){
    sscanf(argv[Ch], "%x", &CharCode);
    Ch++;

    /* GET VECTOR FONT DATA */
    VFData = VF_GetOutline(CharCode, Fd);
    if (VFData == NULL){
      printf(";; CAN'T GET OUTLINE FOR CHARACTER $%x of Font %s\n",
	     CharCode, FontName);
      continue;
    }

    /* DISASSEMBLE IT */
    DisVFData(VFData, Fd);

    /* RELEASE OUTLINE */
    VF_FreeOutline(VFData, Fd);
  }

  printf("END\n");

  /* CLOSE THE FONT */
  VF_CloseFont(Fd);

  /* THEN, FINISH USING VFLIB */
  VF_Deinit();

  return 0;
}


void
usage(void)
{
  printf("disol  --- disassemble outline data\n");
  printf("Usage disol [options] code1 code2 ...\n");
  printf("Options: \n");
  printf("  -f FONT_ENTRY  : specify font entry name. (`min' is default)\n");
  printf("  -v VFONTCAP    : set vfontcap path.\n");	
  /*printf(" -c             : choose font original coordinates. %s\n");*/
  printf("Example: disol -f goth 2124\n");
  exit(0);
}



/*
 * Disassemble Vector Font Data returned by VF_GetOutline()
 */ 

void
DisVFData(long *vfdata, int fd)
{
  long          cmd, *ptr;
  unsigned int  x, y;
  int           m;

  if (vfdata == NULL)
    return;
  PrintCCode(vfdata[0]);
  ptr = &vfdata[2];
  do {
    m = 0;
    cmd = *ptr;
    ptr++; 
    if (cmd == 0L){
      PrintEnd();
      EmptyLine();
    } else if ((cmd & VFD_TOKEN) == VFD_TOKEN){
      PrintToken();
      if ((cmd & VFD_CHAR) == VFD_CHAR)
	Print(&m, "CH");
      if ((cmd & VFD_CWCURV) == VFD_CWCURV)
	Print(&m, "C1");
      if ((cmd & VFD_CCWCURV) == VFD_CCWCURV)
	Print(&m, "C2");
      if ((cmd & VFD_LINE) == VFD_LINE)
	Print(&m, "LI");
      if ((cmd & VFD_ARC) == VFD_ARC)
	Print(&m, "AR");
      if ((cmd & VFD_BEZ) == VFD_BEZ)
	Print(&m, "BE");
      Newline();
    } else {
      x = VFD_GET_X(cmd);
      y = VFD_GET_Y(cmd);
      PrintXY(x, y);
    }
  } while (cmd != 0L);
}


void EmptyLine(void)
{
  printf("\n");
}

void PrintCCode(int n)
{
  printf("CHAR    ");
  printf("$%x\n", n);
}

void PrintToken(void)
{
  printf("        ");
  printf("TOKEN   ");
}

void Print(int *mp, char *str)
{
  if (*mp == 0)
    printf("[");
  if (*mp > 0)
    printf(",");
  printf("%s", str);
  (*mp)++;
}

void Newline(void)
{
  printf("]\n");
}

void PrintEnd(void)
{
  printf("        ");
  printf("END     \n");
}

void PrintXY(int x, int y)
{
  printf("        ");
  printf("XY      ");
  printf("%d %d\n",x,y);
}

