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)); }
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[]>(); }
/** * 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(); }
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; }
/** * 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); }
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); }