/****************************************************************************
 *
 * afshaper.c
 *
 *   HarfBuzz interface for accessing OpenType features (body).
 *
 * Copyright (C) 2013-2022 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * This file is part of the FreeType project, and may only be used,
 * modified, and distributed under the terms of the FreeType project
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
 * this file you indicate that you have read the license and
 * understand and accept it fully.
 *
 */


#include <freetype/freetype.h>
#include <freetype/ftadvanc.h>
#include "afglobal.h"
#include "aftypes.h"
#include "afshaper.h"

#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ


  /**************************************************************************
   *
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
   * messages during execution.
   */
#undef  FT_COMPONENT
#define FT_COMPONENT  afshaper


  /*
   * We use `sets' (in the HarfBuzz sense, which comes quite near to the
   * usual mathematical meaning) to manage both lookups and glyph indices.
   *
   * 1. For each coverage, collect lookup IDs in a set.  Note that an
   *    auto-hinter `coverage' is represented by one `feature', and a
   *    feature consists of an arbitrary number of (font specific) `lookup's
   *    that actually do the mapping job.  Please check the OpenType
   *    specification for more details on features and lookups.
   *
   * 2. Create glyph ID sets from the corresponding lookup sets.
   *
   * 3. The glyph set corresponding to AF_COVERAGE_DEFAULT is computed
   *    with all lookups specific to the OpenType script activated.  It
   *    relies on the order of AF_DEFINE_STYLE_CLASS entries so that
   *    special coverages (like `oldstyle figures') don't get overwritten.
   *
   */


  /* load coverage tags */
#undef  COVERAGE
#define COVERAGE( name, NAME, description,             \
                  tag1, tag2, tag3, tag4 )             \
          static const hb_tag_t  name ## _coverage[] = \
          {                                            \
            HB_TAG( tag1, tag2, tag3, tag4 ),          \
            HB_TAG_NONE                                \
          };


#include "afcover.h"


  /* define mapping between coverage tags and AF_Coverage */
#undef  COVERAGE
#define COVERAGE( name, NAME, description, \
                  tag1, tag2, tag3, tag4 ) \
          name ## _coverage,


  static const hb_tag_t*  coverages[] =
  {
#include "afcover.h"

    NULL /* AF_COVERAGE_DEFAULT */
  };


  /* load HarfBuzz script tags */
#undef  SCRIPT
#define SCRIPT( s, S, d, h, H, ss )  h,


  static const hb_script_t  scripts[] =
  {
#include "afscript.h"
  };


  FT_Error
  af_shaper_get_coverage( AF_FaceGlobals  globals,
                          AF_StyleClass   style_class,
                          FT_UShort*      gstyles,
                          FT_Bool         default_script )
  {
    hb_face_t*  face;

    hb_set_t*  gsub_lookups = NULL; /* GSUB lookups for a given script */
    hb_set_t*  gsub_glyphs  = NULL; /* glyphs covered by GSUB lookups  */
    hb_set_t*  gpos_lookups = NULL; /* GPOS lookups for a given script */
    hb_set_t*  gpos_glyphs  = NULL; /* glyphs covered by GPOS lookups  */

    hb_script_t      script;
    const hb_tag_t*  coverage_tags;
    hb_tag_t         script_tags[] = { HB_TAG_NONE,
                                       HB_TAG_NONE,
                                       HB_TAG_NONE,
                                       HB_TAG_NONE };

    hb_codepoint_t  idx;
#ifdef FT_DEBUG_LEVEL_TRACE
    int             count;
#endif


    if ( !globals || !style_class || !gstyles )
      return FT_THROW( Invalid_Argument );

    face = hb_font_get_face( globals->hb_font );

    coverage_tags = coverages[style_class->coverage];
    script        = scripts[style_class->script];

    /* Convert a HarfBuzz script tag into the corresponding OpenType */
    /* tag or tags -- some Indic scripts like Devanagari have an old */
    /* and a new set of features.                                    */
    {
      unsigned int  tags_count = 3;
      hb_tag_t      tags[3];


      hb_ot_tags_from_script_and_language( script,
                                           HB_LANGUAGE_INVALID,
                                           &tags_count,
                                           tags,
                                           NULL,
                                           NULL );
      script_tags[0] = tags_count > 0 ? tags[0] : HB_TAG_NONE;
      script_tags[1] = tags_count > 1 ? tags[1] : HB_TAG_NONE;
      script_tags[2] = tags_count > 2 ? tags[2] : HB_TAG_NONE;
    }

    /* If the second tag is HB_OT_TAG_DEFAULT_SCRIPT, change that to     */
    /* HB_TAG_NONE except for the default script.                        */
    if ( default_script )
    {
      if ( script_tags[0] == HB_TAG_NONE )
        script_tags[0] = HB_OT_TAG_DEFAULT_SCRIPT;
      else
      {
        if ( script_tags[1] == HB_TAG_NONE )
          script_tags[1] = HB_OT_TAG_DEFAULT_SCRIPT;
        else if ( script_tags[1] != HB_OT_TAG_DEFAULT_SCRIPT )
          script_tags[2] = HB_OT_TAG_DEFAULT_SCRIPT;
      }
    }
    else
    {
      /* we use non-standard tags like `khms' for special purposes;       */
      /* HarfBuzz maps them to `DFLT', which we don't want to handle here */
      if ( script_tags[0] == HB_OT_TAG_DEFAULT_SCRIPT )
        goto Exit;
    }

    gsub_lookups = hb_set_create();
    hb_ot_layout_collect_lookups( face,
                                  HB_OT_TAG_GSUB,
                                  script_tags,
                                  NULL,
                                  coverage_tags,
                                  gsub_lookups );

    if ( hb_set_is_empty( gsub_lookups ) )
      goto Exit; /* nothing to do */

    FT_TRACE4(( "GSUB lookups (style `%s'):\n",
                af_style_names[style_class->style] ));
    FT_TRACE4(( " " ));

#ifdef FT_DEBUG_LEVEL_TRACE
    count = 0;
#endif

    gsub_glyphs = hb_set_create();
    for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, &idx ); )
    {
#ifdef FT_DEBUG_LEVEL_TRACE
      FT_TRACE4(( " %d", idx ));
      count++;
#endif

      /* get output coverage of GSUB feature */
      hb_ot_layout_lookup_collect_glyphs( face,
                                          HB_OT_TAG_GSUB,
                                          idx,
                                          NULL,
                                          NULL,
                                          NULL,
                                          gsub_glyphs );
    }

#ifdef FT_DEBUG_LEVEL_TRACE
    if ( !count )
      FT_TRACE4(( " (none)" ));
    FT_TRACE4(( "\n" ));
    FT_TRACE4(( "\n" ));
#endif

    FT_TRACE4(( "GPOS lookups (style `%s'):\n",
                af_style_names[style_class->style] ));
    FT_TRACE4(( " " ));

    gpos_lookups = hb_set_create();
    hb_ot_layout_collect_lookups( face,
                                  HB_OT_TAG_GPOS,
                                  script_tags,
                                  NULL,
                                  coverage_tags,
                                  gpos_lookups );

#ifdef FT_DEBUG_LEVEL_TRACE
    count = 0;
#endif

    gpos_glyphs = hb_set_create();
    for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gpos_lookups, &idx ); )
    {
#ifdef FT_DEBUG_LEVEL_TRACE
      FT_TRACE4(( " %d", idx ));
      count++;
#endif

      /* get input coverage of GPOS feature */
      hb_ot_layout_lookup_collect_glyphs( face,
                                          HB_OT_TAG_GPOS,
                                          idx,
                                          NULL,
                                          gpos_glyphs,
                                          NULL,
                                          NULL );
    }

#ifdef FT_DEBUG_LEVEL_TRACE
    if ( !count )
      FT_TRACE4(( " (none)" ));
    FT_TRACE4(( "\n" ));
    FT_TRACE4(( "\n" ));
#endif

    /*
     * We now check whether we can construct blue zones, using glyphs
     * covered by the feature only.  In case there is not a single zone
     * (this is, not a single character is covered), we skip this coverage.
     *
     */
    if ( style_class->coverage != AF_COVERAGE_DEFAULT )
    {
      AF_Blue_Stringset         bss = style_class->blue_stringset;
      const AF_Blue_StringRec*  bs  = &af_blue_stringsets[bss];

      FT_Bool  found = 0;


      for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ )
      {
        const char*  p = &af_blue_strings[bs->string];


        while ( *p )
        {
          hb_codepoint_t  ch;


          GET_UTF8_CHAR( ch, p );

          for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups,
                                                         &idx ); )
          {
            hb_codepoint_t  gidx = FT_Get_Char_Index( globals->face, ch );


            if ( hb_ot_layout_lookup_would_substitute( face, idx,
                                                       &gidx, 1, 1 ) )
            {
              found = 1;
              break;
            }
          }
        }
      }

      if ( !found )
      {
        FT_TRACE4(( "  no blue characters found; style skipped\n" ));
        goto Exit;
      }
    }

    /*
     * Various OpenType features might use the same glyphs at different
     * vertical positions; for example, superscript and subscript glyphs
     * could be the same.  However, the auto-hinter is completely
     * agnostic of OpenType features after the feature analysis has been
     * completed: The engine then simply receives a glyph index and returns a
     * hinted and usually rendered glyph.
     *
     * Consider the superscript feature of font `pala.ttf': Some of the
     * glyphs are `real', this is, they have a zero vertical offset, but
     * most of them are small caps glyphs shifted up to the superscript
     * position (this is, the `sups' feature is present in both the GSUB and
     * GPOS tables).  The code for blue zones computation actually uses a
     * feature's y offset so that the `real' glyphs get correct hints.  But
     * later on it is impossible to decide whether a glyph index belongs to,
     * say, the small caps or superscript feature.
     *
     * For this reason, we don't assign a style to a glyph if the current
     * feature covers the glyph in both the GSUB and the GPOS tables.  This
     * is quite a broad condition, assuming that
     *
     *   (a) glyphs that get used in multiple features are present in a
     *       feature without vertical shift,
     *
     * and
     *
     *   (b) a feature's GPOS data really moves the glyph vertically.
     *
     * Not fulfilling condition (a) makes a font larger; it would also
     * reduce the number of glyphs that could be addressed directly without
     * using OpenType features, so this assumption is rather strong.
     *
     * Condition (b) is much weaker, and there might be glyphs which get
     * missed.  However, the OpenType features we are going to handle are
     * primarily located in GSUB, and HarfBuzz doesn't provide an API to
     * directly get the necessary information from the GPOS table.  A
     * possible solution might be to directly parse the GPOS table to find
     * out whether a glyph gets shifted vertically, but this is something I
     * would like to avoid if not really necessary.
     *
     * Note that we don't follow this logic for the default coverage.
     * Complex scripts like Devanagari have mandatory GPOS features to
     * position many glyph elements, using mark-to-base or mark-to-ligature
     * tables; the number of glyphs missed due to condition (b) would be far
     * too large.
     *
     */
    if ( style_class->coverage != AF_COVERAGE_DEFAULT )
      hb_set_subtract( gsub_glyphs, gpos_glyphs );

#ifdef FT_DEBUG_LEVEL_TRACE
    FT_TRACE4(( "  glyphs without GPOS data (`*' means already assigned)" ));
    count = 0;
#endif

    for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_glyphs, &idx ); )
    {
#ifdef FT_DEBUG_LEVEL_TRACE
      if ( !( count % 10 ) )
      {
        FT_TRACE4(( "\n" ));
        FT_TRACE4(( "   " ));
      }

      FT_TRACE4(( " %d", idx ));
      count++;
#endif

      /* glyph indices returned by `hb_ot_layout_lookup_collect_glyphs' */
      /* can be arbitrary: some fonts use fake indices for processing   */
      /* internal to GSUB or GPOS, which is fully valid                 */
      if ( idx >= (hb_codepoint_t)globals->glyph_count )
        continue;

      if ( gstyles[idx] == AF_STYLE_UNASSIGNED )
        gstyles[idx] = (FT_UShort)style_class->style;
#ifdef FT_DEBUG_LEVEL_TRACE
      else
        FT_TRACE4(( "*" ));
#endif
    }

#ifdef FT_DEBUG_LEVEL_TRACE
    if ( !count )
    {
      FT_TRACE4(( "\n" ));
      FT_TRACE4(( "    (none)" ));
    }
    FT_TRACE4(( "\n" ));
    FT_TRACE4(( "\n" ));
#endif

  Exit:
    hb_set_destroy( gsub_lookups );
    hb_set_destroy( gsub_glyphs  );
    hb_set_destroy( gpos_lookups );
    hb_set_destroy( gpos_glyphs  );

    return FT_Err_Ok;
  }


  /* construct HarfBuzz features */
#undef  COVERAGE
#define COVERAGE( name, NAME, description,                \
                  tag1, tag2, tag3, tag4 )                \
          static const hb_feature_t  name ## _feature[] = \
          {                                               \
            {                                             \
              HB_TAG( tag1, tag2, tag3, tag4 ),           \
              1, 0, (unsigned int)-1                      \
            }                                             \
          };


#include "afcover.h"


  /* define mapping between HarfBuzz features and AF_Coverage */
#undef  COVERAGE
#define COVERAGE( name, NAME, description, \
                  tag1, tag2, tag3, tag4 ) \
          name ## _feature,


  static const hb_feature_t*  features[] =
  {
#include "afcover.h"

    NULL /* AF_COVERAGE_DEFAULT */
  };


  void*
  af_shaper_buf_create( FT_Face  face )
  {
    FT_UNUSED( face );

    return (void*)hb_buffer_create();
  }


  void
  af_shaper_buf_destroy( FT_Face  face,
                         void*    buf )
  {
    FT_UNUSED( face );

    hb_buffer_destroy( (hb_buffer_t*)buf );
  }


  const char*
  af_shaper_get_cluster( const char*      p,
                         AF_StyleMetrics  metrics,
                         void*            buf_,
                         unsigned int*    count )
  {
    AF_StyleClass        style_class;
    const hb_feature_t*  feature;
    FT_Int               upem;
    const char*          q;
    int                  len;

    hb_buffer_t*    buf = (hb_buffer_t*)buf_;
    hb_font_t*      font;
    hb_codepoint_t  dummy;


    upem        = (FT_Int)metrics->globals->face->units_per_EM;
    style_class = metrics->style_class;
    feature     = features[style_class->coverage];

    font = metrics->globals->hb_font;

    /* we shape at a size of units per EM; this means font units */
    hb_font_set_scale( font, upem, upem );

    while ( *p == ' ' )
      p++;

    /* count bytes up to next space (or end of buffer) */
    q = p;
    while ( !( *q == ' ' || *q == '\0' ) )
      GET_UTF8_CHAR( dummy, q );
    len = (int)( q - p );

    /* feed character(s) to the HarfBuzz buffer */
    hb_buffer_clear_contents( buf );
    hb_buffer_add_utf8( buf, p, len, 0, len );

    /* we let HarfBuzz guess the script and writing direction */
    hb_buffer_guess_segment_properties( buf );

    /* shape buffer, which means conversion from character codes to */
    /* glyph indices, possibly applying a feature                   */
    hb_shape( font, buf, feature, feature ? 1 : 0 );

    if ( feature )
    {
      hb_buffer_t*  hb_buf = metrics->globals->hb_buf;

      unsigned int      gcount;
      hb_glyph_info_t*  ginfo;

      unsigned int      hb_gcount;
      hb_glyph_info_t*  hb_ginfo;


      /* we have to check whether applying a feature does actually change */
      /* glyph indices; otherwise the affected glyph or glyphs aren't     */
      /* available at all in the feature                                  */

      hb_buffer_clear_contents( hb_buf );
      hb_buffer_add_utf8( hb_buf, p, len, 0, len );
      hb_buffer_guess_segment_properties( hb_buf );
      hb_shape( font, hb_buf, NULL, 0 );

      ginfo    = hb_buffer_get_glyph_infos( buf, &gcount );
      hb_ginfo = hb_buffer_get_glyph_infos( hb_buf, &hb_gcount );

      if ( gcount == hb_gcount )
      {
        unsigned int  i;


        for (i = 0; i < gcount; i++ )
          if ( ginfo[i].codepoint != hb_ginfo[i].codepoint )
            break;

        if ( i == gcount )
        {
          /* both buffers have identical glyph indices */
          hb_buffer_clear_contents( buf );
        }
      }
    }

    *count = hb_buffer_get_length( buf );

#ifdef FT_DEBUG_LEVEL_TRACE
    if ( feature && *count > 1 )
      FT_TRACE1(( "af_shaper_get_cluster:"
                  " input character mapped to multiple glyphs\n" ));
#endif

    return q;
  }


  FT_ULong
  af_shaper_get_elem( AF_StyleMetrics  metrics,
                      void*            buf_,
                      unsigned int     idx,
                      FT_Long*         advance,
                      FT_Long*         y_offset )
  {
    hb_buffer_t*          buf = (hb_buffer_t*)buf_;
    hb_glyph_info_t*      ginfo;
    hb_glyph_position_t*  gpos;
    unsigned int          gcount;

    FT_UNUSED( metrics );


    ginfo = hb_buffer_get_glyph_infos( buf, &gcount );
    gpos  = hb_buffer_get_glyph_positions( buf, &gcount );

    if ( idx >= gcount )
      return 0;

    if ( advance )
      *advance = gpos[idx].x_advance;
    if ( y_offset )
      *y_offset = gpos[idx].y_offset;

    return ginfo[idx].codepoint;
  }


#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */


  FT_Error
  af_shaper_get_coverage( AF_FaceGlobals  globals,
                          AF_StyleClass   style_class,
                          FT_UShort*      gstyles,
                          FT_Bool         default_script )
  {
    FT_UNUSED( globals );
    FT_UNUSED( style_class );
    FT_UNUSED( gstyles );
    FT_UNUSED( default_script );

    return FT_Err_Ok;
  }


  void*
  af_shaper_buf_create( FT_Face  face )
  {
    FT_UNUSED( face );

    return NULL;
  }


  void
  af_shaper_buf_destroy( FT_Face  face,
                         void*    buf )
  {
    FT_UNUSED( face );
    FT_UNUSED( buf );
  }


  const char*
  af_shaper_get_cluster( const char*      p,
                         AF_StyleMetrics  metrics,
                         void*            buf_,
                         unsigned int*    count )
  {
    FT_Face    face      = metrics->globals->face;
    FT_ULong   ch, dummy = 0;
    FT_ULong*  buf       = (FT_ULong*)buf_;


    while ( *p == ' ' )
      p++;

    GET_UTF8_CHAR( ch, p );

    /* since we don't have an engine to handle clusters, */
    /* we scan the characters but return zero            */
    while ( !( *p == ' ' || *p == '\0' ) )
      GET_UTF8_CHAR( dummy, p );

    if ( dummy )
    {
      *buf   = 0;
      *count = 0;
    }
    else
    {
      *buf   = FT_Get_Char_Index( face, ch );
      *count = 1;
    }

    return p;
  }


  FT_ULong
  af_shaper_get_elem( AF_StyleMetrics  metrics,
                      void*            buf_,
                      unsigned int     idx,
                      FT_Long*         advance,
                      FT_Long*         y_offset )
  {
    FT_Face   face        = metrics->globals->face;
    FT_ULong  glyph_index = *(FT_ULong*)buf_;

    FT_UNUSED( idx );


    if ( advance )
      FT_Get_Advance( face,
                      glyph_index,
                      FT_LOAD_NO_SCALE         |
                      FT_LOAD_NO_HINTING       |
                      FT_LOAD_IGNORE_TRANSFORM,
                      advance );

    if ( y_offset )
      *y_offset = 0;

    return glyph_index;
  }


#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */


/* END */
