/*
 * Copyright © 2018 Adobe Systems Incorporated.
 *
 *  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.
 *
 * Adobe Author(s): Michiharu Ariza
 */

#ifndef HB_OT_VORG_TABLE_HH
#define HB_OT_VORG_TABLE_HH

#include "hb-open-type.hh"

/*
 * VORG -- Vertical Origin Table
 * https://docs.microsoft.com/en-us/typography/opentype/spec/vorg
 */
#define HB_OT_TAG_VORG HB_TAG('V','O','R','G')

namespace OT {

struct VertOriginMetric
{
  inline int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this));
  }

  public:
  GlyphID	glyph;
  FWORD		vertOriginY;

  public:
  DEFINE_SIZE_STATIC (4);
};

struct VORG
{
  enum { tableTag = HB_OT_TAG_VORG };

  inline bool has_data (void) const { return version.to_int (); }

  inline int get_y_origin (hb_codepoint_t glyph) const
  {
    unsigned int i;
    if (!vertYOrigins.bfind (glyph, &i))
      return defaultVertOriginY;
    return vertYOrigins[i].vertOriginY;
  }

  inline bool _subset (const hb_subset_plan_t *plan HB_UNUSED,
                       const VORG *vorg_table,
                       const hb_vector_t<VertOriginMetric> &subset_metrics,
                       unsigned int dest_sz,
                       void *dest) const
  {
    hb_serialize_context_t c (dest, dest_sz);

    VORG *subset_table = c.start_serialize<VORG> ();
    if (unlikely (!c.extend_min (*subset_table)))
      return false;

    subset_table->version.major.set (1);
    subset_table->version.minor.set (0);

    subset_table->defaultVertOriginY.set (vorg_table->defaultVertOriginY);
    subset_table->vertYOrigins.len.set (subset_metrics.len);

    bool success = true;
    if (subset_metrics.len > 0)
    {
      unsigned int  size = VertOriginMetric::static_size * subset_metrics.len;
      VertOriginMetric  *metrics = c.allocate_size<VertOriginMetric> (size);
      if (likely (metrics != nullptr))
        memcpy (metrics, &subset_metrics[0u], size);
      else
        success = false;
    }
    c.end_serialize ();

    return success;
  }

  inline bool subset (hb_subset_plan_t *plan) const
  {
    hb_blob_t *vorg_blob = hb_sanitize_context_t().reference_table<VORG> (plan->source);
    const VORG *vorg_table = vorg_blob->as<VORG> ();

    /* count the number of glyphs to be included in the subset table */
    hb_vector_t<VertOriginMetric> subset_metrics;
    subset_metrics.init ();
    unsigned int glyph = 0;
    unsigned int i = 0;
    while ((glyph < plan->glyphs.len) && (i < vertYOrigins.len))
    {
      if (plan->glyphs[glyph] > vertYOrigins[i].glyph)
        i++;
      else if (plan->glyphs[glyph] < vertYOrigins[i].glyph)
        glyph++;
      else
      {
        VertOriginMetric *metrics = subset_metrics.push ();
        metrics->glyph.set (glyph);
        metrics->vertOriginY.set (vertYOrigins[i].vertOriginY);
        glyph++;
        i++;
      }
    }

    /* alloc the new table */
    unsigned int dest_sz = VORG::min_size + VertOriginMetric::static_size * subset_metrics.len;
    void *dest = (void *) malloc (dest_sz);
    if (unlikely (!dest))
    {
      subset_metrics.fini ();
      hb_blob_destroy (vorg_blob);
      return false;
    }

    /* serialize the new table */
    if (!_subset (plan, vorg_table, subset_metrics, dest_sz, dest))
    {
      subset_metrics.fini ();
      free (dest);
      hb_blob_destroy (vorg_blob);
      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 (HB_OT_TAG_VORG, result);
    hb_blob_destroy (result);
    subset_metrics.fini ();
    hb_blob_destroy (vorg_blob);
    return success;
  }

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
                  version.major == 1 &&
                  vertYOrigins.sanitize (c));
  }

  protected:
  FixedVersion<>	version;		/* Version of VORG table. Set to 0x00010000u. */
  FWORD			defaultVertOriginY;	/* The default vertical origin. */
  SortedArrayOf<VertOriginMetric>
			vertYOrigins;		/* The array of vertical origins. */

  public:
  DEFINE_SIZE_ARRAY(8, vertYOrigins);
};
} /* namespace OT */

#endif /* HB_OT_VORG_TABLE_HH */
