public SimpleFont(Document context, string baseFont) : base(context, baseFont) { // assign the glyph list based on the font if ("ZapfDingbats".Equals(baseFont, StringComparison.Ordinal)) { glyphList = GlyphMapping.ZapfDingbats; } else { glyphList = GlyphMapping.Default; } }
protected override void OnLoad() { base.OnLoad(); if (BaseDataObject.Resolve(PdfName.Encoding) is PdfDictionary encodingDictionary && encodingDictionary.Values.Count > 0 && encodingDictionary.Resolve(PdfName.Differences) is PdfArray differencesObject) { var fontMapping = (GlyphMapping)null; if (BaseDataObject.Resolve(PdfName.BaseFont) is PdfName pdfName) { var name = Regex.Replace(pdfName.RawValue, @"[\/?:*""><|]+", "", RegexOptions.Compiled); if (GlyphMapping.IsExist(name)) { fontMapping = new GlyphMapping(name); } } byte[] charCodeData = new byte[1]; foreach (PdfDirectObject differenceObject in differencesObject) { if (differenceObject is PdfInteger pdfInteger) // Subsequence initial code. { charCodeData[0] = (byte)(((int)pdfInteger.Value) & 0xFF); } else // Character name. { ByteArray charCode = new ByteArray(charCodeData); string charName = (string)((PdfName)differenceObject).Value; if (charName.Equals(".notdef", StringComparison.Ordinal)) { codes.Remove(charCode); } else { int?code = GlyphMapping.DLFONT.NameToCode(charName) ?? fontMapping?.NameToCode(charName); if (code != null) { codes[charCode] = code.Value; } else { System.Diagnostics.Debug.WriteLine($" {charName}"); } } charCodeData[0]++; } } } }
/** * Sets the glyph widths in the font dictionary. */ private void SetWidths(PdfDictionary font, GlyphMapping glyphList) { float scaling = 1000f / ttf.Header.UnitsPerEm; HorizontalMetricsTable hmtx = ttf.HorizontalMetrics; Dictionary <int, string> codeToName = FontEncoding.CodeToNameMap; int firstChar = codeToName.Keys.Min(); int lastChar = codeToName.Keys.Max(); List <int> widths = new List <int>(lastChar - firstChar + 1); for (int i = 0; i < lastChar - firstChar + 1; i++) { widths.Add(0); } // a character code is mapped to a glyph name via the provided font encoding // afterwards, the glyph name is translated to a glyph ID. foreach (KeyValuePair <int, string> entry in codeToName) { int code = entry.Key; string name = entry.Value; if (code >= firstChar && code <= lastChar) { var charCode = glyphList.ToUnicode(name) ?? 0; int gid = cmapLookup.GetGlyphId(charCode); widths[entry.Key - firstChar] = (int)Math.Round(hmtx.GetAdvanceWidth(gid) * scaling); } } font[PdfName.FirstChar] = PdfInteger.Get(firstChar); font[PdfName.LastChar] = PdfInteger.Get(lastChar); font[PdfName.Widths] = new PdfArray(widths.Select(p => PdfInteger.Get(p)).ToList()); }