private CMap ReadEncoding(DictionaryToken dictionary, out bool isCMapPredefined) { isCMapPredefined = false; CMap result = default(CMap); if (dictionary.TryGet(NameToken.Encoding, out var value)) { if (value is NameToken encodingName) { var cmap = cMapCache.Get(encodingName.Data); result = cmap ?? throw new InvalidOperationException("Missing CMap for " + encodingName.Data); isCMapPredefined = true; } else if (value is StreamToken stream) { var decoded = stream.Decode(filterProvider); var cmap = cMapCache.Parse(new ByteArrayInputBytes(decoded), false); result = cmap ?? throw new InvalidOperationException("Could not read CMap for " + dictionary); } else { throw new InvalidOperationException("Could not read the encoding, expected a name or a stream but got a: " + value.GetType().Name); } } return(result); }
private CMap ReadEncoding(DictionaryToken dictionary, out bool isCMapPredefined) { isCMapPredefined = false; CMap result; if (dictionary.TryGet(NameToken.Encoding, scanner, out NameToken encodingName)) { var cmap = CMapCache.Get(encodingName.Data); result = cmap ?? throw new InvalidOperationException($"Missing CMap named {encodingName.Data}."); isCMapPredefined = true; } else if (dictionary.TryGet(NameToken.Encoding, scanner, out StreamToken stream)) { var decoded = stream.Decode(filterProvider); var cmap = CMapCache.Parse(new ByteArrayInputBytes(decoded)); result = cmap ?? throw new InvalidOperationException($"Could not read CMap from stream in the dictionary: {dictionary}"); } else { throw new InvalidOperationException( $"Could not read the encoding, expected a name or a stream but it was not found in the dictionary: {dictionary}"); } return(result); }
public IFont Generate(DictionaryToken dictionary, bool isLenientParsing) { var baseFont = dictionary.GetNameOrDefault(NameToken.BaseFont); var cMap = ReadEncoding(dictionary, out var isCMapPredefined); ICidFont cidFont; if (TryGetFirstDescendant(dictionary, out var descendantObject)) { DictionaryToken descendantFontDictionary; if (descendantObject is IndirectReferenceToken obj) { var parsed = DirectObjectFinder.Get<DictionaryToken>(obj, scanner); descendantFontDictionary = parsed; } else { descendantFontDictionary = (DictionaryToken) descendantObject; } cidFont = ParseDescendant(descendantFontDictionary, isLenientParsing); } else { throw new InvalidFontFormatException("No descendant font dictionary was declared for this Type 0 font. This dictionary should contain the CIDFont for the Type 0 font. " + dictionary); } var (ucs2CMap, isChineseJapaneseOrKorean) = GetUcs2CMap(dictionary, isCMapPredefined, cidFont); CMap toUnicodeCMap = null; if (dictionary.ContainsKey(NameToken.ToUnicode)) { var toUnicodeValue = dictionary.Data[NameToken.ToUnicode]; if (DirectObjectFinder.TryGet<StreamToken>(toUnicodeValue, scanner, out var toUnicodeStream)) { var decodedUnicodeCMap = toUnicodeStream?.Decode(filterProvider); if (decodedUnicodeCMap != null) { toUnicodeCMap = CMapCache.Parse(new ByteArrayInputBytes(decodedUnicodeCMap), isLenientParsing); } } else if (DirectObjectFinder.TryGet<NameToken>(toUnicodeValue, scanner, out var toUnicodeName)) { toUnicodeCMap = CMapCache.Get(toUnicodeName.Data); } else { throw new PdfDocumentFormatException($"Invalid type of toUnicode CMap encountered. Got: {toUnicodeValue}."); } } var font = new Type0Font(baseFont, cidFont, cMap, toUnicodeCMap, ucs2CMap, isChineseJapaneseOrKorean); return font; }
private static (CMap, bool isChineseJapaneseOrKorean) GetUcs2CMap(DictionaryToken dictionary, bool isCMapPredefined, ICidFont cidFont) { if (!isCMapPredefined) { return(null, false); } /* * If the font is a composite font that uses one of the predefined CMaps except Identity–H and Identity–V or whose descendant * CIDFont uses the Adobe-GB1, Adobe-CNS1, Adobe-Japan1, or Adobe-Korea1 character collection use a UCS2 CMap. */ var encodingName = dictionary.GetNameOrDefault(NameToken.Encoding); if (encodingName == null) { return(null, false); } var isChineseJapaneseOrKorean = false; if (cidFont != null && string.Equals(cidFont.SystemInfo.Registry, "Adobe", StringComparison.OrdinalIgnoreCase)) { isChineseJapaneseOrKorean = string.Equals(cidFont.SystemInfo.Ordering, "GB1", StringComparison.OrdinalIgnoreCase) || string.Equals(cidFont.SystemInfo.Ordering, "CNS1", StringComparison.OrdinalIgnoreCase) || string.Equals(cidFont.SystemInfo.Ordering, "Japan1", StringComparison.OrdinalIgnoreCase) || string.Equals(cidFont.SystemInfo.Ordering, "Korea1", StringComparison.OrdinalIgnoreCase); } var isPredefinedIdentityMap = encodingName.Equals(NameToken.IdentityH) || encodingName.Equals(NameToken.IdentityV); if (isPredefinedIdentityMap && !isChineseJapaneseOrKorean) { return(null, false); } if (!isChineseJapaneseOrKorean) { return(null, false); } var fullCmapName = cidFont.SystemInfo.ToString(); var nonUnicodeCMap = CMapCache.Get(fullCmapName); if (nonUnicodeCMap == null) { return(null, true); } var unicodeCMapName = $"{nonUnicodeCMap.Info.Registry}-{nonUnicodeCMap.Info.Ordering}-UCS2"; return(CMapCache.Get(unicodeCMapName), true); }