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

#ifndef HB_SUBSET_CFF_COMMON_HH
#define HB_SUBSET_CFF_COMMON_HH

#include "hb.hh"

#include "hb-subset-plan.hh"
#include "hb-cff-interp-cs-common.hh"

namespace CFF {

/* Used for writing a temporary charstring */
struct StrEncoder
{
  inline StrEncoder (StrBuff &buff_)
    : buff (buff_), error (false)
  {}

  inline void reset (void)
  {
    buff.resize (0);
  }

  inline void encode_byte (unsigned char b)
  {
    if (unlikely (buff.push ((const char)b) == &Crap(char)))
      set_error ();
  }

  inline void encode_int (int v)
  {
    if ((-1131 <= v) && (v <= 1131))
    {
      if ((-107 <= v) && (v <= 107))
	encode_byte (v + 139);
      else if (v > 0)
      {
	v -= 108;
	encode_byte ((v >> 8) + OpCode_TwoBytePosInt0);
	encode_byte (v & 0xFF);
      }
      else
      {
	v = -v - 108;
	encode_byte ((v >> 8) + OpCode_TwoByteNegInt0);
	encode_byte (v & 0xFF);
      }
    }
    else
    {
      if (unlikely (v < -32768))
	v = -32768;
      else if (unlikely (v > 32767))
	v = 32767;
      encode_byte (OpCode_shortint);
      encode_byte ((v >> 8) & 0xFF);
      encode_byte (v & 0xFF);
    }
  }

  inline void encode_num (const Number& n)
  {
    if (n.in_int_range ())
    {
      encode_int (n.to_int ());
    }
    else
    {
      int32_t v = n.to_fixed ();
      encode_byte (OpCode_fixedcs);
      encode_byte ((v >> 24) & 0xFF);
      encode_byte ((v >> 16) & 0xFF);
      encode_byte ((v >> 8) & 0xFF);
      encode_byte (v & 0xFF);
    }
  }

  inline void encode_op (OpCode op)
  {
    if (Is_OpCode_ESC (op))
    {
      encode_byte (OpCode_escape);
      encode_byte (Unmake_OpCode_ESC (op));
    }
    else
      encode_byte (op);
  }

  inline void copy_str (const ByteStr &str)
  {
    unsigned int  offset = buff.len;
    buff.resize (offset + str.len);
    if (unlikely (buff.len < offset + str.len))
    {
      set_error ();
      return;
    }
    memcpy (&buff[offset], &str.str[0], str.len);
  }

  inline bool is_error (void) const { return error; }

  protected:
  inline void set_error (void) { error = true; }

  StrBuff &buff;
  bool    error;
};

struct CFFSubTableOffsets {
  inline CFFSubTableOffsets (void)
    : privateDictsOffset (0)

  {
    topDictInfo.init ();
    FDSelectInfo.init ();
    FDArrayInfo.init ();
    charStringsInfo.init ();
    globalSubrsInfo.init ();
    localSubrsInfos.init ();
  }

  inline ~CFFSubTableOffsets (void)
  {
    localSubrsInfos.fini ();
  }

  TableInfo     topDictInfo;
  TableInfo     FDSelectInfo;
  TableInfo     FDArrayInfo;
  TableInfo     charStringsInfo;
  unsigned int  privateDictsOffset;
  TableInfo     globalSubrsInfo;
  hb_vector_t<TableInfo>  localSubrsInfos;
};

template <typename OPSTR=OpStr>
struct CFFTopDict_OpSerializer : OpSerializer
{
  inline bool serialize (hb_serialize_context_t *c,
			 const OPSTR &opstr,
			 const CFFSubTableOffsets &offsets) const
  {
    TRACE_SERIALIZE (this);

    switch (opstr.op)
    {
      case OpCode_CharStrings:
	return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.charStringsInfo.offset));

      case OpCode_FDArray:
	return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.FDArrayInfo.offset));

      case OpCode_FDSelect:
	return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.FDSelectInfo.offset));

      default:
	return_trace (copy_opstr (c, opstr));
    }
    return_trace (true);
  }

  inline unsigned int calculate_serialized_size (const OPSTR &opstr) const
  {
    switch (opstr.op)
    {
      case OpCode_CharStrings:
      case OpCode_FDArray:
      case OpCode_FDSelect:
	return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op);

      default:
	return opstr.str.len;
    }
  }
};

struct CFFFontDict_OpSerializer : OpSerializer
{
  inline bool serialize (hb_serialize_context_t *c,
			 const OpStr &opstr,
			 const TableInfo &privateDictInfo) const
  {
    TRACE_SERIALIZE (this);

    if (opstr.op == OpCode_Private)
    {
      /* serialize the private dict size & offset as 2-byte & 4-byte integers */
      if (unlikely (!UnsizedByteStr::serialize_int2 (c, privateDictInfo.size) ||
		    !UnsizedByteStr::serialize_int4 (c, privateDictInfo.offset)))
	return_trace (false);

      /* serialize the opcode */
      HBUINT8 *p = c->allocate_size<HBUINT8> (1);
      if (unlikely (p == nullptr)) return_trace (false);
      p->set (OpCode_Private);

      return_trace (true);
    }
    else
    {
      HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.len);
      if (unlikely (d == nullptr)) return_trace (false);
      memcpy (d, &opstr.str.str[0], opstr.str.len);
    }
    return_trace (true);
  }

  inline unsigned int calculate_serialized_size (const OpStr &opstr) const
  {
    if (opstr.op == OpCode_Private)
      return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Private);
    else
      return opstr.str.len;
  }
};

struct CFFPrivateDict_OpSerializer : OpSerializer
{
  inline CFFPrivateDict_OpSerializer (bool desubroutinize_, bool drop_hints_)
    : desubroutinize (desubroutinize_), drop_hints (drop_hints_) {}

  inline bool serialize (hb_serialize_context_t *c,
			 const OpStr &opstr,
			 const unsigned int subrsOffset) const
  {
    TRACE_SERIALIZE (this);

    if (drop_hints && DictOpSet::is_hint_op (opstr.op))
      return true;
    if (opstr.op == OpCode_Subrs)
    {
      if (desubroutinize || (subrsOffset == 0))
	return_trace (true);
      else
	return_trace (FontDict::serialize_offset2_op (c, opstr.op, subrsOffset));
    }
    else
      return_trace (copy_opstr (c, opstr));
  }

  inline unsigned int calculate_serialized_size (const OpStr &opstr,
						 bool has_localsubr=true) const
  {
    if (drop_hints && DictOpSet::is_hint_op (opstr.op))
      return 0;
    if (opstr.op == OpCode_Subrs)
    {
      if (desubroutinize || !has_localsubr)
	return 0;
      else
	return OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (opstr.op);
    }
    else
      return opstr.str.len;
  }

  protected:
  const bool  desubroutinize;
  const bool  drop_hints;
};

struct FlattenParam
{
  StrBuff     &flatStr;
  bool	drop_hints;
};

template <typename ACC, typename ENV, typename OPSET>
struct SubrFlattener
{
  inline SubrFlattener (const ACC &acc_,
			const hb_vector_t<hb_codepoint_t> &glyphs_,
			bool drop_hints_)
    : acc (acc_),
      glyphs (glyphs_),
      drop_hints (drop_hints_)
  {}

  inline bool flatten (StrBuffArray &flat_charstrings)
  {
    if (!flat_charstrings.resize (glyphs.len))
      return false;
    for (unsigned int i = 0; i < glyphs.len; i++)
      flat_charstrings[i].init ();
    for (unsigned int i = 0; i < glyphs.len; i++)
    {
      hb_codepoint_t  glyph = glyphs[i];
      const ByteStr str = (*acc.charStrings)[glyph];
      unsigned int fd = acc.fdSelect->get_fd (glyph);
      CSInterpreter<ENV, OPSET, FlattenParam> interp;
      interp.env.init (str, acc, fd);
      FlattenParam  param = { flat_charstrings[i], drop_hints };
      if (unlikely (!interp.interpret (param)))
	return false;
    }
    return true;
  }

  const ACC &acc;
  const hb_vector_t<hb_codepoint_t> &glyphs;
  bool  drop_hints;
};

struct SubrClosures
{
  inline SubrClosures (void)
    : valid (false),
      global_closure (nullptr)
  {
    local_closures.init ();
  }

  inline void init (unsigned int fd_count)
  {
    valid = true;
    global_closure = hb_set_create ();
    if (global_closure == hb_set_get_empty ())
      valid = false;
    if (!local_closures.resize (fd_count))
      valid = false;

    for (unsigned int i = 0; i < local_closures.len; i++)
    {
      local_closures[i] = hb_set_create ();
      if (local_closures[i] == hb_set_get_empty ())
	valid = false;
    }
  }

  inline void fini (void)
  {
    hb_set_destroy (global_closure);
    for (unsigned int i = 0; i < local_closures.len; i++)
      hb_set_destroy (local_closures[i]);
    local_closures.fini ();
  }

  inline void reset (void)
  {
    hb_set_clear (global_closure);
    for (unsigned int i = 0; i < local_closures.len; i++)
      hb_set_clear (local_closures[i]);
  }

  bool is_valid (void) const { return valid; }
  bool  valid;
  hb_set_t  *global_closure;
  hb_vector_t<hb_set_t *> local_closures;
};

struct ParsedCSOp : OpStr
{
  inline void init (unsigned int subr_num_ = 0)
  {
    OpStr::init ();
    subr_num = subr_num_;
    drop_flag = false;
    keep_flag = false;
    skip_flag = false;
  }

  inline void fini (void)
  {
    OpStr::fini ();
  }

  inline bool for_drop (void) const { return drop_flag; }
  inline void set_drop (void) { if (!for_keep ()) drop_flag = true; }
  inline bool for_keep (void) const { return keep_flag; }
  inline void set_keep (void) { keep_flag = true; }
  inline bool for_skip (void) const { return skip_flag; }
  inline void set_skip (void) { skip_flag = true; }

  unsigned int  subr_num;

  protected:
  bool	  drop_flag : 1;
  bool	  keep_flag : 1;
  bool	  skip_flag : 1;
};

struct ParsedCStr : ParsedValues<ParsedCSOp>
{
  inline void init (void)
  {
    SUPER::init ();
    parsed = false;
    hint_dropped = false;
    has_prefix_ = false;
  }

  inline void add_op (OpCode op, const SubByteStr& substr)
  {
    if (!is_parsed ())
      SUPER::add_op (op, substr);
  }

  inline void add_call_op (OpCode op, const SubByteStr& substr, unsigned int subr_num)
  {
    if (!is_parsed ())
    {
      unsigned int parsed_len = get_count ();
      if (likely (parsed_len > 0))
	values[parsed_len-1].set_skip ();

      ParsedCSOp val;
      val.init (subr_num);
      SUPER::add_op (op, substr, val);
    }
  }

  inline void set_prefix (const Number &num, OpCode op = OpCode_Invalid)
  {
    has_prefix_ = true;
    prefix_op_ = op;
    prefix_num_ = num;
  }

  inline bool at_end (unsigned int pos) const
  {
    return ((pos + 1 >= values.len) /* CFF2 */
	|| (values[pos + 1].op == OpCode_return));
  }

  inline bool is_parsed (void) const { return parsed; }
  inline void set_parsed (void) { parsed = true; }
  inline bool is_hint_dropped (void) const { return hint_dropped; }
  inline void set_hint_dropped (void) { hint_dropped = true; }
  inline bool is_vsindex_dropped (void) const { return vsindex_dropped; }
  inline void set_vsindex_dropped (void) { vsindex_dropped = true; }
  inline bool has_prefix (void) const { return has_prefix_; }
  inline OpCode prefix_op (void) const { return prefix_op_; }
  inline const Number &prefix_num (void) const { return prefix_num_; }

  protected:
  bool    parsed;
  bool    hint_dropped;
  bool    vsindex_dropped;
  bool    has_prefix_;
  OpCode  prefix_op_;
  Number  prefix_num_;

  private:
  typedef ParsedValues<ParsedCSOp> SUPER;
};

struct ParsedCStrs : hb_vector_t<ParsedCStr>
{
  inline void init (unsigned int len_ = 0)
  {
    SUPER::init ();
    resize (len_);
    for (unsigned int i = 0; i < len; i++)
      (*this)[i].init ();
  }

  inline void fini (void)
  {
    SUPER::fini_deep ();
  }

  private:
  typedef hb_vector_t<ParsedCStr> SUPER;
};

struct SubrSubsetParam
{
  inline void init (ParsedCStr *parsed_charstring_,
		    ParsedCStrs *parsed_global_subrs_, ParsedCStrs *parsed_local_subrs_,
		    hb_set_t *global_closure_, hb_set_t *local_closure_,
		    bool drop_hints_)
  {
    parsed_charstring = parsed_charstring_;
    current_parsed_str = parsed_charstring;
    parsed_global_subrs = parsed_global_subrs_;
    parsed_local_subrs = parsed_local_subrs_;
    global_closure = global_closure_;
    local_closure = local_closure_;
    drop_hints = drop_hints_;
  }

  inline ParsedCStr *get_parsed_str_for_context (CallContext &context)
  {
    switch (context.type)
    {
      case CSType_CharString:
	return parsed_charstring;

      case CSType_LocalSubr:
	if (likely (context.subr_num < parsed_local_subrs->len))
	  return &(*parsed_local_subrs)[context.subr_num];
	break;

      case CSType_GlobalSubr:
	if (likely (context.subr_num < parsed_global_subrs->len))
	  return &(*parsed_global_subrs)[context.subr_num];
	break;
    }
    return nullptr;
  }

  template <typename ENV>
  inline void set_current_str (ENV &env)
  {
    ParsedCStr  *parsed_str = get_parsed_str_for_context (env.context);
    if (likely (parsed_str != nullptr))
      current_parsed_str = parsed_str;
    else
      env.set_error ();
  }

  ParsedCStr    *current_parsed_str;

  ParsedCStr    *parsed_charstring;
  ParsedCStrs   *parsed_global_subrs;
  ParsedCStrs   *parsed_local_subrs;
  hb_set_t      *global_closure;
  hb_set_t      *local_closure;
  bool	  drop_hints;
};

struct SubrRemap : Remap
{
  inline void create (hb_set_t *closure)
  {
    /* create a remapping of subroutine numbers from old to new.
     * no optimization based on usage counts. fonttools doesn't appear doing that either.
     */
    reset (closure->get_max () + 1);
    for (hb_codepoint_t old_num = 0; old_num < len; old_num++)
    {
      if (hb_set_has (closure, old_num))
	add (old_num);
    }

    if (get_count () < 1240)
      bias = 107;
    else if (get_count () < 33900)
      bias = 1131;
    else
      bias = 32768;
  }

  inline hb_codepoint_t operator[] (unsigned int old_num) const
  {
    if (old_num >= len)
      return CFF_UNDEF_CODE;
    else
      return Remap::operator[] (old_num);
  }

  inline int biased_num (unsigned int old_num) const
  {
    hb_codepoint_t new_num = (*this)[old_num];
    assert (new_num != CFF_UNDEF_CODE);
    return (int)new_num - bias;
  }

  protected:
  int bias;
};

struct SubrRemaps
{
  inline SubrRemaps (void)
  {
    global_remap.init ();
    local_remaps.init ();
  }

  inline ~SubrRemaps (void)
  {
    fini ();
  }

  inline void init (unsigned int fdCount)
  {
    local_remaps.resize (fdCount);
    for (unsigned int i = 0; i < fdCount; i++)
      local_remaps[i].init ();
  }

  inline void create (SubrClosures& closures)
  {
    global_remap.create (closures.global_closure);
    for (unsigned int i = 0; i < local_remaps.len; i++)
      local_remaps[i].create (closures.local_closures[i]);
  }

  inline void fini (void)
  {
    global_remap.fini ();
    local_remaps.fini_deep ();
  }

  SubrRemap	       global_remap;
  hb_vector_t<SubrRemap>  local_remaps;
};

template <typename SUBSETTER, typename SUBRS, typename ACC, typename ENV, typename OPSET>
struct SubrSubsetter
{
  inline SubrSubsetter (void)
  {
    parsed_charstrings.init ();
    parsed_global_subrs.init ();
    parsed_local_subrs.init ();
  }

  inline ~SubrSubsetter (void)
  {
    closures.fini ();
    remaps.fini ();
    parsed_charstrings.fini_deep ();
    parsed_global_subrs.fini_deep ();
    parsed_local_subrs.fini_deep ();
  }

  /* Subroutine subsetting with --no-desubroutinize runs in phases:
   *
   * 1. execute charstrings/subroutines to determine subroutine closures
   * 2. parse out all operators and numbers
   * 3. mark hint operators and operands for removal if --no-hinting
   * 4. re-encode all charstrings and subroutines with new subroutine numbers
   *
   * Phases #1 and #2 are done at the same time in collect_subrs ().
   * Phase #3 walks charstrings/subroutines forward then backward (hence parsing required),
   * because we can't tell if a number belongs to a hint op until we see the first moveto.
   *
   * Assumption: a callsubr/callgsubr operator must immediately follow a (biased) subroutine number
   * within the same charstring/subroutine, e.g., not split across a charstring and a subroutine.
   */
  inline bool subset (ACC &acc, const hb_vector_t<hb_codepoint_t> &glyphs, bool drop_hints)
  {
    closures.init (acc.fdCount);
    remaps.init (acc.fdCount);

    parsed_charstrings.init (glyphs.len);
    parsed_global_subrs.init (acc.globalSubrs->count);
    parsed_local_subrs.resize (acc.fdCount);
    for (unsigned int i = 0; i < acc.fdCount; i++)
    {
      parsed_local_subrs[i].init (acc.privateDicts[i].localSubrs->count);
    }
    if (unlikely (!closures.valid))
      return false;

    /* phase 1 & 2 */
    for (unsigned int i = 0; i < glyphs.len; i++)
    {
      hb_codepoint_t  glyph = glyphs[i];
      const ByteStr str = (*acc.charStrings)[glyph];
      unsigned int fd = acc.fdSelect->get_fd (glyph);

      CSInterpreter<ENV, OPSET, SubrSubsetParam> interp;
      interp.env.init (str, acc, fd);

      SubrSubsetParam  param;
      param.init (&parsed_charstrings[i],
		  &parsed_global_subrs,  &parsed_local_subrs[fd],
		  closures.global_closure, closures.local_closures[fd],
		  drop_hints);

      if (unlikely (!interp.interpret (param)))
	return false;

      /* finalize parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */
      SUBSETTER::finalize_parsed_str (interp.env, param, parsed_charstrings[i]);
    }

    if (drop_hints)
    {
      /* mark hint ops and arguments for drop */
      for (unsigned int i = 0; i < glyphs.len; i++)
      {
	unsigned int fd = acc.fdSelect->get_fd (glyphs[i]);
	SubrSubsetParam  param;
	param.init (&parsed_charstrings[i],
		    &parsed_global_subrs,  &parsed_local_subrs[fd],
		    closures.global_closure, closures.local_closures[fd],
		    drop_hints);

	DropHintsParam  drop;
	if (drop_hints_in_str (parsed_charstrings[i], param, drop))
	{
	  parsed_charstrings[i].set_hint_dropped ();
	  if (drop.vsindex_dropped)
	    parsed_charstrings[i].set_vsindex_dropped ();
	}
      }

      /* after dropping hints recreate closures of actually used subrs */
      closures.reset ();
      for (unsigned int i = 0; i < glyphs.len; i++)
      {
	unsigned int fd = acc.fdSelect->get_fd (glyphs[i]);
	SubrSubsetParam  param;
	param.init (&parsed_charstrings[i],
		    &parsed_global_subrs,  &parsed_local_subrs[fd],
		    closures.global_closure, closures.local_closures[fd],
		    drop_hints);
	collect_subr_refs_in_str (parsed_charstrings[i], param);
      }
    }

    remaps.create (closures);

    return true;
  }

  inline bool encode_charstrings (ACC &acc, const hb_vector_t<hb_codepoint_t> &glyphs, StrBuffArray &buffArray) const
  {
    if (unlikely (!buffArray.resize (glyphs.len)))
      return false;
    for (unsigned int i = 0; i < glyphs.len; i++)
    {
      unsigned int  fd = acc.fdSelect->get_fd (glyphs[i]);
      if (unlikely (!encode_str (parsed_charstrings[i], fd, buffArray[i])))
	return false;
    }
    return true;
  }

  inline bool encode_subrs (const ParsedCStrs &subrs, const SubrRemap& remap, unsigned int fd, StrBuffArray &buffArray) const
  {
    unsigned int  count = remap.get_count ();

    if (unlikely (!buffArray.resize (count)))
      return false;
    for (unsigned int old_num = 0; old_num < subrs.len; old_num++)
    {
      hb_codepoint_t new_num = remap[old_num];
      if (new_num != CFF_UNDEF_CODE)
      {
	if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num])))
	  return false;
      }
    }
    return true;
  }

  inline bool encode_globalsubrs (StrBuffArray &buffArray)
  {
    return encode_subrs (parsed_global_subrs, remaps.global_remap, 0, buffArray);
  }

  inline bool encode_localsubrs (unsigned int fd, StrBuffArray &buffArray) const
  {
    return encode_subrs (parsed_local_subrs[fd], remaps.local_remaps[fd], fd, buffArray);
  }

  protected:
  struct DropHintsParam
  {
    inline DropHintsParam (void)
      : seen_moveto (false),
	ends_in_hint (false),
	vsindex_dropped (false) {}

    bool  seen_moveto;
    bool  ends_in_hint;
    bool  vsindex_dropped;
  };

  inline bool drop_hints_in_subr (ParsedCStr &str, unsigned int pos,
				 ParsedCStrs &subrs, unsigned int subr_num,
				 const SubrSubsetParam &param, DropHintsParam &drop)
  {
    drop.ends_in_hint = false;
    bool has_hint = drop_hints_in_str (subrs[subr_num], param, drop);

    /* if this subr ends with a stem hint (i.e., not a number a potential argument for moveto),
     * then this entire subroutine must be a hint. drop its call. */
    if (drop.ends_in_hint)
    {
      str.values[pos].set_drop ();
      /* if this subr call is at the end of the parent subr, propagate the flag
       * otherwise reset the flag */
      if (!str.at_end (pos))
	drop.ends_in_hint = false;
    }

    return has_hint;
  }

  /* returns true if it sees a hint op before the first moveto */
  inline bool drop_hints_in_str (ParsedCStr &str, const SubrSubsetParam &param, DropHintsParam &drop)
  {
    bool  seen_hint = false;

    for (unsigned int pos = 0; pos < str.values.len; pos++)
    {
      bool  has_hint = false;
      switch (str.values[pos].op)
      {
	case OpCode_callsubr:
	  has_hint = drop_hints_in_subr (str, pos,
					*param.parsed_local_subrs, str.values[pos].subr_num,
					param, drop);

	  break;

	case OpCode_callgsubr:
	  has_hint = drop_hints_in_subr (str, pos,
					*param.parsed_global_subrs, str.values[pos].subr_num,
					param, drop);
	  break;

	case OpCode_rmoveto:
	case OpCode_hmoveto:
	case OpCode_vmoveto:
	  drop.seen_moveto = true;
	  break;

	case OpCode_hintmask:
	case OpCode_cntrmask:
	  if (drop.seen_moveto)
	  {
	    str.values[pos].set_drop ();
	    break;
	  }
	  HB_FALLTHROUGH;

	case OpCode_hstemhm:
	case OpCode_vstemhm:
	case OpCode_hstem:
	case OpCode_vstem:
	  has_hint = true;
	  str.values[pos].set_drop ();
	  if (str.at_end (pos))
	    drop.ends_in_hint = true;
	  break;

	case OpCode_dotsection:
	  str.values[pos].set_drop ();
	  break;

	default:
	  /* NONE */
	  break;
      }
      if (has_hint)
      {
	for (int i = pos - 1; i >= 0; i--)
	{
	  ParsedCSOp  &csop = str.values[(unsigned)i];
	  if (csop.for_drop ())
	    break;
	  csop.set_drop ();
	  if (csop.op == OpCode_vsindexcs)
	    drop.vsindex_dropped = true;
	}
	seen_hint |= has_hint;
      }
    }

    return seen_hint;
  }

  inline void collect_subr_refs_in_subr (ParsedCStr &str, unsigned int pos,
					 unsigned int subr_num, ParsedCStrs &subrs,
					 hb_set_t *closure,
					 const SubrSubsetParam &param)
  {
    hb_set_add (closure, subr_num);
    collect_subr_refs_in_str (subrs[subr_num], param);
  }

  inline void collect_subr_refs_in_str (ParsedCStr &str, const SubrSubsetParam &param)
  {
    for (unsigned int pos = 0; pos < str.values.len; pos++)
    {
      if (!str.values[pos].for_drop ())
      {
	switch (str.values[pos].op)
	{
	  case OpCode_callsubr:
	    collect_subr_refs_in_subr (str, pos,
				       str.values[pos].subr_num, *param.parsed_local_subrs,
				       param.local_closure, param);
	    break;

	  case OpCode_callgsubr:
	    collect_subr_refs_in_subr (str, pos,
				       str.values[pos].subr_num, *param.parsed_global_subrs,
				       param.global_closure, param);
	    break;

	  default: break;
	}
      }
    }
  }

  inline bool encode_str (const ParsedCStr &str, const unsigned int fd, StrBuff &buff) const
  {
    buff.init ();
    StrEncoder  encoder (buff);
    encoder.reset ();
    /* if a prefix (CFF1 width or CFF2 vsindex) has been removed along with hints,
     * re-insert it at the beginning of charstreing */
    if (str.has_prefix () && str.is_hint_dropped ())
    {
      encoder.encode_num (str.prefix_num ());
      if (str.prefix_op () != OpCode_Invalid)
	encoder.encode_op (str.prefix_op ());
    }
    for (unsigned int i = 0; i < str.get_count(); i++)
    {
      const ParsedCSOp  &opstr = str.values[i];
      if (!opstr.for_drop () && !opstr.for_skip ())
      {
	switch (opstr.op)
	{
	  case OpCode_callsubr:
	    encoder.encode_int (remaps.local_remaps[fd].biased_num (opstr.subr_num));
	    encoder.encode_op (OpCode_callsubr);
	    break;

	  case OpCode_callgsubr:
	    encoder.encode_int (remaps.global_remap.biased_num (opstr.subr_num));
	    encoder.encode_op (OpCode_callgsubr);
	    break;

	  default:
	    encoder.copy_str (opstr.str);
	    break;
	}
      }
    }
    return !encoder.is_error ();
  }

  protected:
  SubrClosures	      closures;

  ParsedCStrs	       parsed_charstrings;
  ParsedCStrs	       parsed_global_subrs;
  hb_vector_t<ParsedCStrs>  parsed_local_subrs;

  SubrRemaps		remaps;

  private:
  typedef typename SUBRS::count_type subr_count_type;
};
};  /* namespace CFF */

HB_INTERNAL bool
hb_plan_subset_cff_fdselect (const hb_vector_t<hb_codepoint_t> &glyphs,
			    unsigned int fdCount,
			    const CFF::FDSelect &src, /* IN */
			    unsigned int &subset_fd_count /* OUT */,
			    unsigned int &subset_fdselect_size /* OUT */,
			    unsigned int &subset_fdselect_format /* OUT */,
			    hb_vector_t<CFF::code_pair> &fdselect_ranges /* OUT */,
			    CFF::Remap &fdmap /* OUT */);

HB_INTERNAL bool
hb_serialize_cff_fdselect (hb_serialize_context_t *c,
			  unsigned int num_glyphs,
			  const CFF::FDSelect &src,
			  unsigned int fd_count,
			  unsigned int fdselect_format,
			  unsigned int size,
			  const hb_vector_t<CFF::code_pair> &fdselect_ranges);

#endif /* HB_SUBSET_CFF_COMMON_HH */
