/* example1.c                                                      */
/*                                                                 */
/* This small program shows how to print a rotated string with the */
/* FreeType 2 library.                                             */


#include <stdio.h>
#include <string.h>
#include <math.h>

#include <ft2build.h>
#include FT_FREETYPE_H

typedef unsigned char UB;
typedef unsigned short UH;

struct strdef {
  char *label;
  UH *xstr;
} string_tab[500];

struct font_header {
  UH mincode;
  UH maxcode;
  UH height;
  short ascender;
  short descender;
  UH numchars;
} __attribute__((packed));

struct bitmap_info {
  UB width;
  UB height;
  UB pitch;
  UB top;
  UB left;
  UB advance;
  int offset;
} __attribute__((packed));

typedef unsigned short WCHAR;

int str_index;
int num_xchars;
int lineno;
int monoflag, boldflag;

/* Replace this function with something useful. */
void
draw_bitmap(FILE *fp, FT_Bitmap*  bitmap)
{
  FT_Int  i, j, p, q;
  int nb;
  UB val, mask, *pb;

#ifdef VDEBUG
printf("width: %d, height: %d, mode: %d (%d)\n",
 bitmap->width, bitmap->rows, bitmap->pixel_mode, ft_pixel_mode_mono);
#endif

  if (bitmap->pixel_mode == ft_pixel_mode_mono) {
#ifdef VDEBUG
printf("mono mode\n");
#endif
    nb = bitmap->pitch;
    fwrite(bitmap->buffer, nb, bitmap->rows, fp);
#ifdef CHDUMP
    for (q = 0; q < bitmap->rows; q++) {
      pb = bitmap->buffer + nb * q;
      for (p = 0; p < bitmap->width; p++) {
	mask = 0x80 >> (p & 7);
	putchar((*pb & mask)? '*' : ' ');
	if (mask == 1) pb++;
      }
      putchar('\n');
    }
#endif
  } else {
    fwrite(bitmap->buffer, bitmap->width, bitmap->rows, fp);
#ifdef CHDUMP
    for (q = 0; q < bitmap->rows; q++) {
      for (p = 0; p < bitmap->width; p++) {
        val = bitmap->buffer[q * bitmap->width + p];
        putchar(val == 0? ' ' : (val < 128? '+' : '*'));
      }
      putchar('\n');
    }
#endif
  }
}

int
main( int     argc,
      char**  argv )
{
  FT_Library    library;
  FT_Face       face;

  FT_GlyphSlot  slot;
  FT_Error      error;

  char*         filename;

  int           n;
  int		ptsize;
  FILE		*fp;
  int		offset;

  FT_UInt gindex;
  struct font_header fheader;
  struct bitmap_info *binfo, *bp;
  char *prog = argv[0];
  char *ttfile;
  WCHAR unicode, *puni;
  char fullname[100];


  while (argc > 1 && argv[1][0] == '-') {
	switch (argv[1][1]) {
	case 'b': boldflag++;
		break;
	case 'm': monoflag++;
		break;
	}
	argc--;
	argv++;
  }
  if ( argc != 3 )
  {
    fprintf ( stderr, "usage: %s size fontfile\n", prog );
    exit( 1 );
  }

  ptsize = atoi(argv[1]);
  ttfile = argv[2];
  num_xchars = 128 - 0x20;

  sprintf(fullname, "romedat%d", ptsize);
  fp = fopen(fullname, "w");
  if (fp == NULL) {
    fprintf( stderr, "can't open fontdata\n", fullname);
    exit(1);
  }

  fheader.mincode = 0x20;
  fheader.maxcode = 0x7f;
  fheader.numchars = num_xchars;
printf("num_xchars = %d, maxcode = %x\n", num_xchars, fheader.maxcode);

  error = FT_Init_FreeType( &library );            /* initialize library */
  /* error handling omitted */

#ifdef USE_DEFFONT
#define	TTF_FONTNAME	"GenBasB.ttf"
  ttfile = TTF_FONTNAME;
#endif
  error = FT_New_Face( library, ttfile, 0, &face ); /* create face object */
  if (error) {
	fprintf(stderr, "can't open %s\n", ttfile);
	exit(1);
  }
  /* error handling omitted */

  error = FT_Set_Char_Size( face, ptsize * 64, 0,
                            100, 0);              /* set character size */
  /* error handling omitted */

  slot = face->glyph;
  fheader.height = face->size->metrics.height >> 6;
  fheader.descender = face->size->metrics.descender >> 6;
  fheader.ascender = face->size->metrics.ascender >> 6;
#ifdef VERBOSE
printf("height: %d (%d, %d)\n", fheader.height, fheader.descender, fheader.ascender);
#endif

  binfo = (struct bitmap_info *)calloc(sizeof(struct bitmap_info), num_xchars);
  bp = binfo;
  offset = sizeof(fheader) + sizeof(struct bitmap_info) * num_xchars;

  for ( n = 0; n < num_xchars; n++ ) {
    /* load glyph image into the slot (erase previous one) */
    if (monoflag) {
#ifdef USE_LOAD_CHAR
	error = FT_Load_Char( face, sjis2uni[n*2+1], FT_LOAD_RENDER|FT_RENDER_MODE_MONO|FT_LOAD_MONOCHROME);
#else
	gindex = FT_Get_Char_Index(face, fheader.mincode + n);
	error = FT_Load_Glyph(face, gindex, FT_LOAD_MONOCHROME);
	if (error)
	    continue;
	if (boldflag) FT_GlyphSlot_Embolden(face->glyph);
	error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
#endif
    } else {
#ifdef USE_LOAD_CHAR
	error = FT_Load_Char( face, sjis2uni[n*2+1], FT_LOAD_RENDER);
#else
	gindex = FT_Get_Char_Index(face, fheader.mincode +n);
	error = FT_Load_Glyph(face, gindex, FT_LOAD_RENDER);
	if (error)
	    continue;
	if (boldflag) FT_GlyphSlot_Embolden(face->glyph);
	error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
#endif
    }
    if ( error )
      continue;                 /* ignore errors */

    /* now, draw to our target surface (convert position) */
    bp->left = slot->bitmap_left;
    bp->top = slot->bitmap_top;
    bp->advance = slot->advance.x >> 6;
    bp->width = slot->bitmap.width;
    bp->height = slot->bitmap.rows;
    bp->pitch = slot->bitmap.pitch;
    bp->offset = offset;
    if (monoflag)
	offset += bp->pitch * bp->height;
    else
	offset += bp->width * bp->height;
#ifdef VERBOSE
printf("bitmap_left: %d, bitmap_top: %d\n", slot->bitmap_left, slot->bitmap_top);
printf("height: %d, advance: %d\n", slot->bitmap.rows, slot->advance.x >> 6);
printf("width: %d, pitch: %d\n", slot->bitmap.width, slot->bitmap.pitch);
printf("offset: %x\n", bp->offset);
#endif
    bp++;
  }
printf("offset: %x\n", offset);

  fwrite((char *)&fheader, sizeof(fheader), 1, fp);

  bp = binfo;
  fwrite((UB *)binfo, sizeof(struct bitmap_info), num_xchars, fp);

  for ( n = 0; n < num_xchars; n++ ) {
    /* load glyph image into the slot (erase previous one) */
    if (monoflag) {
#ifdef USE_LOAD_CHAR
	error = FT_Load_Char( face, sjis2uni[n*2+1], FT_LOAD_RENDER|FT_RENDER_MODE_MONO|FT_LOAD_MONOCHROME);
#else
	gindex = FT_Get_Char_Index(face, fheader.mincode + n);
	error = FT_Load_Glyph(face, gindex, FT_LOAD_MONOCHROME);
	if (error)
		continue;
	if (boldflag) FT_GlyphSlot_Embolden(face->glyph);
	error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
#endif
    } else {
#ifdef USE_LOAD_CHAR
	error = FT_Load_Char( face, sjis2uni[n*2+1], FT_LOAD_RENDER);
#else
	gindex = FT_Get_Char_Index(face, fheader.mincode +n);
	error = FT_Load_Glyph(face, gindex, FT_LOAD_RENDER);
	if (error)
		continue;
	if (boldflag) FT_GlyphSlot_Embolden(face->glyph);
	error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
#endif
    }
    if ( error )
      continue;                 /* ignore errors */
    draw_bitmap(fp, &slot->bitmap);
#ifdef VDEBUG
printf("advance: %d\n", slot->advance);
#endif
  }

  FT_Done_Face    ( face );
  FT_Done_FreeType( library );

  fclose(fp);

  return 0;
}

/* EOF */
