Example #1
0
        internal PdfType1Font(PdfDirectObject baseObject) : base(baseObject)
        {
            codeToBytesMap = new Dictionary <int, byte[]>();

            var       fd            = FontDescriptor;
            Type1Font t1            = null;
            bool      fontIsDamaged = false;

            if (fd != null)
            {
                // a Type1 font may contain a Type1C font
                var fontFile3 = fd.FontFile3;
                if (fontFile3 != null)
                {
                    throw new ArgumentException("Use PDType1CFont for FontFile3");
                }

                // or it may contain a PFB
                var fontFile = fd.FontFile;
                if (fontFile != null)
                {
                    try
                    {
                        t1 = 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;
                    }
                }
            }
            isEmbedded = t1 != null;
            isDamaged  = fontIsDamaged;
            type1font  = t1;

            // find a generic font to use for rendering, could be a .pfb, but might be a .ttf
            if (type1font != null)
            {
                genericFont = type1font;
            }
            else
            {
                FontMapping <BaseFont> mapping = FontMappers.Instance.GetBaseFont(BaseFont, fd);
                genericFont = mapping.Font;

                if (mapping.IsFallback)
                {
                    Debug.WriteLine($"warn Using fallback font {genericFont.Name} for {BaseFont}");
                }
            }
            ReadEncoding();
            fontMatrixTransform = FontMatrix;
            fontMatrixTransform = fontMatrixTransform.PreConcat(SKMatrix.CreateScale(1000, 1000));
        }
Example #2
0
        public PdfType1Font(Document doc, Bytes.IInputStream pfbIn, Encoding encoding) : base(doc)
        {
            PdfType1FontEmbedder embedder = new PdfType1FontEmbedder(doc, Dictionary, pfbIn, encoding);

            this.encoding       = encoding;
            glyphList           = embedder.GlyphList;
            type1font           = embedder.Type1Font;
            genericFont         = embedder.Type1Font;
            isEmbedded          = true;
            isDamaged           = false;
            fontMatrixTransform = SKMatrix.Identity;
            codeToBytesMap      = new Dictionary <int, byte[]>();
        }
Example #3
0
        /**
         * This will load a PFB to be embedded into a document.
         *
         * @param doc The PDF document that will hold the embedded font.
         * @param dict The Font dictionary to write to.
         * @param pfbStream The pfb input.
         * @throws IOException If there is an error loading the data.
         */
        public PdfType1FontEmbedder(Document doc, PdfDictionary dict, Bytes.IInputStream pfbStream, Encoding encoding)
        {
            dict[PdfName.Subtype] = PdfName.Type1;

            // read the pfb
            byte[]    pfbBytes  = pfbStream.ToByteArray();
            PfbParser pfbParser = new PfbParser(pfbBytes);

            type1 = Type1Font.CreateWithPFB(pfbBytes);

            if (encoding == null)
            {
                fontEncoding = Type1Encoding.FromFontBox(type1.Encoding);
            }
            else
            {
                fontEncoding = encoding;
            }

            // build font descriptor
            FontDescriptor fd = BuildFontDescriptor(type1);

            PdfStream fontStream = new PdfStream(pfbParser.GetInputStream());

            fontStream.Header[PdfName.Length] = PdfInteger.Get(pfbParser.Size);
            for (int i = 0; i < pfbParser.Lengths.Length; i++)
            {
                fontStream.Header[new PdfName("Length" + (i + 1))] = PdfInteger.Get(pfbParser.Lengths[i]);
            }
            fd.FontFile = new FontFile(doc, fontStream);

            // set the values
            dict[PdfName.FontDescriptor] = fd.BaseObject;
            dict[PdfName.BaseFont]       = PdfName.Get(type1.Name);

            // widths
            List <int> widths = new List <int>(256);

            for (int code = 0; code <= 255; code++)
            {
                string name  = fontEncoding.GetName(code);
                int    width = (int)Math.Round(type1.GetWidth(name));
                widths.Add(width);
            }

            dict[PdfName.FirstChar] = PdfInteger.Get(0);
            dict[PdfName.LastChar]  = PdfInteger.Get(255);
            dict[PdfName.Widths]    = new PdfArray(widths.Select(p => PdfInteger.Get(p)));
            dict[PdfName.Encoding]  = encoding.GetPdfObject();
        }
Example #4
0
        public PdfType1Font(Document context, string baseFont) : base(context, baseFont)
        {
            Dictionary[PdfName.Subtype]  = PdfName.Type1;
            Dictionary[PdfName.BaseFont] = PdfName.Get(baseFont);
            switch (baseFont)
            {
            case "ZapfDingbats":
                encoding = ZapfDingbatsEncoding.Instance;
                break;

            case "Symbol":
                encoding = SymbolEncoding.Instance;
                break;

            default:
                encoding = WinAnsiEncoding.Instance;
                Dictionary[PdfName.Encoding] = PdfName.WinAnsiEncoding;
                break;
            }

            // standard 14 fonts may be accessed concurrently, as they are singletons
            codeToBytesMap = new Dictionary <int, byte[]>();

            // todo: could load the PFB font here if we wanted to support Standard 14 embedding
            type1font = null;
            FontMapping <BaseFont> mapping = FontMappers.Instance.GetBaseFont(BaseFont, FontDescriptor);

            genericFont = mapping.Font;

            if (mapping.IsFallback)
            {
                string fontName;
                try
                {
                    fontName = genericFont.Name;
                }
                catch (IOException e)
                {
                    Debug.WriteLine($"debug: Couldn't get font name - setting to '?' {e}");
                    fontName = "?";
                }
                Debug.WriteLine($"warn: Using fallback font {fontName} for base font {BaseFont}");
            }
            isEmbedded          = false;
            isDamaged           = false;
            fontMatrixTransform = SKMatrix.Identity;
        }
Example #5
0
        /**
         * Returns a FontDescriptor for the given PFB.
         */
        public static FontDescriptor BuildFontDescriptor(Type1Font type1)
        {
            bool isSymbolic = type1.Encoding is BuiltInEncoding;

            FontDescriptor fd = new FontDescriptor();

            fd.FontName    = type1.Name;
            fd.FontFamily  = type1.FamilyName;
            fd.NonSymbolic = !isSymbolic;
            fd.Symbolic    = isSymbolic;
            fd.FontBBox    = new Rectangle(type1.FontBBox);
            fd.ItalicAngle = type1.ItalicAngle;
            fd.Ascent      = type1.FontBBox.Top;
            fd.Descent     = type1.FontBBox.Bottom;
            fd.CapHeight   = type1.BlueValues[2];
            fd.StemV       = 0; // for PDF/A
            return(fd);
        }
Example #6
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);
        }