Example #1
0
        /**
         * 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();
        }
Example #2
0
        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);
        }
Example #3
0
        /**
         * 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));
        }