@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; }
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; }
private List<Object> parse( byte[] bytes, IndexData globalSubrIndex, IndexData localSubrIndex, boolean init) throws IOException { if (init) { hstemCount = 0; vstemCount = 0; sequence = new ArrayList<Object>(); } DataInput input = new DataInput(bytes); boolean localSubroutineIndexProvided = localSubrIndex != null && localSubrIndex.getCount() > 0; boolean globalSubroutineIndexProvided = globalSubrIndex != null && globalSubrIndex.getCount() > 0; while (input.hasRemaining()) { int b0 = input.readUnsignedByte(); if (b0 == 10 && localSubroutineIndexProvided) { // process subr command Integer operand = (Integer) sequence.remove(sequence.size() - 1); // get subrbias int bias = 0; int nSubrs = localSubrIndex.getCount(); if (nSubrs < 1240) { bias = 107; } else if (nSubrs < 33900) { bias = 1131; } else { bias = 32768; } int subrNumber = bias + operand; if (subrNumber < localSubrIndex.getCount()) { byte[] subrBytes = localSubrIndex.getBytes(subrNumber); parse(subrBytes, globalSubrIndex, localSubrIndex, false); Object lastItem = sequence.get(sequence.size() - 1); if (lastItem instanceof CharStringCommand && ((CharStringCommand) lastItem).getKey().getValue()[0] == 11) { sequence.remove(sequence.size() - 1); // remove "return" command } } } else if (b0 == 29 && globalSubroutineIndexProvided) { // process globalsubr command Integer operand = (Integer) sequence.remove(sequence.size() - 1); // get subrbias int bias = 0; int nSubrs = globalSubrIndex.getCount(); if (nSubrs < 1240) { bias = 107; } else if (nSubrs < 33900) { bias = 1131; } else { bias = 32768; } int subrNumber = bias + operand; if (subrNumber < globalSubrIndex.getCount()) { byte[] subrBytes = globalSubrIndex.getBytes(subrNumber); parse(subrBytes, globalSubrIndex, localSubrIndex, false); Object lastItem = sequence.get(sequence.size() - 1); if (lastItem instanceof CharStringCommand && ((CharStringCommand) lastItem).getKey().getValue()[0] == 11) { sequence.remove(sequence.size() - 1); // remove "return" command } } } else if (b0 >= 0 && b0 <= 27) { sequence.add(readCommand(b0, input)); } else if (b0 == 28) { sequence.add(readNumber(b0, input)); } else if (b0 >= 29 && b0 <= 31) { sequence.add(readCommand(b0, input)); } else if (b0 >= 32 && b0 <= 255) { sequence.add(readNumber(b0, input)); } else { throw new IllegalArgumentException(); } } return sequence; }