@Override public GeneralPath getPath(int code) throws IOException { int cid = codeToCID(code); if (cid2gid != null && isEmbedded) { // PDFBOX-4093: despite being a type 0 font, there is a CIDToGIDMap cid = cid2gid[cid]; } Type2CharString charstring = getType2CharString(cid); if (charstring != null) { return charstring.getPath(); } else if (isEmbedded && t1Font instanceof CFFType1Font) { return ((CFFType1Font)t1Font).getType2CharString(cid).getPath(); } else { return t1Font.getPath(getGlyphName(code)); } }
private Type2CharString getType2CharString(int gid, String name) throws IOException { Type2CharString type2 = charStringCache.get(gid); if (type2 == null) { byte[] bytes = null; if (gid < charStrings.length) { bytes = charStrings[gid]; } if (bytes == null) { // .notdef bytes = charStrings[0]; } Type2CharStringParser parser = new Type2CharStringParser(fontName, name); List<Object> type2seq = parser.parse(bytes, globalSubrIndex, getLocalSubrIndex()); type2 = new Type2CharString(reader, fontName, name, gid, type2seq, getDefaultWidthX(), getNominalWidthX()); charStringCache.put(gid, type2); } return type2; }
addCommand(numbers, command); return Collections.emptyList(); numbers = clearStack(numbers, numbers.size() % 2 != 0); expandStemHints(numbers, true); break; case "vstem": numbers = clearStack(numbers, numbers.size() % 2 != 0); expandStemHints(numbers, false); break; case "vmoveto": numbers = clearStack(numbers, numbers.size() > 1); markPath(); addCommand(numbers, command); break; case "rlineto": addCommandList(split(numbers, 2), command); break; case "hlineto": drawAlternatingLine(numbers, true); break; case "vlineto": drawAlternatingLine(numbers, false); break; case "rrcurveto": addCommandList(split(numbers, 6), command); break; case "endchar": numbers = clearStack(numbers, numbers.size() == 5 || numbers.size() == 1);
private void addCommandList(List<List<Number>> numbers, CharStringCommand command) { for (List<Number> ns : numbers) { addCommand(ns, command); } }
private void markPath() { if (pathCount > 0) { closePath(); } pathCount++; }
/** * Constructor. * @param font Parent CFF font * @param fontName font name * @param glyphName glyph name (or CID as hex string) * @param gid GID * @param sequence Type 2 char string sequence * @param defaultWidthX default width * @param nomWidthX nominal width */ public Type2CharString(Type1CharStringReader font, String fontName, String glyphName, int gid, List<Object> sequence, int defaultWidthX, int nomWidthX) { super(font, fontName, glyphName); this.gid = gid; type2sequence = sequence; defWidthX = defaultWidthX; nominalWidthX = nomWidthX; convertType1ToType2(sequence); }
private void drawAlternatingLine(List<Number> numbers, boolean horizontal) { while (numbers.size() > 0) { addCommand(numbers.subList(0, 1), new CharStringCommand( horizontal ? 6 : 7)); numbers = numbers.subList(1, numbers.size()); horizontal = !horizontal; } }
private void markPath() { if (pathCount > 0) { closePath(); } pathCount++; }
/** * Constructor. * @param font Parent CFF font * @param fontName font name * @param glyphName glyph name (or CID as hex string) * @param gid GID * @param sequence Type 2 char string sequence * @param defaultWidthX default width * @param nomWidthX nominal width */ public Type2CharString(Type1CharStringReader font, String fontName, String glyphName, int gid, List<Object> sequence, int defaultWidthX, int nomWidthX) { super(font, fontName, glyphName); this.gid = gid; type2sequence = sequence; defWidthX = defaultWidthX; nominalWidthX = nomWidthX; convertType1ToType2(sequence); }
addCommand(numbers, command); return Collections.emptyList(); numbers = clearStack(numbers, numbers.size() % 2 != 0); expandStemHints(numbers, true); break; case "vstem": numbers = clearStack(numbers, numbers.size() % 2 != 0); expandStemHints(numbers, false); break; case "vmoveto": numbers = clearStack(numbers, numbers.size() > 1); markPath(); addCommand(numbers, command); break; case "rlineto": addCommandList(split(numbers, 2), command); break; case "hlineto": drawAlternatingLine(numbers, true); break; case "vlineto": drawAlternatingLine(numbers, false); break; case "rrcurveto": addCommandList(split(numbers, 6), command); break; case "endchar": numbers = clearStack(numbers, numbers.size() == 5 || numbers.size() == 1);
@Override public GeneralPath getPath(String name) throws IOException { int gid = nameToGID(name); return getCFF().getFont().getType2CharString(gid).getPath(); }
private void closePath() { CharStringCommand command = pathCount > 0 ? (CharStringCommand) type1Sequence .get(type1Sequence.size() - 1) : null; CharStringCommand closepathCommand = new CharStringCommand(9); if (command != null && !closepathCommand.equals(command)) { addCommand(Collections.<Number> emptyList(), closepathCommand); } }
private void markPath() { if (pathCount > 0) { closePath(); } pathCount++; }
/** * Constructor. * @param font Parent CFF font * @param fontName font name * @param glyphName glyph name (or CID as hex string) * @param gid GID * @param sequence Type 2 char string sequence * @param defaultWidthX default width * @param nomWidthX nominal width */ public Type2CharString(Type1CharStringReader font, String fontName, String glyphName, int gid, List<Object> sequence, int defaultWidthX, int nomWidthX) { super(font, fontName, glyphName); this.gid = gid; type2sequence = sequence; defWidthX = defaultWidthX; nominalWidthX = nomWidthX; convertType1ToType2(sequence); }
private Type2CharString getType2CharString(int gid, String name) throws IOException { Type2CharString type2 = charStringCache.get(gid); if (type2 == null) { byte[] bytes = null; if (gid < charStrings.length) { bytes = charStrings[gid]; } if (bytes == null) { // .notdef bytes = charStrings[0]; } Type2CharStringParser parser = new Type2CharStringParser(fontName, name); List<Object> type2seq = parser.parse(bytes, globalSubrIndex, getLocalSubrIndex()); type2 = new Type2CharString(reader, fontName, name, gid, type2seq, getDefaultWidthX(), getNominalWidthX()); charStringCache.put(gid, type2); } return type2; }
numbers = clearStack(numbers, numbers.size() % 2 != 0); expandStemHints(numbers, true); numbers = clearStack(numbers, numbers.size() % 2 != 0); expandStemHints(numbers, false); numbers = clearStack(numbers, numbers.size() > 1); markPath(); addCommand(numbers, command); addCommandList(split(numbers, 2), command); drawAlternatingLine(numbers, true); drawAlternatingLine(numbers, false); addCommandList(split(numbers, 6), command); numbers = clearStack(numbers, numbers.size() == 5 || numbers.size() == 1); closePath(); if (numbers.size() == 4) addCommand(numbers, new CharStringCommand(12, 6)); addCommand(numbers, command); numbers = clearStack(numbers, numbers.size() > 2); markPath(); addCommand(numbers, command);
@Override public GeneralPath getPath(int code) throws IOException { if (ttf instanceof OpenTypeFont && ((OpenTypeFont)ttf).isPostScript()) { // we're not supposed to have CFF fonts inside PDCIDFontType2, but if we do, // then we treat their CIDs as GIDs, see PDFBOX-3344 int cid = codeToGID(code); Type2CharString charstring = ((OpenTypeFont)ttf).getCFF().getFont().getType2CharString(cid); return charstring.getPath(); } else { int gid = codeToGID(code); GlyphData glyph = ttf.getGlyph().getGlyph(gid); if (glyph != null) { return glyph.getPath(); } return new GeneralPath(); } }
private List<Number> clearStack(List<Number> numbers, boolean flag) { if (type1Sequence.isEmpty()) { if (flag) { addCommand(Arrays.asList((Number) 0f, numbers.get(0).floatValue() + nominalWidthX), new CharStringCommand(13)); numbers = numbers.subList(1, numbers.size()); } else { addCommand(Arrays.asList((Number) 0f, defWidthX), new CharStringCommand(13)); } } return numbers; }
private Type2CharString getType2CharString(int gid, String name) throws IOException { Type2CharString type2 = charStringCache.get(gid); if (type2 == null) { byte[] bytes = null; if (gid < charStrings.length) { bytes = charStrings[gid]; } if (bytes == null) { // .notdef bytes = charStrings[0]; } Type2CharStringParser parser = new Type2CharStringParser(fontName, name); List<Object> type2seq = parser.parse(bytes, globalSubrIndex, getLocalSubrIndex()); type2 = new Type2CharString(reader, fontName, name, gid, type2seq, getDefaultWidthX(), getNominalWidthX()); charStringCache.put(gid, type2); } return type2; }
@Override public GeneralPath getPath(int code) throws IOException { int cid = codeToCID(code); Type2CharString charstring = getType2CharString(cid); if (charstring != null) { return charstring.getPath(); } else if (isEmbedded && t1Font instanceof CFFType1Font) { return ((CFFType1Font)t1Font).getType2CharString(cid).getPath(); } else { return t1Font.getPath(getGlyphName(code)); } }