/** * Constructor. * * @param fontDictionary The font dictionary according to the PDF specification. * @param parent The parent font. * @param trueTypeFont The true type font used to create the parent font * @throws IOException */ public CIDFontType2(PdfDirectObject fontDictionary, PdfType0Font parent, TrueTypeFont trueTypeFont) : base(fontDictionary, parent) { FontDescriptor fd = FontDescriptor; if (trueTypeFont != null) { ttf = trueTypeFont; isEmbedded = true; isDamaged = false; } else { bool fontIsDamaged = false; TrueTypeFont ttfFont = null; FontFile stream = null; if (fd != null) { // Acrobat looks in FontFile too, even though it is not in the spec, see PDFBOX-2599 stream = fd.FontFile2 ?? fd.FontFile3 ?? fd.FontFile; } if (stream != null) { try { // embedded OTF or TTF OTFParser otfParser = new OTFParser(true); ttfFont = otfParser.Parse((Bytes.Buffer)stream.BaseDataObject.ExtractBody(true), fd.FontName); if (ttfFont is OpenTypeFont otf && otf.IsPostScript) { // PDFBOX-3344 contains PostScript outlines instead of TrueType fontIsDamaged = true; Debug.WriteLine($"warning: Found CFF/OTF but expected embedded TTF font {fd.FontName}"); } } catch (IOException e) { fontIsDamaged = true; Debug.WriteLine($"warning: Could not read embedded OTF for font {BaseFont} {e}"); } } isEmbedded = ttfFont != null; isDamaged = fontIsDamaged; if (ttfFont == null) { ttfFont = FindFontOrSubstitute(); } ttf = ttfFont; } cmapLookup = ttf.GetUnicodeCmapLookup(false); cid2gid = ReadCIDToGIDMap(); }
internal static Type1Font LoadType1Font(FontFile fontFile) { Type1Font t1 = null; var stream = fontFile.BaseDataObject; int length1 = fontFile.Length1; int length2 = fontFile.Length2; // repair Length1 and Length2 if necessary byte[] bytes = stream.ExtractBody(true).GetBuffer(); length1 = RepairLength1(bytes, length1); length2 = RepairLength2(bytes, length1, length2); if (bytes.Length > 0 && (bytes[0] & 0xff) == PFB_START_MARKER) { // some bad files embed the entire PFB, see PDFBOX-2607 t1 = Type1Font.CreateWithPFB(bytes); } else { // the PFB embedded as two segments back-to-back byte[] segment1 = new byte[length1]; Array.Copy(bytes, 0, segment1, 0, length1); byte[] segment2 = new byte[length2]; Array.Copy(bytes, length1, segment2, 0, length2); // empty streams are simply ignored if (length1 > 0 && length2 > 0) { t1 = Type1Font.CreateWithSegments(segment1, segment2); } } return(t1); }
/** * Constructor. * * @param fontDictionary The font dictionary according to the PDF specification. * @param parent The parent font. */ public CIDFontType0(PdfDirectObject fontDictionary, PdfType0Font parent) : base(fontDictionary, parent) { FontDescriptor fd = FontDescriptor; FontFile fontFile = null; byte[] bytes = null; if (fd != null) { fontFile = fd.FontFile3 ?? fd.FontFile; if (fontFile != null) { bytes = fontFile.BaseDataObject.ExtractBody(true).GetBuffer(); } } bool fontIsDamaged = false; CFFFont cffFont = null; if (bytes != null && bytes.Length > 0 && (bytes[0] & 0xff) == '%') { // PDFBOX-2642 contains a corrupt PFB font instead of a CFF Debug.WriteLine("warn: Found PFB but expected embedded CFF font " + fd.FontName); try { t1Font = PdfType1Font.LoadType1Font(fontFile); } catch (DamagedFontException e) { Debug.WriteLine($"warn: Can't read damaged embedded Type1 font {fd.FontName} {e}"); fontIsDamaged = true; } catch (IOException e) { Debug.WriteLine($"error: Can't read the embedded Type1 font {fd.FontName} {e}"); fontIsDamaged = true; } } else if (bytes != null) { CFFParser cffParser = new CFFParser(); try { cffFont = cffParser.Parse(bytes, new FF3ByteSource(fd, bytes))[0]; } catch (IOException e) { Debug.WriteLine("error: Can't read the embedded CFF font " + fd.FontName, e); fontIsDamaged = true; } } if (cffFont != null) { // embedded if (cffFont is CFFCIDFont) { cidFont = (CFFCIDFont)cffFont; t1Font = null; } else { cidFont = null; t1Font = cffFont; } cid2gid = ReadCIDToGIDMap(); isEmbedded = true; isDamaged = false; } else if (t1Font != null) { if (t1Font is Type1Font type1Font) { cidFont = null; } cid2gid = ReadCIDToGIDMap(); isEmbedded = true; isDamaged = false; } else { // find font or substitute CIDFontMapping mapping = FontMappers.Instance.GetCIDFont(BaseFont, FontDescriptor, CIDSystemInfo); BaseFont font; if (mapping.IsCIDFont) { cffFont = mapping.Font.CFF.Font; if (cffFont is CFFCIDFont) { cidFont = (CFFCIDFont)cffFont; t1Font = null; font = cidFont; } else { // PDFBOX-3515: OpenType fonts are loaded as CFFType1Font CFFType1Font f = (CFFType1Font)cffFont; cidFont = null; t1Font = f; font = f; } } else { cidFont = null; t1Font = mapping.TrueTypeFont; font = t1Font; } if (mapping.IsFallback) { Debug.WriteLine($"warning: Using fallback {font.Name} for CID-keyed font {BaseFont}"); } isEmbedded = false; isDamaged = fontIsDamaged; } fontMatrixTransform = FontMatrix; fontMatrixTransform = fontMatrixTransform.PostConcat(SKMatrix.CreateScale(1000, 1000)); }