parser = new OpenFontParser(fontFileStream.getBody());
}
else if(descriptor.containsKey(PdfName.FontFile3))
{
PdfStream fontFileStream = (PdfStream)descriptor.resolve(PdfName.FontFile3);
PdfName fontFileSubtype = (PdfName)fontFileStream.getHeader().get(PdfName.Subtype);
if(fontFileSubtype.equals(PdfName.OpenType)) // Embedded OpenFont/TrueType font file (with 'glyf' table).
{parser = new OpenFontParser(fontFileStream.getBody());}
else // Unknown.
throw new UnsupportedOperationException("Unknown embedded font file format: " + fontFileSubtype);
}
else
{parser = null;}
}
if(parser != null) // Embedded font file.
{
// Glyph indexes.
glyphIndexes = parser.glyphIndexes;
if(codes != null
&& parser.metrics.isCustomEncoding)
{
/*
NOTE: In case of symbolic font,
glyph indices are natively mapped to character codes,
so they must be remapped to Unicode whenever possible
(i.e. when ToUnicode stream is available).
*/
Map<Integer,Integer> unicodeGlyphIndexes = new Hashtable<Integer,Integer>();
for(Map.Entry<Integer,Integer> glyphIndexEntry : glyphIndexes.entrySet())
{
Integer code = codes.get(new ByteArray(new byte[]{(byte)(int)glyphIndexEntry.getKey()}));
if(code == null)
continue;
unicodeGlyphIndexes.put(code,glyphIndexEntry.getValue());
}
glyphIndexes = unicodeGlyphIndexes;
}
}
PdfDataObject encodingObject = getBaseDataObject().resolve(PdfName.Encoding);
EnumSet<FlagsEnum> flags = getFlags();
if(flags.contains(FlagsEnum.Symbolic)
|| (!flags.contains(FlagsEnum.Nonsymbolic) && encodingObject == null)) // Symbolic.
{
symbolic = true;
if(glyphIndexes == null)
{
/*
NOTE: In case no font file is available, we have to synthesize its metrics
from existing entries.
*/
glyphIndexes = new Hashtable<Integer,Integer>();
PdfArray glyphWidthObjects = (PdfArray)getBaseDataObject().resolve(PdfName.Widths);
if(glyphWidthObjects != null)
{
int code = ((PdfInteger)getBaseDataObject().get(PdfName.FirstChar)).getRawValue();
for(PdfDirectObject glyphWidthObject : glyphWidthObjects)
{
if(((PdfInteger)glyphWidthObject).getRawValue() > 0)
{glyphIndexes.put(code,code);}
code++;
}
}
}
if(codes == null)
{
Map<ByteArray,Integer> codes = new HashMap<ByteArray,Integer>();
for(Map.Entry<Integer,Integer> glyphIndexEntry : glyphIndexes.entrySet())
{
if(glyphIndexEntry.getValue() > 0)
{
int glyphCharCode = glyphIndexEntry.getKey();
byte[] charCode = new byte[]{(byte)glyphCharCode};
codes.put(new ByteArray(charCode),glyphCharCode);
}
}
this.codes = new BiMap<ByteArray,Integer>(codes);
}
}
else // Nonsymbolic.
{
symbolic = false;
if(codes == null)
{
Map<ByteArray,Integer> codes;
if(encodingObject == null) // Default encoding.
{codes = Encoding.get(PdfName.StandardEncoding).getCodes();}
else if(encodingObject instanceof PdfName) // Predefined encoding.
{codes = Encoding.get((PdfName)encodingObject).getCodes();}
else // Custom encoding.
{
PdfDictionary encodingDictionary = (PdfDictionary)encodingObject;
// 1. Base encoding.
PdfName baseEncodingName = (PdfName)encodingDictionary.get(PdfName.BaseEncoding);
if(baseEncodingName == null) // Default base encoding.
{codes = Encoding.get(PdfName.StandardEncoding).getCodes();}
else // Predefined base encoding.
{codes = Encoding.get(baseEncodingName).getCodes();}