/* Pango
 * otttest.c: Test program for OpenType
 *
 * Copyright (C) 2000 Red Hat Software
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

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

#include "ftxopen.h"
#include <freetype/internal/ftmemory.h>

#include "disasm.h"

#define N_ELEMENTS(arr) (sizeof(arr)/ sizeof((arr)[0]))

int
croak (const char *situation, FT_Error error)
{
  fprintf (stderr, "%s: Error %d\n", situation, error);

  exit (1);
}

enum {
  I = 1 << 0,
  M = 1 << 1,
  F = 1 << 2,
  L = 1 << 3
};

void
print_tag (FT_ULong tag)
{
  fprintf (stderr, "%c%c%c%c", 
	  (unsigned char)(tag >> 24),
	  (unsigned char)((tag & 0xff0000) >> 16),
	  (unsigned char)((tag & 0xff00) >> 8),
	  (unsigned char)(tag & 0xff));
}

void
maybe_add_feature (TTO_GSUB  gsub,
		   FT_UShort script_index,
		   FT_ULong  tag,
		   FT_UShort property)
{
  FT_Error error;
  FT_UShort feature_index;
  
  /* 0xffff == default language system */
  error = TT_GSUB_Select_Feature (gsub, tag, script_index, 0xffff, &feature_index);
  
  if (error)
    {
      if (error == TTO_Err_Not_Covered)
	{
	  print_tag (tag);
	  fprintf (stderr, " not covered, ignored\n");
	  return;
	}

      croak ("TT_GSUB_Select_Feature", error);
    }

  if ((error = TT_GSUB_Add_Feature (gsub, feature_index, property)))
    croak ("TT_GSUB_Add_Feature", error);
}

void
select_cmap (FT_Face face)
{
  FT_UShort  i;
  FT_CharMap cmap = NULL;
  
  for (i = 0; i < face->num_charmaps; i++)
    {
      if (face->charmaps[i]->platform_id == 3 && face->charmaps[i]->encoding_id == 1)
	{
	  cmap = face->charmaps[i];
	  break;
	}
    }
  
  /* we try only pid/eid (0,0) if no (3,1) map is found -- many Windows
     fonts have only rudimentary (0,0) support.                         */

  if (!cmap)
    for (i = 0; i < face->num_charmaps; i++)
      {
	if (face->charmaps[i]->platform_id == 3 && face->charmaps[i]->encoding_id == 1)
	  {
	    cmap = face->charmaps[i];
	    break;
	  }
      }

  if (cmap)
    FT_Set_Charmap (face, cmap);
  else
    {
      fprintf (stderr, "Sorry, but this font doesn't contain"
	       " any Unicode mapping table.\n");
      exit (1);
    }
}

void
add_features (TTO_GSUB gsub)
{
  FT_Error error;
  FT_ULong tag = FT_MAKE_TAG ('a', 'r', 'a', 'b');
  FT_UShort script_index;

  error = TT_GSUB_Select_Script (gsub, tag, &script_index);

  if (error)
    {
      if (error == TTO_Err_Not_Covered)
	{
	  fprintf (stderr, "Arabic not covered, no features used\n");
	  return;
	}

      croak ("TT_GSUB_Select_Script", error);
    }

  maybe_add_feature (gsub, script_index, FT_MAKE_TAG ('i', 'n', 'i', 't'), I);
  maybe_add_feature (gsub, script_index, FT_MAKE_TAG ('m', 'e', 'd', 'i'), M);
  maybe_add_feature (gsub, script_index, FT_MAKE_TAG ('f', 'i', 'n', 'a'), F);
  maybe_add_feature (gsub, script_index, FT_MAKE_TAG ('l', 'i', 'g', 'a'), L);
}

void 
dump_string (TTO_GSUB_String *str)
{
  FT_ULong i;

  fprintf (stderr, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
  for (i = 0; i < str->length; i++)
    {
      fprintf (stderr, "%2lu: %#06x %#06x %4d %4d\n",
	       i,
	       str->string[i],
	       str->properties[i],
	       str->components[i],
	       str->ligIDs[i]);
    }
  fprintf (stderr, "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
}

FT_UShort arabic_str[]   = { 0x645, 0x643, 0x64a, 0x644, 0x639, 0x20, 0x645, 0x627, 0x644, 0x633, 0x644, 0x627 };
FT_UShort arabic_props[] = { I|L,   M|L,   M|L,   M|L,   M|L,   F|L,   I|L,  M|L,   M|L,   M|L,   M|L,   F|L };

void
try_string (FT_Library library,
	    FT_Face    face,
	    TTO_GSUB   gsub)
{
  FT_Error error;
  TTO_GSUB_String *in_str;
  TTO_GSUB_String *out_str;
  FT_ULong i;

  if ((error = TT_GSUB_String_New (face->memory, &in_str)))
    croak ("TT_GSUB_String_New", error);
  if ((error = TT_GSUB_String_New (face->memory, &out_str)))
    croak ("TT_GSUB_String_New", error);

  if ((error = TT_GSUB_String_Set_Length (in_str, N_ELEMENTS (arabic_str))))
    croak ("TT_GSUB_String_Set_Length", error);

  for (i=0; i < N_ELEMENTS (arabic_str); i++)
    {
      in_str->string[i] = FT_Get_Char_Index (face, arabic_str[i]);
      in_str->properties[i] = arabic_props[i];
      in_str->components[i] = i;
      in_str->ligIDs[i] = i;
    }

  if ((error = TT_GSUB_Apply_String (gsub, in_str, out_str)))
    croak ("TT_GSUB_Apply_String", error);

  dump_string (in_str);
  dump_string (out_str);

  if ((error = TT_GSUB_String_Done (in_str)))
    croak ("TT_GSUB_String_New", error);
  if ((error = TT_GSUB_String_Done (out_str)))
    croak ("TT_GSUB_String_New", error);
}

int 
main (int argc, char **argv)
{
  FT_Error error;
  FT_Library library;
  FT_Face face;
  TTO_GSUB gsub;
  TTO_GPOS gpos;

  if (argc != 2)
    {
      fprintf (stderr, "Usage: ottest MYFONT.TTF\n");
      exit(1);
    }

  if ((error = FT_Init_FreeType (&library)))
    croak ("FT_Init_FreeType", error);

  if ((error = FT_New_Face (library, argv[1], 0, &face)))
    croak ("FT_New_Face", error);

  printf("----> GSUB <----\n");
  if (!(error = TT_Load_GSUB_Table (face, &gsub, NULL)))
    {
      TT_Dump_GSUB_Table (gsub, stdout);
      
      if ((error = TT_Done_GSUB_Table (gsub)))
	croak ("FT_Done_GSUB_Table", error);
    }
  else
    fprintf (stderr, "TT_Load_GSUB_Table %x\n", error);

  printf("----> GPOS <----\n");
  if (!(error = TT_Load_GPOS_Table (face, &gpos, NULL)))
    {
      TT_Dump_GPOS_Table (gpos, stdout);
      
      if ((error = TT_Done_GPOS_Table (gpos)))
	croak ("FT_Done_GPOS_Table", error);
    }
  else
    fprintf (stderr, "TT_Load_GPOS_Table %x\n", error);

#if 0  
  select_cmap (face);

  add_features (gsub);
  try_string (library, face, gsub);
#endif


  if ((error = FT_Done_Face (face)))
    croak ("FT_Done_Face", error);

  if ((error = FT_Done_FreeType (library)))
    croak ("FT_Done_FreeType", error);
  
  return 0;
}

