PDFsharp & MigraDoc Foundation
https://forum.pdfsharp.net/

Bug discovered when using condensed font in PdfSharp
https://forum.pdfsharp.net/viewtopic.php?f=3&t=2826
Page 1 of 1

Author:  philfordjour [ Thu May 29, 2014 8:25 pm ]
Post subject:  Bug discovered when using condensed font in PdfSharp

I discovered an issue with how font names are being constructed inside PdfSharp which affects the library from picking the appropriate font face. Also, when you examine the fonts embedded inside a PDF file (created from PdfSharp lib), Adobe does not recognize the font names correctly under the document properties or if you try to modify the document using Acrobat. I have a working solution below that addresses these font issues.

Code:
//File: PDFsharp/PdfSharp.Pdf.Advanced/PdfTrueTypeFont.cs
//Class: PdfSharp.Pdf.Advanced.PdfTrueTypeFont

//OLD CODE:
public PdfType0Font(PdfDocument document, XFont font, bool vertical)
      : base(document)
    {
      Elements.SetName(Keys.Type, "/Font");
      Elements.SetName(Keys.Subtype, "/Type0");
      Elements.SetName(Keys.Encoding, vertical ? "/Identity-V" : "/Identity-H");

      OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(font);
      this.fontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
      this.fontOptions = font.PdfOptions;
      Debug.Assert(this.fontOptions != null);

      this.cmapInfo = new CMapInfo(ttDescriptor);
      this.descendantFont = new PdfCIDFont(document, this.fontDescriptor, font);
      this.descendantFont.CMapInfo = this.cmapInfo;

      // Create ToUnicode map
      this.toUnicode = new PdfToUnicodeMap(document, this.cmapInfo);
      document.Internals.AddObject(toUnicode);
      Elements.Add(Keys.ToUnicode, toUnicode);

      //if (this.fontOptions.BaseFont != "")
      //{
      //  BaseFont = this.fontOptions.BaseFont;
      //}
      //else
      {
        BaseFont = font.Name.Replace(" ", "");
        switch (font.Style & (XFontStyle.Bold | XFontStyle.Italic))
        {
          case XFontStyle.Bold:
            this.BaseFont += ",Bold";
            break;

          case XFontStyle.Italic:
            this.BaseFont += ",Italic";
            break;

          case XFontStyle.Bold | XFontStyle.Italic:
            this.BaseFont += ",BoldItalic";
            break;
        }
      }
      // CID fonts are always embedded
      BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont);

      this.fontDescriptor.FontName = BaseFont;
      this.descendantFont.BaseFont = BaseFont;

      PdfArray descendantFonts = new PdfArray(document);
      Owner.irefTable.Add(descendantFont);
      descendantFonts.Elements.Add(descendantFont.Reference);
      Elements[Keys.DescendantFonts] = descendantFonts;
    }



Code:
//NEW CODE:
public PdfTrueTypeFont(PdfDocument document, XFont font)
            : base(document)
{
   Elements.SetName(Keys.Type, "/Font");
   Elements.SetName(Keys.Subtype, "/TrueType");

   // TrueType with WinAnsiEncoding only
   OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(font);
   this.fontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
   this.fontOptions = font.PdfOptions;
   Debug.Assert(this.fontOptions != null);

   this.cmapInfo = new CMapInfo(ttDescriptor);

   if (ttDescriptor.fontData.name != null && !string.IsNullOrEmpty(ttDescriptor.fontData.name.Name))
   {
      BaseFont = ttDescriptor.fontData.name.Name.Replace(" ", "");
   }
   else
   {
      BaseFont = font.Name.Replace(" ", "");
      switch (font.Style & (XFontStyle.Bold | XFontStyle.Italic))
      {
         case XFontStyle.Bold:
           BaseFont += ",Bold";
           break;

         case XFontStyle.Italic:
           BaseFont += ",Italic";
           break;

         case XFontStyle.Bold | XFontStyle.Italic:
           BaseFont += ",BoldItalic";
           break;
      }
   }
   
   // CID fonts are always embedded
   BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont);

   this.fontDescriptor.FontName = BaseFont;
   this.descendantFont.BaseFont = BaseFont;

   PdfArray descendantFonts = new PdfArray(document);
   Owner.irefTable.Add(descendantFont);
   descendantFonts.Elements.Add(descendantFont.Reference);
   Elements[Keys.DescendantFonts] = descendantFonts;
}


Similar code change is required for the following class.
File: PDFsharp/PdfSharp.Pdf.Advanced/PdfType0Font.cs
Class: PdfSharp.Pdf.Advanced.PdfType0Font
Actual code is not shown here.

Code:
//File: PDFSharp/PdfSharp.Fonts.OpenType/OpenTypeDescriptor.cs
//Class: PdfSharp.Fonts.OpenType.OpenTypeDescriptor

//OLD CODE:
public OpenTypeDescriptor(XFont font, XPdfFontOptions options)
{
   try
   {
      this.fontData = new FontData(font, options);
      this.fontName = font.Name;
      Initialize();
   }
   catch
   {
      throw;
   }
}

//NEW CODE:
public OpenTypeDescriptor(XFont font, XPdfFontOptions options)
{
   try
   {
      this.fontData = new FontData(font, options);

      if (this.fontData.name != null && !string.IsNullOrEmpty(this.fontData.name.Name))
      {
         this.fontName = this.fontData.name.Name;
      }
      else
      {
         this.fontName = font.Name;
      }

      this.fontStretch = font.Stretch;
      Initialize();
   }
   catch
   {
      throw;
   }
}



The FontSeclector class should include XFontStretch property as a member variable. Also need an accessor method.
Code:
//File: PDFSharp/PdfSharp.Fonts/FontDescriptorStock.cs
//Class: PdfSharp.Fonts.FontSelector

//OLD CODE:
public FontSelector(XFontFamily family, XFontStyle style)
{
   this.name = family.Name;
   this.style = style;
   this.fontType = FontType.Type0;
}

public override int GetHashCode()
{
   return this.name.GetHashCode() ^ this.style.GetHashCode();
}

//NEW CODE:
public FontSelector(XFontFamily family, XFontStyle style, XFontStretch stretch)
{
   this.name = family.Name;
   this.style = style;
   this.fontType = FontType.Type0;
   this.stretch = stretch;
}

public override int GetHashCode()
{
   return this.name.GetHashCode() ^ this.style.GetHashCode() ^ this.stretch.GetHashCode();
}

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/