private List<Integer> handleType1Command(List<Integer> numbers, CharStringCommand command) {
    String name = CharStringCommand.TYPE1_VOCABULARY.get(command.getKey());

    if ("hstem".equals(name)) {
      numbers = clearStack(numbers, numbers.size() % 2 != 0);
      expandStemHints(numbers, true);
    } else if ("vstem".equals(name)) {
      numbers = clearStack(numbers, numbers.size() % 2 != 0);
      expandStemHints(numbers, false);
    } else if ("vmoveto".equals(name)) {
      numbers = clearStack(numbers, numbers.size() > 1);
      markPath();
      addCommand(numbers, command);
    } else if ("rlineto".equals(name)) {
      addCommandList(split(numbers, 2), command);
    } else if ("hlineto".equals(name)) {
      drawAlternatingLine(numbers, true);
    } else if ("vlineto".equals(name)) {
      drawAlternatingLine(numbers, false);
    } else if ("rrcurveto".equals(name)) {
      addCommandList(split(numbers, 6), command);
    } else if ("endchar".equals(name)) {
      numbers = clearStack(numbers, numbers.size() > 0);
      closePath();
      addCommand(numbers, command);
    } else if ("rmoveto".equals(name)) {
      numbers = clearStack(numbers, numbers.size() > 2);
      markPath();
      addCommand(numbers, command);
    } else if ("hmoveto".equals(name)) {
      numbers = clearStack(numbers, numbers.size() > 1);
      markPath();
      addCommand(numbers, command);
    } else if ("vhcurveto".equals(name)) {
      drawAlternatingCurve(numbers, false);
    } else if ("hvcurveto".equals(name)) {
      drawAlternatingCurve(numbers, true);
    } else if ("callsubr".equals(name)) {
      // get subrbias
      int bias = 0;
      int nSubrs = localSubrIndex.getCount();

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

      List<Integer> result = null;
      int subrNumber = bias + numbers.get(numbers.size() - 1);
      if (subrNumber < localSubrIndex.getCount()) {
        Type2CharStringParser parser = new Type2CharStringParser();
        byte[] bytes = localSubrIndex.getBytes(subrNumber);
        List<Object> parsed = null;
        try {
          parsed = parser.parse(bytes);
          parsed.addAll(0, numbers.subList(0, numbers.size() - 1));
          result = handleSequence(parsed);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      return result;
    } else if ("return".equals(name)) {
      return numbers;
    } else {
      addCommand(numbers, command);
    }
    return null;
  }
  @SuppressWarnings(value = {"unchecked"})
  private List<Integer> handleType2Command(List<Integer> numbers, CharStringCommand command) {
    String name = CharStringCommand.TYPE2_VOCABULARY.get(command.getKey());
    if ("hflex".equals(name)) {
      List<Integer> first =
          Arrays.asList(
              numbers.get(0),
              Integer.valueOf(0),
              numbers.get(1),
              numbers.get(2),
              numbers.get(3),
              Integer.valueOf(0));
      List<Integer> second =
          Arrays.asList(
              numbers.get(4),
              Integer.valueOf(0),
              numbers.get(5),
              Integer.valueOf(-numbers.get(2).intValue()),
              numbers.get(6),
              Integer.valueOf(0));
      addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
    } else if ("flex".equals(name)) {
      List<Integer> first = numbers.subList(0, 6);
      List<Integer> second = numbers.subList(6, 12);
      addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
    } else if ("hflex1".equals(name)) {
      List<Integer> first =
          Arrays.asList(
              numbers.get(0),
              numbers.get(1),
              numbers.get(2),
              numbers.get(3),
              numbers.get(4),
              Integer.valueOf(0));
      List<Integer> second =
          Arrays.asList(
              numbers.get(5),
              Integer.valueOf(0),
              numbers.get(6),
              numbers.get(7),
              numbers.get(8),
              Integer.valueOf(0));
      addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
    } else if ("flex1".equals(name)) {
      int dx = 0;
      int dy = 0;
      for (int i = 0; i < 5; i++) {
        dx += numbers.get(i * 2).intValue();
        dy += numbers.get(i * 2 + 1).intValue();
      }
      List<Integer> first = numbers.subList(0, 6);
      List<Integer> second =
          Arrays.asList(
              numbers.get(6),
              numbers.get(7),
              numbers.get(8),
              numbers.get(9),
              (Math.abs(dx) > Math.abs(dy) ? numbers.get(10) : Integer.valueOf(-dx)),
              (Math.abs(dx) > Math.abs(dy) ? Integer.valueOf(-dy) : numbers.get(10)));
      addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
    } else if ("hstemhm".equals(name)) {
      numbers = clearStack(numbers, numbers.size() % 2 != 0);
      expandStemHints(numbers, true);
    } else if ("hintmask".equals(name) || "cntrmask".equals(name)) {
      numbers = clearStack(numbers, numbers.size() % 2 != 0);
      if (numbers.size() > 0) {
        expandStemHints(numbers, false);
      }
    } else if ("vstemhm".equals(name)) {
      numbers = clearStack(numbers, numbers.size() % 2 != 0);
      expandStemHints(numbers, false);
    } else if ("rcurveline".equals(name)) {
      addCommandList(split(numbers.subList(0, numbers.size() - 2), 6), new CharStringCommand(8));
      addCommand(numbers.subList(numbers.size() - 2, numbers.size()), new CharStringCommand(5));
    } else if ("rlinecurve".equals(name)) {
      addCommandList(split(numbers.subList(0, numbers.size() - 6), 2), new CharStringCommand(5));
      addCommand(numbers.subList(numbers.size() - 6, numbers.size()), new CharStringCommand(8));
    } else if ("vvcurveto".equals(name)) {
      drawCurve(numbers, false);
    } else if ("hhcurveto".equals(name)) {
      drawCurve(numbers, true);
    } else if ("callgsubr".equals(name)) {
      // get subrbias
      int bias = 0;
      int nSubrs = globalSubrIndex.getCount();

      if (nSubrs < 1240) {
        bias = 107;
      } else if (nSubrs < 33900) {
        bias = 1131;
      } else {
        bias = 32768;
      }
      List<Integer> result = null;
      int subrNumber = bias + numbers.get(numbers.size() - 1);
      if (subrNumber < nSubrs) {
        Type2CharStringParser parser = new Type2CharStringParser();
        byte[] bytes = globalSubrIndex.getBytes(subrNumber);
        List<Object> parsed = null;
        try {
          parsed = parser.parse(bytes);
          parsed.addAll(0, numbers.subList(0, numbers.size() - 1));
          result = handleSequence(parsed);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      return result;
    } else {
      addCommand(numbers, command);
    }
    return null;
  }