/* 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 "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;
}

