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