/*
 * 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
 */

#ifndef HB_OT_HDMX_TABLE_HH
#define HB_OT_HDMX_TABLE_HH

#include "hb-open-type.hh"

/*
 * hdmx -- Horizontal Device Metrics
 * https://docs.microsoft.com/en-us/typography/opentype/spec/hdmx
 */
#define HB_OT_TAG_hdmx HB_TAG('h','d','m','x')


namespace OT {


struct DeviceRecord
{
  struct SubsetView
  {
    const DeviceRecord *source_device_record;
    unsigned int sizeDeviceRecord;
    hb_subset_plan_t *subset_plan;

    inline void init (const DeviceRecord *source_device_record,
		      unsigned int sizeDeviceRecord,
		      hb_subset_plan_t   *subset_plan)
    {
      this->source_device_record = source_device_record;
      this->sizeDeviceRecord = sizeDeviceRecord;
      this->subset_plan = subset_plan;
    }

    inline unsigned int len () const
    {
      return this->subset_plan->glyphs.len;
    }

    inline const HBUINT8* operator [] (unsigned int i) const
    {
      if (unlikely (i >= len ())) return nullptr;
      hb_codepoint_t gid = this->subset_plan->glyphs [i];

      if (gid >= sizeDeviceRecord - DeviceRecord::min_size)
        return nullptr;
      return &(this->source_device_record->widthsZ[gid]);
    }
  };

  static inline unsigned int get_size (unsigned int count)
  {
    return hb_ceil_to_4 (min_size + count * HBUINT8::static_size);
  }

  inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view)
  {
    TRACE_SERIALIZE (this);

    unsigned int size = get_size (subset_view.len ());
    if (unlikely (!c->allocate_size<DeviceRecord> (size)))
    {
      DEBUG_MSG(SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.",
		 size);
      return_trace (false);
    }

    this->pixelSize.set (subset_view.source_device_record->pixelSize);
    this->maxWidth.set (subset_view.source_device_record->maxWidth);

    for (unsigned int i = 0; i < subset_view.len (); i++)
    {
      const HBUINT8 *width = subset_view[i];
      if (!width)
      {
	DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i);
	return_trace (false);
      }
      widthsZ[i].set (*width);
    }

    return_trace (true);
  }

  inline bool sanitize (hb_sanitize_context_t *c, unsigned int sizeDeviceRecord) const
  {
    TRACE_SANITIZE (this);
    return_trace (likely (c->check_struct (this) &&
			  c->check_range (this, sizeDeviceRecord)));
  }

  HBUINT8			pixelSize;	/* Pixel size for following widths (as ppem). */
  HBUINT8			maxWidth;	/* Maximum width. */
  UnsizedArrayOf<HBUINT8>	widthsZ;	/* Array of widths (numGlyphs is from the 'maxp' table). */
  public:
  DEFINE_SIZE_ARRAY (2, widthsZ);
};


struct hdmx
{
  enum { tableTag = HB_OT_TAG_hdmx };

  inline unsigned int get_size (void) const
  {
    return min_size + numRecords * sizeDeviceRecord;
  }

  inline const DeviceRecord& operator [] (unsigned int i) const
  {
    /* XXX Null(DeviceRecord) is NOT safe as it's num-glyphs lengthed.
     * https://github.com/harfbuzz/harfbuzz/issues/1300 */
    if (unlikely (i >= numRecords)) return Null (DeviceRecord);
    return StructAtOffset<DeviceRecord> (&this->firstDeviceRecord, i * sizeDeviceRecord);
  }

  inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
  {
    TRACE_SERIALIZE (this);

    if (unlikely (!c->extend_min ((*this))))  return_trace (false);

    this->version.set (source_hdmx->version);
    this->numRecords.set (source_hdmx->numRecords);
    this->sizeDeviceRecord.set (DeviceRecord::get_size (plan->glyphs.len));

    for (unsigned int i = 0; i < source_hdmx->numRecords; i++)
    {
      DeviceRecord::SubsetView subset_view;
      subset_view.init (&(*source_hdmx)[i], source_hdmx->sizeDeviceRecord, plan);

      if (!c->start_embed<DeviceRecord> ()->serialize (c, subset_view))
	return_trace (false);
    }

    return_trace (true);
  }

  static inline size_t get_subsetted_size (const hdmx *source_hdmx, hb_subset_plan_t *plan)
  {
    return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->glyphs.len);
  }

  inline bool subset (hb_subset_plan_t *plan) const
  {
    size_t dest_size = get_subsetted_size (this, plan);
    hdmx *dest = (hdmx *) malloc (dest_size);
    if (unlikely (!dest))
    {
      DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for hdmx subset output.", (unsigned long) dest_size);
      return false;
    }

    hb_serialize_context_t c (dest, dest_size);
    hdmx *hdmx_prime = c.start_serialize<hdmx> ();
    if (!hdmx_prime || !hdmx_prime->serialize (&c, this, plan))
    {
      free (dest);
      DEBUG_MSG(SUBSET, nullptr, "Failed to serialize write new hdmx.");
      return false;
    }
    c.end_serialize ();

    hb_blob_t *hdmx_prime_blob = hb_blob_create ((const char *) dest,
						 dest_size,
						 HB_MEMORY_MODE_READONLY,
						 dest,
						 free);
    bool result = plan->add_table (HB_OT_TAG_hdmx, hdmx_prime_blob);
    hb_blob_destroy (hdmx_prime_blob);

    return result;
  }

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
		  !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) &&
		  sizeDeviceRecord >= DeviceRecord::min_size &&
		  c->check_range (this, get_size ()));
  }

  protected:
  HBUINT16		version;		/* Table version number (0) */
  HBUINT16		numRecords;		/* Number of device records. */
  HBUINT32		sizeDeviceRecord;	/* Size of a device record, 32-bit aligned. */
  DeviceRecord		firstDeviceRecord;	/* Array of device records. */
  public:
  DEFINE_SIZE_MIN (8);
};

} /* namespace OT */


#endif /* HB_OT_HDMX_TABLE_HH */
