/*
 * 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
{
  static unsigned int get_size (unsigned count)
  { return hb_ceil_to_4 (min_size + count * HBUINT8::static_size); }

  template<typename Iterator,
	   hb_requires (hb_is_iterator (Iterator))>
  bool serialize (hb_serialize_context_t *c,
		  unsigned pixelSize,
		  Iterator it,
		  const hb_vector_t<hb_codepoint_pair_t> new_to_old_gid_list,
		  unsigned num_glyphs)
  {
    TRACE_SERIALIZE (this);

    if (unlikely (!c->extend (this, num_glyphs)))  return_trace (false);

    this->pixelSize = pixelSize;
    this->maxWidth =
    + it
    | hb_reduce (hb_max, 0u);

    for (auto &_ : new_to_old_gid_list)
      widthsZ[_.first] = *it++;

    return_trace (true);
  }

  bool sanitize (hb_sanitize_context_t *c, unsigned 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_UNBOUNDED (2);
};


struct hdmx
{
  static constexpr hb_tag_t tableTag = HB_OT_TAG_hdmx;

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

  template<typename Iterator,
	   hb_requires (hb_is_iterator (Iterator))>
  bool serialize (hb_serialize_context_t *c,
		  unsigned version,
		  Iterator it,
		  const hb_vector_t<hb_codepoint_pair_t> &new_to_old_gid_list,
		  unsigned num_glyphs)
  {
    TRACE_SERIALIZE (this);

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

    this->version = version;
    this->numRecords = it.len ();
    this->sizeDeviceRecord = DeviceRecord::get_size (num_glyphs);

    for (const hb_item_type<Iterator>& _ : +it)
      c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second, new_to_old_gid_list, num_glyphs);

    return_trace (c->successful ());
  }


  bool subset (hb_subset_context_t *c) const
  {
    TRACE_SUBSET (this);

    auto *hdmx_prime = c->serializer->start_embed <hdmx> ();

    unsigned num_input_glyphs = get_num_glyphs ();
    auto it =
    + hb_range ((unsigned) numRecords)
    | hb_map ([c, num_input_glyphs, this] (unsigned _)
	{
	  const DeviceRecord *device_record =
	    &StructAtOffset<DeviceRecord> (&firstDeviceRecord,
					   _ * sizeDeviceRecord);
	  auto row =
	    + hb_iter (c->plan->new_to_old_gid_list)
	    | hb_map ([num_input_glyphs, device_record] (hb_codepoint_pair_t _)
		      {
			return device_record->widthsZ.as_array (num_input_glyphs) [_.second];
		      })
	    ;
	  return hb_pair ((unsigned) device_record->pixelSize, +row);
	})
    ;

    hdmx_prime->serialize (c->serializer, version, it,
			   c->plan->new_to_old_gid_list,
			   c->plan->num_output_glyphs ());
    return_trace (true);
  }

  unsigned get_num_glyphs () const
  {
    return sizeDeviceRecord - DeviceRecord::min_size;
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
		  !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) &&
                  min_size + numRecords * sizeDeviceRecord > 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 */
