/*
 * Copyright © 2011,2012  Google, Inc.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Google Author(s): Behdad Esfahbod, Roderick Sheeter
 */

#ifndef HB_OT_HMTX_TABLE_HH
#define HB_OT_HMTX_TABLE_HH

#include "hb-open-type.hh"
#include "hb-ot-hhea-table.hh"
#include "hb-ot-os2-table.hh"
#include "hb-ot-var-hvar-table.hh"

/*
 * hmtx -- Horizontal Metrics
 * https://docs.microsoft.com/en-us/typography/opentype/spec/hmtx
 * vmtx -- Vertical Metrics
 * https://docs.microsoft.com/en-us/typography/opentype/spec/vmtx
 */
#define HB_OT_TAG_hmtx HB_TAG('h','m','t','x')
#define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')


namespace OT {


struct LongMetric
{
  UFWORD	advance; /* Advance width/height. */
  FWORD		sb; /* Leading (left/top) side bearing. */
  public:
  DEFINE_SIZE_STATIC (4);
};

template <typename T, typename H>
struct hmtxvmtx
{
  inline bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
  {
    TRACE_SANITIZE (this);
    /* We don't check for anything specific here.  The users of the
     * struct do all the hard work... */
    return_trace (true);
  }


  inline bool subset_update_header (hb_subset_plan_t *plan,
                                    unsigned int num_hmetrics) const
  {
    hb_blob_t *src_blob = hb_sanitize_context_t().reference_table<H> (plan->source, H::tableTag);
    hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail(src_blob);
    hb_blob_destroy (src_blob);

    if (unlikely (!dest_blob)) {
      return false;
    }

    unsigned int length;
    H *table = (H *) hb_blob_get_data (dest_blob, &length);
    table->numberOfLongMetrics.set (num_hmetrics);

    bool result = plan->add_table (H::tableTag, dest_blob);
    hb_blob_destroy (dest_blob);

    return result;
  }

  inline bool subset (hb_subset_plan_t *plan) const
  {
    typename T::accelerator_t _mtx;
    _mtx.init (plan->source);

    /* All the trailing glyphs with the same advance can use one LongMetric
     * and just keep LSB */
    hb_vector_t<hb_codepoint_t> &gids = plan->glyphs;
    unsigned int num_advances = gids.len;
    unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]);
    while (num_advances > 1
        && last_advance == _mtx.get_advance (gids[num_advances - 2]))
    {
      num_advances--;
    }

    /* alloc the new table */
    size_t dest_sz = num_advances * 4
                  + (gids.len - num_advances) * 2;
    void *dest = (void *) malloc (dest_sz);
    if (unlikely (!dest))
    {
      return false;
    }
    DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in src has %d advances, %d lsbs", HB_UNTAG(T::tableTag), _mtx.num_advances, _mtx.num_metrics - _mtx.num_advances);
    DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in dest has %d advances, %d lsbs, %u bytes", HB_UNTAG(T::tableTag), num_advances, gids.len - num_advances, (unsigned int) dest_sz);

    const char *source_table = hb_blob_get_data (_mtx.blob, nullptr);
    // Copy everything over
    LongMetric * old_metrics = (LongMetric *) source_table;
    FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances);
    char * dest_pos = (char *) dest;

    bool failed = false;
    for (unsigned int i = 0; i < gids.len; i++)
    {
      /* the last metric or the one for gids[i] */
      LongMetric *src_metric = old_metrics + MIN ((hb_codepoint_t) _mtx.num_advances - 1, gids[i]);
      if (gids[i] < _mtx.num_advances)
      {
        /* src is a LongMetric */
        if (i < num_advances)
        {
          /* dest is a LongMetric, copy it */
          *((LongMetric *) dest_pos) = *src_metric;
        }
        else
        {
          /* dest just sb */
          *((FWORD *) dest_pos) = src_metric->sb;
        }
      }
      else
      {
	if (gids[i] >= _mtx.num_metrics)
	{
	  DEBUG_MSG(SUBSET, nullptr, "gid %d is >= number of source metrics %d",
		    gids[i], _mtx.num_metrics);
	  failed = true;
	  break;
	}
	FWORD src_sb = *(lsbs + gids[i] - _mtx.num_advances);
        if (i < num_advances)
        {
          /* dest needs a full LongMetric */
          LongMetric *metric = (LongMetric *)dest_pos;
          metric->advance = src_metric->advance;
          metric->sb = src_sb;
        }
        else
        {
          /* dest just needs an sb */
          *((FWORD *) dest_pos) = src_sb;
        }
      }
      dest_pos += (i < num_advances ? 4 : 2);
    }
    _mtx.fini ();

    // Amend header num hmetrics
    if (failed || unlikely (!subset_update_header (plan, num_advances)))
    {
      free (dest);
      return false;
    }

    hb_blob_t *result = hb_blob_create ((const char *)dest,
                                        dest_sz,
                                        HB_MEMORY_MODE_READONLY,
                                        dest,
                                        free);
    bool success = plan->add_table (T::tableTag, result);
    hb_blob_destroy (result);
    return success;
  }

  struct accelerator_t
  {
    friend struct hmtxvmtx;

    inline void init (hb_face_t *face,
		      unsigned int default_advance_ = 0)
    {
      default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);

      bool got_font_extents = false;
      if (T::os2Tag)
      {
	hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table<OS2> (face);
	const OS2 *os2_table = os2_blob->as<OS2> ();
#define USE_TYPO_METRICS (1u<<7)
	if (0 != (os2_table->fsSelection & USE_TYPO_METRICS))
	{
	  ascender = abs (os2_table->sTypoAscender);
	  descender = -abs (os2_table->sTypoDescender);
	  line_gap = os2_table->sTypoLineGap;
	  got_font_extents = (ascender | descender) != 0;
	}
	hb_blob_destroy (os2_blob);
      }

      hb_blob_t *_hea_blob = hb_sanitize_context_t().reference_table<H> (face);
      const H *_hea_table = _hea_blob->as<H> ();
      num_advances = _hea_table->numberOfLongMetrics;
      if (!got_font_extents)
      {
	ascender = abs (_hea_table->ascender);
	descender = -abs (_hea_table->descender);
	line_gap = _hea_table->lineGap;
	got_font_extents = (ascender | descender) != 0;
      }
      hb_blob_destroy (_hea_blob);

      has_font_extents = got_font_extents;

      blob = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag);

      /* Cap num_metrics() and num_advances() based on table length. */
      unsigned int len = hb_blob_get_length (blob);
      if (unlikely (num_advances * 4 > len))
	num_advances = len / 4;
      num_metrics = num_advances + (len - 4 * num_advances) / 2;

      /* We MUST set num_metrics to zero if num_advances is zero.
       * Our get_advance() depends on that. */
      if (unlikely (!num_advances))
      {
	num_metrics = num_advances = 0;
	hb_blob_destroy (blob);
	blob = hb_blob_get_empty ();
      }
      table = blob->as<hmtxvmtx> ();

      var_blob = hb_sanitize_context_t().reference_table<HVARVVAR> (face, T::variationsTag);
      var_table = var_blob->as<HVARVVAR> ();
    }

    inline void fini (void)
    {
      hb_blob_destroy (blob);
      hb_blob_destroy (var_blob);
    }

    /* TODO Add variations version. */
    inline unsigned int get_side_bearing (hb_codepoint_t glyph) const
    {
      if (glyph < num_advances)
        return table->longMetricZ[glyph].sb;

      if (unlikely (glyph >= num_metrics))
        return 0;

      const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances];
      return bearings[glyph - num_advances];
    }

    inline unsigned int get_advance (hb_codepoint_t glyph) const
    {
      if (unlikely (glyph >= num_metrics))
      {
	/* If num_metrics is zero, it means we don't have the metrics table
	 * for this direction: return default advance.  Otherwise, it means that the
	 * glyph index is out of bound: return zero. */
	if (num_metrics)
	  return 0;
	else
	  return default_advance;
      }

      return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance;
    }

    inline unsigned int get_advance (hb_codepoint_t  glyph,
                                     hb_font_t      *font) const
    {
      unsigned int advance = get_advance (glyph);
      if (likely(glyph < num_metrics))
      {
	advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
      }
      return advance;
    }

    public:
    bool has_font_extents;
    unsigned short ascender;
    unsigned short descender;
    unsigned short line_gap;

    protected:
    unsigned int num_metrics;
    unsigned int num_advances;
    unsigned int default_advance;

    private:
    const hmtxvmtx *table;
    hb_blob_t *blob;
    const HVARVVAR *var_table;
    hb_blob_t *var_blob;
  };

  protected:
  UnsizedArrayOf<LongMetric>longMetricZ;/* Paired advance width and leading
					 * bearing values for each glyph. The
					 * value numOfHMetrics comes from
					 * the 'hhea' table. If the font is
					 * monospaced, only one entry need
					 * be in the array, but that entry is
					 * required. The last entry applies to
					 * all subsequent glyphs. */
/*UnsizedArrayOf<FWORD>	leadingBearingX;*//* Here the advance is assumed
					 * to be the same as the advance
					 * for the last entry above. The
					 * number of entries in this array is
					 * derived from numGlyphs (from 'maxp'
					 * table) minus numberOfLongMetrics.
					 * This generally is used with a run
					 * of monospaced glyphs (e.g., Kanji
					 * fonts or Courier fonts). Only one
					 * run is allowed and it must be at
					 * the end. This allows a monospaced
					 * font to vary the side bearing
					 * values for each glyph. */
  public:
  DEFINE_SIZE_ARRAY (0, longMetricZ);
};

struct hmtx : hmtxvmtx<hmtx, hhea> {
  static const hb_tag_t tableTag	= HB_OT_TAG_hmtx;
  static const hb_tag_t variationsTag	= HB_OT_TAG_HVAR;
  static const hb_tag_t os2Tag		= HB_OT_TAG_OS2;
};
struct vmtx : hmtxvmtx<vmtx, vhea> {
  static const hb_tag_t tableTag	= HB_OT_TAG_vmtx;
  static const hb_tag_t variationsTag	= HB_OT_TAG_VVAR;
  static const hb_tag_t os2Tag		= HB_TAG_NONE;
};

struct hmtx_accelerator_t : hmtx::accelerator_t {};
struct vmtx_accelerator_t : vmtx::accelerator_t {};

} /* namespace OT */


#endif /* HB_OT_HMTX_TABLE_HH */
