This site uses advanced css techniques
Most printers support multiple paper sizes, each selectable from the printer setup menu. These sizes include Letter, A4, Legal, and the like (though there are hundreds of standard sizes used throughout the world). The print system in Windows NT/2K/XP OS has a centralized mechanism for managing named paper sizes via a "Forms API".
Most users won't have any direct exposure to the forms system, but in a project recently while building a PPD (Postscript Printer Description) for a customer's printer, we found it necessary to become much more familiar with it than we wanted.
Our research was done on Windows 2000 w/ SP4. We hope our findings are helpful to others.
Management of the forms database is done with five API functions provided by WINSPOOL.LIB:
A "Form" is a name for a certain type of media, and all printers share the common database. Each form is described by a FORM_INFO_1 structure, which has four members:
"Printer" forms are stored in the registry, as are "User" forms. The Microsoft documentation suggests that the "Printer" forms are associated with individual printers, but we've not found any indication that they are anything other than system wide and available to all printers. We have not found how "user" forms are implemented.
The database of user and print forms (but not builtin forms) is found in the registry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Forms\
It is possible to delete or rename form names in the registry directly, but of course this is a terrible idea: use the Forms API instead.
We have observed several bits of behavior of the Forms API that are not strictly documented. We'll touch on them here.
API | NT4 | Win2000 |
---|---|---|
EnumForms() | printer | printer or server |
AddForm() | printer | printer or server |
DeleteForm() | printer | printer or server |
SetForm() | printer | printer or server |
GetForm() | printer | printer |
finfo.pName = "NewForm"; ... SetForm(hPrinter, "OldForm", 1, &finfo);but it doesn't work right. NewForm is added to the registry with the updated dimensions, and OldForm remains with the old ones, but this is not visible via the forms API. Instead, the old form is updated with the new dimensions. Restarting the spooler service makes visible the registry parameters, including leaving the old form around.
This looks like a bug.
Windows provides a way to view and manage all the forms (builtin and otherwise), and it's reached by opening the Printers applet from the control panel. Pull down File:Server Properties from the top menu:
which opens the forms management dialog box:
Some forms - like Letter shown here - are builtin and are not available for edit or delete, but any forms that were added by the user or a print driver installer can be managed directly.
Though the GUI permits use of both English and metric units of measure, internally all forms are measured to the thousandths of a millimeter.
Virtually all PostScript-capable printers use the Adobe/Microsoft print driver, and it's quite full featured. Rather than modify the driver itself to tailor its behavior to the capabilities of the printer, one instead provides a PPD (Postscript Printer Description) file that characterizes the output device.
Creating a PPD is far beyond the scope of this Tech Tip, but one section relates to the Forms API. The PaperDimension tags describe all the media sizes supported by this printer, and the driver makes them available to the application.
*% === Paper Dimension ====================== *DefaultPaperDimension: 14x17 *PaperDimension Letter: "612 792" *PaperDimension A4: "595 842" *PaperDimension 8x10: "576 720" *PaperDimension 11x14: "792 1008" *PaperDimension 14x17: "1008 1224"
This part is documented in the Adobe PPD Specification (PDF), but the interaction between the PaperDimension tag and the Forms API is not. We've found some very disconcerting behavior.
When a printer is installed, the .PPD file is copied deep into the Windows hierarchy, and on our Windows 2000 system it's stored into this directory:
C:\WINNT\system32\spool\drivers\w32x86\3\
The .PPD file is "compiled" into a binary .BPD file whenever the driver sees that the source file has changed - this seems to happen any time a new print job starts, andit presumably makes the driver run faster due to the reduced parsing of the file.
Some changes in the .PPD are reflected immediately, which makes it easy to test a PPD. By simply editing it in place, the next print job recompiles the file and reads the parameters. But other attributes - including the media sizes - are only reconsidered when the driver is installed or updated.
In any case, there doesn't appear to be any error feedback mechanism for syntactical or semantic errors. We wish that MS/Adobe would provide a "PPD Validator" that used the same parsing logic that the driver did (perhaps exposed by an API in the driver itself) - it would allow for us to catch silly mistakes up front.
The biggest problem with the driver so far is the integration with the Forms API: as it processes the media descriptions, it attempts to resolve the PPD sizes with those found in the database. It seems that if the name of the media is already in the database but the dimensions don't match exactly, that and all subsequent PPD media names are ignored.
Not only are these names not added to the database, but they are not even added to the list of valid media supported by this printer - it's as if they were not even found in the PPD.
In the above list of PaperDimensions, if the size to (say) 8x10 does not match what's found in the forms database, this and all following media are ignored. This means that the Printer Setup GUI only shows Letter and A4 as valid media.
The only real fix to this is to examine the forms database ahead of time and delete any pre-existing forms that don't match the right size. We don't see any easy way to do this with the standard printer installation mechanism: We've had to develop custom C++ code that deletes any non-matching entries and repopulates the forms with the proper sizes.