/*
 * Copyright © 2018  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): Garret Rieger, Rod Sheeter, Behdad Esfahbod
 */

#include "hb.hh"
#include "hb-open-type.hh"

#include "hb-subset.hh"

#include "hb-open-file.hh"
#include "hb-ot-cmap-table.hh"
#include "hb-ot-glyf-table.hh"
#include "hb-ot-hdmx-table.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-hhea-table.hh"
#include "hb-ot-hmtx-table.hh"
#include "hb-ot-maxp-table.hh"
#include "hb-ot-os2-table.hh"
#include "hb-ot-post-table.hh"
#include "hb-ot-cff1-table.hh"
#include "hb-ot-cff2-table.hh"
#include "hb-ot-vorg-table.hh"
#include "hb-ot-name-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"


HB_UNUSED static inline unsigned int
_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
				  unsigned int table_len);
static inline unsigned int
_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
				  unsigned int table_len)
{
  unsigned int src_glyphs = plan->source->get_num_glyphs ();
  unsigned int dst_glyphs = plan->glyphset ()->get_population ();

  if (unlikely (!src_glyphs))
    return 512 + table_len;

  return 512 + (unsigned int) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
}

template<typename TableType>
static bool
_subset2 (hb_subset_plan_t *plan)
{
  bool result = true;
  hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
  const TableType *table = source_blob->as<TableType> ();

  hb_tag_t tag = TableType::tableTag;
  if (source_blob->data)
  {
    hb_vector_t<char> buf;
    /* TODO Not all tables are glyph-related.  'name' table size for example should not be
     * affected by number of glyphs.  Accommodate that. */
    unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length);
    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
    if (unlikely (!buf.alloc (buf_size)))
    {
      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
      return false;
    }
  retry:
    hb_serialize_context_t serializer ((void *) buf, buf_size);
    serializer.start_serialize<TableType> ();
    hb_subset_context_t c (plan, &serializer);
    bool needed = table->subset (&c);
    if (serializer.ran_out_of_room)
    {
      buf_size += (buf_size >> 1) + 32;
      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size);
      if (unlikely (!buf.alloc (buf_size)))
      {
	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size);
	return false;
      }
      goto retry;
    }
    serializer.end_serialize ();

    result = !serializer.in_error ();

    if (result)
    {
      if (needed)
      {
	hb_blob_t *dest_blob = serializer.copy_blob ();
	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
	result = c.plan->add_table (tag, dest_blob);
	hb_blob_destroy (dest_blob);
      }
      else
      {
	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
      }
    }
  }
  else
    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));

  hb_blob_destroy (source_blob);
  DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!");
  return result;
}

template<typename TableType>
static bool
_subset (hb_subset_plan_t *plan)
{
  hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
  const TableType *table = source_blob->as<TableType> ();

  hb_tag_t tag = TableType::tableTag;
  hb_bool_t result = false;
  if (source_blob->data)
    result = table->subset (plan);
  else
    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));

  hb_blob_destroy (source_blob);
  DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!");
  return result;
}


static bool
_subset_table (hb_subset_plan_t *plan,
	       hb_tag_t          tag)
{
  DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG (tag));
  bool result = true;
  switch (tag) {
    case HB_OT_TAG_glyf:
      result = _subset2<const OT::glyf> (plan);
      break;
    case HB_OT_TAG_hdmx:
      result = _subset2<const OT::hdmx> (plan);
      break;
    case HB_OT_TAG_name:
      result = _subset2<const OT::name> (plan);
      break;
    case HB_OT_TAG_head:
      // TODO that won't work well if there is no glyf
      DEBUG_MSG(SUBSET, nullptr, "skip head, handled by glyf");
      result = true;
      break;
    case HB_OT_TAG_hhea:
      DEBUG_MSG(SUBSET, nullptr, "skip hhea handled by hmtx");
      return true;
    case HB_OT_TAG_hmtx:
      result = _subset<const OT::hmtx> (plan);
      break;
    case HB_OT_TAG_vhea:
      DEBUG_MSG(SUBSET, nullptr, "skip vhea handled by vmtx");
      return true;
    case HB_OT_TAG_vmtx:
      result = _subset<const OT::vmtx> (plan);
      break;
    case HB_OT_TAG_maxp:
      result = _subset<const OT::maxp> (plan);
      break;
    case HB_OT_TAG_loca:
      DEBUG_MSG(SUBSET, nullptr, "skip loca handled by glyf");
      return true;
    case HB_OT_TAG_cmap:
      result = _subset<const OT::cmap> (plan);
      break;
    case HB_OT_TAG_OS2:
      result = _subset<const OT::OS2> (plan);
      break;
    case HB_OT_TAG_post:
      result = _subset<const OT::post> (plan);
      break;

#ifndef HB_NO_SUBSET_CFF
    case HB_OT_TAG_cff1:
      result = _subset<const OT::cff1> (plan);
      break;
    case HB_OT_TAG_cff2:
      result = _subset<const OT::cff2> (plan);
      break;
    case HB_OT_TAG_VORG:
      result = _subset<const OT::VORG> (plan);
      break;
#endif

#ifndef HB_NO_SUBSET_LAYOUT
    case HB_OT_TAG_GDEF:
      result = _subset2<const OT::GDEF> (plan);
      break;
    case HB_OT_TAG_GSUB:
      result = _subset2<const OT::GSUB> (plan);
      break;
    case HB_OT_TAG_GPOS:
      result = _subset2<const OT::GPOS> (plan);
      break;
#endif

    default:
      hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
      if (likely (source_table))
	result = plan->add_table (tag, source_table);
      else
	result = false;
      hb_blob_destroy (source_table);
      break;
  }
  DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG (tag), result ? "ok" : "FAILED");
  return result;
}

static bool
_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
{
  if (plan->drop_tables->has (tag))
    return true;

  switch (tag) {
    case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
    case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */
    case HB_TAG ('f', 'p', 'g', 'm'): /* hint table, fallthrough */
    case HB_TAG ('p', 'r', 'e', 'p'): /* hint table, fallthrough */
    case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */
    case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */
      return plan->drop_hints;

#ifdef HB_NO_SUBSET_LAYOUT
    // Drop Layout Tables if requested.
    case HB_OT_TAG_GDEF:
    case HB_OT_TAG_GPOS:
    case HB_OT_TAG_GSUB:
    case HB_TAG ('m', 'o', 'r', 'x'):
    case HB_TAG ('m', 'o', 'r', 't'):
    case HB_TAG ('k', 'e', 'r', 'x'):
    case HB_TAG ('k', 'e', 'r', 'n'):
      return true;
#endif

    default:
      return false;
  }
}

/**
 * hb_subset:
 * @source: font face data to be subset.
 * @input: input to use for the subsetting.
 *
 * Subsets a font according to provided input.
 **/
hb_face_t *
hb_subset (hb_face_t *source,
	   hb_subset_input_t *input)
{
  if (unlikely (!input || !source)) return hb_face_get_empty ();

  hb_subset_plan_t *plan = hb_subset_plan_create (source, input);

  hb_tag_t table_tags[32];
  unsigned int offset = 0, count;
  bool success = true;
  do {
    count = ARRAY_LENGTH (table_tags);
    hb_face_get_table_tags (source, offset, &count, table_tags);
    for (unsigned int i = 0; i < count; i++)
    {
      hb_tag_t tag = table_tags[i];
      if (_should_drop_table (plan, tag))
      {
	DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG (tag));
	continue;
      }
      success = success && _subset_table (plan, tag);
    }
    offset += count;
  } while (success && count == ARRAY_LENGTH (table_tags));

  hb_face_t *result = success ? hb_face_reference (plan->dest) : hb_face_get_empty ();
  hb_subset_plan_destroy (plan);
  return result;
}
