Printer’s Apprentice – More Keyboards

October 31st, 2007 by Bryan Kinkel

We have keyboards for the screen, now we have keyboards for the printed page.

The keyboard rendering code for print outs is almost exactly the same as the screen. Which is very cool. The screen version has more properties and methods. So it is in a separate class. But the end result is the same.

Elements for a printed sample sheet or catalog are defined in individual XML files. Keyboard elements are specified like this in the XML.

<!-- keyboards-->
<element Key="KeyboardLower" Type="Keyboard" FontKey="KeyboardFont" 
UpperCase="True" x1="0" y1="15" x2="655" y2="266" Align="center" />
 

When the printing engine sees this element, the keyboard class kicks in and does the actual rendering based on the specified location and dimensions.

Here are two shots of the new keyboard sample sheet. The second is zoomed in to show the details.

printedkeyboard1   printedkeyboard2

And since the keyboard class is self contained and scales nicely, I can use it in font catalogs as well.

printedkeyboard3

Hopefully I will have a beta package soon. Stay tuned. — Bryan

Posted in Fonts, Printer's Apprentice | 3 Comments »

Printer’s Apprentice Update – Keyboard Tab

October 12th, 2007 by Bryan Kinkel

I spent the week working on the keyboard tab for Printer’s Apprentice. It is coming along quite nicely.

The keyboard itself is a standalone .NET control. Drawing is done using a mix of Win32 GDI and GDI+. The traditional Win32 GDI is used to draw the actual text as the newer GDI+ cannot render Type 1 based fonts.

I designed it so I can easily reuse the code in the printable keyboard sheet. And I have to say, it looks a lot nicer than the PA 7.5 keyboard. The next step is to add the printed keyboard sheet. — Bryan

pa8-keyboard
Keyboard – Printer’s Apprentice 8.0

pa75-keyboard 
Keyboard – Printer’s Apprentice 7.5

Posted in Fonts, Printer's Apprentice | 1 Comment »

XP Service Pack 3 & PrivateFontCollections – Do we have a fix?

October 11th, 2007 by Bryan Kinkel

This is a follow up to my original post about a PrivateFontCollection bug in Windows XP. According to a post at msbetas.org, Windows XP Service Pack 3 will include the hot fix for 901026. This is very good news.

XP SP3 Fix List at msbetas.org

Memory corruption or an access violation may occur in a custom application that uses the PrivateFontCollection object in Windows XP

http://support.microsoft.com/kb/901026

Posted in .NET Framework 2.0, Fonts, Microsoft, Printer's Apprentice | 1 Comment »

PrivateFontCollection – Access Violation Errors

October 2nd, 2007 by Bryan Kinkel

About two weeks ago I started working on the “Print All Fonts In Path” feature in Printer’s Apprentice. This feature print catalogs and sample sheet for all fonts in a selected folder tree. And the fonts are typically not currently installed in Windows. (note: Previous versions could print catalogs. But v8 will print both catalogs and sample sheets.)

Once I got the whole process working start to finish, I started to get these errors when the Print dialog box was closed.

The image on the left is the error as it occurs in Visual Studio 2005 (VS). And on the right is what happens when the compiled executable runs by itself. The exception detail follows below.

paxp-vs2005-1 paxp-exe


System.AccessViolationException was unhandled
  Message=”Attempted to read or write protected memory. This is often an indication that other memory is corrupt.”
  Source=”System.Drawing”
  StackTrace:
       at System.Drawing.SafeNativeMethods.Gdip.IntGdipDeleteFontFamily(HandleRef fontFamily)
       at System.Drawing.SafeNativeMethods.Gdip.GdipDeleteFontFamily(HandleRef fontFamily)
       at System.Drawing.FontFamily.Dispose(Boolean disposing)
       at System.Drawing.FontFamily.Finalize()

How nice. This bug became the problem of the week.

The first place to start is an understanding of the GDI+ and PrivateFontCollection (PFC) objects. Applications based on .NET use GDI+ for drawing and printing. GDI+ is the successor to the existing Win32 GDI subsystem. It makes programming complex text and graphic layouts much easier and gives us print preview objects built right into the platform. GDI+ also includes it own font management functions and you need to use them if you use the GDI+ PrintDocument and PrintPreview controls. (GDI+ will not render text in a font loaded with the Win32 AddFontResource() function.)

To draw a string using an uninstalled font, you first load the font into a PrivateFontCollection. This class, from system.drawing.text namespace, is a wrapper around an object of the same name in Microsoft’s GDI+ library. It allows the developer to use uninstalled fonts in an application. For example, a developer might ship a proprietary bar code font along with his mailing label application.

Printer’s Apprentice uses a globally scoped PFC to manage fonts on the printed page. The Print All Fonts in Path function goes through these steps to generate a catalog:

  1. Walk the directory path to generate a list of TrueType and OpenType fonts.
  2. Add each font to a globally scoped PFC – oPFC.AddFontFile(pFileName).
  3. Show the Print Preview window. Text functions create and use fonts from the oPFC object. A PrintDocument object does the heavy lifting and draws the layout on a PrintPreview control or printer device.
  4. Once the dialog closes, the PFC is disposed.
  5. Boom – the app crashes.

It was easy to narrow the error to the lines below. The stack trace clearly points to disposing the PrivateFontCollection. What was strange is that VS did not halt on the actual line. It would fail a few moments after the line was executed.

oPFC.Dispose()oPFC = Nothing

But the PrivateFontCollection.Dispose() call gave me some ammunition to search with. And I was eventually lead to MS Knowledge Base article 901026.

Memory corruption or an access violation may occur in a custom application that uses the PrivateFontCollection object in Windows XP
http://support.microsoft.com/kb/901026

What is interesting about the article is that it states that the corruption occurs when the application has outstanding references to GpFontFamily objects. To me, this means the code loads a font to a PFC, creates a Font object, renders some text, then disposes the PFC without disposing the Font object. I then spent a lot of time combing through code trying to find Font objects that were not properly disposed. I even loaded up SciTech’s .NET Memory Profiler looking for leaks. No luck. The app still crashes.

I then built a demonstration application in an attempt to duplicate the problem in a very simple environment. PFCTest.exe simply reads a directory of TTFs, adds the fonts to a PFC and then disposes the fonts. The fonts are not used at all in the application. It runs and crashes as expected under Windows XP. With Vista, it runs fine. I was able to read the fonts and dispose the PFC over 100 times. Look at the execution count label in the screenshots below.

pfc-xp-full pfc-vista

 
Here is the Visual Studio 2005 project: pfctest.zip

My next step was to obtain and install the 901026 hotfix. Since it is a hotfix and not part of a regular Windows XP update, I had to request it from Microsoft. They got the fix to me rather quickly. But I could not install it.

pfc-hotfix-bad

What next? I need to get in touch with Microsoft again about this and see if I can get a setup package that will install. The package they sent appears to be for Windows Server 2003.

But a larger issue looms. This is clearly a bug in the GDI+ subsystem. When will it get fixed? Will a fix be included in XP Service Pack 3? And it is not the first bug I have run into… If I take out the oPFC.Dispose() code, then Printer’s Apprentice will have a slow memory leak. Until I get a resolution from Microsoft, it will have to be my solution for now as I have to continue working on other features. Yuck.  — Bryan

Posted in .NET Framework 2.0, Fonts, Microsoft, Printer's Apprentice | 2 Comments »