/*
 * 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_CFF1_TABLE_HH
#define HB_OT_CFF1_TABLE_HH

#include "hb-ot-head-table.hh"
#include "hb-ot-cff-common.hh"
#include "hb-subset-cff1.hh"

namespace CFF {

/*
 * CFF -- Compact Font Format (CFF)
 * http://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf
 */
#define HB_OT_TAG_cff1 HB_TAG('C','F','F',' ')

#define CFF_UNDEF_SID   CFF_UNDEF_CODE

enum EncodingID { StandardEncoding = 0, ExpertEncoding = 1 };
enum CharsetID { ISOAdobeCharset = 0, ExpertCharset = 1, ExpertSubsetCharset = 2 };

typedef CFFIndex<HBUINT16>  CFF1Index;
template <typename Type> struct CFF1IndexOf : CFFIndexOf<HBUINT16, Type> {};

typedef CFFIndex<HBUINT16>  CFF1Index;
typedef CFF1Index         CFF1CharStrings;
typedef FDArray<HBUINT16> CFF1FDArray;
typedef Subrs<HBUINT16>   CFF1Subrs;

struct CFF1FDSelect : FDSelect {};

/* Encoding */
struct Encoding0 {
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) && codes[nCodes - 1].sanitize (c));
  }

  inline hb_codepoint_t get_code (hb_codepoint_t glyph) const
  {
    if (glyph < nCodes)
    {
      return (hb_codepoint_t)codes[glyph];
    }
    else
      return CFF_UNDEF_CODE;
  }

  inline unsigned int get_size (void) const
  { return HBUINT8::static_size * (nCodes + 1); }

  HBUINT8     nCodes;
  HBUINT8     codes[VAR];

  DEFINE_SIZE_ARRAY(1, codes);
};

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

  HBUINT8   first;
  HBUINT8   nLeft;

  DEFINE_SIZE_STATIC (2);
};

struct Encoding1 {
  inline unsigned int get_size (void) const
  { return HBUINT8::static_size + Encoding1_Range::static_size * nRanges; }

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) && ((nRanges == 0) || (ranges[nRanges - 1]).sanitize (c)));
  }

  inline hb_codepoint_t get_code (hb_codepoint_t glyph) const
  {
    for (unsigned int i = 0; i < nRanges; i++)
    {
      if (glyph <= ranges[i].nLeft)
      {
        return (hb_codepoint_t)ranges[i].first + glyph;
      }
      glyph -= (ranges[i].nLeft + 1);
    }
    return CFF_UNDEF_CODE;
  }

  HBUINT8           nRanges;
  Encoding1_Range   ranges[VAR];

  DEFINE_SIZE_ARRAY (1, ranges);
};

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

  HBUINT8   code;
  HBUINT16  glyph;

  DEFINE_SIZE_STATIC (3);
};

struct CFF1SuppEncData {
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) && ((nSups == 0) || (supps[nSups - 1]).sanitize (c)));
  }

  inline void get_codes (hb_codepoint_t sid, hb_vector_t<hb_codepoint_t> &codes) const
  {
    for (unsigned int i = 0; i < nSups; i++)
      if (sid == supps[i].glyph)
        codes.push (supps[i].code);
  }

  inline unsigned int get_size (void) const
  { return HBUINT8::static_size + SuppEncoding::static_size * nSups; }

  HBUINT8         nSups;
  SuppEncoding   supps[VAR];

  DEFINE_SIZE_ARRAY (1, supps);
};

struct Encoding {
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);

    if (unlikely (!c->check_struct (this)))
      return_trace (false);
    unsigned int fmt = format & 0x7F;
    if (unlikely (fmt > 1))
      return_trace (false);
    if (unlikely (!((fmt == 0)? u.format0.sanitize (c): u.format1.sanitize (c))))
      return_trace (false);
    return_trace (((format & 0x80) == 0) || suppEncData ().sanitize (c));
  }

  /* serialize a fullset Encoding */
  inline bool serialize (hb_serialize_context_t *c, const Encoding &src)
  {
    TRACE_SERIALIZE (this);
    unsigned int size = src.get_size ();
    Encoding *dest = c->allocate_size<Encoding> (size);
    if (unlikely (dest == nullptr)) return_trace (false);
    memcpy (dest, &src, size);
    return_trace (true);
  }

  /* serialize a subset Encoding */
  inline bool serialize (hb_serialize_context_t *c,
                         uint8_t format,
                         unsigned int enc_count,
                         const hb_vector_t<code_pair>& code_ranges,
                         const hb_vector_t<code_pair>& supp_codes)
  {
    TRACE_SERIALIZE (this);
    Encoding *dest = c->extend_min (*this);
    if (unlikely (dest == nullptr)) return_trace (false);
    dest->format.set (format | ((supp_codes.len > 0)? 0x80: 0));
    if (format == 0)
    {
      Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count);
    if (unlikely (fmt0 == nullptr)) return_trace (false);
      fmt0->nCodes.set (enc_count);
      unsigned int glyph = 0;
      for (unsigned int i = 0; i < code_ranges.len; i++)
      {
        hb_codepoint_t code = code_ranges[i].code;
        for (int left = (int)code_ranges[i].glyph; left >= 0; left--)
          fmt0->codes[glyph++].set (code++);
        assert ((glyph <= 0x100) && (code <= 0x100));
      }
    }
    else
    {
      Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.len);
      if (unlikely (fmt1 == nullptr)) return_trace (false);
      fmt1->nRanges.set (code_ranges.len);
      for (unsigned int i = 0; i < code_ranges.len; i++)
      {
        assert ((code_ranges[i].code <= 0xFF) && (code_ranges[i].glyph <= 0xFF));
        fmt1->ranges[i].first.set (code_ranges[i].code);
        fmt1->ranges[i].nLeft.set (code_ranges[i].glyph);
      }
    }
    if (supp_codes.len > 0)
    {
      CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.len);
      if (unlikely (suppData == nullptr)) return_trace (false);
      suppData->nSups.set (supp_codes.len);
      for (unsigned int i = 0; i < supp_codes.len; i++)
      {
        suppData->supps[i].code.set (supp_codes[i].code);
        suppData->supps[i].glyph.set (supp_codes[i].glyph); /* actually SID */
      }
    }
    return_trace (true);
  }

  /* parallel to above: calculate the size of a subset Encoding */
  static inline unsigned int calculate_serialized_size (
                        uint8_t format,
                        unsigned int enc_count,
                        unsigned int supp_count)
  {
    unsigned int  size = min_size;
    if (format == 0)
      size += Encoding0::min_size + HBUINT8::static_size * enc_count;
    else
      size += Encoding1::min_size + Encoding1_Range::static_size * enc_count;
    if (supp_count > 0)
      size += CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_count;
    return size;
  }

  inline unsigned int get_size (void) const
  {
    unsigned int size = min_size;
    if (table_format () == 0)
      size += u.format0.get_size ();
    else
      size += u.format1.get_size ();
    if (has_supplement ())
      size += suppEncData ().get_size ();
    return size;
  }

  inline hb_codepoint_t get_code (hb_codepoint_t glyph) const
  {
    if (table_format () == 0)
      return u.format0.get_code (glyph);
    else
      return u.format1.get_code (glyph);
  }

  inline uint8_t table_format (void) const { return (format & 0x7F); }
  inline bool  has_supplement (void) const { return (format & 0x80) != 0; }

  inline void get_supplement_codes (hb_codepoint_t sid, hb_vector_t<hb_codepoint_t> &codes) const
  {
    codes.resize (0);
    if (has_supplement ())
      suppEncData().get_codes (sid, codes);
  }

  protected:
  inline const CFF1SuppEncData &suppEncData (void) const
  {
    if ((format & 0x7F) == 0)
      return StructAfter<CFF1SuppEncData> (u.format0.codes[u.format0.nCodes-1]);
    else
      return StructAfter<CFF1SuppEncData> (u.format1.ranges[u.format1.nRanges-1]);
  }

  public:
  HBUINT8       format;

  union {
    Encoding0   format0;
    Encoding1   format1;
  } u;
  /* CFF1SuppEncData  suppEncData; */

  DEFINE_SIZE_MIN (1);
};

/* Charset */
struct Charset0 {
  inline bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) && sids[num_glyphs - 1].sanitize (c));
  }

  inline hb_codepoint_t get_sid (hb_codepoint_t glyph) const
  {
    if (glyph == 0)
      return 0;
    else
      return sids[glyph - 1];
  }

  inline unsigned int get_size (unsigned int num_glyphs) const
  {
    assert (num_glyphs > 0);
    return HBUINT16::static_size * (num_glyphs - 1);
  }

  HBUINT16  sids[VAR];

  DEFINE_SIZE_ARRAY(0, sids);
};

template <typename TYPE>
struct Charset_Range {
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this));
  }

  HBUINT16  first;
  TYPE      nLeft;

  DEFINE_SIZE_STATIC (HBUINT16::static_size + TYPE::static_size);
};

template <typename TYPE>
struct Charset1_2 {
  inline bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const
  {
    TRACE_SANITIZE (this);
    if (unlikely (!c->check_struct (this)))
      return_trace (false);
    num_glyphs--;
    for (unsigned int i = 0; num_glyphs > 0; i++)
    {
      if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1)))
        return_trace (false);
      num_glyphs -= (ranges[i].nLeft + 1);
    }
    return_trace (true);
  }

  inline hb_codepoint_t get_sid (hb_codepoint_t glyph) const
  {
    if (glyph == 0) return 0;
    glyph--;
    for (unsigned int i = 0;; i++)
    {
      if (glyph <= ranges[i].nLeft)
        return (hb_codepoint_t)ranges[i].first + glyph;
      glyph -= (ranges[i].nLeft + 1);
    }
  
    return 0;
  }

  inline unsigned int get_size (unsigned int num_glyphs) const
  {
    unsigned int size = HBUINT8::static_size;
    int glyph = (int)num_glyphs;
  
    assert (glyph > 0);
    glyph--;
    for (unsigned int i = 0; glyph > 0; i++)
    {
      glyph -= (ranges[i].nLeft + 1);
      size += Charset_Range<TYPE>::static_size;
    }

    return size;
  }

  Charset_Range<TYPE>   ranges[VAR];

  DEFINE_SIZE_ARRAY (0, ranges);
};

typedef Charset1_2<HBUINT8>     Charset1;
typedef Charset1_2<HBUINT16>    Charset2;
typedef Charset_Range<HBUINT8>  Charset1_Range;
typedef Charset_Range<HBUINT16> Charset2_Range;

struct Charset {
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);

    if (unlikely (!c->check_struct (this)))
      return_trace (false);
    if (format == 0)
      return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
    else if (format == 1)
      return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
    else if (likely (format == 2))
      return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
    else
      return_trace (false);
  }

  /* serialize a fullset Charset */
  inline bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs)
  {
    TRACE_SERIALIZE (this);
    unsigned int size = src.get_size (num_glyphs);
    Charset *dest = c->allocate_size<Charset> (size);
    if (unlikely (dest == nullptr)) return_trace (false);
    memcpy (dest, &src, size);
    return_trace (true);
  }

  /* serialize a subset Charset */
  inline bool serialize (hb_serialize_context_t *c,
                         uint8_t format,
                         unsigned int num_glyphs,
                         const hb_vector_t<code_pair>& sid_ranges)
  {
    TRACE_SERIALIZE (this);
    Charset *dest = c->extend_min (*this);
    if (unlikely (dest == nullptr)) return_trace (false);
    dest->format.set (format);
    if (format == 0)
    {
      Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
    if (unlikely (fmt0 == nullptr)) return_trace (false);
      unsigned int glyph = 0;
      for (unsigned int i = 0; i < sid_ranges.len; i++)
      {
        hb_codepoint_t sid = sid_ranges[i].code;
        for (int left = (int)sid_ranges[i].glyph; left >= 0; left--)
          fmt0->sids[glyph++].set (sid++);
      }
    }
    else if (format == 1)
    {
      Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.len);
      if (unlikely (fmt1 == nullptr)) return_trace (false);
      for (unsigned int i = 0; i < sid_ranges.len; i++)
      {
        assert (sid_ranges[i].glyph <= 0xFF);
        fmt1->ranges[i].first.set (sid_ranges[i].code);
        fmt1->ranges[i].nLeft.set (sid_ranges[i].glyph);
      }
    }
    else /* format 2 */
    {
      Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.len);
      if (unlikely (fmt2 == nullptr)) return_trace (false);
      for (unsigned int i = 0; i < sid_ranges.len; i++)
      {
        assert (sid_ranges[i].glyph <= 0xFFFF);
        fmt2->ranges[i].first.set (sid_ranges[i].code);
        fmt2->ranges[i].nLeft.set (sid_ranges[i].glyph);
      }
    }
    return_trace (true);
  }

  /* parallel to above: calculate the size of a subset Charset */
  static inline unsigned int calculate_serialized_size (
                        uint8_t format,
                        unsigned int count)
  {
    unsigned int  size = min_size;
    if (format == 0)
      size += Charset0::min_size + HBUINT16::static_size * (count - 1);
    else if (format == 1)
      size += Charset1::min_size + Charset1_Range::static_size * count;
    else
      size += Charset2::min_size + Charset2_Range::static_size * count;

    return size;
  }

  inline unsigned int get_size (unsigned int num_glyphs) const
  {
    unsigned int size = min_size;
    if (format == 0)
      size += u.format0.get_size (num_glyphs);
    else if (format == 1)
      size += u.format1.get_size (num_glyphs);
    else
      size += u.format2.get_size (num_glyphs);
    return size;
  }

  inline hb_codepoint_t get_sid (hb_codepoint_t glyph) const
  {
    if (format == 0)
      return u.format0.get_sid (glyph);
    else if (format == 1)
      return u.format1.get_sid (glyph);
    else
      return u.format2.get_sid (glyph);
  }

  HBUINT8       format;
  union {
    Charset0    format0;
    Charset1    format1;
    Charset2    format2;
  } u;

  DEFINE_SIZE_MIN (1);
};

struct CFF1StringIndex : CFF1Index
{
  inline bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings, unsigned int offSize_, const Remap &sidmap)
  {
    TRACE_SERIALIZE (this);
    if (unlikely ((strings.count == 0) || (sidmap.get_count () == 0)))
    {
      if (!unlikely (c->extend_min (this->count)))
        return_trace (false);
      count.set (0);
      return_trace (true);
    }
    
    hb_vector_t<ByteStr> bytesArray;
    bytesArray.init ();
    if (!bytesArray.resize (sidmap.get_count ()))
      return_trace (false);
    for (unsigned int i = 0; i < strings.count; i++)
    {
      hb_codepoint_t  j = sidmap[i];
      if (j != CFF_UNDEF_CODE)
        bytesArray[j] = strings[i];
    }

    bool result = CFF1Index::serialize (c, offSize_, bytesArray);
    bytesArray.fini ();
    return_trace (result);
  }
  
  /* in parallel to above */
  inline unsigned int calculate_serialized_size (unsigned int &offSize /*OUT*/, const Remap &sidmap) const
  {
    offSize = 0;
    if ((count == 0) || (sidmap.get_count () == 0))
      return count.static_size;

    unsigned int dataSize = 0;
    for (unsigned int i = 0; i < count; i++)
      if (sidmap[i] != CFF_UNDEF_CODE)
        dataSize += length_at (i);

    offSize = calcOffSize(dataSize);
    return CFF1Index::calculate_serialized_size (offSize, sidmap.get_count (), dataSize);
  }
};

struct CFF1TopDictInterpEnv : NumInterpEnv
{
  inline CFF1TopDictInterpEnv (void)
    : NumInterpEnv(), prev_offset(0), last_offset(0) {}

  unsigned int prev_offset;
  unsigned int last_offset;
};

struct NameDictValues
{
  enum NameDictValIndex
  {
      version,
      notice,
      copyright,
      fullName,
      familyName,
      weight,
      postscript,
      fontName,
      baseFontName,
      registry,
      ordering,

      ValCount
  };

  inline void init (void)
  {
    for (unsigned int i = 0; i < ValCount; i++)
      values[i] = CFF_UNDEF_SID;
  }

  inline unsigned int& operator[] (unsigned int i)
  { assert (i < ValCount); return values[i]; }

  inline unsigned int operator[] (unsigned int i) const
  { assert (i < ValCount); return values[i]; }

  static inline enum NameDictValIndex name_op_to_index (OpCode op)
  {
    switch (op) {
      case OpCode_version:
        return version;
      case OpCode_Notice:
        return notice;
      case OpCode_Copyright:
        return copyright;
      case OpCode_FullName:
        return fullName;
      case OpCode_FamilyName:
        return familyName;
      case OpCode_Weight:
        return weight;
      case OpCode_PostScript:
        return postscript;
      case OpCode_FontName:
        return fontName;
      default:
        assert (0);
      }
  }

  unsigned int  values[ValCount];
};

struct CFF1TopDictVal : OpStr
{
  unsigned int  last_arg_offset;
};

struct CFF1TopDictValues : TopDictValues<CFF1TopDictVal>
{
  inline void init (void)
  {
    TopDictValues<CFF1TopDictVal>::init ();

    nameSIDs.init ();
    ros_supplement = 0;
    cidCount = 8720;
    EncodingOffset = 0;
    CharsetOffset = 0;
    FDSelectOffset = 0;
    privateDictInfo.init ();
  }

  inline void fini (void)
  {
    TopDictValues<CFF1TopDictVal>::fini ();
  }

  inline bool is_CID (void) const
  { return nameSIDs[NameDictValues::registry] != CFF_UNDEF_SID; }

  NameDictValues  nameSIDs;
  unsigned int    ros_supplement_offset;
  unsigned int    ros_supplement;
  unsigned int    cidCount;

  unsigned int    EncodingOffset;
  unsigned int    CharsetOffset;
  unsigned int    FDSelectOffset;
  TableInfo       privateDictInfo;
};

struct CFF1TopDictOpSet : TopDictOpSet<CFF1TopDictVal>
{
  static inline void process_op (OpCode op, CFF1TopDictInterpEnv& env, CFF1TopDictValues& dictval)
  {
    CFF1TopDictVal  val;
    val.last_arg_offset = (env.last_offset-1) - dictval.opStart;  /* offset to the last argument */

    switch (op) {
      case OpCode_version:
      case OpCode_Notice:
      case OpCode_Copyright:
      case OpCode_FullName:
      case OpCode_FamilyName:
      case OpCode_Weight:
      case OpCode_PostScript:
      case OpCode_BaseFontName:
        dictval.nameSIDs[NameDictValues::name_op_to_index (op)] = env.argStack.pop_uint ();
        env.clear_args ();
        break;
      case OpCode_isFixedPitch:
      case OpCode_ItalicAngle:
      case OpCode_UnderlinePosition:
      case OpCode_UnderlineThickness:
      case OpCode_PaintType:
      case OpCode_CharstringType:
      case OpCode_UniqueID:
      case OpCode_StrokeWidth:
      case OpCode_SyntheticBase:
      case OpCode_CIDFontVersion:
      case OpCode_CIDFontRevision:
      case OpCode_CIDFontType:
      case OpCode_UIDBase:
      case OpCode_FontBBox:
      case OpCode_XUID:
      case OpCode_BaseFontBlend:
        env.clear_args ();
        break;
        
      case OpCode_CIDCount:
        dictval.cidCount = env.argStack.pop_uint ();
        env.clear_args ();
        break;

      case OpCode_ROS:
        dictval.ros_supplement = env.argStack.pop_uint ();
        dictval.nameSIDs[NameDictValues::ordering] = env.argStack.pop_uint ();
        dictval.nameSIDs[NameDictValues::registry] = env.argStack.pop_uint ();
        env.clear_args ();
        break;

      case OpCode_Encoding:
        dictval.EncodingOffset = env.argStack.pop_uint ();
        env.clear_args ();
        break;

      case OpCode_charset:
        dictval.CharsetOffset = env.argStack.pop_uint ();
        env.clear_args ();
        break;

      case OpCode_FDSelect:
        dictval.FDSelectOffset = env.argStack.pop_uint ();
        env.clear_args ();
        break;
    
      case OpCode_Private:
        dictval.privateDictInfo.offset = env.argStack.pop_uint ();
        dictval.privateDictInfo.size = env.argStack.pop_uint ();
        env.clear_args ();
        break;
    
      default:
        env.last_offset = env.substr.offset;
        TopDictOpSet<CFF1TopDictVal>::process_op (op, env, dictval);
        /* Record this operand below if stack is empty, otherwise done */
        if (!env.argStack.is_empty ()) return;
        break;
    }

    if (unlikely (env.in_error ())) return;

    dictval.addOp (op, env.substr, val);
  }
};

struct CFF1FontDictValues : DictValues<OpStr>
{
  inline void init (void)
  {
    DictValues<OpStr>::init ();
    privateDictInfo.init ();
    fontName = CFF_UNDEF_SID;
  }

  inline void fini (void)
  {
    DictValues<OpStr>::fini ();
  }

  TableInfo       privateDictInfo;
  unsigned int    fontName;
};

struct CFF1FontDictOpSet : DictOpSet
{
  static inline void process_op (OpCode op, NumInterpEnv& env, CFF1FontDictValues& dictval)
  {
    switch (op) {
      case OpCode_FontName:
        dictval.fontName = env.argStack.pop_uint ();
        env.clear_args ();
        break;
      case OpCode_FontMatrix:
      case OpCode_PaintType:
        env.clear_args ();
        break;
      case OpCode_Private:
        dictval.privateDictInfo.offset = env.argStack.pop_uint ();
        dictval.privateDictInfo.size = env.argStack.pop_uint ();
        env.clear_args ();
        break;
    
      default:
        DictOpSet::process_op (op, env);
        if (!env.argStack.is_empty ()) return;
        break;
    }

    if (unlikely (env.in_error ())) return;

    dictval.addOp (op, env.substr);
  }
};

template <typename VAL>
struct CFF1PrivateDictValues_Base : DictValues<VAL>
{
  inline void init (void)
  {
    DictValues<VAL>::init ();
    subrsOffset = 0;
    localSubrs = &Null(CFF1Subrs);
  }

  inline void fini (void)
  {
    DictValues<VAL>::fini ();
  }

  inline unsigned int calculate_serialized_size (void) const
  {
    unsigned int size = 0;
    for (unsigned int i = 0; i < DictValues<VAL>::getNumValues; i++)
      if (DictValues<VAL>::getValue (i).op == OpCode_Subrs)
        size += OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Subrs);
      else
        size += DictValues<VAL>::getValue (i).str.len;
    return size;
  }

  unsigned int      subrsOffset;
  const CFF1Subrs    *localSubrs;
};

typedef CFF1PrivateDictValues_Base<OpStr> CFF1PrivateDictValues_Subset;
typedef CFF1PrivateDictValues_Base<NumDictVal> CFF1PrivateDictValues;

struct CFF1PrivateDictOpSet : DictOpSet
{
  static inline void process_op (OpCode op, NumInterpEnv& env, CFF1PrivateDictValues& dictval)
  {
    NumDictVal val;
    val.init ();

    switch (op) {
      case OpCode_BlueValues:
      case OpCode_OtherBlues:
      case OpCode_FamilyBlues:
      case OpCode_FamilyOtherBlues:
      case OpCode_StemSnapH:
      case OpCode_StemSnapV:
        env.clear_args ();
        break;
      case OpCode_StdHW:
      case OpCode_StdVW:
      case OpCode_BlueScale:
      case OpCode_BlueShift:
      case OpCode_BlueFuzz:
      case OpCode_ForceBold:
      case OpCode_LanguageGroup:
      case OpCode_ExpansionFactor:
      case OpCode_initialRandomSeed:
      case OpCode_defaultWidthX:
      case OpCode_nominalWidthX:
        val.single_val = env.argStack.pop_num ();
        env.clear_args ();
        break;
      case OpCode_Subrs:
        dictval.subrsOffset = env.argStack.pop_uint ();
        env.clear_args ();
        break;

      default:
        DictOpSet::process_op (op, env);
        if (!env.argStack.is_empty ()) return;
        break;
    }

    if (unlikely (env.in_error ())) return;

    dictval.addOp (op, env.substr, val);
  }
};

struct CFF1PrivateDictOpSet_Subset : DictOpSet
{
  static inline void process_op (OpCode op, NumInterpEnv& env, CFF1PrivateDictValues_Subset& dictval)
  {
    switch (op) {
      case OpCode_BlueValues:
      case OpCode_OtherBlues:
      case OpCode_FamilyBlues:
      case OpCode_FamilyOtherBlues:
      case OpCode_StemSnapH:
      case OpCode_StemSnapV:
      case OpCode_StdHW:
      case OpCode_StdVW:
      case OpCode_BlueScale:
      case OpCode_BlueShift:
      case OpCode_BlueFuzz:
      case OpCode_ForceBold:
      case OpCode_LanguageGroup:
      case OpCode_ExpansionFactor:
      case OpCode_initialRandomSeed:
      case OpCode_defaultWidthX:
      case OpCode_nominalWidthX:
        env.clear_args ();
        break;

      case OpCode_Subrs:
        dictval.subrsOffset = env.argStack.pop_uint ();
        env.clear_args ();
        break;

      default:
        DictOpSet::process_op (op, env);
        if (!env.argStack.is_empty ()) return;
        break;
    }

    if (unlikely (env.in_error ())) return;

    dictval.addOp (op, env.substr);
  }
};

typedef DictInterpreter<CFF1TopDictOpSet, CFF1TopDictValues, CFF1TopDictInterpEnv> CFF1TopDict_Interpreter;
typedef DictInterpreter<CFF1FontDictOpSet, CFF1FontDictValues> CFF1FontDict_Interpreter;
typedef DictInterpreter<CFF1PrivateDictOpSet, CFF1PrivateDictValues> CFF1PrivateDict_Interpreter;

typedef CFF1Index CFF1NameIndex;
typedef CFF1IndexOf<TopDict> CFF1TopDictIndex;

}; /* namespace CFF */

namespace OT {

using namespace CFF;

struct cff1
{
  static const hb_tag_t tableTag        = HB_OT_TAG_cff1;

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

  template <typename PRIVOPSET, typename PRIVDICTVAL>
  struct accelerator_templ_t
  {
    inline void init (hb_face_t *face)
    {
      topDict.init ();
      fontDicts.init ();
      privateDicts.init ();
      
      this->blob = sc.reference_table<cff1> (face);

      /* setup for run-time santization */
      sc.init (this->blob);
      sc.start_processing ();
      
      const OT::cff1 *cff = this->blob->template as<OT::cff1> ();

      if (cff == &Null(OT::cff1))
      { fini (); return; }

      nameIndex = &cff->nameIndex (cff);
      if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc))
      { fini (); return; }

      topDictIndex = &StructAtOffset<CFF1TopDictIndex> (nameIndex, nameIndex->get_size ());
      if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0))
      { fini (); return; }

      { /* parse top dict */
        const ByteStr topDictStr = (*topDictIndex)[0];
        if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; }
        CFF1TopDict_Interpreter top_interp;
        top_interp.env.init (topDictStr);
        if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
      }
      
      fdCount = 1;
      if (is_CID ())
      {
        fdArray = &StructAtOffsetOrNull<CFF1FDArray> (cff, topDict.FDArrayOffset);
        fdSelect = &StructAtOffsetOrNull<CFF1FDSelect> (cff, topDict.FDSelectOffset);
        if (unlikely ((fdArray == &Null(CFF1FDArray)) || !fdArray->sanitize (&sc) ||
            (fdSelect == &Null(CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count)))
        { fini (); return; }

        fdCount = fdArray->count;
      }
      else
      {
        fdArray = &Null(CFF1FDArray);
        fdSelect = &Null(CFF1FDSelect);
      }

      stringIndex = &StructAtOffset<CFF1StringIndex> (topDictIndex, topDictIndex->get_size ());
      if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc))
      { fini (); return; }

      globalSubrs = &StructAtOffset<CFF1Subrs> (stringIndex, stringIndex->get_size ());
      if ((globalSubrs != &Null (CFF1Subrs)) && !stringIndex->sanitize (&sc))
      { fini (); return; }

      charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset);

      if ((charStrings == &Null(CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc)))
      { fini (); return; }

      num_glyphs = charStrings->count;
      if (num_glyphs != sc.get_num_glyphs ())
      { fini (); return; }

      privateDicts.resize (fdCount);
      for (unsigned int i = 0; i < fdCount; i++)
        privateDicts[i].init ();

      // parse CID font dicts and gather private dicts
      if (is_CID ())
      {
        for (unsigned int i = 0; i < fdCount; i++)
        {
          ByteStr fontDictStr = (*fdArray)[i];
          if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
          CFF1FontDictValues  *font;
          CFF1FontDict_Interpreter font_interp;
          font_interp.env.init (fontDictStr);
          font = fontDicts.push ();
          if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
          PRIVDICTVAL  *priv = &privateDicts[i];
          const ByteStr privDictStr (StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset), font->privateDictInfo.size);
          if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
          DictInterpreter<PRIVOPSET, PRIVDICTVAL> priv_interp;
          priv_interp.env.init (privDictStr);
          if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }

          priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (privDictStr.str, priv->subrsOffset);
          if (priv->localSubrs != &Null(CFF1Subrs) &&
              unlikely (!priv->localSubrs->sanitize (&sc)))
          { fini (); return; }
        }
      }
      else  /* non-CID */
      {
        CFF1TopDictValues  *font = &topDict;
        PRIVDICTVAL  *priv = &privateDicts[0];
        
        const ByteStr privDictStr (StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset), font->privateDictInfo.size);
        if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
        DictInterpreter<PRIVOPSET, PRIVDICTVAL> priv_interp;
        priv_interp.env.init (privDictStr);
        if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }

        priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (privDictStr.str, priv->subrsOffset);
        if (priv->localSubrs != &Null(CFF1Subrs) &&
            unlikely (!priv->localSubrs->sanitize (&sc)))
        { fini (); return; }
      }
    }

    inline void fini (void)
    {
      sc.end_processing ();
      topDict.fini ();
      fontDicts.fini ();
      privateDicts.fini_deep ();
      hb_blob_destroy (blob);
      blob = nullptr;
    }

    inline bool is_valid (void) const { return blob != nullptr; }
    inline bool is_CID (void) const { return topDict.is_CID (); }

    protected:
    hb_blob_t               *blob;
    hb_sanitize_context_t   sc;

    public:
    const CFF1NameIndex     *nameIndex;
    const CFF1TopDictIndex  *topDictIndex;
    const CFF1StringIndex   *stringIndex;
    const CFF1Subrs         *globalSubrs;
    const CFF1CharStrings   *charStrings;
    const CFF1FDArray       *fdArray;
    const CFF1FDSelect      *fdSelect;
    unsigned int            fdCount;

    CFF1TopDictValues       topDict;
    hb_vector_t<CFF1FontDictValues>   fontDicts;
    hb_vector_t<PRIVDICTVAL>          privateDicts;

    unsigned int            num_glyphs;
  };

  struct accelerator_t : accelerator_templ_t<CFF1PrivateDictOpSet, CFF1PrivateDictValues>
  {
    HB_INTERNAL bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
  };

  struct accelerator_subset_t : accelerator_templ_t<CFF1PrivateDictOpSet_Subset, CFF1PrivateDictValues_Subset>
  {
    inline void init (hb_face_t *face)
    {
      SUPER::init (face);
      if (blob == nullptr) return;
    
      const OT::cff1 *cff = this->blob->as<OT::cff1> ();
      encoding = &Null(Encoding);
      if (is_predef_charset ())
        charset = &Null(Charset);
      else
      {
        charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset);
        if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc))) { fini (); return; }
      }
      if (is_CID ())
      {
        if (unlikely (charset == &Null(Charset))) { fini (); return; }
      }
      else
      {
        if (!is_predef_encoding ())
        {
          encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset);
          if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; }
        }
      }
    }

    inline bool is_predef_encoding (void) const { return topDict.EncodingOffset <= ExpertEncoding; }
    inline bool is_predef_charset (void) const { return topDict.CharsetOffset <= ExpertSubsetCharset; }

    inline hb_codepoint_t  glyph_to_code (hb_codepoint_t glyph) const
    {
      if (encoding != &Null(Encoding))
        return encoding->get_code (glyph);
      else
      {
        hb_codepoint_t  sid = glyph_to_sid (glyph);
        if (sid == 0) return 0;
        hb_codepoint_t  code = 0;
        switch (topDict.EncodingOffset)
        {
          case  StandardEncoding:
            code = lookup_standard_encoding (sid);
            break;
          case  ExpertEncoding:
            code = lookup_expert_encoding (sid);
            break;
          default:
            break;
        }
        return code;
      }
    }

    inline hb_codepoint_t  glyph_to_sid (hb_codepoint_t glyph) const
    {
      if (charset != &Null(Charset))
        return charset->get_sid (glyph);
      else
      {
        hb_codepoint_t sid = 0;
        switch (topDict.CharsetOffset)
        {
          case  ISOAdobeCharset:
            if (glyph <= 228 /*zcaron*/) sid = glyph;
            break;
          case  ExpertCharset:
            sid = lookup_expert_charset (glyph);
            break;
          case  ExpertSubsetCharset:
              sid = lookup_expert_subset_charset (glyph);
            break;
          default:
            break;
        }
        return sid;
      }
    }

    const Encoding          *encoding;
    const Charset           *charset;

    private:
    typedef accelerator_templ_t<CFF1PrivateDictOpSet_Subset, CFF1PrivateDictValues_Subset> SUPER;
  };

  inline bool subset (hb_subset_plan_t *plan) const
  {
    hb_blob_t *cff_prime = nullptr;

    bool success = true;
    if (hb_subset_cff1 (plan, &cff_prime)) {
      success = success && plan->add_table (HB_OT_TAG_cff1, cff_prime);
      hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (plan->source);
      success = success && head_blob && plan->add_table (HB_OT_TAG_head, head_blob);
      hb_blob_destroy (head_blob);
    } else {
      success = false;
    }
    hb_blob_destroy (cff_prime);

    return success;
  }

  protected:
  HB_INTERNAL static hb_codepoint_t lookup_standard_encoding (hb_codepoint_t sid);
  HB_INTERNAL static hb_codepoint_t lookup_expert_encoding (hb_codepoint_t sid);
  HB_INTERNAL static hb_codepoint_t lookup_expert_charset (hb_codepoint_t glyph);
  HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset (hb_codepoint_t glyph);

  public:
  FixedVersion<HBUINT8> version;          /* Version of CFF table. set to 0x0100u */
  OffsetTo<CFF1NameIndex, HBUINT8> nameIndex; /* headerSize = Offset to Name INDEX. */
  HBUINT8               offSize;          /* offset size (unused?) */

  public:
  DEFINE_SIZE_STATIC (4);
};

struct cff1_accelerator_t : cff1::accelerator_t {};
} /* namespace OT */

#endif /* HB_OT_CFF1_TABLE_HH */
