/* Pango
 * pango-ot-ruleset.c: Shaping using OpenType features
 *
 * 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 <freetype/internal/ftmemory.h>

#include <pango/pango-ot.h>
#include "pango-ot-private.h"

typedef struct _PangoOTRule PangoOTRule;

struct _PangoOTRule 
{
  gulong     property_bit;
  FT_UShort  feature_index;
  guint      table_type : 1;
};

static void pango_ot_ruleset_class_init (GObjectClass   *object_class);
static void pango_ot_ruleset_init       (PangoOTRuleset *ruleset);
static void pango_ot_ruleset_finalize   (GObject        *object);

static GObjectClass *parent_class;

GType
pango_ot_ruleset_get_type (void)
{
  static GType object_type = 0;

  if (!object_type)
    {
      static const GTypeInfo object_info =
      {
        sizeof (PangoOTRulesetClass),
        (GBaseInitFunc) NULL,
        (GBaseFinalizeFunc) NULL,
        (GClassInitFunc)pango_ot_ruleset_class_init,
        NULL,           /* class_finalize */
        NULL,           /* class_data */
        sizeof (PangoOTRuleset),
        0,              /* n_preallocs */
        (GInstanceInitFunc)pango_ot_ruleset_init,
      };
      
      object_type = g_type_register_static (G_TYPE_OBJECT,
                                            "PangoOTRuleset",
                                            &object_info, 0);
    }
  
  return object_type;
}

static void 
pango_ot_ruleset_class_init (GObjectClass *object_class)
{
  parent_class = g_type_class_peek_parent (object_class);
  
  object_class->finalize = pango_ot_ruleset_finalize;
}

static void 
pango_ot_ruleset_init (PangoOTRuleset *ruleset)
{
  ruleset->rules = g_array_new (FALSE, FALSE, sizeof (PangoOTRule));
}

static void 
pango_ot_ruleset_finalize (GObject *object)
{
  PangoOTRuleset *ruleset = PANGO_OT_RULESET (object);

  g_array_free (ruleset->rules, TRUE);
  g_object_unref (G_OBJECT (ruleset->info));
}

PangoOTRuleset *
pango_ot_ruleset_new (PangoOTInfo *info)
{
  PangoOTRuleset *ruleset;

  ruleset = g_object_new (PANGO_TYPE_OT_RULESET, NULL);

  ruleset->info = g_object_ref (G_OBJECT (info));

  return ruleset;
}

void
pango_ot_ruleset_add_feature (PangoOTRuleset   *ruleset,
			      PangoOTTableType  table_type,
			      guint             feature_index,
			      gulong            property_bit)
{
  PangoOTRule tmp_rule;

  g_return_if_fail (PANGO_OT_IS_RULESET (ruleset));

  tmp_rule.table_type = table_type;
  tmp_rule.feature_index = feature_index;
  tmp_rule.property_bit = property_bit;

  g_array_append_val (ruleset->rules, tmp_rule);
}

void
pango_ot_ruleset_shape (PangoOTRuleset   *ruleset,
			PangoGlyphString *glyphs,
			gulong           *properties)
{
  int i;
  int last_cluster;
  
  TTO_GSUB gsub = NULL;
  TTO_GPOS gpos = NULL;
  
  TTO_GSUB_String *in_string = NULL;
  TTO_GSUB_String *out_string = NULL;
  TTO_GSUB_String *result_string = NULL;
  TTO_GPOS_Data *pos_data;

  gboolean need_gsub = FALSE;
  gboolean need_gpos = FALSE;

  g_return_if_fail (PANGO_OT_IS_RULESET (ruleset));

  for (i = 0; i < ruleset->rules->len; i++)
    {
      PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i);

      if (rule->table_type == PANGO_OT_TABLE_GSUB)
	need_gsub = TRUE;
      else 
	need_gpos = TRUE;
    }

  if (need_gsub)
    {
      gsub = pango_ot_info_get_gsub (ruleset->info);

      if (gsub)
	TT_GSUB_Clear_Features (gsub);
    }

  if (need_gpos)
    {
      gpos = pango_ot_info_get_gpos (ruleset->info);

      if (gpos)
	TT_GPOS_Clear_Features (gpos);
    }

  for (i = 0; i < ruleset->rules->len; i++)
    {
      PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i);

      if (rule->table_type == PANGO_OT_TABLE_GSUB)
	{
	  if (gsub)
	    TT_GSUB_Add_Feature (gsub, rule->feature_index, rule->property_bit);
	}
      else
	{
	  if (gpos)
	    TT_GPOS_Add_Feature (gpos, rule->feature_index, rule->property_bit);
	}
    }

  if (!gsub && !gpos)
    return;

  g_assert (TT_GSUB_String_New (ruleset->info->face->memory,
				&in_string) == FT_Err_Ok);
  g_assert (TT_GSUB_String_Set_Length (in_string, glyphs->num_glyphs) == FT_Err_Ok);

  for (i = 0; i < glyphs->num_glyphs; i++)
    {
      in_string->string[i] = glyphs->glyphs[i].glyph;
      in_string->properties[i] = properties[i];
      in_string->logClusters[i] = glyphs->log_clusters[i];
    }
  in_string->max_ligID = i;
  
  if (gsub)
    {
      g_assert (TT_GSUB_String_New (ruleset->info->face->memory,
				    &out_string) == FT_Err_Ok);
      result_string = out_string;

      TT_GSUB_Apply_String (gsub, in_string, out_string);
    }
  else
    result_string = in_string;
  
  pango_glyph_string_set_size (glyphs, result_string->length);

  last_cluster = -1;
  for (i = 0; i < result_string->length; i++)
    {
      glyphs->glyphs[i].glyph = result_string->string[i];
      glyphs->glyphs[i].glyph = result_string->string[i];

      glyphs->log_clusters[i] = result_string->logClusters[i];
      if (glyphs->log_clusters[i] != last_cluster)
	glyphs->glyphs[i].attr.is_cluster_start = 1;
      else
	glyphs->glyphs[i].attr.is_cluster_start = 0;

      last_cluster = glyphs->log_clusters[i];
    }

  if (in_string)
    TT_GSUB_String_Done (in_string);
  if (out_string)
    TT_GSUB_String_Done (out_string);
}
