Modular and extensible printer device driver and text based method for characterizing printer devices for use therewith

Information

  • Patent Grant
  • 6825941
  • Patent Number
    6,825,941
  • Date Filed
    Monday, September 21, 1998
    26 years ago
  • Date Issued
    Tuesday, November 30, 2004
    19 years ago
Abstract
A modular Universal Printer Driver is provided which dramatically improves the extensibility of the driver architecture and the support for printer features. This driver operates in conjunction with OEM developed minidrivers which utilize the text based Generic Printer Description (GPD) format of the instant invention. The universal driver allows the GPD text based minidrivers to add and define new features introduced by the printer OEM. The universal driver also allows the GPD minidriver to modify, add, or replace the standard user interface provided by the universal driver. The universal driver and the text based GPD minidrivers are included in a computer system for outputting data to an output device, such as a printer. This system includes an application program which invokes a plurality of graphics device interface functions to control the sending of data to the printer. Within the system, a graphics device interface invokes device driver functions for controlling the outputting of data. The text based minidriver contains a characterization of the output device, and an implementation of device specific device driver functions invoked by the graphic device interface. This text based minidriver outputs this data to the universal driver. This universal driver incorporates the text based characterization passed by the minidriver. The universal driver implements the device specific driver functions and controls the outputting of data to the printer in accordance with the incorporated text based characterization.
Description




FIELD OF THE INVENTION




This invention relates to output device characterization methods and device drivers, and more particularly to a method for characterizing and customizing output printer devices and a driver architecture for use therewith.




BACKGROUND OF THE INVENTION




The phenomenal growth of the computer industry in both the commercial and consumer market segments has spawned an increasing number of companies who provide both software and peripheral hardware products to the market. It becomes the job of the operating system designer to coordinate and ensure compatibility of data flow within, between, and without of the computers on which this software and peripheral hardware is installed. To ensure that the literally thousands of application programs are able to output their data to peripheral printing devices, the operating system designers have developed a graphics device interface (GDI). The GDI affects the output data from the application programs by invoking functions which allow access to printing devices in a device-independent manner. This GDI provides a uniform interface between the literally thousands of application programs and the output peripheral devices to which these programs wish to send data to be printed.




While the GDI provides a uniform interface from the application programs, it is unable to produce actual printer control commands which are capable of driving each of the hundreds of different models of printer devices available on the market. In the past each individual printer


10




1


,


10




2


, . . .


10




n


required its own individual printer driver


12




1


,


12




2


, . . .


12




n


as illustrated in FIG.


15


. These individual printer drivers


12




1


,


12




2


, . . .


12




n


, implemented various control functions for their respective printers based upon the standardized output from the graphics device interface


14


. These standard functions included initialization, information, output, attribute, mode, and escape. While each of these individual monolithic printer drivers provided the necessary interface to allow proper driving of each individual printer model, they were typically were several megabytes in size. The need for such extensive printer dirvers impacted not only the individual printer manufacturer, but also the individual computer system


16


into which it was to be installed. Specifically, a computer system


16


would require a significant amount of memory dedicated to the storage of individual printer drivers if more then one printer were to be supported by the system


16


. This obviously limited the space remaining within the computer system


16


for storage of application programs


18


. In addition, because of the complexity of printer drivers, different printer drivers tend to have various quirks (or bugs) that cause great headache for application developers. Consistent, high-quaility printing is a luxury for users. For the same reason, many printer devices do not have drivers for everyOS platoform. For example, many popular consumer printers dondo nott have Windows NT drivers.




For the purpose of easing the development of Windows printer drivers and improving the driver quality across the board, engineers at Microsoft developed a new universal printer driver to be included within the Windows operating system. This new universal printer driver included a standard set of device driver functions based on device characterization which is needed to drive the individual printers. As illustrated in

FIG. 16

, the computer system


19


implementing the universal driver still utilizes the graphics device interface (GDI)


14


as a means of coordinating the output from the various application programs. The GDI


14


function invokes the device driver functions of a minidriver


17




1


,


17




2


, . . .


17




n


which correspond to and contain the characterization of individual printer devices


10




1


,


10




2


, . . .


10




n


.




The difference in this system from that illustrated in

FIG. 15

is that the operating system includes the unidriver


15


which includes a standard set of device driver functions required to drive a printing device. In this way, the individual printer manufactures need not provide this coding. In order to actually drive any particular printer device, the unidriver


15


must receive individual printer characterization information from a selected minidriver


17




1


. The universal driver


15


then stores this device characterization data, preferably within a device context, to be used by the device driver functions of the universal driver


15


. Other device driver functions of the minidriver


17




1


forward their invocation to the universal driver


15


by invoking an analogous function of the universal driver


15


. In this way, the printer hardware manufacturer needs only supply a relatively small minidriver which contains characterization data for their particular device and which will be used by the unidriver


15


to actually drive the printer. This unidriver/minidriver system is described in U.S. Pat. No. 5,604,843 to Shaw et al. for METHOD AND SYSTEM FOR INTERFACING WITH A COMPUTER OUTPUT DEVICE, the disclosure and teachings of which are incorporated herein by reference.




While this system provides significant advantages over the prior operating system requirement of large monolithic printer drivers, the inability of this universal driver


15


to support continued advances from printer manufacturers, and the difficulty of coding and debugging the required minidriver format has become apparent. Specifically, the architecture of this prior universal printer driver could be likened to a database into which individual printer characterization data from the minidriver must be directly mapped. As such, new features supplied by the printer manufacturers could not be supported by the universal driver because there was nowhere within the universal driver for this new function to be mapped. A new feature could only be implemented if its support were included in a new release of a new version of the universal driver. However, new version releases often lagged quite significantly behind the introduction of new printers having advanced features. As a result of this inability to map new features into the existing universal driver, many original equipment manufacturers (OEMs) reverted to writing their own monolithic printer drivers to allow full support functionality of their new printing devices.




Additionally, the structure of the universal driver required that the minidrivers be of a specific binary format. Since development and coding of these binary minidrivers was difficult at best, Microsoft introduced a graphical user interface (GUI) tool called unitool to aid the software engineer in writing these minidrivers. This unitool driven generic printer characterization (GPC) was intended to provide an application independent way of describing the total functionality and capabilities of one or more printers supplied by a printer OEM. Once this GPC file had been written using the unitool GUI, it was then compiled and linked into a resource DLL. This compiled and linked resource DLL was then installed for use by the universal driver. Unfortunately, if a bug were discovered in the GPC file, the entire process would need to be repeated. This process included accessing the unitool GUI, modifying the binary GPC characterization file, recompiling and relinking this GPC file into the resource DLL, and then reinstalling this compiled and linked resource DLL for use by the unidriver. This significantly impacted the time required for debugging and development of the individual minidrivers.




Because of its rigid architecture, the universal driver provided very limited support for any customization, and that which was provided was only in the areas of command callback, raster dump, filter graphics, and font related callbacks. Additionally, the universal printer driver architecture was neither modular nor extensible further limiting its ability to allow for customized support of new features. This resulted in a master-slave relationship between the universal driver and the minidriver, constraining the support and functionality to its implemented structure and supported features. This resulted in a great deal of consternation within the printer OEM community.




SUMMARY OF THE INVENTION




The universal printer driver (Unidrv5) of the instant invention is a new 32-bit universal printer driver developed by Microsoft for initial implementation in Windows NT5.0. Compared to previous versions of a universal printer driver in various Windows operating systems (OS), the Unidrv5 of the instant invention is designed to dramatically improve the extensibility of the driver architecture and the support for printer features. A key new feature of the instant invention includes a new printer data description format called Generic Printer Description (GPD). Compared to GPC/UNITOOL described above, GPD offers much improved capability to describe printer devices. The architecture of Unidrv5 also supports extensive original equipment manufacturer (OEM) customization interface. This extensibility allows OEM's to plug in special code for customizing the UI, bitmap handling, font and text processing, and general printer control.




The Unidrv5 of the instant invention utilizes a flexible modular architecture which allows enhancements to the driver to be implemented to provide better support for more varieties of output devices, and to improve the output quality, ease of use and performance without the necessity for redesign. Examples include the support for a generic font installer interface, limited vector printing capability, using page content analysis to improve printing quality and performance, and offering more flexibility in UI customization including complete UI functionality replacement.




Generic Printer Description (GPD) is a new text-based printer description file format for creating minidrivers that run with the Unidrv5 of the instant invention. In a preferred embodiment of the instant invention, there is one GPD file for each printer model. But different printers can share GPD data by using the *Include capability in GPD. A GPD file describes all the features on a printer and how to display and invoke these features. It also contains printer-specific commands and attributes that enable the Unidrv5 to generate the correct printer-ready output data. Compared to the binary-based GPC file format used by previous versions of UNIDRV, GPD offers several key advantages.




First, GPD provides support for generic features. This allows adding support for new printer features (such as Print Density, Stapling, etc.) without any change to the Unidrv5. Second, GPD also provides support for custom help. A printer vendor can specify a custom help file to augment the default help file, which would provide users specific context-sensitive help for generic features and other features. Third, GPD provides support for installable options. This allows minidriver developers to specify which printer options are installable. The driver UI asks the user which options are actually installed and allow users to select only those that are installed. Fourth, GPD provides support for various types of constraints. This allows minidriver developers to specify constraints between option selections, such as “the combination of 720 dpi, plain paper and color printing is an invalid configuration”, or constraints between option installations, or constraints between option installation and option selection.




Additionally, GPD provides support for value dependency. This generic mechanism gives minidriver developers great power to describe any kind of dependency between printer commands and/or attributes. Combined with the new command parameter specification scheme, it significantly reduces the need to write command callback code. Further, GPD provides a new command parameter specification scheme. In GPC, each printing command (ex. x-move-to) has a pre-defined list of parameters and there are only limited ways (as supported in EXTCD structure) to manipulate the actual parameter values. GPD, however, allows each command to pick any parameters from a pool of standard variables (essentially a partial snapshot of the printer and driver state that the Unidrv5 maintains). GPD also supports arbitrary arithmetic manipulation of these parameters. Additionally, GPD provides great extensibility. It is very easy to add new features, printer commands or attributes to the GPD file without any impact on Unidrv5. The GPD parser parses the data into a single binary format and Unidrv5 never needs to worry about different binary formats, as was the case with GPC revisions.




The driver user interface (UI) of the Unidrv5 utilizes a similar tree view UI as used by Windows NT4.0 printer drivers, as shown in FIG.


7


. Standard Properties are included on the layout and paper/quality property sheets illustrated in FIG.


8


.




The driver UI, implemented as the user-mode DRIVERUI.DLL, displays all printer features specified in GPD, whether they are standard or generic. For generic features, they are displayed in the order listed in the GPD file generally. The driver UI also enforces the constraints specified in the GPD file. It checks on installable options and allow users to select only those options that are actually installed.




The Unidrv5 of the instant invention preferably is titled UNIDRV.DLL. It handles all DDI calls and generates printer-specific output data based on information in the given GPD file. Unidrv5 also handles raster printing. Unidrv5 supports a large set of printer raster data formats. This includes all types of dot-matrix printers, serial ink jet printers, and page printers. Both monochrome and color printing are supported. In fact, the minidriver developer can define multiple color printing modes in GPD, for example, one with driver rendering in 4 bpp format and another in 24 bpp format. Unidrv5 performs the necessary data conversion and/or halftone to generate raster data ready for the printer. The GPD file can specify what is the default printing mode. It could even suppress the monochrome mode if desired. Unidrv5 also provides color matching support by using ICM2.0 on the host machine. Printer vendors can provide ICC color profiles for their printers and make the association via the printer's .INF file.




Unidrv5 supports device-resident fonts, font cartridges, host-based bitmap fonts, and host-based TrueType fonts. Unidrv5 has built-in support for incremental downloading of TrueType fonts as PCL soft fonts (bitmap and maybe outline). It also supports OEM plug-in's to download TrueType fonts in other printer-specific formats. Unidrv5 also supports FE fonts and wide device fonts (i.e. fonts with more than 256 glyphs). It also supports font substitution (substituting device fonts for system TrueType fonts for better performance).




In the render mode, OEM's can write a plug-in module to extend the capability of Unidrv5 in the various areas. First, an OEM can extend the capability of Unidrv5 in the area of raster data processing. Unidrv5 allows OEM's to hook out raster processing at two levels: at the band level where Unidrv5 would pass a whole band of data; or at the scanline level where Unidrv5 would pass a buffer of raster data for feeding one print head pass. OEM's can also define custom halftone patterns (up to 256×256 size) in the GPD file. Unidrv5 passes the information of the currently selected halftone pattern to GDI which uses it instead of a standard system halftone pattern. Second, an OEM can extend the capability of Unidrv5 in the area of font downloading. Unidrv5 supports an extensible font downloading interface to allow minidrivers to support non-PCL formats. Additionally, an OEM can extend the capability of Unidrv5 in the area of command callbacks. For any GPD command, the minidriver can specify a callback id in order to gain control at the point of emitting that particular command. This essentially gives minidrivers an extensive set of injection points where they can influence the output data stream dynamically. OEM's can also hook out any DDI function for state checking and information caching.




Unidrv5 color support has many improvements compared to previous drivers. First, Unidrv5 adds support for dithered text and allows the driver to query the original brush color at DrvTextOut time. This enables Unidrv5 to achieve WYSIWYG effect on text colors, resulting in better text quality. Unidrv5 also has improved halftone support by improving the standard set of halftone patterns for better output. quality. Unidrv5 also adds support for custom halftone patterns provided by the printer driver. Additionally, Unidrv5 also supports custom image processing. Unidrv5 allows OEM's to plug in special code for optimized halftone and/or color correction at the backend. Unidrv5 supports ICM2.0 for better color output quality.











BRIEF DESCRIPTION OF THE DRAWINGS





FIG. 1

is a simplified block diagram illustrating an exemplary operating environment suitable for application of the instant invention;





FIG. 2

is a simplified block diagram illustrating data flow between components of an embodiment of the instant invention;





FIG. 3

is a simplified block diagram illustrating high level modular interface between the universal printer driver of the instant invention and the OEM customization modules written in accordance with the GPD of the instant invention;





FIG. 4

is a simplified flow diagram illustrating system operation allowing for built—once—run—always functionality;





FIG. 5

is a simplified data exchange diagram illustrating communication between COM components in accordance with the instant invention;





FIG. 6

is a simplified module/function interface diagram illustrating functional interfaces between elements of the instant invention;





FIG. 7

is a UI default document properties illustration as generated by a component of the instant invention;





FIG. 8

is a UI default document properties advanced sheet illustration as generated in accordance with an embodiment of the instant invention;





FIG. 9

is a simplified data structure diagram illustrating an aspect of the instant invention;





FIG. 10

is a simplified data structure diagram illustrateing an aspect of the instant invention;





FIG. 11

is a simplified data structure diagram illustrating an aspect of the instant invention;





FIG. 12

is a simplified data structure diagram illustrating an aspect of the instant invention;





FIG. 13

is a simplified data structure diagram illustrating an aspect of the instant invention;





FIG. 14

is a simplified data structure diagram illustrating an aspect of the instant invention;





FIG. 15

is a simplified block diagram of a prior operating system requiring individual printer drivers for each individual printer; and





FIG. 16

is a simplified block diagram of an overall computer system architecture incorporating minidrivers and a unidriver to provide appropriate interface and control of multiple printers.











While the invention is susceptible of various modifications and alternative constructions, certain illustrative embodiments thereof have been shown in the drawings and will be described below in detail. It should be understood, however, that there is no intention to limit the invention to the specific forms disclosed, but on the contrary, the intention is to cover all modifications, alternative constructions and equivalents falling within the spirit and scope of the invention as defined by the appended claims.




DESCRIPTION OF THE PREFERRED EMBODIMENT




FIG.


1


and the following discussion are intended to provide a brief, general description of a suitable computing environment in which the invention may be implemented. Although not required, the invention will be described in the general context of computer-executable instructions, such as program modules, being executed by a personal computer. Generally, program modules include routines, programs, objects, components, data structures, etc. that perform particular tasks or implement particular abstract data types. Moreover, those skilled in the art will appreciate that the invention may be practiced with other computer system configurations, including hand-held devices, microprocessor systems, microprocessor-based or programmable computer electronics, network PCs, minicomputers, mainframe computers, and the like. The invention may also be practiced and distributed computing environments where tasks are performed by remote processing devices that are linked through a communications network. In a distributed computing environment, program modules may be located in both local and remote memory storage devices.




With reference to

FIG. 1

, an exemplary system for implementing the invention includes a general purposed computing device in the form of a conventional personal computer


20


, including a processing unit


21


, a system memory


22


, and a system bus


23


that couples various system components including the system memory to the processing unit


21


. The system bus


23


may be any of several types of bus structures including a memory bus or memory controller, a peripheral bus, and a local bus using any of a variety of bus architectures. The system memory includes read-only memory (ROM)


24


and random access memory (RAM)


25


. A basic input/output system


26


(BIOS), containing the basic routines that help to transfer information between elements within the personal computer


20


, such as during startup, is stored in ROM


24


. The personal computer


20


further includes a hard disk drive


27


for reading from and writing to a hard disk, not shown, a magnetic disk drive


28


for reading from or writing to a removable magnetic disk


29


, and an optical disk drive


30


for reading from or writing to a removable optical disk


31


such as a CD ROM or other optical media. The hard disk drive


27


, magnetic disk drive


28


, and optical disk drive


30


are connected to the system bus


23


by a hard disk drive interface


32


, a magnetic disk drive interface


33


, and an optical drive interface


34


, respectively. The drives and their associated computer-readable media provide nonvolatile storage of computer readable instructions, data structures, program modules and other date for the personal computer


20


. Although the exemplary environment described herein employs a hard disk, a removable magnetic disk


29


and a removable optical disk


31


, it should be appreciated by those skilled in the art that other types of computer readable media which can store data that is accessible by the computer, such as magnetic cassettes, flash memory cards, digital video disks, Bernoulli cartridges, random access memories (RAMs), read-only memories (ROMs), and the like, may also be used in the exemplary operating environment.




A number of program modules may be stored on the hard disk, magnetic disk


29


, optical disk


31


, ROM


24


, or RAM


25


, including an operating system


35


, one or more application programs


36


, other program modules


37


, and program data


38


. A user may enter commands and information into the personal computer


20


through input devices such as a keyboard


40


and a pointing device


42


. Other input devices (not shown) may include a microphone, joystick, game pad, satellite dish, scanner, or the like. These and other input devices are often connected to the processing unit


21


through a serial port interface


46


that is coupled to the system bus, but may be connected by other interfaces, such as a parallel port, game port, or a universal serial bus (USB). A monitor


47


or other type of display device is also connected to the system busy


23


via an interface, such as a video adapter


48


. In addition to the monitor, personal computers typical include other peripheral output devices (not shown), such as speakers and printers.




The personal computer


20


may operate in a networked environment using logical connections to one or more remote computers, such as a remote computer


49


. The remote computer


49


may be another personal computer, a server, a router, a network PC, a peer device, or other common network node, and typically includes many or all of the elements described above relative to the personal computer


20


, although only a memory storage device


50


has been illustrated in FIG.


1


. The logical connections depicted in

FIG. 1

include a local area network (LAN)


51


and a wide area network (WAN)


52


. Such networking environments are commonplace in offices, enterprise-wide computer networks, intranets, and the Internet.




When used in a LAN working environment, the personal computer


20


is connected to the local network


51


through a network interface or adapter


53


. When used in a WAN networking environment, the personal computer


20


typically includes a modem


54


or other means for establishing communications over the y-area network


52


, such as the Internet. The modem


54


, which may be internal or external, is connected to the system bus


23


via the serial port interface


46


. In a networked environment, program modules depicted relative to the personal computer


20


, or portions thereof, may be stored in the remote memory storage device. It will be appreciated that the network connections shown are exemplary and other means of establishing the communications link between the computers may be used.




Turning now to the Universal Printer Driver (Unidrv5) of the instant invention, this Unidrv5 allows original equipment manufacturers (OEMs) to provide customization components (plugins) to modify the standard driver user interface and the output data stream sent to the printer. A simplified view of the data flow between the components of the universal printer driver of the instant invention and the OEM developed generic printer description (GPD) file is illustrated in FIG.


2


. As may be seen from this figure, the driver architecture is open, i.e. the OEMs are allowed to plug-in custom functions wherever appropriate. This allows this architecture to be very extensible, allowing OEMs to support new printers and features between additional releases of the universal driver of the instant invention. Additionally, because most OEM presumably know better how to generate outputs tailored for their specific printers, better graphics and text quality also results, especially for ink jet printers. As may be seen from

FIG. 2

the driver architecture is modular. This modular driver architecture is composed of multiple well-defined modules based on functionality. Any particular printer may use some or all of these modules' functionality as desired by the OEM.




As may be seen from

FIG. 2

, the design of the generic printer description (GPD) file


102


has a significant influence on the driver's flexibility. A detailed description of the GPD format, features, and advantages is included more fully hereinbelow. The GPD parser


104


parses the text based GPD file into internal binary data structures


106


. The parser


104


is called only once when the printer is installed. After that, the driver accesses the cached binary data structures


106


unless the GPD file


102


has since been updated. The parser


104


also generates helpful error and warning messages for improper GPD files. Note that the GPDfile format continues to evolve over time to order to provide new printing functionality.




The driver user interface (UI) DLL


108


is a separate DLL that handles all device capability/setting queries and presents the graphical user interface (GUI). This DLL


108


interacts with the user and applications, and it provides the device and document settings


110


for the rendering driver


112


. The support provided by the driver user interface DLL of OEM custom UII


14


exists at two different levels. First, the OEM adds custom items and/or makes minor changes to the standard UI. In this scenario the driver controls the UI and its overall look and feel. Second, the OEM may replace the functionality of the UI DLL


108


completely for cases where the first level of support cannot accommodate the OEM requirements.




The driver rendering control


112


covers all DDI calls and font-related calls. The driver rendering DLL's


112


primary function is to convert DDI calls into printer-specific data and send them to the spooler. This DLL


112


also handles information queries regarding the device surface, such as fonts, brushes, colors, etc.




The control module


116


within the driver rendering DLL


112


initializes pdev and sets up the dispatch for rendering DDI calls based on the printer's capability. It also handles banding and dumping raster data to the printer. Both banding and non-banding methods are supported.




Also within the driver rendering DLL


112


, a font module


120


, and a raster module


122


. The font module


120


enumerates device fonts and handles TextOut DDI, including downloading true type fonts to the printer. This module


120


will handle interfacing with font downloaders. In 4 bpp mode bitmap fonts should be half-toned as well, i.e. more than eight colors. The driver also supports gray scale fonts, including both bitmap fonts and device fonts. The raster module


122


handles all bitmap related DDI calls, whether the target is a compatible memory bitmap, or the banding buffer, or the printer's surface. This module


122


also supports OEM custom half-toning and color correction DLL interface. It also supports OEM custom dithering patterns.




In a preferred embodiment of the instant invention, the driver allows for multiple OEM plugin modules as illustrated in FIG.


3


. First, the OEM plugin can have an user interface (UI) module


60


which interacts with the UI module


62


of the printer driver


64


of the instant invention. This module is responsible for UI customization and reporting device capabilities. Second, the OEM plugin can include an OEM rendering module


66


which interacts with the rendering module


62


of the printer driver


64


. This module is responsible for customizing the output data stream.




It is not necessary to have both modules


60


,


66


to customize a printer; one or both modules can be present depending on the needs of the OEM. If, however, multiple OEM plugins are provided for a printer driver


64


, it is up to the OEM who creates the INF file for the printer to ensure that these plugins work well with each other. The driver of the instant invention calls these modules in a predefined order described more fully hereinbelow. The driver of the instant invention supports up to 16 OEM plugins for each printer.




There are several reasons for providing OEMs the capability to customize the standard printer driver


64


of the instant invention. First, OEMs can provide custom features specific to their printer models that are not specifically supported by the driver of the instant invention. This requires that the OEM present an UI to display the features and perhaps sending appropriate data to the printer while printing. Second, printer OEMs can differentiate their printers by customizing the look and feel of the UI presented to the user. This may preferably involve complete functionality replacement of the standard UI provided by the universal printer driver of the instant invention. Third, OEMs can provide a custom help file to supplement or replace the standard driver help content. This is especially helpful for generic features supported in Generic Printer Description (GPD) files and for added custom features. If the OEM is replacing the whole UI functionality, this help file will be used by the OEM UI module


60


.




The driver of the instant invention includes functionality to ensure backward and forward compatibility of the OEM plugins. This feature is known as “build once and run always.” This functionality ensures that “Older” OEM plugins will work with the “Newer” Unidrv5 driver of the instant invention. For example, OEM plugins built for NT5 should work with NT6 (or greater) Unidrv driver. Any changes to the customization interface are transparent to OEM plugins. This functionality also ensures that “Newer” OEM plugins will work with “Older” Unidrv5 driver of the instant invention. For example, OEM plugins built for NT6 (or greater) should work with the Unidrv5 driver of the instant invention which is first being implemented in NT5, assuming the OEM plugin support older customization interfaces (i.e. NT 5 interface).




In order to fulfill the requirements above, OEM plugins are preferably Component Object Model (COM) components. COM is an industry wide specification standard, providing a standard for the driver and plugins to follow to ensure seamless compatibility with each other. COM specifies that a client (Unidrv5 driver of the instant invention) communicates with the component (OEM plugins) through an interface, where an interface is a set of functions that a component implements and the clients use. To find out whether a component supports a specific interface, the client queries the component for the interface, using an interface identifier, a unique constant that is associated with a specific interface. Conversely, the OEM plugins can use the Unidrv5 driver as helper function component.




As COM components, OEM plugins are able to encapsulate the implementation details of the customization interface. To the Unidrv5 driver of the instant invention, the OEM plugin is just a set of interfaces. The driver doesndoes nott know all the interfaces that the component supports, only the interface OEM plugin publishes for any given interface identifier. As OEM customization interfaces evolve, these new interfaces will also be supported, in addition to supporting old interfaces. This way, multiple interfaces allows the support of new interfaces as well as older interfaces. To comply with COM specification, a new interface and interface identifier will be defined as described herein if any of the following conditions are changed: the number of functions in an interface; the order/meaning/return value/type of return value of any functions in an interface; the number of parameters in a function; and/or the order/types/meaning of the parameters in a function.




The driver subsystem of the instant invention can be treated as a set of 4 COM components which communicate to each other solely via interfaces. The first two, as stated above, are the Rendering module


68


and the User Interface (UI) module


62


of the Unidrv5 driver


64


of the instant invention. The last two COM components are the OEM supplied Rendering plugin module


66


and the OEM supplied User Interface plugin module


60


. For simplicity, the following assumes that there is one OEM supplied UI


60


and Rendering


66


plugin, although the OEM may supply more than one or none of each type of plugin. Additional plugins still communicate with the system driver of the instant invention using the same interfaces as the first plugin, and plugins do not communicate among themselves. Therefore, adding more plugins does not change the manner in which the interfaces are used.




As will now be apparent to one skilled in the art, the system User Interface


62


and OEM UI


60


plugin modules communicate via the IPrintOemUI and IPrintOemDriverUI interfaces, while the system rendering modules


68


and OEM rendering plugins


66


communicate via the IPrintOemUni and IPrintOemDriverUni interfaces. Additionally, the IPrintOemUni interface allows the Unidrv5 of the instant invention to access the methods implemented by the Unidrv5 OEM plugin rendering module


66


. Further, the IPrintOemDriverUni interface allows the Unidrv5 OEM plugin rendering module


66


to access the render mode helper function services implemented by Unidrv5


64


. The IPrintOemUI interface allows the system UI module


62


to access the methods implemented by the OEM UI plugin module


60


. Finally, the IPrintOemDriverUI interface allows the OEM UI plugin module


60


to access the UI helper function services implemented by the system UI module


62


.




The OEM must also implement a subset of the COM Class Factory interface. That interface is also defined below. Each interface consists of a set of Methods or Member functions, which may be accessed once a pointer to the interface has been obtained. Not all methods are implemented, so components should be able to handle cases where a method returns E_NOTIMPL. It is expected that as the system drivers and printer hardware are enhanced, new member functions will be needed and existing functions may become obsolete. As this occurs, a new interface will be defined in accordance with the teachings of the instant invention. The system drivers will always support all previous interfaces in addition to the current interface. OEM plugins may choose to support some, all or none of the previous interfaces depending on the level of backward compatibility and functionality desired. As shown in FIG.


4


. Unidrv5 will always start by querying for the current OEM interface


70


and if that is not supported by the OEM plugin


72


, will work backwards, requesting older


74


and older interfaces


76


until one is found


78


,


80


that is supported by the OEM plugin


82


,


84


,


86


. An OEM plugin that supports only the original interface is guaranteed to work with any future version of Unidrv5, but it may not be able to take advantage of features available through the more recent interfaces.




For the purposes of version control, each of the types of interfaces listed above is independent of each other. For example, assume a new version release (i.e. NT6) supports new version interfaces: IPrintOemUni6, IPrintOemDriverUni6, IPrintOemUI6, and IPrintOemDriverUI6. The OEM UI module may choose to implement the original IPrintOemUI interface while using the enhanced IPrintOemDriverUI6 helper functions interface. Similarly the version of the interfaces used or implemented by the OEM UI module have no bearing on the version of the interfaces used or implemented by the OEM Rendering Module.




In addition to the core UI/rendering module functionality, OEM plugins are also responsible for implementing and exposing the class factory. A class factory is a COM component with a single job: creating other components. To be more specific, a particular class factory creates components that correspond only to a single, specific CLSID. OEM plugins first need to define an object that implements the IClassFactory interface and implement its member functions as illustrated generally in FIG.


5


. Among the member functions, CreateInstance is class factory specific.




















HRESULT CreateInstance(







 IUnknown *pUnkOuter,







 const IID &iid,







 void **ppv)















pUnkOuter: Specifies the controlling IUnknown interface of aggregation. Since there is no aggregation, the function should return CLASS_E_NOAGGREGATION if this parameter is not NULL.




iid: Specifies the OEM interface driver wants to communicate with, which is always IID_IUnknown.




ppv: Returns pointer to the requested interface (IUnknown), which will be used by the driver to query for the specific OEM interface.




CreateInstance should create a new instance of the object that implements the corresponding OEM interface defined by the driver (i.e. IPrintOemUI, IprintOemUni, etc). It should return S_OK if succeeded, and return appropriate error code (refer to COM specification) otherwise.




After the class factory is implemented, it needs to be exposed so that the driver will be able to locate the class factory after it has loaded the OEM plugins. To expose its class factory, OEM plugins must export the function DllGetClassObject.




















HRESULT DIIGetClassObject(







 const CLSID &clsid,







 const IID &iid,







 void **ppv)















clsid: Specifies the class ID of the class factory being requested. Driver's UI module will pass in CLSID_OEMUI and driver's rendering module will pass in CLSID_OEMRENDER. The function should return CLASS_E_CLASSNOTAVAILABLE if clsid does not match these two CLSIDs defined in NT DDK header file.




iid: Specifies the interface in the class factory with which driver wants to talk to, which is always IID_IClassFactory.




ppv: Returns pointer to the requested interface (IClassFactory), which will be used by the driver to ask the class factory to create plugin components (by calling its member function CreateInstance).




DllGetClassObject should return S_OK if succeeded, and return appropriate error code (refer to COM specification) otherwise.




OEM plugins must export another function DllCanUnloadNow, which will be called during plugin unloading by the driver to ask OEM plugin whether it can be unloaded or not.




HRESULT DllCanUnloadNow( )




In this function, OEM plugin should check whether it is serving any components. If not, the function should return S_OK and the plugin will be unloaded by the driver. Otherwise, it should return S_FALSE and the plugin will not be unloaded.




The above discussion illustrates the need for COM. The components talk to each other using a known interface. Driver


64


and OEM customization DLL


88


are components as illustrated in FIG.


5


. They are also clients for each other. So driver


64


is a client for OEM customization component


88


and at the same time OEM customization component


8


is a client for driver


64


. They interact with each other using two types of interfaces. The OEM interface is used by the driver of the instant invention to call different OEM customization functions. The driver helper function interface is used by the OEM to call driver provided helper functions like DrvWriteSpoolBuf.




It is recognized that the driver and OEM can have different versions. To make sure that they work together, the interaction starts with establishing a relationship, which involves finding out which interface the OEM component supports as discussed above and as illustrated in FIG.


5


. This involves getting the class factory interface from the OEM component


80


and using this interface to get the IUnknown interface. To do this driver


64


does a GetProcaddress for standard COM function DllGetClassObject. If the OEM component


88


does not export this function, then driver


64


assumes that OEM is not supporting COM interface. If this function is exported and driver


64


gets an IUnknown, then it uses IUnknown->QueryInterface to query interface. Driver


64


starts asking for highest known interface. If the OEM


88


component does not know about that interface, it fails the call. Driver


64


then asks for next lower interface and keeps calling till OEM


88


returns success. Now driver


64


knows which interface OEM component


88


supports. This approach allows driver


64


to use the highest known OEM interface, so that no functionality is lost.




Once the driver finds out about the OEM component's interface, it creates IUnknown interface for its own helper function interface. The driver passes IUnknown interface pointer to OEM component using PublishDriverInterface method of OEM interface. Once OEM gets the IUnknown interface pointer from driver, it should call IUnknown->QueryInterface to find out which helper function interface is supported by the driver. The OEM component should also query from highest known interface to lowest known interface. Driver will return success for the known interface and failure if the interface is not known. Now the OEM component also has the interface pointer of the highest known helper function interface. OEM saves this interface in it is own data structure. Now that both driver and OEM have known interfaces, they can then use interface functions to call each other. Using this method the driver of the instant invention can work with any version of the OEM component. OEM can also write the component in such a way that it supports all known driver helper function interfaces. This will make the OEM DLL “Build Once Run Always.”




In COM implementation all the methods have to be written, even if they do not do anything. The method normally returns E_NOTIMPL if it is not implemented. This makes the implementation easier but degrades the performance. The driver has to call the OEMs for every method of the interface. Unidrv5 needs to know whether or not the OEM implements some methods before it calls the method. This is needed for appropriate initializations. To obtain this information ahead of time, Unidrv5 queries the OEM component for implemented methods by calling GetImplementedMethod in the OEM interface. GetImplementedMethod takes a method name as a parameter. If a given method is implemented the OEM component returns S_OK otherwise it returns S_FALSE. Unidrv5 caches this information and calls only the implemented methods.




Once the job is done, the driver of the instant invention releases the OEM interface by calling Release method. It then does a GetProcAddress on standard COM function DllCanUnloadNow and calls it. This function must be exported by the OEM component. OEM should release any driver interface at this time and all the memory allocated for an interface. If the OEM has no more instances of its interface DllCanUnloadNow returns S_OK and driver unloads the OEM DLL. If all the instances of OEM interface are not released, then this function returns failure and OEM DLL is not unloaded.




OEM plugins are installed in the system as special dependent files of the printer driver. They are preferably listed in the CopyFiles entry of printer driver's INF file. One of the dependent files is preferably a configuration file with INI filename extension. Its purpose is to help to identify other dependent files. The INI file can be either an ANSI or a Unicode text file. It is recommended that Unicode text file be used to avoid potential localization problems. (Notepad can save text file in Unicode format.) The INI filename should be specific enough to avoid conflicts with INI files from other OEMs. The format of an INI file is defined as:




[section]




key=value




. . .




Currently, only [OEMFiles] section is meaningful to the driver. Entries outside of [OEMFiles] section are ignored. Lines starting with ‘#’ character are treated as comments.




Each OEM plugin can have up to two entries in the INI file: OEMDriverFileN, and OEMConfigFileN, where N is a number from 1 upward. When multiple OEM plugins are present, they are called in the order of increasing N. OEMDriverFileN entry specifies the OEM rendering module, and OEMConfigFileN entry specifies the OEM UI module. Any of the two entries can be omitted if the plugin has no corresponding module, but at least one entry must be present. In the following example, there are two OEM plugins associated with the driver. Notice that the second plugin does not have a user mode UI module.




#OEM plugin configuration file for . . .




[OEMFiles]




OEMDriverFile


1


=OEMDRV1.DLL




OEMConfigFile


1


=OEMUI1.DLL




OEMDriverFile


2


=OEMDRV2.DLL




It is important to note that filenames listed in [OEMFiles] section must not have any directory prefix. Also, there must not be any spaces before or after the “=” specifier. These files will be copied into appropriate system directories during the installation process. The driver can determine the full path to those directories, which is not trivial in order to point-and-print to work smoothly.




The OEM UI 60 module is a 32-bit Dynamic Link Library (DLL) that runs in user mode and interacts with the Microsoft printer driver UI modules as shown in FIG.


6


. The OEM UI module


60


can modify the standard UI first by adding nodes to the standard treeview in the device settings and the Advanced dialog in the printing preference UI (see FIG.


8


). Additionally, it can modify the standard UI by adding property sheet pages to the driver UI.




For the UI control, the printer driver UI module interacts with the OEM UI modules


62


through functions, OEMGetInfo, OEMDevMode, OEMCommonUI, and a callback function for processing printer properties and document properties callback messages. The OEMGetInfo function is called by the driver when the OEM module is loaded to get the signature or version of the plugin. It is defined as follows:




















HRESULT







GetInfo(







 IN DWORD dwMode,







 OUT PVOID pBuffer,







 IN DWORD cbSize,







 OUT PDWORD pcbNeeded







 );















dwMode: Identify the query type. It can be any of the following values:




OEMGI_GETSIGNATURE




OEMGI_GETVERSION




pBuffer: Pointer to output buffer which holds the return data.




cbSize: Specifies the size of the buffer pointed by pBuffer.




pcbNeeded: Pointer to a DWORD. Returns the number of bytes written into the output buffer by the OEM plugin. If the output buffer is not large enough, OEM plugin should return FALSE and set the error code to ERROR_INSUFFICIENT_BUFFER. In that case, this variable returns the size of the expected output buffer.




Return Value:




S_OK if the function succeeds, E_FAIL if it fails. The reason for the failure should be set via SetLastError.




GetInfo(OEMGI_GETSIGNATURE) is used to get the 4-byte OEM signature. This signature is used by the driver to uniquely identify the OEM plugin and its private devmode information. So it should be chosen with care in order to avoid conflict with other OEM plugins. Zero is not allowed to be used as a signature. Small integers should be avoided as well. One scheme is to use a four-character abbreviation which is relevant to a particular company and/or products. If multiple OEM plugins use the same signature, only the first plugin will be loaded. OEMGetInfo(OEMGI_GETVERSION) is used to get OEM plugin's version number. Same signature and version information should also be used in OEM_DMEXTRAHEADER structure described below.




Devmode support is required only if the OEM plugin needs a private devmode. The OEM plugins can store their own private data in the devmode. The overall structure of the devmode


90


is as shown in FIG.


9


. Note that to the application and the spooler, all of the extra data appears to be owned by driver.




OEM private devmode must always start with the following structure


92


as illustrated in FIG.


10


.




















typedef struct_OEM_DMEXTRAHEADER {







 DWORD  dwSize;







 DWORD  dwSignature;







 DWORD dwVersion;







} OEM_DMEXTRAHEADER, *POEM_DMEXTRAHEADER;















dwSize: Size of OEM private devmode in bytes, including the header itself.




dwSignature: OEM plugin signature.




dwVersion: OEM plugin version number.




An OEM plugin is called to get the size of its private DEVMODE, initialize its private DEVMODE with default values, convert an arbitrary version DEVMODE to its current version private DEVMODE, and validate an existing OEM private DEVMODE and merge the information into an output devmode.




All of these happen through the DevMode function:




















HRESULT







DevMode(







  IN DWORD  dwMode,







 POEMDMPARAM pOemDMParam







 );















dwMode: One of the following constants (more details on these later):




OEMDM_SIZE




OEMDM_DEFAULT




OEMDM_CONVERT




OEMDM_MERGE




pOemDMParam: pointer to OEMDMPARAM structure defined as following.




















typedef struct_OEMDMPARAM {







 DWORD cbSize;







 PVOID pdriverobj;







 HANDLE hPrinter;







 HANDLE hModule;







 PDEVMODE pPublicDMIn;







 PDEVMODE pPublicDMOut;







 PVOID pOEMDMIn;







 PVOID pOEMDMOut;







 DWORD cbBufSize;







} OEMDMPARAM, *POEMDMPARAM;















cbSize: Size of OEMDMPARAM structure.




pdriverobj: Reference pointer to driver's data structure. This is used to call




DrvGetDriverSetting.




In rendering module, it is the same as pdevobj. In UI module, it is the poemuiobj.




hPrinter: Handle to the current printer.




hModule: Instance handle to the OEM plugin DLL.




pPublicDMIn: Pointer to input public devmode.




pPublicDMOut: Pointer to output public devmode.




pOEMDMIn: Pointer to input OEM private devmode.




pOEMDMOut: Pointer to output OEM private devmode.




cbBufSize: Size of output OEM private devmode buffer.




Return value:




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented.




E_FAIL return value from OEM plugin causes the driver to fail its current entry point and return error to its caller (e.g. spooler or GDI). Specifically, OEM plugin should not return E_FAIL just because the input devmode is invalid. It should take what valid information from the input devmode and use appropriate defaults for invalid fields.




An OEM plugin should be very careful when accessing devmode fields, either public or private. It must take into consideration of different versions of devmode. Devmode may grow by adding new fields to the end for both public and private parts. An OEM plugin must be able to handle older smaller devmode by verifying the validity of a field before accessing it, and handle future bigger devmode by recognizing that the size may grow. For the most part, this has already been taken care of by the driver. Except for OEMDM_CONVERT, the driver will provide OEM plugin with its current version DEVMODE.




Conceptually, the driver goes through the following steps upon receiving an arbitrary input devmode. First, it calls DevMode(OEMDM_SIZE) to get the size of OEM private devmode, allocates enough memory, and calls devMode (OEMDM_DEFAULT) to let OEM plugin provide its default devmode settings. Second, it then calls DevMode(OEMDM_CONVERT), with the default OEM private devmode allocated in the previous step in pOEMDMOut in case it is needed. OEM plugin must be prepared to deal with the fact that the input OEM private devmode may be from an older or a new version of the OEM plugin. If it is the same version, then it can simply copy the input devmode to the output buffer. Third, the converted OEM private devmode is finally merged with the printer's default devmode information. (Set through “Printing Preferences . . . ” menu item from the “Printers” folder.) The driver calls DevMode(OEMDM_MERGE) with the printer default devmode as output and the converted devmode from step


2


as input. It is important to note that an OEM plugin should never assume that it can locate its extra data from the top of the public devmode. All access to its private devmode data must happen through pOEMDMIn and pOEMDMOut.




To get the size of an OEM plugin's private devmode, the driver calls DevMode with the dwMode field set to OEMDM_SIZE. OEM plugin should put the size required for its private devmode data in the cbBufSize field


94


of OEMDMPARAM structure and return TRUE to indicate success as illustrated in FIG.


11


. If an OEM plugin does not need a private devmode, it should not implement DevMode function from its DLL.

















Field




In




Out











CbSize




sizeof(OEMDMPARAM)











Pdriverobj




Reference to driver's data structure











HPrinter




Handle to the current printer











HModule




Handle to OEM plugin DLL











PPublicDMIn




NULL











PPublicDMOut




NULL











POEMDMIn




NULL











POEMDMOut




NULL











CbBufSize




0




size of OEM








private devmode














To fill the OEM private devmode with default values, the driver calls DevMode with dwMode set to OEMDM_DEFAULT.

















Field




In




Out











CbSize




sizeof












(OEM_DEVMODEPAPAM)






Pdriverobj




Reference to driver's data structure











HPrinter




Handle of Printer











HModule




Handle to OEM plugin DLL











PPublicDMIn




Points to input public DEVMODE












containing default values set by the







driver






PPublicDMOut




NULL











POEMDMIn




NULL











pOEMDMOut




Pointer to output OEM private




OEM plugin should







devmode buffer




fill the output buffer








with its default








private devmode








settings.






cbBufSize




size of OEM private devmode



















The driver calls DevMode with dwMode set to OEMDM_CONVERT to request an OEM plugin to convert its private devmode to the current version (without validation) as illustrated in FIG.


12


.

















Field




In




Out











CbSize




sizeof(OEM_DEVMODEPARAM)











Pdriverobj




Reference to driver's data structure











HPrinter




Handle to the current printer











HModule




Handle to OEM plugin DLL











PPublicDMIn




Pointer to input public devmode











PPublicDMOut




Pointer to output public devmode,












containing information which the







driver has already converted from the







input devmode






POEMDMIn




Pointer to input OEM private












devmode to be converted






POEMDMOut




Pointer to output OEM private




OEM plugin







devmode buffer, containing the




should convert







default current version OEM private




the input dev-







devmode information




mode and stores








the result in the








output devmode








buffer.






CbBufSize




size of current version OEM private












devmode














As Windows NT supports printer connections over the network, pOEMDMIn


96


could point to data from older, newer or current version of the same OEM plugin. An OEM plugin converts this to the current format retaining as much information as possible, and copies it to the output buffer pOEMDMOut


98


. OEM plugin should not access any bytes beyond (PBYTE) pOEMDMIn+pOEMDMIn→dwSize. Some caution should be exercised as well when accessing fields in pPublicDMIn


100


.




The driver calls DevMode with dwMode set to OEMDM_MERGE to request an OEM plugin to validate the information in the input private devmode and merge it with the default private devmode, placing the result in the output buffer (pOEMDMOut)


98


as illustrated in FIG.


13


. OEM plugin can assume both pOEMDMIn


96


and pOEMDMOut


98


point to its version devmodes, although pOEMDMIn may contain invalid information.

















Field




In




Out











CbSize




sizeof(OEM_DEVMODEPARAM)











Pdriverobj




Reference to driver's data structure











HPrinter




Handle of Printer











HModule




Handle of OEM module











PPublicDMIn




Points to input public devmode











PPublicDMOut




Points to output public devmode











POEMDMIn




Points to input OEM private












devmode, containing information







returned from OEMDevMode







(OEMDM_CONVERT)






POEMDMOut




Points to output OEM private




OEM plugin







devmode, containing valid current




should merge any







version OEM private settings.




valid information








from the input








devmode into the








output devmode.






CbBufSize




size of OEM private devmode



















The driver allows OEM plugins to access and update driver's private settings through DrvGetDriverSetting and DrvUpdateUISetting and DrvUpgradeRegistrySetting helper functions. OEM plugins can obtain the address of these helper functions in the driver's helper function interface, IPrintOemDriverUI.




DrvGetDriverSetting helper function allows the OEM plugins to access the driver's private setting.




















HRESULT







DrvGetDriverSetting(







 PVOID pdriverobj,







 PCSTR Feature,







 PVOID pOutput,







 DWORD cbSize,







 PDWORD pcbNeeded,







 PDWORD pdwOptionsReturned







 );















pdriverobj: Reference pointer to driver's data structure.




Feature: Specifies what feature the caller is interested in.




pOutput: Points to output buffer.




cbSize: Specifies the size of the output buffer.




pcbNeeded: Returns the minimum size for the output buffer.




pdwOptionsReturned: Returns the number of options currently selected for the specified feature.




Feature specifies the name of the feature in which the caller is interested. The name must be an ANSI string containing only printable ASCII characters. The name should come from the printer description file. For generic printer features, the output buffer will return the name(s) of currently selected option(s). The output will be in the MULTI_SZ form, i.e. a sequence of nul-terminated ASCII character strings followed by an extra nul-character at the end.




If the value of Feature is less than 0x10000, then Feature refers to one of the predefined driver features. For a list of predefined driver feature indices, refer to OEMGDS_constants defined in printoem.h. Index values from 1 to 0x7fff refer to document-sticky settings in the current devmode. Index values from 0x8000 to 0xffff refer to printer-sticky settings in the registry. For predefined driver features, the meaning of output value varies.




To determine how big the output buffer should be, DrvGetDriverSetting should be first called with pOutput set to NULL and cbSize set to 0. DrvGetDriverSetting will return E_FAIL in this case and the last error code will be set to ERROR_INSUFFICIENT_BUFFER.




In most situations, an output buffer size of 64 bytes should be big enough. So OEM plugins may want to start out with a buffer of this size to avoid having to call DrvGetDriverSetting twice.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented




DrvUpdateUISetting helper function allows the OEM plugins to update the driver's UI settings and shows UI constraints, if applicable. This function is valid only while the UI is present.




















HRESULT







DrvUpdateUISetting(







 PVOID  pdriverobj,







  PVOID pOptItem,







  DWORD  dwPreviousSelection,







  DWORD  dwMode







  );















pdriverobj: Reference pointer to driver's data structure.




pOptItem: Specifies the OPTITEM that contains the information to be updated in driver's settings.




dwPreviousSelection: Specifies the previous selection of the OPTITEM. This selection is used to restore the UI setting to the previous selection once a contraints is found with the new selection and the user wishes to cancel the selection.




dwMode: Specifies the document property mode or device property mode.




OEMCUIP_DOCPROP—This function is called from DrvDocumentPropertySheets




OEMCUIP_PRNPROP—This function is called from DrvDevicePropertySheets




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




The OEM plugin calls this helper function to upgrade their device settings stored in private registry keys into the driver's internal private data. This function is needed only if the OEM, in previous driver version, had stored device settings, which are now part of the GPD file, in private registry keys. This is necessary and valid only when called from OEM's UpgradePrinter function.





















HRESULT








DrvUpgradeRegistrySetting(







 HANDLE




hPrinter,







 PCSTR




pFeature,







 PCSTR




pOption







 );















hPrinter: Handle to printer driver module.




pFeature: Pointer to FEATURE keyword name to upgrade.




pOption: Pointer to OPTION keyword name to upgrade.




The driver will use the (pFeature, pOption) pair to upgrade its internal data to the requested settings.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




OEM plugins can add, replace or hide nodes in the treeview display on the device settings UI or the Printing Preferences UI. To accomplish this, an OEM plugin should implement the CommonUIProp function. The driver calls CommonUIProp to give OEM plugin a chance to add its UI items after the driver's items. An OEM plugin can also modify the driver's items at this point. The driver first calls this function to get the number of OPTITEMs that the OEM wishes to add, allocates the required memory for OPTITEMs, and calls this function again for the OEM to provide the OPTITEMs. Note that any memory required to fill out the OPTITEMs, such as OPTTYPEs and OPTPARAMs, can be allocated by the OEM from the memory heap supplied by the driver. The driver is responsible for disposing the heap when the items are no longer needed. The behavior is the same for both DocumentPropertySheets items and PrinterPropertySheets items.





















HRESULT








CommonUIProp(







 DWORD




dwMode,







 POEMCUIPPARAM




pOemCUIPParam







 );















dwMode: one of the following values.




OEMCUIP_DOCPROP—This function is called from DrvDocumentPropertySheets




OEMCUIP_PRNPROP—This function is called from DrvDevicePropertySheets




pOemCUIPParam: pointer to OEMCUIPPARAM structure defined below.




















typedef struct_OEMCUIPPARAM {







 DWORD  cbSize;







 POEMUIOBJ  poemuiobj;







  HANDLE  hPrinter;







 PWSTR  pPrinterName;







 HANDLE  hModule;







 HANDLE  hOEMHeap;







 PDEVMODE  pPublicDM;







 PVOID  pOEMDM;







 DWORD  dwFlags;







 POPTITEM  pDrvOptItems;







 DWORD  cDrvOptItems;







 POPTITEM  pOEMOptItems;







 DWORD  coEMOptItems;







 PVOID  pOEMUserData;







 OEMUICALLBACK  OEMUICallback;







} OEMCUIPPARAM, *POEMCUIPPARAM;















cbSize: Size of OEMCUIPPARAM structure.




poemuiobj: Reference pointer to driver's data structure; used to call DrvGetDriverSetting.




hPrinter: Handle to the current printer.




pPrinterName: Name of the current printer.




hModule: Instance handle to OEM plugin DLL.




hOEMHeap: Handle to a memory heap from which OEM plugin should allocate all of its memory.




pPublicDM: Points to public devmode.




pOEMDM: Points to OEM private devmode.




dwFlags: the fMode parameter passed in for either DrvDocumentPropertySheets or DrvDevicePropertySheets.




pDrvOptItems: Points to driver's UI items (array of OPTITEM's).




cDrvOptItems: Count of driver's UI items.




pOEMOptItems: Points to OEM plugin's UI items.




cOEMOptItems: Count of OEM plugin's UI items.




pOEMUserData: Points to OEM plugin's private data.




OEMUICallback: Address of OEM plugin's UI callback function.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




The table below summarizes the contents of the OEMCUIPPARAM structure for the first call to get OEM plugin's OPTITEM count: (Although this example is for OEMCUIP_DOCPROP, it is very similar for OEMCUIP_PRNPROP.)

















Field




In




Out











CbSize




sizeof(OEMCUIPPARAM)











Poemuiobj




Reference to driver's data structure











HPrinter




Handle to the current printer











PPrinterName




Name of the current printer











HOEMHeap




Handle to OEM memory heap











PPublicDM




Pointer to public DEVMODE











POEMDM




Pointer to OEM private devmode











DwFlags




fMode passed in for












DrvDocumentPropertySheets call






PDrvOptItems




NULL











CDrvOptItems




Expected count of driver's












OPTITEMs






POEMOptItems




NULL











COEMOptItems




0




count of OEM








OPTITEMs






POEMUserData




NULL











OEMCUIPCallback




NULL



















The second call asks the OEM plugin to actually fill out its OPTITEMs:

















Field




In




Out











CbSize




sizeof(OEMCUIPPARAM)











Poemuiobj




Reference to driver's data structure











HPrinter




Handle to the current printer











PPrinterName




Name of the current printer











HOEMHeap




Handle to OEM memory heap











PpublicDM




Pointer to public DEVMODE











POEMDM




Pointer to OEM private devmode











DwFlags




fMode passed in for












DrvDocumentPropertySheets call






PDrvOptItems




Points to driver's OPTITEMs











CDrvOptItems




Count of driver's OPTITEMs











POEMOptItems




Points to OEM's OPTITEMs




Filled out







buffer




OPTITEMs






COEMOptItems




count of OEM OPTITEMs











POEMUserData




NULL




pointer to OEM








private data






OEMCUIPCallback




NULL




address of








OEM UI call-








back function














pOEMUserData field should return a pointer to OEM plugin's private data structure. Later during callbacks, the driver will give OEM plugin a pointer to this same OEMCUIPPARAM structure. OEM plugin can easily obtain a pointer to its private data from there. If dwMode is OEMCUIP_PRNPROP, there will be no devmode information and both pPublicDM and pOEMDM will be NULL.




















typedef LONG (APIENTRY *OEMCUIPCALLBACK)(







 PCPSUICBPARAM pCallbackParam,







 POEMCUIPPARAM pOemCUIPParam







 );















During dialog processing, COMPSTUI normally calls the driver to process messages for node items. For example, the driver gets called by compstui when there is a selection change or when the user presses OK or Cancel. The driver first processes the message itself and then calls each OEM plugin to give them a chance to process the message as well.




In addition to PCPSUICBPARAM pointer from COMPSTUI, the driver passes an additional parameter to OEM plugin's callback function. This is a pointer to the same OEMCUIPPARAM structure that the driver passed to CommonUIProp earlier.




Given OEMCUIPPARAM, OEM plugin can easily determine whether a particular item pOptItem belongs to it:




pOptItem>=pOemCUIPParam→pOEMOptItems &&




pOptItem−pOemCUIPParam→pOEMOptItems<pOemCUIPParam→cOEMOptItems




If OEM plugin does not care about a particular message (e.g. if the message was meant for a UI item belonging to some other component), it should return CPSUICB_ACTION_NONE from its callback function. Otherwise, it should process the message and return an appropriate result value. Result values from different components (the driver and OEM plugins) are combined as follows:




1. If the callback reason is CPSUICB_REASON_APPLYNOW:




As soon as one of the components returns




CPSUICB_ACTION_NO_APPLY_EXIT, the driver returns that result value to compstui. Otherwise, the result value must be CPSUICB_ACTION_ITEMS_APPLIED.




2. Otherwise, the precedence for different result values is defined as (in decreasing order):




CPSUICB_ACTION_REINIT_ITEMS




CPSUICB_ACTION_OPTIF_CHANGED




CPSUICB_ACTION_NONE





FIG. 14

illustrates what happens during a callback when an item selection changes.




An OEM plugin may add its own property sheet pages to existing property sheet pages provided by the spooler and driver. This is accomplished by the two functions described below. If an OEM plugin does not have its own property sheet pages, then it should not implement these functions.




















HRESULT







DocumentPropertySheets(







 PPROPSHEETUI_INFO pPSUIInfo,







 LPARAM  IParam







 );







HRESULT







DevicePropertySheets(







 PPROPSHEETUI_INFO pPSUIInfo,







 LPARAM  IParam







 );















Note: The driver will always add its own pages before calling compstui to add OEM pages. The control flow is as follows:




1. Application calls spooler's DocumentProperties API.




2. Spooler adds its pages and tells compstui to call the driver's DrvDocumentPropertySheets entry point.




3. compstui calls the driver which adds its own pages and asks compstui to call OEM's DocumentPropertySheets function.




4. compstui calls OEM plugin's DocumentPropertySheets function.




When multiple OEM plugins are present, the driver adds it pages, and then calls each OEM DLL in turn (through compstui).




The driver passes an OEMUIPSPARAM structure as a parameter to each OEM plugin's DocumentPropertySheets and DevicePropertySheets functions. To get a pointer to this parameter, an OEM plugin should do the following at the beginning of DocumentPropertySheets or DevicePropertySheets:




pOemUIPSParam=(POEMUIPSPARAM) pPSUIInfo→lParamInit;




OEMUIPSPARAM is defined as following:




















typedef struct_OEMUIPSPARAM {







 DWORD  cbSize;







 POEMUIOBJ  poemuiobj;







 HANDLE  hPrinter;







 PWSTR  pPrinterName;







 HANDLE  hModule;







 HANDLE  hOEMHeap;







 PDEVMODE  pPublicDM;







 PVOID  pOEMDM;







  PVOID  pOEMUserData;







 DWORD  dwFlags;







} OEMUIPSPARAM, *POEMUIPSPARAM;















The meaning of each field is the same as in OEMCUIPPARAM structure except for dwFlags:




For DocumentPropertySheets call, dwFlags is the DOCUMENTPROPERTYHEADER.fMode value passed into the driver's DrvDocumentPropertySheets entry point.




For DevicePropertySheets call, dwFlags is the DEVICEPROPERTYHEADER.Flags value passed into the driver's DrvDevicePropertySheets entry point. (Please refer to Windows NT DDK documentation and winddiui.h for more information about these driver entry points.)




It should be noted that an OEM DLL should not access pPublicDM and pOEMDM fields in DevicePropertySheets call.




An OEM plugin can also optionally implement the following functions. These functions have almost the same prototype as their equivalent DDI entry points exported by the driver. OEM plugins that do not want to handle any of the following functions should not implement them from their DLLs.




The DevQueryPrintEx function allows the spooler to manage mismatched jobs. The driver first checks if the job is printable or not based on the input devmode information and the printer settings in the registry. If it is not printable, it returns to the spooler with an appropriate error message. If it believes that the job is printable, it then calls OEM plugins' DevQueryPrintEx functions. A job is printable only if the driver and all OEM plugins believe that it is printable. If multiple OEM plugins are present, the driver calls them in order until one of them reports that the job is unprintable or all of them agree that it is printable.




















HRESULT







DevQueryPrintEx(







 IN POEMUIOBJ  poemuiobj,







 IN  PDEVQUERYPRINT_INFO pDQPInfo,







 IN PDEVMODE  pPublicDM,







 IN PVOID  pOEMDM







 );















poemuiobj: Reference pointer to driver's data structure; used to call DrvGetDriverSetting.




pDQPInfo: Same as what the spooler passed to the driver's DevQueryPrintEx entry point.




pPublicDM: Points to public devmode structure. pOEMDM: Points to OEM plugin's private devmode, if any.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




This function reports the capabilities of the device. When the driver is called through its DeviceCapabilities entry point, it validates the input devmode information, processes the request, and stores information in the output buffer if applicable. The driver then calls each OEM plugin's DeviceCapabilities function. DeviceCapabilities gets the same information as what the driver got from DeviceCapabilities with a couple of exceptions: 1) OEM plugin gets pointers to both public devmode and to its private devmode. 2) OEM plugin gets an additional parameter which is the return value from its previous plugin. The first plugin get the return value from the driver itself.




To ensure harmonious cooperation between the driver and possibly multiple OEM plugins, OEM plugins must follow the following guidelines in their DeviceCapabilities implementations. If an OEM plugin does not support the device capabilities in question, it should simply return the input result value and leave everything else untouched. If an OEM plugin wants to completely handle a particular device capability, it should overwrite any existing information in the output buffer and return an appropriate result value. If any errors occur in the process, it should return GDI_ERROR as the result value. If an OEM plugin wants to modify the output information for a device capability that's already handled by the driver or another plugin, it should update the output buffer and return an appropriate result value.




Note that if the input result value is GDI_ERROR, there is no way for an OEM plugin to determine whether earlier components had an error or they simply didn't support the particular device capability.




















HRESULT







DeviceCapabilities(







 IN POEMUIOBJ  poemuiobj,







 IN  HANDLE  hPrinter,







 IN  PWSTR  pDeviceName,







 IN WORD  wCapability,







 OUT PVOID  pOutput,







 IN PDEVMODE  pPublicDM,







 IN PVOID  pOEMDM,







 IN DWORD  dwOld







  IN  DWORD  dwResult







 );















poemuiobj: Reference pointer to driver's data structure; used to call DrvGetDriverSetting.




hPrinter:




pDeviceName:




wCapability:




pOutput: These parameters are identical to what spooler passed to the driver's DeviceCapabilities entry point.




pPublicDM: Points to public devmode structure.




pOEMDM: Points to OEM plugin's private devmode.




dwOld: Return value from the previous plugin. In the case of the first OEM plugin, this is the return value from the driver itself.




dwResult: Return value for DeviceCapabilities.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




This API gives the driver a chance during the upgrade process to update its device settings stored in the registry from one version to the next. This function is needed only if any new registry information needs to be added or old information needs to be validated or updated. The driver UI module always processes its own upgrade first and then calls OEM plugins' UpgradePrinter functions.




















HRESULT







UpgradePrinter(







 DWORD dwLevel,







 PBYTE pDriverUpgradeInfo







 );















dwLevel:




pDriverUpgradeInfo: Same as what's passed into the driver's DrvUpgradePrinter entry point. Currently, dwLevel is always 1 and pDriverUpgradeInfo is a pointer to an DRIVER_UPGRADE_INFO_


1


structure.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




This API is called when certain events occur that might require action by the printer driver. For example, the driver is notified when a local printer is installed or when the spooler has detected changes in the cache from a printer server. The driver always processes the events first and then calls OEM plugins' PrinterEvent functions for further processing.




















HRESULT







PrinterEvent(







 PWSTR  pPrinterName,







 INT  iDriverEvent,







 DWORD  dwFlags,







 LPARAM  IParam







 );















pPrinterName:




iDriverEvent:




dwFlags:




lParam: Same as what spooler passed to the driver's DrvPrinterEvent entry point.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




This API is used to get information about the default color profile for a given devmode, to be used with ICM.




















HRESULT







QueryColorProfile(







  HANDLE  hPrinter,







 PDEVMODEW  pdevmode,







 ULONG  ulReserved,







 VOID  *pvProfileData,







 ULONG  *pcbProfileData,







 FLONG  *pflProfileData







  );















hPrinter: Handle to printer driver module.




pdevmode: Pointer to DEVMODE.




ulReserved: Reserved.




pvProfileData: Pointer to store color profile data. If this is NULL, the OEM plugin should set the necessary size in cbProfileData.




pcbProfileData: Pointer to size of pvProfileData buffer in byte and store size of color profile data written to pvProfileData on return.




pflProfileData: Pointer to store color profile data type.




QCP_PROFILEMEMORY—The pvProfileData points to the color profile data itself.




QCP_PROFILEDISK—The pvProfileData points to the color profile name in Unicode.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




The FontInstallerDlgProc function is the call back function handling the UI shown by the font installer.




















HRESULT







FontInstallerDlgProc(







 HWND   hWnd,







 UINT  usMsg,







  WORD  wParam,







  LONG  IParam







 );















The parameters above are similar to ones defined for a UI dialog procedure defined in the SDK. When it is called with the WM_INIT message, or the WM_USER+WM_FI_NAME message, IPram points to an OEMFONTINSTAPRAM structure.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




The UpdateExternalFonts function is called by the driver UI module to update the set of cartridge fonts in the font file.




















HRESULT UpdateExternalFonts (







  HANDLE hPrinter,







 HANDLE hHeap,







 PWSTR pwstrCartridges







  );















PwstrCartridges specifies the list of cartridges currently installed on the printer, and the font installer should make sure only cartridge fonts belonging to these cartridges are in the font file. To add fonts belonging to cartridges not in the font file, the font installer uses the font file specified by the “ExtFontCartFile” name in the registry.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




Preferably, the driver rendering module interacts with the OEM rendering module DLLs. The OEM DLLs may request direct access to DDI calls, or rely on callbacks from the driver for special processing at predefined points during the driver's output generation. It is important to note that the OEM rendering module DLLs must not have any global variables. The OEM rendering module DLL are required to support the following function in addition to GetInfo described above:




PublishDriverInterface




GetImplementedMethod




When multiple OEM plugins are present, the same function from each OEM DLL is called in turn except for UNIDRV-only callback functions which allow at most one OEM DLL to hook out for each function. The order in which they are called is determined through the mechanism described above.




The driver calls this function during DrvEnablePDEV time to determine which functions the OEM DLL provides and which DDI functions OEM DLL wants to hook out.




















HRESULT







EnableDriver(







 DWORD  dwOemIntfVersion,







 DWORD  cbSize,







 PDRVENABLEDATA  pded







 );















dwOemIntfVersion: specifies the OEM interface version number used by the driver.




cbSize: size of the buffer pointed to by pded, in bytes.




pded: pointer to a DRVENABLEDATA structure used by OEM DLL to return output data to the driver. pded→iDriverVersion should be the same as DriverVersion parameter. pded→c specifies the number of DDI entry points the OEM DLL has hooked out. pded→pdrvfn points to a function table containing the address of hooked DDI entry points.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




Following DDI entry points can be hooked out by the OEM:




INDEX_DrvRealizeBrush




INDEX_DrvDitherColor




INDEX_DrvCopyBits




INDEX_DrvBitBlt




INDEX_DrvStretchBlt




INDEX_DrvStretchBltROP




INDEX_DrvPlgBlt




INDEX_DrvAlphaBlend




INDEX_DrvGradientFill




INDEX_DrvTransparentBlt




INDEX_DrvTextOut




INDEX_DrvStrokePath




INDEX_DrvFillPath




INDEX_DrvStrokeAndFillPath




INDEX_DrvPaint




INDEX_DrvLineTo




INDEX_DrvStartPage




INDEX_DrvSendPage




INDEX_DrvEscape




INDEX_DrvStartDoc




INDEX_DrvEndDoc




INDEX_DrvStartBanding




INDEX_DrvNextBand




INDEX_DrvQueryFont




INDEX_DrvQueryFontTree




INDEX_DrvQueryFontData




INDEX_DrvQueryAdvanceWidths




INDEX_DrvFontManagement




INDEX_DrvGetGlyphMode




If multiple OEM rendering module DLLs are present, the driver calls them in order. Any DDI function can only be hooked out by at most one OEM DLL. So if subsequent OEM DLLs try to hook out the same function, they will be ignored. Most of the interfaces between the system driver and the OEM DLL have a PDEVOBJ parameter. In some cases, this parameter is directly passed to the OEM DLL by the driver. In the case of DDI entry points hooked out by the OEM DLL, the OEM DLL can obtain this PDEVOBJ parameter from the SURFOBJ pointer as follows:




pdevobj=(PDEVOBJ) pso→dhpdev;




DEVOBJ structure is defined as:




















typedef PVOID PDEVOEM;







typedef struct_DEVOBJ {







 DWORD  dwSize;







 PDEVOEM  pdevOEM;







 HANDLE  hEngine;







 HANDLE  hPrinter;







   HANDLE  hOEM;







 PDEVMODE  pPublicDM;







 PVOID  pOEMDM;







 PDRVPROCS  pDrvProcs;







} DEVOBJ, *PDEVOBJ;















dwSize: size of DEVOBJ structure. As the customization interface evolves, this structure may grow.




pdevOEM: pointer to OEM DLL's device data structure. This value is returned to the driver by the OEM DLL during OEMEnablePDEV call. It can be used by the OEM DLL whichever way it sees fit (e.g. a pointer to some piece of memory).




hEngine: handle used by GDI to identify the current printer device. This parameter is passed into the driver by GDI during DrvEnablePDEV.




hPrinter: spooler handle to the current printer. It is passed into the driver during DrvEnablePDEV.




hOEM: instance handle to the OEM plugin DLL. It is obtained when the driver loads the OEM DLL.




pPublicDM: pointer to public devmode associated with the current device. pOEMDM: pointer to OEM DLL's private devmode, if any.




pDrvProcs: Pointer to a table of helper functions provided by the system driver.




Details provided later in this section.




Before the driver returns its PDEV to GDI, it calls the OEM DLL's EnablePDEV to allow it to construct its own PDEV. At this time, the driver also passes a function table which contains its own implementation of DDI entry points. This allows the OEM DLL to pre or post process the parameters and use the driver function to achieve the functionality. The return value from EnablePDEV is passed back to the OEM DLL on subsequent calls as DEVOBJ.pdevOEM parameter.




















HRESULT







EnablePDEV(














PDEVOBJ




 pdevobj,







PWSTR




pPrinterName,







ULONG




 cPatterns,







HSURF




*phsurfPatterns,







ULONG




 cjGdiInfo,







GDIINFO




 *pGdiInfo,







ULONG




 cjDevInfo,







DEVINFO




 *pDevInfo,














DRVENABLEDATA




 *pded














PDEVOEM




 *pDevOem







);















pdevobj: pointer to a DEVOBJ structure. pdevobj→pdevOEM is undefined.




pPrinterName: name of the current printer.




Cpatterns:




phsurfPatterns:




cjGdiInfo:




pGdiInfo:




cjDevInfo:




pDevInfo: These parameters are identical to what is passed into DrvEnablePDEV.




pded: points to a function table which contains the system driver's implementation of DDI entry points.




pDevOem: OEM PDEV.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented.




















HRESULT







DisablePDEV(













PDEVOBJ pdevobj







);















If EnablePDEV is implemented, then during DrvDisablePDEV, the driver will call the OEM DLL's DisablePDEV function to allow the OEM to free any memory associated with its PDEV. The OEM DLL should free resources allocated for the PDEV.




















HRESULT







ResetPDEV(













PDEVOBJ pdevobjOld,







PDEVOBJ pdevobjNew







);















ResetPDEV transfers the state of the driver from the old PDEVOBJ to the new PDEVOBJ when an application calls ResetDC.




















HRESULT







DisableDriver(













VOID







);















If EnableDriver is implemented, the driver will call DisableDriver to notify the OEM DLL that it is no longer required and is ready to be unloaded. The OEM DLL should free all resources, and get prepared to be unloaded.




If the OEM UI DLL adds private data to the DEVMODE structure, it must provide a rendering module version of the DevMode function described herein. The driver uses this at print time to validate, convert and generate default DEVMODEs as necessary. This function should be identical to the one provided by the OEM UI DLL, as described herein. This code can be implemented in a library and statically linked to the OEM UI modules and rendering modules.




The GetInfo function should be provided by the OEM rendering module DLL, and should be identical to the one provided by the OEM UI DLL as described above. This can also be implemented as part of a library as mentioned above for DevMode.




The PublishDriverInterface function provides a method for the driver to publish its helper function interface. The driver calls the OEM plugin's PublishDriverInterface function with the IPrintOemDriverUni interface which the OEM plugin can then use to access the driver's helper functions such as DrvWriteSpoolBuf.




















HRESULT







PublishDriverInterface(













IUnknown * pIUnknown













);















The GetImplementedMethod function allows the driver to get information about the implemented methods of the interface. The OEM plugin must define all of the member functions of a given interface, but not all of the functions need to be implemented. This function is called by Unidrv5 to determine which of the members of the interface are implemented by the OEM plugin.




















HRESULT







GetImplementedMethod(













PSTR  pMethodName













);















Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented.




In a preferred embodiment, the Unidriver is a bitmap surface driver. This means that GDI manages the surface completely. Vector graphics and raster are rendered together in the same band and sent to the printer. The driver does not distinguish between a pie chart and bitmap sent from a Windows application. High-level printer graphics languages like, PCL


5


and PCL-XL, have the capability to distinguish between vectors and raster. PCL


5


c will even color treat the objects differently based on the type of object it is drawing. For the current Unidriver, vectors and raster are color treated as raster, so the output may not be color corrected in the manner intended by the user. Preferably, the Unidriver allows the creation of a device managed surface. GDI cannot manage a device surface since it has no knowledge of the physical device. This means a device-managed driver will be required to draw its own graphics through the OEM mechanism. It is not possible for a device-managed driver to call any Eng calls that perform drawing onto the surface. However, a device-managed surface does not render graphics into bands and has more control over when objects are sent to the printer.




The OEM must create a custom-rendering module described in oemcust.doc. In addition to OEMGetInfo and OEMDevmode, the OEM must also export OEMDriverDMS.




The OEMDriverDMS function is called during DrvEnableSurface to determine the type of surface to create—Bitmap or Device.




BOOL APIENTRY




OEMDriverDMS (




IN PDEVOBJ pDevObj,




OUT PVOID pBuffer,




IN DWORD cbSize,




OUT PDWORD pcbNeeded




);




A DMS driver cannot call GDI provide Eng drawing calls to render onto the device managed surface. It can however create a temporary bitmap surface and pass that as drawing surface to Eng calls. All DDI rendering calls must be hooked.




These are:




DrvRealizeBrush




DrvDitherColor




DrvCopyBits




DrvBitBlt




DrvStretchBlt




DrvStretchBltROP




DrvPlgBlt




DrvTransparentBlt




DrvAlphaBlend




DrvGradientFill




DrvTextOut




DrvStrokePath




DrvFillPath




DrvStrokeAndFillPath




DrvPaint




DrvLineTo




DrvEnableSurface is not hookable. The Unidriver creates the type of surface based on the information derived from OEMDriverDMS. This can be changed on a job by job basis. The UI has to be customized in order for the OEM to get this capability. If the OEM does not want it to be modified on a job by job basis but permanently for all jobs, the OEM does not have to create a custom UI—they just have to always return the proper parameters in OEMDriverDMS in the render DLL. If the OEM DLL does not return an answer for OEMDriverDMS or returns an error, then a Bitmap surface is created by default.




The DrvTextOut call is sent to OEM minidriver. OEM will have to handle text clipping, text rotation, underline, and strikethrough. The OEM should also sent commands for text brush. Unidriver provides a helper function, DrvUniTextOut, to do the actual textout. This helper call expects the same parameters as DrvTextOut. After sending commands for text brush, rotation and clipping, OEM calls the Unidriver helper function DrvUniTextOut to do the actual text. In a preferred embodiment, rotation is not supported and glyph based clipping is done by DrvUniTextOut. An alternative embodiment allows the OEM driver to do the clipping.




OEMs must export a new function that will draw the text as bitmap. The function OEMTextOutAsBitmap utilizes the same parameters as DrvTextOut. DrvUniTextOut may call OEMTextOutAsBitmap if the text cannot be downloaded. This can happen when downloading fails or text is rotated. An alternative embodiment gives the OEM the opportunity to rotate the text. If the OEM does not want to rotate the text, it can always call the OEMTextOutAsBitmap routine to rasterize the text.




After DrvUniTextOut is complete the OEM will have to draw underline and sytike throughs. Underline and strikethrough come into the function call as a series of rectangles in prclExtra. The OEM driver can creates rectangles based on the coordinates in prclExtra using vector commands.




















DrvUniTextOut code looks like:







if(DownloadFont)







{













// send the glyphs













}







else // font could not be downloaded







{













if(DEVICE_MANAGED( ))













pfnOEMTextOutAsBitmap ( . . . );













else













EngTextOut( . . . );













}















Unidrv5 supports OEM customization in following areas: GPD command callback; raster data processing callbacks; and font handling callbacks. The OEM can choose what callbacks to provide individually based on the specific needs of the printer. Support for OEM DLL modification of the print stream will be implemented through command callbacks as defined in the GPD. For any GPD command, the OEM can specify a unique callback identifier via *CallbackID entry inside any GPD *Command construct. This identifier, a positive integer, will be passed to the minidriver during callback as one of the parameters (see below). At print time, when Unidrv5 is ready to emit a command but finds out that it is a callback id instead, it will call the minidriver's implemented command callback routine with the command ID and a parameter list as specified by *Params entry in the same *Command construct.




















HRESULT







CommandCallback(














PDEVOBJ




pdevobj,







DWORD




dwCmdCbID,














DWORD




 dwCount,














PDWORD




pdwParams














INT *




piResult







(;















pdevobj: pointer to the DEVOBJ.




dwCmdCbID: the command callback ID as specified in the GPD file.




dwCount: the count of the number of parameters (each a DWORD value) in pdwParams list.




pdwParams: pointer to an array of DWORD parameter values in the same order as specified by the corresponding *Params entry in the GPD file.




piResult: 0 for most GPD commands except X/Y movement commands in which case, the return value is the difference (positive) between the requested cursor position vs. the actual cursor position that the command has imposed.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




If a command callback requires no parameter, then dwCount is set to 0 and pdwParams is NULL.




The ColorMode feature of GPD, as described in detail below, allows the GPD author to specify the format of the shadow bitmap (format in which GDI performs imaging operations), the format of the bitmap to be dumped to the printer and an OEM callback function (ImageProcessing) which may be used to perform the transformation from GDI to dump format. The OEM callback may perform halftoning (conversion to a dump format with smaller pixel depth than the GDI format) or image processing (like color adjustments, ink removal) or both. Depending on the configuration specified, the halftoning may actually be performed by GDI, by the OEM callback or by the printer itself. See the GPD spec for examples.




Multiple ColorMode options may be specified so the user may select the desired output color depth, halftone process etc. Different sets of halftone options are available for each ColorMode. The OEM callback (if used) may provide, via the custom UI extensions, additional controls to allow the user to adjust various properties of the printed image. If so desired, the OEM may allow ImageProcessing to perform the dumping of the raster bitmap to the printer by setting the keywords *DevNumOfPlanes and *DevBPP to zero in the ColorMode option.




The halftone options enumerated in the GPD fall into one of 3 categories: GDI supported, OEM supported, and device supported (requires invocation string to enable). A custom halftone pattern, although defined by the OEM in the GPD, is considered a GDI supported halftone because GDI does the actual work. For any given ColorMode option, only one of the three halftone categories is applicable. First, if *DrvBPP is 1 or 4 BPP and specifies the same color depth as *DevBPP/*DevNumOfPlanes, then only GDI supported halftone should be available. For this purpose, 4 bpp rendering depth is considered an exact match for any of 4 bpp, RGB, CMY, or CMYK output depth. Second, if *DrvBPP is 24 BPP and specifies the same color depth as *DevBPP/*DevNumOfPlanes then device supported halftoning is assumed whether or not there is a *IPCallbackID entry in this ColorMode option. Finally, if *DrvBPP specifies higher color depth than *DevBPP/*DevNumOfPlanes, there must be a valid *IPCallbackID entry in this ColorMode option, and only OEM supported halftone should be available.




It is the responsibility of the GPD author to provide the correct UI constraints between the ColorMode options and the Halftone options so only desired combinations can be selected. For GDI halftoning, the GPD can enumerate as halftone options one or more GDI built-in patterns or OEM defined patterns. A built-in GDI halftoning option must be assigned one of the predefined symbol names. For OEM defined patterns (up to 256×256 in size), the option must contain the entry *HTPatternSize and also *rcHTPatternID if the pattern is stored in the resource file. An optional OEM callback to perform image processing may be specified in the ColorMode. Note that the GPD should not supply an invocation string for an OEM defined dither pattern since this is not a printer feature.




For halftoning performed by an OEM callback, the Halftoning option need only specify the name of the option to be displayed in the halftoning listbox. The control module will pass the index of this option as a parameter into the callback function ImageProcessing which should take the appropriate action based on the value of this index. For halftoning performed by the printer, an invocation string is required. An optional OEM callback to perform image processing may be specified in the ColorMode. Again the index of the halftone option selected will be passed down to the OEM callback (if any is used).




The ImageProcessing callback allows the OEM to access, manipulate and convert the format of the shadow bitmap after all GDI imaging is complete and before any dump processing is performed. It also allows the OEM to perform the dumping of the raster bitmap data directly to the printer. As mentioned in the discussion of ColorMode, the OEM may specify the format of both the shadow bitmap imaged to by GDI and the format of the bitmap to be dumped by the driver. As a result, the OEM may cause the halftoning to be performed by GDI at imaging time, in OEMImageProcessing, or by the printer. The following is the function prototype required for ImageProcessing:

















HRESULT






ImageProcessing(














PDEVOBJ




pdevobj,














BYTE




pSrcBitmap,














PBITMAPINFOHEADER




pBitmapInfoHeader,














PBYTE




pColorTable,














DWORD




dwCallbackID,














PIPPARAMS




pIPParams,







PBYTE




*ppbResult







);















pdevobj: pointer to the DEVOBJ.




pSrcBitmap: pointer to the source shadow bitmap.




pBitmapInfoHeader: describes source bitmap, DIB format, topdown scan ordering.




In a preferred embodiment, 1, 4, 8, and 24 BPP formats are supported (planes=1) with no compressed formats supported. Both source and destination formats will be organized as DIBs with ulPrimaryOrder=PRIMARY_ORDER_CBA. For example, if the format is RGB(CMY), the ordering of the color planes in each pixel is: least significant m bits are B(Y), next m bits are G(M), and next m bits are R (C) where m is 8 for 24 BPP and 1 for 4 BPP. The black plane (if any), occupies the next m bits. If there are unused bits, these will be the most significant bits. The driver assumes the OEM callback creates pDestBitmap to the pixel depth specified in the GPD information so the callback should not change pBitmapInfo.




pColorTable: It is the source palette if the format is 8 bpp. It gives the OEM access to the source palette which can be used to halftone the data to customize the printer's palette by creating a new 8 bit colortable. If the OEM wishes to create a new 8 bpp palette the OEM module will be responsible for downloading the data.




dwCallbackID: the callback ID value specified in the ColorMode option (IPCallback) in the GPD file. This selects one particular image processing method if the ColorMode specifies multiple image processing callback ids.




pIPParams: Pointer to IPPARAMS structure containing current driver state information.




















typedef struct {














DWORD




dwSize;







POINT




ptOffset;







PSTR




pHalftoneOption;













BOOL bBanding;














BOOL




bBlankBand;













} IPPARAMS, *PIPPARAMS;















dwSize: size of this structure in bytes.




ptOffset: offset of the band relative to upper left corner of imageable area.




pHalftoneOption: string pointer to the name of the currently selected halftone option. The callback should know what each option corresponds to in the GPD file. It uses this to determine what type of halftoning to provide.




bBanding: flag specifying banding is active when TRUE.




bBlankBand: flag specifying that nothing was drawn in the input bitmap so it should be considered blank when TRUE. Since nothing needed to be drawn in the bitmap it wasn't erased so the bitmap data is invalid and should not be used.




ppbResult: caller supplied address of a pointer to the destination bitmap buffer if successful and NULL (0) if unsuccessful when the OEM function is not dumping the data itself. If the function will dump the data then it should return TRUE if successful or FALSE (0) if not. The destination bitmap may be in the same format as the source bitmap. It may point to the same memory as pSrcBitmap or point to a buffer allocated by the OEM. Currently, 1, 4, 8 and 24 BPP (planes=1), are valid formats that can be returned in the destination bitmap where ulPrimaryOrder must be PRIMARY_ORDER_CBA with topdown scan ordering. The bitmap data is then dumped to the device as specified in the GPD file with the exception that in 4 BPP, no black synthesis or RGB to CMY conversion will take place so the OEM callback is responsible for initializing all 4 planes. This will allow the OEM the option of implementing a more sophisticated black synthesis.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




This callback will be made immediately before the driver executes its own code to render the bitmap. The callback is expected to allocate any buffers it requires to perform the bitmap conversion or image processing. The callback may overwrite the source bitmap, or it may allocate its own output bitmap. This callback may also be used to dump the bitmap directly to the printer without any further assistance or intervention from the driver. The driver assumes OEMImageProcessing will perform the dump if *DevNumOfPlanes and *DevBPP are set to 0 in the ColorMode. If the OEM DLL is assuming the responsibility of dumping the raster bitmap, it should use the XMoveTo and YMoveTo unidrv5 provided functions to do all the required positioning. If the dll wishes to do its own positioning it will still need to update the current driver cursor position on exit by calling XMoveTo and YMoveTo with the MV_UPDATE flag set.




If the Compression callback is provided by the OEM DLL and the CmdEnableOEMComp command is defined in the GPD, the callback will be used to compress the next block of data. The relative size of the newly compressed data will be compared to any other enabled unidrv5 compression modes to determine the most efficient compression algorithm for this block of data. If it results in the smallest size, unidrv5 will send the CmdEnableOEMComp command followed by the data. The OEM function only compresses and returns the data and is not responsible for any output. Unidrv5 will provide a buffer in which to compress the data. The size of this buffer will be specified and may represent the size of best compression algorithm checked so far. In this way an early out algorithm can be used to stop compressing if it is not going to result in smaller output.

















HRESULT






Compression (






 PDEVOBJ pdevobj,//Pointer to DEVOBJ






 PBYTE  pInBuf, //Pointer to raster data to compress






 PBYTE  pOutBuf,  //Pointer to output buffer for compressed data






 DWORD  dwInLen,  //size of input data to compress






 DWORD  dwOutLen,  //size of output buffer in bytes






 INT*   piResult






 );














piResult: Contains the number of compressed bytes created if successful otherwise—1 if unable to compress the data within the specified buffer.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




The Compression callback can be used to implement a special compression method that may or may not be more efficient than existing unidrv5 compression modes thus allowing the best method to be utilized. Since there is some overhead involved with compressing the data the OEM should only enable those compression methods most likely to yield the best results. To utilize this callback the device must be able to switch compression modes and support disabled compression on a per scan line basis.




If FilterGraphics callback is provided by the OEM DLL, it will be used in place of the driver's normal blockout/compression code for sending a block of raster data to the printer. The number of scanlines in a block is specified by *PinsPerPhysPass entry of the current Resolution option. For most inkjet printers and page printers, this number is 1.

















HRESULT






FilterGraphics(













PDBVOBJ pdevobj,















PBYTE




pBuf,




// Pointer to buffer containing scanline raster







data to be













// compressed/manipulated and sent out.















DWORD




dwLen




// length (in bytes) of the buffer







);















Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




The FilterGraphics callback can be used to implement a special compression method, or to perform bit manipulation on the data stream that is sent to the printer, or both. In either case, the driver's built-in compression code is not used. FilterGraphics is presented with a block of data and it is required to send all the data and using DrvWriteSpoolBuf. The driver will perform no further processing of the raster data after calling FilterGraphics. This callback is expected to allocate any buffers it requires, such as to perform the compression. The callback may overwrite the source buffer if the compressed results occupy fewer bytes than the original data. Otherwise it must allocate its own output buffer. Any memory allocated by FilterGraphics may be freed at DisablePDEV time.




Since some compression methods under certain situations may produce more data than the original, it is recommended the OEM callback not to overwrite the input data buffer. If the compressed results are worse, it may wish to disable compression for this block and emit the original data uncompressed. The OEM is responsible for inserting any compression invocation command in front of the compressed data if needed




If HalftonePattern callback is provided by the OEM DLL and the GPD provided HTCallbackID parameter is greater than 0, the callback will be used to generate a custom OEM halftone pattern for GDI halftoning when the OEM wishes to keep the pattern proprietary. This is accomplished by either encrypting it in the resource dll or generating it in the OEM dll. If the rcHTPatternID is zero it is assumed there is no resource and that this callback will generate a pattern on the fly. If a valid ID does exist, unidrv5 will retrieve the resource and if this callback exists, let it unencrypt or otherwise modify the pattern. If this callback does not exist and halftone resource is valid it is assumed the resource is not encrypted and will be used directly.




















HRESULT













HalftonePattern (














PDEVOBJ




pdevobj,














PBYTE




pHTPattern,







DWORD




dwHTPatternX,







DWORD




dwHTPatternY,







DWORD




dwHTNumPatterns,







DWORD




dwCallbackID,







PBYTE




pResource,







DWORD




dwResourceSize







);















pdevobj: pointer to the DEVOBJ.




pHTPattern: Pointer to location to store halftone pattern with a size of (((dwHTPatternX*dwHTPatternY)+3)/4)*4*dwHTNumPatterns bytes. Each individual pattern must be DWORD aligned.




dwHTPatternX: The X size of the custom halftone pattern as specified in the GPD.




dwHTPatternY: The Y size of the custom halftone pattern as specified in the GPD.




dwHTNumPatterns: The number of dither patterns defined which will be either 1 or 3 as specified in the GPD. When one, the same pattern is used for all color planes. Otherwise three different patterns are defined which allows a different halftone pattern for each color.




dwCallbackID: the callback ID value specified in the Halftone option (HTCallback) in the GPD file. This selects one particular halftone method if the Halftone option specifies multiple halftoning callback ids.




pResource: Pointer to the resource found for this halftone type. If NULL it implies the function will generate a halftone pattern internally.




dwResourceSize: Size of the resource if any. If pResource is NULL this will be zero.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




If the MemoryUsage callback is provided by the OEM DLL, it will be used to determine the amount of memory required by the ImageProcessing function. This information will be used to adjust the optimum size of the shadow bitmap for banding. For example, if GDI reports that the optimum memory to use for banding is 8MB this value will be reduced by the results of this function and a smaller band will result. If this function does not exist it will be assumed that the memory usage is negligible.




















HRESULT













MemoryUsage (














PDEVOBJ




pdevobj,













POEMMEMORYUSAGE pMemoryUsage







);















pdevobj: pointer to the DEVOBJ.




pMemoryUsage: Pointer to structure to be filled in by OEM function specifying memory requirements.




















typedef struct {















DWORD




dwFixedMemoryUsage;




// fixed memory











used by function in bytes















DWORD




dwPercentMemoryUsage;




// variable memory











used as a percentage of shadow bitmap















DWORD




dwMaxBandSize;




// [in]











parameter, specified current max band size













} OEMMEMORYUSAGE, *POEMMEMORYUSAGE;















Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




The fixed memory usage specifies the amount of memory used independent of the size of the shadow bitmap. The variable memory usage is specified as a percentage of the memory used by the shadow bitmap. For example if the shadow bitmap is 24 BPP and the OEMImageProcessing function is going to halftone it down to 4 BPP into a separate buffer then the dwPercentMemoryUsage should be set to about 17 since the buffer will be about 17% of the size of the shadow bitmap. The dwMaxBandSize parameter is an in parameter that specifies what the maximum band size will be if both MemoryUsage parameters are set to zero.




UNIDRV5 font module callback interface is a GDI-object-like interface. Callback functions have UNIFONTOBJ as a parameter, which is a font module callback interface base object. Basic information is stored in this object. Additionally UNIDRV5 provides a service function for minidrivers to let them get an extra information. Minidriver must not change UNIFONTOBJ members.

















typedef BOOL (*PFNGETINFO)(PUNIFONTOBJ, DWORD, PVOID);






typedef struct_UNIFONTOBJ {















ULONG




uIFontID;




// download id . . .













// Font Resource id incase of Device Fonts.















DWORD




dwFlags;




// General Flags.













IFIMETRICS *pIFIMetrics; // Pointer to IFIMETRICS.







PFNGETINFO pfnGetInfo;  // Pointer to UNIFONTOBJ_GetInfo







callback.











} UNIFONTOBJ, *PUNIFONTOBJ;






//






// UNIFONTOBJ.dwFlags






//












#define UFOFLAG_TTFONT




0x00000001













// only set if this is TrueType font.











#define UFOFLAG_TTDOWNLOAD_BITMAP 0x00000002






#define UFOFLAG_TTDOWNLOAD_TTOUTLINE 0x00000004














UNIFONTOBJ.dwFlags is set by UNIDRV5. A minidriver must not change this flag.




This function downloads the font header as an appropriate format to a printer to create download font. UNIDRV5 supports only PCL type bitmap/TT outline download. If a printer has bitmap/outline font download feature of which format is different from PCL format, minidriver can support its download format by providing the font download callbacks. If minidriver supports this function, it has to support DownloadCharGlyph callback function as well.




















HRESULT







DownloadFontHeader(














PDEVOBJ




pdevobj,













 PUNIFONTOBJ pUFObj,














DWORD




*pdwResult);














Pdevobj




Pointer to the DEVOBJ







PUFObj




Pointer to the UNIFONTOBJ







PdwResult




Contains the amount of necessary mem-








ory to download the font header















Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




The DownloadCharGlyph function download the character glyph data. There are two glyph data formats that are supported: bitmap and TrueType outline.




















HRESULT













DownloadCharGlyph(














PDEVOBJ




pdevobj,













PUNIFONTOBI pUFObj,














HGLYPR




hGlyph,







PDWORD




pdwWidth,














DWORD




*pdwResult);












Pdevobj




Pointer to the DEVOBJ.






PUFObj




Pointer to the UNIFONTOBJ






HGlyph




Glyph handle to downlooad.






PdwWidth




Pointer to the DWORD width buffer.







Minidirer has to set the width of







downloaded glyph data.






PdwResult




Necessary amount of memory to







download this character glyph in the







printer. If returning 0, UNIDRV5







assumes that this function failed














Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




The OutputCharStr callback is provided for a character code manipulation. Minidriver can convert a character code to an appropriate one for the printer. If minidriver needs to get the width data of a character, minidriver can get the width by UNIFONTOBJ_GetInfo callback or access UFM data directly to get width table.




















HRESULT







OutputCharStr(














PDEVOBJ




 pdevobj,













PUNIFONTOBJ pUFObj,














DWORD




 dwType,







DWORD




 dwCount,







PVOID




pGlyph);















#define TYPE_UNICODE





1







#define TYPE_TRANSDATA




2







#define TYPE_GLYPHHANDLE




3







#define TYPE_GLYPHID





4












Pdevobj




Pointer to the DEVOBJ






PUFObj




Pointer to the UNIFONTOBJ






DwType




Type of pglyph string. One of following is







specified by UNIDRV5.













TYPE_GLYPHHANDLE







TYPE_GLYPHID












DwCount




Number of the glyph store in pGlyph






PGlyph




Pointer to glyph string to







HGLYPH* (TYPE_GLYPHHANDLE)







Glyph handle that GDI passes.







DWORD* (TYPE_GLYPHID). Glyph ID







that UNIDRV5 creates from Glyph Handle.







In case of TrueType font, string type is







HGLYPH*. For Device font, string type







is DWORD*.














Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




Before downloading a TrueType font, UNIDRV5 calls this function to determine which format is supported or if TrueType can be downloaded for this font given the current situation.




















HRESULT







TTDownloadMethod(














PDEVOBJ




pdevobj,













PUNIFONTOBJ pFontObj,














DWORD




*pdwResult);















#define TTDOWNLOAD_DONTCARE




0








#define TTDOWNLOAD_GRAPHICS




1







#define TTDOWNLOAD_BITMAP





2







#define TTDOWNLOAD_TTOUTLINE




3












Pdevobj




Pointer to the DEVOBJ.






PfontObj




Pointer to the FONTOBJ.














pdwResult:




TTDOWNLOAD_DONTCARE Minidriver does not care how this font is handled.




TTDOWNLOAD_GRAPHICS Minidriver prefers printing this TT font as graphics.




TTDOWNLOAD_BITMAP Minidriver prefers download this TT font as bitmap soft font.




TTDOWNLOAD_TTOUTLINE Minidriver prefers downloading this TT fonta as TT outline soft font. This printer must have TT rasterizer support. UNIDRV5 will provide pointer to the memory mapped TT file, through callback. The minidriver has to parser the TT file by itself.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it's not implemented.




UNIDRV5 supports only PCL scalable font select command format. If OEM printer supports a different command format from PCL for scalable font select command, minidriver has to support this callback function. The select command in font metrics data is passed in FInv parameter and the minidriver can customize the command string before sending it via DrvWriteSpoolBuf.




















HRESULT







SendFontCmd(














PDEVOBJ




pdevobj,














PUNIFONTOBJ




pUFObj,














PFINVOCATION




pFInv);













typedef struct_FINVOCATION {














DWORD dwCount;




// Size of command







PBYTE pubCommand;




 // Pointer to font selection command













} FINVOCATION, *PFINVOCATION;















Pdevobj Pointer to the PDEVOBJ.




PUFObj Pointer to the UNIFONTOBJ




PFInv Pointer to the FINVOCATION




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented.




Example: UFM has the font selection command in it. Following is the example of font selection command.




“\x1B(9U\x1B(s4148t0b0s#FontHeight1P\x1B)6J\x1B)s4148t0b0s#FontWidth1P”




UNIDRV5 passes this selection command in pFInv.




pFInv→dwCount=57;




pFInv→pubCommand=




“\x1B(9U\x1B(s4148t0b0s#FontHeight1P\x1B)6J\x1B)s4148t0b0s#FontWidth1P”




In this callback function, a minidriver has to set correct value in #FontHeight and #FontWidth, using UNIFONTOBJ information. And it sends to the printer.




UNIFONTOBJ provides GDI-object-like callback interface for minidrivers. Minidriver can query a necessary information with this interface.




















BOOL







UNIFONTOBJ_GetInfo(













UNIFONTOBJ pUFObj,














DWORD




 dwInfoID,







PVOID




pData);














PUFObj




Pointer to the UNIFONTOBJ







DwInfoID




Type of information to get







PData




Pointer to the data structure















Return value: Return TRUE if succeeds. Otherwise, FALSE.




This function supports following functionality to return data to the minidriver.
















DwInfoID




Functionality











UFO_GETINFO_FONTOBJ




Get FONTOBJ






UFO_GETINFO_GLYPHSTRING




Get glyph string






UFO_GETINFO_GLYPHDATA




Get glyph data






UFO_GETINFO_GLYPHWIDTH




Get glyph width data






UFO_GETINFO_MEMORY




Get remained memory






UFO_GETINFO_STDVARIABLE




Get GPD standard variable.














Minidriver has to pass a pointer to GETINFO_FONTOBJ structure in pData and dwSize in GETINFO_FONTOBJ structure. UNIDRV5 sets a pointer to FONTOBJ in GETINFO_FONTOBJ.pFontObj. This function is available in any font callback function.




















typedef struct_GETINFO_FONTOBJ {













DWORD  dwSize; // Size of the buffer.







FONTOBJ *pFontobj; // Pointer to FONTOBJ













} GETINFO_FONTOBJ, *PGETINFO_FONTOBJ;















Minidriver has to pass a pointer to GETINFO_GLYPHSTRING structure in pData. A minidrver sets values in dwSize, dwTypeIn, dwTypeOut and pGlyphIn, and prepares a buffer for pGlyphOut. UNIDRV5 returns glyph data in pGlyphOut. This function is available for printer device fonts in any font callback function. But for TrueType font, only characters that is passed via DrvTextOut can be handled by UNIDRV5.

















typedef struct_GETINFO_GLYPHSTRING {














DWORD




dwSize; // Size of the buffer.







DWORD




dwTypeIn; // Type of glyph,TYPE_GLYPHID or








TYPE_GLYPHHANDLE














PVOID




pGlyphIn; // Glyph string














DWORD




dwTypeOut;// Type of glyph,TYPE_UNICODE








or TYPE_TRANSDATA














PVOID




pGlyphOut;// Glyph string to be filled by UNIDRV5











} GETINFO_GLYPHSTRING, *PGETINFO_GLYPHSTRING;














Minidriver has to pass a pointer to GETINFO_GLYPHDATA structure in pData and set dwSize. Minidriver sets values in dwGlyphID and dwType. UNIDRV5 returns glyph data in pGlyphData. This function is available in any font callback function.

















typedef struct_GETINFO_GLYHPHDATA {















DWORD




dwSize;




// Size of the buffer.







HGLYPH




hGlyph;




// Glyph handle













GLYPHDATA *pGlyphData; // Pointer to GLYPHDATA











} GETINFO_GLYPHDATA, *PGETINFO_GLYPHDATA;














Minidriver has to pass a pointer to GETINFO_GLYPHWIDTH structure in pData. In GETINFO_GLYPHWIDTH structure minidriver has to set the type of glyph, UNICODE or Glyph Handle. And set a pointer to the strings.

















typedef struct_GETINFO_GLYHPHWIDTH {













DWORD dwSize; // Size of the buffer.







DWORD dwType; // TYPE_GLYPHHANDLE or







TYPE_GLYPHID.







DWORD dwCount; // Count of glyph.







PVOID pvGlyph; // Glyph string of which width data is required.







PLONG plWidth; // Width buffer to be filled by UNIDRV5.











} GETINFO_GLYPHWIDTH, *PGETINFO_GLYPHWIDTH;














Minidriver has to set the type of glyph and glyph width data.




Minidriver has to pass a pointer to GETINFO_MEMORY structure in pData.

















typedef struct_GETINFO_MEMORY {














DWORD dwSize;




// Size of the buffer.













DWORD dwRemainingMemory; // UNIDRV5 returns the remaining







memory.











} GETINFO_MEMORY,*PGETINFOR_MEMORY;














Minidriver has to pass a pointer to GETINFO_FONTOBJ structure in pData. Minidriver can get standard variables from UNIDRV5 at any time in font callback.




















typedef struct GETNFO_STDVAR {













DWORD dwSize; // Size of the buffer.







DWORD dwNumOfVariable;







struct {













DWORD dwStdVarID;







LONG lStdVariable;













} Stdvar[1];













} GETINFO_STDVER, *PGETINFO_STDVER;















#define FNT_INFO_PRINTDIRINCCDEGREES 0//PrintDirInCCDegrees




#define FNT_INFO_GRAYPERCENTAGE 1//GrayPercentage




#define FNT_INFO_NEXTFONTID 2//NextfontID




#define FNT_INFO_NEXTGLYPH 3//NextGlyph




#define FNT_INFO_FONTHEIGHT 4//FontHeight




#define FNT_INFO_FONTWIDTH 5//FontWidth




#define FNT_INFO_FONTINTLEADING 6//FontIntLeading




#define FNT_INFO_FONTBOLD 7//FontBold




#define FNT_INFO_FONTITALIC 8//FontItalic




#define FNT_INFO_FONTUNDERLINE 9//FontUnderline




#define FNT_INFO_FONTSTRIKETHRU 10//FontStrikeThru




#define FNT_INFO_CURRENTFONTID 11//Current




#define FNT_INFO_TEXTYRES 12//TextYRes




#define FNT_INFO_TEXTXRES 13//TextXRes




#define FNT_INFO_MAX 14




The following callbacks are used for Device Managed Surface. The DriverDMS function is called during DrvEnableSurface to determine the type of surface to create—Bitmap or Device.




















HRESULT







DriverDMS(













PVOID pDevObj,







PVOID pBuffer,







DWORD cbSize,







PDWORD pcbNeeded













);















pDevObj: Driver's PDEV.




pBuffer: Pointer to output buffer which holds the return data. pBuffer is used to find out if the driver will be a bitmap surface driver or a device managed driver. If OEMGetInfo returns FALSE, the default mode will be a bitmap surface driver. If pBuffer is 0 a bitmap surface is created in DrvEnableSurface. If pBuffer is not 0, then a device managed surface is created. The pBuffer value is used as flHooks in the EngAssociateSurface call.




cbSize: Specifies the size of the buffer pointed by pBuffer.




pcbNeeded: Pointer to a DWORD. Returns the number of bytes written into the output buffer by the OEM plugin. If the output buffer is not large enough, OEM plugin should return FALSE and set the error code to ERROR_INSUFFICIENT_BUFFER. In that case, this variable returns the size of the expected output buffer.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented. The reason for the failure should be set via SetLastError.




For DMS support, OEMs must export this function that will draw the text as bitmap. The function TextOutAsBitmap will have the same parameters as DrvTextOut.




















TextOutAsBitmap(














SURFOBJ




 *pso,







STROBJ




*pstro,







FONTOBJ




 *pfo,







CLIPOBJ




*pco,







RECTL




*prclExtra,







RECTL




*prclOpaque,














BRUSHOBJ




*pboFore,







BRUSHOBJ




*pboOpaque,














POINTL




*pptlOrg,














MIX




mix













);















Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented. The reason for the failure should be set via SetLastError.




The following call back is required for Text Only minidriver. The TTYGetInfo callback need not be implemented by other OEMs minidrivers. This callback function is used to get the information, like margin, from Text Only minidriver.




















HRESULT







TTYGetInfo(














PDEVOBJ




pdevobj,














DWORD




 dwInfoIndex,







PVOID




pOutputBuf,







DWORD




 dwSize,







DWORD




 *pcbcNeeded);















pDevObj: Driver's PDEV.




dwInfoIndex: Information Index for which call is made. Currently following indexes are supported




#define OEMTTY_INFO_MARGINS 1




#define OEMTTY_INFO_CODEPAGE 2




pOutputBuffer: Buffer where data will be copied.




dwSize: Specifies the size of the buffer pointed by pOutputBuffer.




pcbNeeded: Pointer to a DWORD. Returns the number of bytes written into the output buffer by the OEM plugin. If the output buffer is not large enough, OEM plugin should return FALSE and set the error code to ERROR_INSUFFICIENT_BUFFER. In that case, this variable returns the size of the expected output buffer.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented. The reason for the failure should be set via SetLastError.




The printer driver of the instant invention provides a helper function interface to the OEM DLL. These helper functions are obtained by the OEM DLL through querying the driver for its helper function interface.




















HRESULT







DrvWriteSpoolBuf(













PDEVOBJ pdevobj,







PVOID pBuffer,














DWORD




cbSize,














DWORD




*pdwResult













);















pdevobj: points to DEVOBJ structure




pBuffer: points to the buffer of data to be sent to the spooler.




cbSize: number of bytes in the buffer.




pdwResult: contains the number of bytes actually sent to the spooler.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented.




















HRESULT







DrvXMoveTo(













PDEVOBJ pdevobj,














INT




x,







DWORD




dwFlags,







INT




*piResult







);













HRESULT







DrvYMoveTo(













PDEVOBJ pdevobj,














INT




y,







DWORD




dwFlags,







INT




*piResult







);















pdevobj: points to DEVOBJ structure.




x (y): the move value.




dwFlags: a combination of one or more of the following flags.




MV_UPDATE: update the driver's tracking of the cursor position but do not send any printer escapes to position the cursor. If this flag is not set, the driver will send printer escapes to move the cursor and update its internal cursor tracking. This flag is used when the cursor position is changed due to sending graphics data or text.




MV_RELATIVE: the given x (y) value is relative to the previous cursor position. If this flag is not set, then the given x (y) value is the absolute cursor position.




MV_GRAPHICS: the given x (y) value is in the graphics resolution unit (as defined by *DPI entry of the currently selected resolution). If this flag is not set, then the given x (y) value is in the master unit.




MV_PHYSICAL: the given x (y) value is relative to the printer's cursor origin. If this flag is not set, then the given x (y) value is relative to the printable origin. Note that this flag cannot be set if MV_RELATIVE is set.




piResult: Contains the difference (in the master unit) between the requested move amount and the actual move amount. It is always positive.




The DrvGetStandardVariable function is used by OEM to retrieve state variables known to Unidriver.




















HRESULT







DrvGetStandardVariable(














PDEVOBJ




 pdevobj,







DWORD




 dwIndex,







PVOID




pBuffer,







DWORD




 cbSize,







PDWORD




pcbNeeded







);















pdevobj: points to DEVOBJ structure.




dwIndex: index of standard variable to retrieve.




pBuffer: Pointer to output buffer which holds the return data.




cbSize: Specifies the size of the buffer pointed by pBuffer.




pcbNeeded: Pointer to a DWORD. Returns the number of bytes written into the output buffer by the Unidriver. If the output buffer is not large enough, Unidriver will return E_FAIL and set the error code to ERROR_INSUFFICIENT_BUFFER. In that case, this variable returns the size of the expected output buffer. OEM should allocate a buffer of this new size and call this function again.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented.




The reason for the failure should be set via SetLastError.




DrvUniTextOut is provided as a helper call so that OEMs do not have to replicate the entire text functionality of Unidrive. This helper function expects the same parameters as DrvTextOut.




















HRESULT







DrvUniTextOut(














SURFOBJ




*pso,














STROBJ




*pstro,














FONTOBJ




 *pfo,







CLIPOBJ




 *pCO,







RECTL




*prclExtra,







RECTL




*prclOpaque,














BRUSHOBJ




*pboFore,







BRUSHOBJ




*pboOpaque,














POINTL




*pptlBrushOrg,







MIX




mix













);















DrvGetGPDData is provided as a helper call so that OEMs mini drivers can access vendor specific binary data defined in GPD file.




















HRESULT







DrvGetGPDData(














PDEVOBJ




pdevobj,














DWORD




dwType,














PVOID




pInputData,







PVOID




pBuffer,







DWORD




cbSize,







PDWORD




pcbNeeded













);















pdevobj: points to DEVOBJ structure.




dwType: Type of the GPD data. In NT 5.0 only the following type is recognized.




Other values are ignored.




#define GPD_OEMCUSTOMDATA 1




pInputData: Reserved. Should be set to 0




pBuffer: Pointer to output buffer, which holds the return data.




cbSize: Specifies the size of the buffer pointed by pBuffer.




pcbNeeded: If the output buffer is not large enough, Unidriver will return E_FAIL and set the error code to ERROR_INSUFFICIENT_BUFFER. In that case, this variable returns the size of the expected output buffer. OEM should allocate a buffer of this new size and call this function again.




Return Value




S_OK if the function succeeds, E_FAIL if it fails, or E_NOTIMPL if it is not implemented.




The reason for the failure should be set via SetLastError.




To allow the above described OEM customization of the Unidrv5, a text based generic printer description (GPD) must be generated as the minidriver. A Generic Printer Description (GPD) file in accordance with the instant invention is a text-based file used to describe a printer for printing from Microsoft Windows NT using the Universal Printer Driver (Unidrv5) of the instant invention. Such a file utilizing GPD contains information about the printer features which Unidrv5 will use to present in the UI and allow the user to configure the printer. It also contains the printer commands and attributes which enable Unidrv5 to generate the correct printer-ready output data when the user prints from a Windows application. Creating a Windows NT printer driver utilizing the teachings of the instant invention can be as simple as creating a GPD file if there is no custom functionality beyond what Unidrv5 provides.




The following defines an exemplary embodiment of a GPD file format and its semantics. A feature of GPD is its built-in capability of evolving as new printers appear on the market. It is designed to be simple, extensible, easy to understand, maintain, and localize. As described above, the Unidrv5 of the instant invention is compatible with and will run on operating systems, such as Windows NT 5.0 and above, although adaptation of these teachings to other operating systems is possible. However, the development of new minidrivers directly in the new GPD format as described herein provides much more flexibility in describing printer-specific features, installable options, constraints, dependency and command ordering than is possible with the older GPC. In addition, the text-based nature of the GPD data files are much easier to maintain and track than binary data files created with GPC.




An exemplary embodiment of a file structure is described hereinbelow in accordance with the teachings of the instant invention. One skilled in the art will recognize, however, that other embodiments and particulars of a file structure are possible in accordance with the teachings of the instant invention. Therefore, this exemplary embodiment should be taken as illustrative only, and should not be used to limit the scope of the invention as defined by the appended claims.




A GPD file composed in accordance with the instant invention is basically a series of attribute definitions in the form of <name>:<value> pair. Such a <name>:<value> pair is called an entry. Entries must be separated from each other by a logical line break. Related entries can be grouped together, via grouping constructs, to represent an abstract object such as a PaperSize feature or a Letter size option. An entry is a basic element of a GPD file which defines a specific attribute. Some entries are mandatory, such as the printer model name, while others are optional either because the default value meets the needs or because they are applicable only to a particular type of printers. If an entry definition is repeated, the last definition is used unless otherwise specified. All entries are pre-defined, including the entry name and the value type. For clarity, all entry names start with a asterisk (‘*’). As an example of this concept, the Canon BubbleJet BJC-600 printer model name is specified as:




 *ModelName: “Canon BubbleJet BJC-600”




The name of this entry is *ModelName, and its value is a quoted string “Canon BubbleJet BJC-600”. Another required entry is the definition of the master units, which are used to express measurements in a GPD file:






*MasterUnits: PAIR(360,360)






Here, the entry name is *MasterUnits and the value is a pair of integers (360,360), defining the master X and master Y units in dots-per-inch.




A white space is either a space character or a TAB character. A line break character is a CR (carriage return), LF (line feed), or both together, which typically terminates an entry. A white character is defined to be either a white space or a line break character. A comment starts with the character sequence “*%” and ends with a line break character, which typically terminates the entry. Comments are treated as whitespace, and can appear anywhere a white character can. The comment indicator “*%” must be preceded by a white character (except that no preceding white character is needed if the comment indicator is at the beginning of the file). For example,






*% both master X and master Y units are 360 dpi.








*MasterUnits: PAIR(360,360)






or, alternatively,






*MasterUnits: PAIR(360,360) *% both master X and master Y units are 360 dpi.






The plus character, ‘+’, is used as the continuation character and it must appear as the first character (at column


0


) in a line. A line break character followed immediately by a continuation character is called a continuation line break. An arbitrary white space is defined to be a white space, a continuation line break, a comment terminated by a continuation line break, or any combination of them. An arbitrary white space of any length can appear between any two tokens and it is ignored by the parser. Arbitrary white space does not terminate an entry—this is accomplished only by a logical line break. A token is a basic parsing entity in GPD. In the above example, there are 8 tokens:




1. *MasterUnits




2. :




3. PAIR




4. (




5. 360




6. ,




7. 360




8. )




A line break character not followed by the continuation character is called a logical line break. A logical line break terminates an entry definition. Construct delimiters, the curly brace ‘{’ and ‘}’, may also terminate an entry. Construct delimiters also act as entry delimiters i.e. as a logical line break.




A Construct Keyword is one that introduces a construct. It is followed by an open curly brace, one or more statements or constructs and a closing curly brace. If a Construct Keyword is not recognized by the parser, the entire construct is ignored. A special keyword *IgnoreBlock allows blocks of statements to be ‘commented out’. If *IgnoreBlock is followed by an open curly brace, all statements up to the matching closing curly brace are ignored. This may be useful when GPD files are being developed or debugged. All statements within the *IgnoreBlock must still adhere to the basic GPD syntax. The construct delimiters define a nesting level, that is to say, all entries bracketed by a pair of curly braces are considered to be at a non-zero nesting level. The level is determined by the number of pairs of curly braces by which the entries are bracketed. Entries which are not enclosed by any curly braces are at nesting level


0


or the root level. Entries defined within curly braces often have limited scope.




The following is a list and associated description of value types supported by this exemplary embodiment of GPD.




Quoted String: a quoted string is enclosed by a pair of double quotes. It may contain any byte values expressed in the form of ASCII characters or hexadecimals. Hexadecimals are enclosed by a pair of angle brackets (‘<’ and ‘>’). To use the left angle bracket or the double quote letter literally within a quoted string, the escape letter (‘%’) must precede it. The escape char ‘%’ is not used when the right angle bracket (‘>’) appears literally within a string.




“%”” this is a quoted string containing one double quote character.




“%” this is a quoted string containing one left angle bracket character.




“>” this is a quoted string containing one right angle bracket character.




“abc<64 65 66>” is the same as “abc<646566>” is the same as




“abc<64><65><66>” is the same as “abcdef”




Within a normal quoted string an escape char ‘%’ not immediately followed by a double quote or left angle bracket character is treated as a literal. However within a quoted string being used as part of a command invocation, the escape char ‘%’ must be followed by another ‘%’ to be treated as a single literal ‘%’—the escape char ‘%’ therefore must appear in only 3 possible combinations: followed by a double quote, left angle bracket or another escape char . Example: “set print intensity to 100%.”—the ‘percent-period’ combination is treated as a literal pair in a normal quoted string. However this combination is illegal if the quoted string is used in a command invocation, the percent character must be expressed using the double %%: “set print intensity to 100%%.”




The only way to escape the escape character is to express it in hexadecimal form <25>. For example “<25>” is a quoted string containing one character, a literal ‘%’, but “%” is an incomplete quoted string containing the literal double quote character, but no closing double quote—resulting in a syntax error. Arbitrary white spaces are allowed inside a hexadecimal sequence and they are ignored. But logical line breaks cannot appear inside a hexadecimal sequence or a quoted string. For example, the selection command for Letter size on Canon BJC-600 is the byte sequence 1B 28 67 03 00 6E 01 72 and it can be described as:






*CmdSelect: “<1B>(g<03 00>n<01>r”






A string value can be comprised of one or more quoted string segments. Each quoted string segment may be separated from the next by zero, one or more characters of arbitrary white space. The string value is the concatenation of all the quoted substrings. For example:






*Name: “abc” *% embedded comment—note continuation character on next line+“def” “gh” “ijk”






is the same as






*Name: “abcdefghijk”






If a quoted string is too long to fit into one line, it can be broken up into multiple segments and each segment enclosed by a pair of double quotes. The continuation character can be used to concatenate multiple string segments and it must appear as the first character (at column


0


) of a line.




In general, there are two ways to define a quoted string in a GPD file: define it directly in the GPD file or reference a Windows string resource ID defined in the resource DLL specified via *ResourceDLL entry. For strings that require localization, it may be preferable to define them in resource DLL since there are standard localization tools. When a string is defined in a Windows resource DLL, it must follow the rules of a Windows resource file.




Symbol: a symbol is a user-defined name that can be used to identify an entity such as a grouping construct or an option. A symbol must start with a letter (except ‘*’) and is composed of letters, numbers, and the underscore letter ‘_’ (case-sensitive). There are some pre-defined symbols for standard features and options, such as PaperSize, Letter, Legal, A4, InputBin, EnvFeed, etc.




Constants: a constant is a pre-defined value such as a section name: JOB_SETUP, DOC_SETUP, PAGE_SETUP, etc. Typically, the constant names are all in capital letters.




Integer: an integer is used to express a measurement. It can be either positive or negative. For example, HP LaserJet 4L limits the maximum number of copies to 99:






*MaxCopies: 99






A special value, ‘*’, represents “any value” or “no limit” depending on the specific entry meaning. If applicable, all measurements are in the master X and Y units. Integers may also be expressed in hexadecimal format. In this case the hex digits must be immediately preceded by 0x, for example 0xffff. No + or − sign may be used in hexadecimal format.




PAIR: a PAIR is a pair of integers that are used to express measurements in the master units if applicable. For example, on HP LaserJet 4L, the cursor origin on Letter size paper in Portrait orientation is X=150 and Y=100 (in 600 dpi unit):






*CursorOrigin: PAIR(150,100)






RECT: a RECT is a group of four integers that are used to express measurements in the master units (if applicable).




Boolean: a Boolean value is either TRUE or FALSE.




Qualified Name: a qualified name is the concatenation of two symbols in the form of <FeatureName>.<OptionName>. For example, to identify the Letter size paper option, we can use PaperSize.Letter. The name on the left of the dot serves as a qualifier which narrows down the scope of the name on the right. A qualified name is viewed as one identifier, i.e. no white space is allowed before and after the concatenating letter ‘.’. Sometimes it is acceptable to specify just the <FeatureName> which is generally equivalent to enumerating all options in that feature.




LIST: a list is an enumeration of zero or more values. For example, Canon BJC-600 wants both enclosed and trailing blanks to be removed from the raster data:






*StripBlanks: LIST(ENCLOSED, TRAILING)






The values in the list must be of the same type which can be symbols, constants, integers, or qualified names. The ordering of these values can be significant depending on the specific entry meaning. For example, Canon BJC-600 wants to send out color plane data in increasing darkness:






*ColorPlaneOrder: LIST(YELLOW, MAGENTA, CYAN, BLACK)






Global entries are simple <name>:<value> pair entries whose meaning applies to the whole GPD file. Non Relocatable Global entries are used to describe attributes or values that are static, unchanging and independent of printer configuration. They always appear at the root level and typically at the beginning of a GPD file. In a preferred embodiment of the instant invention, the following keywords are declared to be Non Relocatable Global entries:

















Entry Name




Description




Comments











*GPDSpecVersion




Quoted string in the




Required. This must be







form of




the first entry in a GPD







“<MajorVerNumber>.




file, before any com-







<MinorVerNumber >”,




ments. In other words,







the GPD spec version.




the first 15 characters in







Example: “1.0”.




any root GPD file must








be *GpDSpecVersion.






*GPDFileVersion




User defined Quoted




Optional. If exists will be







string.




displayed in About Box.








The suggested format is








that used for








*GPDSpecVersion. If








omitted, the string is








NULL.






*GPDFileName




Quoted string containing




Optional.







the name of the GPD







file. No path information







should be included.






*MasterUnits




PAIR(<xUnit>,<yUnit>),




Required. All numbers in







the X and Y master units.




the GPD are expressed in







The master units must be




master units, if appli-







the common multiples




cable. It is suggested that







that all resolution units




the resolution units used







and the X/Y movement




in the font metrics data







units evenly factor into.




be identical to the master







For example, if the




units in order to reduce







resolutions are 240x216




round-off errors in cal-







dpi and 120x144 dpi, the




culation.







X-move unit is {fraction (1/60)} inch,







and the Y-move unit is







{fraction (1/216)} inch, then the







smallest master units are







PAIR(240,432). PAIR







(720,432) is also fine







since 240 factor evenly







into 720.






*CodePage




Integer, any of Microsoft




Optional. If missing,







Windows pre-defined




assume the string is in







code page id's. It speci-




UNICODE. Note that







fies the code page in




*CodePage applies only







which *ModelName,




to strings as listed on







*Name, *CartridgeName,




the left. If used, it must







*TTFontName, and




be defined before any







*DevFontName entry




such string entries are de-







values are expressed in.




fined. If it is re-defined,







For example, Windows




the new value applies to







3.1 US (ANSI) is 1252;




string entries after this







Windows 3.1 Cyrillic is




point. Multi-byte char-







1251; Japanese is 932.




acters must be expressed








as <hex strings>. Two








hex chars define one








byte, the leftmost byte








occupies the lowest ad-








dress in the string, with








subsequent bytes having








successively higher








addresses. Therefore








strings expressed in








multi-byte character sets








may need to be revised








if ported to processors








with a different byte








ordering.






*ModelName




Quoted string, the printer




Required. It must match







model name.




the name in the








SETUP.INF file.






*ResourceDLL




Quoted string, the name




Optional. If missing,







of the associated




assume that the GPD file







Windows resource DLL.




has no reference to re-







This dll contains all




source strings, icons,







display names, icons,




bitmaps, fonts, etc . . .







bitmaps, fonts and







other resources refer-







enced by the GPD file.







The name shouldn't







contain path information







like backslash char ‘\’.







It should just be the







DLL name.






*rcPrinterIconID




Integer, the Windows




Optional. If missing, the







RC_ICON resource ID




default printer icon is







for the printer icon in




used in the user interface.







the associated resource







DLL. It is suggested that







all RC_ICON ID's in a







resource DLL be con-







tiguous and start from 1.






*PrinterType




Constant(PAGE, SER-




Required.







IAL or TTY), the







printer's type.






*Include




Quoted string, the name




Optional. If missing, no







of the GPD file to be




embedded GPD files. It







embedded. If multiple




cannot reference any







instances exist, all refer-




value macros and must







enced GPD files are




be terminated by a







inserted in the order




logical line break.







specified.






*HelpFile




Quoted string, the




Optional. If missing, use







custom help file name




the default help file for







(with the extension




Unidrv5. If present, it







.HLP).




will be used to extend








and/or overwrite the de-








fault help text.






*InstalledOp-




Quoted string. When




Optional. If it is missing






tionName




there is any installable




and there is installable







feature or option speci-




feature or option speci-







fied in the GPD file via




fied via *Installable?







“Installable? entry




entry, then *rcIn-







(defined later), the




stalledOptionNameID is







parser will synthesize a




required.







feature for each one.







Such kind of features







always have two options







which correspond to







whether the feature/







option is installed or







not. This entry will be







used as the display name







for the option which







corresponds to







“installed” state. Note







that this display name







will be used by all such







synthesized features.






*rcInstalledOption




Integer, the Windows




Optional. If it is missing






NameID




string resource id corres-




and there is installable







ponding to the string




feature or option speci-







represented by




fied via *Installable?







*InstalledOptionName.




entry, then








*InstalledOptionName








is required.






*NotInstalledOp-




Quoted string. When




Optional. If it is missing






tionName




there is any installable




and there is installable







feature or option speci-




feature or option speci-







fied in the GPD file via




fied via *Installable?







*Installable? entry




entry, then *rcNotIn-







(defined later), the parser




stalledOptionNameID is







will synthesize a feature




required.







for each one. Such kind







of features always







have two options







which correspond







to whether the feature/







option is installed or







not. This entry will be







used as the display name







for the option which







corresponds to “not







installed” state. Note







that this display name







will be used by all such







synthesized features.






*rcNotIn-




Integer, the Windows




Optional. If it is missing






stalledOp-




string resource id corres-




and there is installable






tionNameID




ponding to the string




feature or option speci-







represented by




fied via *Installable?







*NotInstalledOp-




entry, then *NotIn-







tionName.




stalledOptionName is








required.






*MaxCopies




Integer, the maximum




Optional. If missing,







number of copies that




assume no support for







the printer supports.




multiple-copy printing.






*PrintRate




an integer, describing the




This entry is optional.







printer's printing speed




If missing, assume 0.







in monochrome mode.







The unit for the value is







defined in







*PrintRateUnit.






*PrintRateUnit




a constant: PPM (pages




This entry is required if







per minute), CPS (char-




*PrintRate is defined.







acters per second),







LPM (lines per minute),







IPM (inches per minute







for plotters). The GPD







file should specify the







appropriate unit based







on the printer type (ex.







use PPM for page







printers).






*PrintRatePPM




An integer, printing




Optional. If missing







speed in Pages Per




assume 0.







Minute.






*FontCartSlots




Integer, the number of




Optional. If missing,







font cartridge slots on




assume 0.







the printer.














Relocatable Global entries are used to describe attributes or values that may be dependent on printer configuration. They may be placed at the root level to signify this value/attribute has no such dependency but may also appear within *Option or *case constructs if there is some dependency. For example the set of available device fonts may depend on whether the printer is in portrait or landscape orientation. Therefore the keyword describing the list of available device fonts is defined by this spec to be a Relocatable Global keyword. The specifics of using Relocatable Global keywords to express such dependencies will be introduced later. To summarize, the classification of keywords into Relocatable and non-Relocatable entries is predetermined by the parser. It is not user definable. However the user may choose to treat Relocatable Globals the same as non-Relocatables if the attribute represented by that keyword is in fact independent of printer configuration. The following keywords are Relocatable Globals:

















Entry Name




Description




Comments











*OEMCustomData




Quoted string, the con-




Optional. Required if







tents of the string will




OEM calls







be presented to an OEM




DrvGetGPDData( ).







plug in module that calls




This entry may occur







DrvGetGPDData( ). The




within a switch/case con-







parser and driver does




struct. The contents of







nothing more with this




the quoted string may







data.




include binary data, ascii








or both. The contents is








entirely determined by








the GPD writer.














Grouping constructs are used to define logical entities. The function of a Construct is similar the function of a structure in the C language. A construct allows a more detailed description of a printing attribute than is possible with a single *Keyword: Value pair. A construct begins with a construct keyword and it is associated value. Examples of construct keywords are *Feature, *Option, and *Command. The value is a symbolname that is used to uniquely identify this instance of the construct. For example the *Command: CmdStartPage construct is distinct from the *Command: CmdSleepTimeOut construct. If a construct with the same *Keyword and symbolname occurs more than once in the same GPD, the parser understands this to be a redefinition or elaboration of the original instance. Some constructs allow user-defined instances (symbolnames). For example the user is free to define as many *Feature constructs as he desires, labeling each instance using a symbolname of his choosing in addition to using any of the predefined Feature symbolnames. Some *Options are also user-definable in this manner, while some only allow the use the predefined symbolnames. For example user-defined Papersizes are allowed, but the only options allowed for the PageProtect and Collate features are “ON” and “OFF”. The construct keyword and symbol name are followed by one or more entries surrounded by curly braces. For ease of readability, it is customary to indent all the entries bracketed by the curly braces. These entries form the body of the construct. An exemplary set of keywords and sub-constructs which are allowed within the body of each tpe of construct are described below. Some keywords are mandatory while others may be optional. The inclusion of other keywords will result in a parsing error.




Two of the most common constructs in this exemplary embodiment are *Feature and *Option. The *Feature construct defines a printer feature and provides Unidrv5's UI component the necessary information to present to the end-user a control that allows the end-user to select one or more options for that feature. Various features offer the user the opportunity to select a papersize, an input paperbin, to turn collation, stapling on/off etc. Each *Feature construct contains one or more *Option constructs that at a minimum enumerates the optionname the UI should display and the command that should be sent to the printer to invoke or select this particular option. Some features require additional information to be supplied to the driver to describe each of the options, for example the driver needs to know the imageable area of each supported papersize in order for the app to compose its pages properly and to avoid clipping or truncation of the output. All optional and required keywords allowed for each construct are enumerated herein. As an example, the following is a fragment of the *Feature construct describing the paper sizes supported by Canon BJC-600 printer showing the *Option constructs nested within the body of the *Feature construct. Note some required keyword entries have been omitted for the sake of simplicity.




















*Feature: PaperSize







{














*DefaultOption: Letter




*% the default paper size is Letter.







*Option: Letter




*% define Letter option.







{













*Name: “Letter 8½ × 11 inch”














}








*Option: A4




*% define A4 option.







{













*Name: “A4 210 × 297 mm”













}







*% define more paper sizes . . .







. . .













}















Although it may appear arbitrary, *Option constructs must be nested within *Feature constructs. *Feature constructs must always appear at the root level. Every *Feature construct should contain at least one *Option construct. If the *DefaultOption entry is missing, the first option listed is used as the default. If desired, the Default Option may be specified within *switch/*case constructs to express its dependence on the current option selection of other features, though if this is done, care must be taken when specifying the *ConflictPriority so an inconsistency or circular dependency does not arise.




The order of features and options within a feature relative to one another has some effect on the driver. For example, the UI code displays features and options in the order in which they appear in the GPD file. This is not a hard and fast rule, and one should consult specific UI documentation for specifics. Also in the absence of a *DefaultOption keyword, the first option becomes the default. The current implementation of the parser considers Features to be ordered based on their appearance in either a *switch or *Feature keyword. The exception to this rule is the InputBin feature, which is always the first feature. Options are ordered based on their appearance in either a *case or *Option keyword. The exception to this rule is the synthesized “Automatically Select” InputBin slot which has the meaning that the FormToTray assignment table will be used to assign the input slot based on the selected paper size.




If the GPD writer wishes to define the order of the features and options relative to each other, he may ‘declare’ them ahead of any use in the GPD file using empty *Feature/*Option constructs, for example:

















*Feature: EconoMode{ *Option: Off{} *Option: On{} }






*Feature: Orientation{ *Option: PORTRAIT{} *Option:






LANDSCAPE_CC90{} }






*Feature: PaperSize{ *Option: LETTER{} *Option:






LEGAL{} *Option: EXECUTIVE{}













*Option: A4{} *Option: ENV10{} *Option: ENV_DL{}







*Option: ENV_MONARCH{} }















There are two types of UI features: custom features and standard features. Custom features are used to describe special printer features that Unidrv5 can fully implement knowing only the name of the *Feature and *Option for display in the UI and the selection command (and its order dependency) for invoking the feature. This allows new printer features to be supported without any modification to Unidrv5. For example, on the HP LaserJet 4L, there are several custom features such as EconoMode:

















*Feature: EconoMode






{













*Name: “EconoMode”







*DefaultOption: Off







*Option: Off







{













*Name: “Off”







*Command: CmdSelect







{













*Order: DOC_SETUP.5  *% define the sequencing order













for this command.













*Cmd: “@PJL SET ECONOMODE=OFF<0A>”













}













}







*Option: On







{













*Name: “On”







*Command: CmdSelect







{













*Order: DOC_SETUP.5  *% define the sequencing order













for this command.













*Cmd: “@PJL SET ECONOMODE=ON<0A>”













}













}











}














Standard features are used to describe common printer features which Unidrv5 supports using special case code. For example Unidrv5 needs to be aware of the printer's current Landscape orientation setting since it will have to perform the landscape rotation if the printer does not have rotation capabilities built in. Standard features can have additional feature-specific entries that Unidrv5 understands and uses in printing. For example, PaperSize is a standard feature and its options contain the *PrintableArea entry which Unidrv5 uses to determine where pixels and text can be placed. The following is an exemplary list of standard features and options provided for by the instant invention.


















Standard Features




Description




Standard Options




Comments











Orientation




The list of logical




PORTRAIT,




Optional. If missing, the







orientations.




LANDSCAPE_CC90,




printer supports only








LANDSCAPE_CC270. No




Portrait logical orientation.








custom options.




Standard orientation









options use the id's defined









in Windows SDK/DDK.






PaperSize




The list of paper sizes




CUSTOMSIZE, LETTER,




Required. At least one







supported on the printer.




LETTERSMALL




option must be enumerated.







These paper sizes will be




TABLOID, LEDGER,




Standard paper size options







enumerated to the apps and




LEGAL, STATEMENT,




use the dimensions and id's







used in formatting




EXECUTIVE, A3, A4, etc.




as defined in Windows







documents.




All Windows pre-defined




SDK/DDK. Custom option








paper sizes have associated




names cannot exceed the








standard names. Custom




string length limit








options are allowed.




CCHFORMNAME defined









in wingdi.h in the Windows









SDK/DDK.






Resolution




The list of printing




All options are considered




Required. At least one







resolutions.




custom.




option must be enumerated.






MediaType




The list of media types




STANDARD,




Optional. If missing, the







supported.




TRANSPARENCY,




printer's default media type








GLOSSY. Custom options




is always used. Standard








are allowed.




media options use the id's









defined in Windows SDK/DDK.






InputBin




The list of input bins




UPPER, LOWER,




Required. Standard input







supported.




MIDDLE, MANUAL,




bin options use the id's








ENVFEED,




defined in Windows








ENVMANUAL, AUTO,




SDK/DDK.








TRACTOR, SMALLFMT,








LARGEFMT,








LARGECAPACITY,








CASSETTE. Custom








options are allowed.






OutputBin




Enumeration of output bins




All options are considered




Optional. If missing,







supported.




custom.




assume the printer does not









support multiple or user









selectable output bins.






Duplex




Two-sided printing.




NONE, VERTICAL,




Optional. If missing,








HORIZONTAL. No




assume the printer does not








custom options.




support two-sided printing.









Standard duplex options









use the id's defined in









Windows SDK/DDK.






Collate




Collate printed pages or




ON, OFF. No custom




Optional. If missing,







not.




options.




assume the printer does not









support collation.






Memory




The list of printer memory




All options are considered




Optional. If missing,







configurations.




custom.




Unidrv5 will not attempt to









track memory usage.









*FeatureType =









PRINTER_PROPERTY by









default






ColorMode




The list of color printing




All options are considered




Optional. If missing, it







modes.




custom.




implies that the printer is









monochrome and the driver









will render images in









1 bpp/1 plane format.






Halftone




The list of halftoning




Custom options are




Optional. If missing, only







options




allowed.




the standard halftone









methods will be displayed









for the user to choose. The









default??






Stapling




List of stapling options




All options are custom.




Optional. However using









this feature keyword will









cause Directory Services to









assume your printer supports stapling.






PageProtect




The list of page protection




ON, OFF. No custom




Optional. This feature is







options (used on page




options.




enabled only if the current







printers to prevent print





printer memory is greater.







overrun errors).





than the page protection









memory needed for the









current paper size.









“FeatureType =









PRINTER_PROPERTY by default














If any *Feature or *Option construct is multiply defined, the contents (body) of the separate construct definitions are merged (Union) into a single construct. If this single construct now contains 2 or more statements containing the same keyword, the latter occurrence overwrites all previous occurrences. As an example:

















*Feature: PaperSize






{














*rcNameID: 2101








*DefaultOption: Letter




*% the default paper size is Letter.







*Option: Letter




*% define Letter option.







{













*Name: “Letter 8½ × 11 inch”







*PrintableOrigin: PAIR(300,300)













}











}






*Feature: PaperSize






{













*% rcNameID not redefined.














*DefaultOption: A4




*% redefine the default papersize.







*Option: Letter




*% redefine Letter option.







{













*Name: “Letter” *% redefine name













*% *PrintableOrigin statement is not







*% repeated hence original definition remains







*% in effect.













*PrintableArea: PAIR(9600, 12648) *% define more













*% attributes not present in the original construct.













}














*Option: A4




*% define A4 option for the first time.







{













*Name: “A4 210 × 297 mm”













}







*% define more paper sizes . . .







. . .











}














Entries within a *Feature or *Option construct define that logical entity, such as the name, icon representation, and other inherent attributes. The tables below list these entries and where they can appear. Some of these entries are related to printing, but they show up in these constructs because they are inherent attributes of a particular standard feature, or because the designer just felt like it. For example, *PrintableArea is used in printing, but its values are always specific to a particular paper size. All generic entries, except *Command:CmdSelect{ } construct, are related to the user interface display.


















Entry Name




Description




Location




Comments











*FeatureType




Constant(DOC_PROPERTY,




Any custom




Required for custom features.







JOB_PROPERTY,




*Feature




The setting for a







PRINTER_PROPERTY), the




construct




DOC_PROPERTY feature is







association type of a feature.





typically saved with a document,









while the setting for a









PRINTER_PROPERTY feature is









save in the user's registry on per









printer instance basis.









JOBPROPERTY features are set









per job and hence not saved









anywhere. Note that in NT5.0,









JOB_PROPERTY features are









treated in the same way as









DOC_PROPERTY features.









Predefined features default to









DOC_PROPERTY except for









Memory and PageProtection









which default to









PRINTER_PROPERTY.






*DefaultOption




Symbol, the symbolname of the




Any *Feature or




Optional. If missing, the first







default option for the feature.




*case




option is used as the default.








(dependency)








construct






*Name




Quoted string, the display name




Same as above.




Optional. If *Name is missing,







for a feature or option.





then *rcNameID must be present.






*rcNameID




Integer, the Windows string




Same as above.




Optional. If missing, *Name







resource ID for a feature or





must be present. If localization is







option name.





important, use *rcNameID instead









of *Name. Zero is not a valid









value for any string resource ID.






*ConflictPriority




an integer, describing the priority




*Feature




optional. Parser always assigns







of a feature when resolving




construct only no




Synthesized features the highest







conflicts. 1 is the highest.




dependency




priority, PRINTER_PROPERTY









features next, and DOC and









JOB_PROPERTY the lowest









priority. The ConflictPriority









value supplied by the user only









orders the member features within









these 3 groups. If there are









features in a group without a user









specified Conflict priority, the









parser will assign these features a









priority lower than any explicitly









specified within that group.






*ConcealFromUI?




Boolean, if TRUE, this Feature




*Feature




Optional. If missing, assume







will not be displayed in the UI.




construct only no




FALSE.







This may be desired if a printer




dependency







supports only one option for a







feature (ie only 300 dpi) and the







GPD writer determines it serves







no purpose to display a feature a







user cannot change. The writer







may also create features that are







indirectly controlled by other







features and macros and are not







directly accessible through the







UI.






*UpdateQuality




Boolean, if QualityMacros have a




*Feature




Optional. If missing, assume






Macro?




dependency on this Feature, (that




construct only no




FALSE.







is they are enclosed within a




dependency







switch construct controlled by







this Feature) this value should be







set to TRUE. UI will not be







updated properly otherwise.






*Installable?




Boolean, whether this feature or




Any *Feature or




Optional. If missing, assume







option is installable. When this




*Option




FALSE, i.e. the feature or option







entry is TRUE, the GPD parser




construct




is always installed. Note that







will synthesize a feature which





another way of specifying







has two options: Installed, and





installable features or options is to







Not_Installed. The default is





define them and their associated







always Not_Installed. When the





constraints explicitly. One







*Installable keyword appears





advantage of explicitly defining







within a *Feature construct, this





the Installable features is the user







feature is referred to as the host





may directly specify its priority







feature. When the Not Installed





and customize the constraints.







option of the synthesized feature







is selected, all options of the host







feature except the first are







disabled via *Constraints. When







the Installed option is selected, all







options of the host feature are







enabled including the first.







When the *Installable keyword







appears within an *Option







construct, this Option is referred







to as the host option. When the







Not Installed option of the







synthesized feature is selected,







the host option is disabled via







*Constraints. When the Installed







option is selected, the host option







is enabled. The display name for







the synthesized feature must be







defined via







*InstallableFeatureName or







*rcInstallableFeatureNameID.







The display names for the two







options must be defined via







*InstalledOptionName/







*NotInstalledOptionName or







*rcInstalledOptionName/







*rcNotInstalledOptionNameID.







The parser will also synthesize the







constraints needed to implement







the behavior described.






*InstallableFeatureName




Quoted string, the display name




Same as above.




Optional. If it is missing and







for the UI control which allows





*Installable? is TRUE, then







the user to specify the install





*rcInstallableNameFeatureID







status of the host feature or





must be present.







option.






*rcInstallableFea-




Integer, the Windows string




Same as above.




Optional. If it is missing and






tureNameID




resource ID for string





*Installable? is TRUE, then







corresponding to





*InstallableFeatureName must be







*InstallableName.





present.






*HelpIndex




Integer, the custom help index




Same as above.




Optional. If missing, no custom







corresponding to this





help text for this feature/option.







feature/option. The index is





If it is specified, then *HelpFile







referring to the file specified in





entry must be present too. Note:







*HelpFile entry.





0 and (DWORD)(−1) are not valid









values for *HelpIndex.






*rcIconID




Integer, the Windows RC_ICON




Any *Option or




Optional. If missing, no icon







resource ID for a feature or




*case




image is displayed.







option in the associated resource




(dependency)







DLL.




construct






*OptionID




Integer, the ID value that will be




Same as above.




Optional. Can only be used for







reported in the devmode for this





user-defined options (where the







feature when this option is





ID's are above 256 and by default







selected.





are assigned by the parser). Can









only be used for these features:









Halftone, PageSize, InputSlot and









Mediatype. The value supplied









must not conflict with any other









ID value for this feature whether









defined via OptionID or supplied









by the parser. To avoid problems,









use values >512.









User assigned OptionIDs are also









allowed for any Resolution









option. However they must be









negative and smaller (more









negative) than









RES_ID_IGNORE, currently









defined as −200. If OptionID is









defined, the ID is stored in the









Devmode and the driver will









attempt to find an option with the









same OptionID value instead of









the same DPI.






*rcPromptMsgID




Integer, the Windows string




Same as above.




Optional. If missing, assume no







resource ID for the prompt





prompting is needed, which is the







message to be displayed if the





most common case. This entry is







option is selected.





used mostly for prompting to









insert paper when Manual Feed is









selected.






*PromptTime




Constant(UISETUP,




Any *Option




Required if the *rcPromptMsgID







PRTSTARTDOC), when to




construct.




entry is present. If there are







display the prompt message,





multiple prompt messages at







either at the driver UI when the





PRTSTARTDOC, they are







user selects the option or at





merged into one for display. The







printing when the job is started.





only user option is to hit the OK









button in the message dialog.






*DisabledFeatures




LIST(FeaKeyword1,




Any *Option




Optional: If missing, assume all







FeaKeyword2, . . .) a list of one




construct.




Features enumerated in the GPD







or more Feature Keywords





file are available unconditionally.







specifying Features which are





Note also that any Feature that







disabled if the current option is





appears within a







selected. The keyword may be





*DisabledFeatures cannot make







nested within switch/case





use of the *Installable? Keyword.







constructs to express more





One must explicitly define the







complex conditions. Unidrv5





installed feature in the GPD file.







may use this information for





For example if Duplexing is







example to simulate Duplexing,





disabled if the “Optional







if the printer's duplexing option





Duplexing Unit” is not installed







is not installed, and to publish the





and consequently Duplex is







printer's current capabilities in





desired to appear as a







the Directory Services.





DisabledFeatures, one must define









an “Optional Duplexing Unit”









feature with two options









“Installed”, “Not Installed”. The









*DisabledFeatures: Duplexing









entry will appear within the









*Option: NotInstalled construct.









When one manually defines the









installable features be sure to









include all necessary *Constraints









entries.






*Command:




Construct




Any *Option




Optional. CmdSelect is a






CmdSelect{}





construct.




standard *Command construct









used to describe how to select a









feature setting.














Individual features may have additional entries defined for their *Feature and *Option constructs. A PaperSize option defines dimension related attributes of the printing media, such as the physical paper dimensions, the printable area (origin and size), the cursor origin (0,0), etc. All these values are defined relative to the PORTRAIT orientation. For example, the standard paper size LETTER has 8.5″ width (X-axis) and 11″ length (Y-axis). If an attribute, such as the cursor origin, changes depending on the orientation (such as on most page printers which can rotate the coordinate system to fit the logical orientation), the *switch/*case constructs should be used to express the orientation dependency though the values must still be defined relative to the PORTRAIT orientation. Additionally for Standard (pre-defined) papersizes, the GPD writer may choose to have the operating system assign the papersize option a standard display name instead of specifying one via *Name or *rcNameID. To default to using the system assigned name, omit the *Name entry and set *rcNameID: 0x7fffffff (the largest positive 32 bit signed value). Obviously the resource file does not need to actually contain such a resource ID. To emphasize the special meaning of this value, the GPD writer could define a Valuemacro:




















*Macros: myMacros







{













RCID_DMPAPER_SYSTEM_NAME: 0x7fffffff













}







then a reference to this value would be







*rcNameID: =RCID_DMPAPER_SYSTEM_NAME















The following are entries that can appear inside *Option constructs of the PaperSize feature.


















Entry Name




Description




Location




Comments











*PrintableArea




PAIR(width, height), the




Any PaperSize




Required for all PaperSize







printable width and height (in




*Option




options except CUSTOMSIZE.







master units)relative to the




construct or







PORTRAIT orientation no




*switch/*case







matter where this entry




construct. For







appears.




printers which








can rotate its








coordinate








system to fit the








logical








orientation, this








value might be








dependent on the








orientation setting.






*PrintableOrigin




PAIR(x, y), the offset (in




Same as above




Required for all PaperSize







master units) of the upper left





options except CUSTOMSIZE.







corner of the printable area in







PORTRAIT orientation relative







to the upper left corner of the







physical page in PORTRAIT







orientation no matter where







this entry appears.






*CursorOrigin




PAIR(<x>, <y>), the offset of




Same as above.




Optional. If missing, assume the







the cursor (0,0) relative to the




For printers




cursor origin is the same as the







upper left corner of the




which can rotate




printable origin in any







physical page(in master




its coordinate




orientation.







units)in PORTRAIT




system to fit the




Required for CUSTOMSIZE.







orientation no matter where




logical




The current driver assumes the







this entry appears.




orientation, this




cursor origin wrt the printer itself








value is always




is unaffected by changing the








dependent on




papersize.








the orientation








setting.






*MinSize




PAIR(minX, minY), the




CUSTOMSIZE




Required for CUSTOMSIZE







minimum X and Y dimensions




option.




option.







for the CUSTOMSIZE option







(in master units). The X and Y







dimensions must be relative to







the PORTRAIT orientation.






*MaxSize




PAIR(maxX, maxY), the




Same as above




Required for CUSTOMSIZE







maximum X and Y dimensions





option.







for the CUSTOMSIZE option







(in master units). The X and Y







dimensions must be relative to







the PORTRAIT orientation.






*TopMargin




Integer, the top margin (in




CUSTOMSIZE




Optional. If missing, assume 0.







master Y unit) for any custom




option only.







size in PORTRAIT orientation.






*BottomMargin




Integer, the bottom margin (in




CUSTOMSIZE




Optional. If missing, assume 0.







master Y unit) for any custom




option only.







size in PORTRAIT orientation.






*MaxPrintableWidth




Integer, the maximum printable




CUSTOMSIZE




Required for CUSTOMSIZE







width on a printer. It applies




option only.




option.







to all custom sizes supported







by the printer.






*MinLeftMargin




Integer, the minimum left




CUSTOMSIZE




Optional. If missing, assume 0.







margin on a printer. It applies




option only.







to all custom paper sizes







supported by the printer.






*CenterPrintable?




Boolean, whether the printable




CUSTOMSIZE




Optional. If missing, assume







width is centered, i.e. whether




option only.




FALSE, i.e. the left margin is as







the left and right margins





defined in *MinLeftMargin and







should be equal. It applies to





the rest of the unprintable width







all custom paper sizes





is on the right. Note that this







supported by the printers.





entry is applicable only to









CUSTOMSIZE option.






*PageDimensions




PAIR(<x>, <y>), the physical




Any custom




Required for non-standard







dimensions of a non-standard




options of




options of PaperSize.







paper size (in master units).




PaperSize







The X and Y dimensions must







be relative to the PORTRAIT







orientation.






*RotateSize?




Boolean, whether to rotate the




Any standard




Optional. If missing, assume







physical dimensions of a




PaperSize




FALSE. Note that if this entry is







standard paper size in order to




options




TRUE, than the X/Y physical







suit the paper feed method.




(excluding




dimensions should be exchanged







This is typically used by




CUSTOMSIZE)




regardless of the orientation.







printers which feed standard





Note that id this is TRUE, the







envelopes length-wise since the





values in *PrintableArea and







standard envelope sizes have





*PrintableOrigin apply to the







smaller width than height. For





dimensions after the rotation.







example, if this is TRUE for







Env#10 (4.125″ × 9.5″), then







its physical size is 9.5″ (width)







by 4.125″ (height) in







PORTRAIT orientation.






*PageProtectMem




Integer, the printer memory




Any PaperSize




Required if there is PageProtect







required (in KB) for enabling




options, or




feature.







page protection.




*case construct














The following are additional entries that can appear inside option constructs of OutputBin feature.


















Entry Name




Description




Location




Comments











*OutputOr-




BOOLEAN, when a




Any OutputBin




Optional. If






derReversed?




multi-page document




options, or




missing,







prints to this bin, are




*case construct.




assume







the pages sorted last




This is a reloca-




FALSE.







page to first?




table global and








may appear at the








root level. The








root level defini-








tion (if present)








must precede any








redefinition








within *Option or








*case constructs.














The following are Resolution Option Entries:


















Entry Name




Description




Location




Comments











*DPI




PAIR(<xdpi>,<ydpi>), the




Any Resolution




Required.







X and Y units of the




options.







graphics resolution.






*SpotDiameter




Integer, the spot diameter




Any Resolution




Required.







value for this resolution.




options, or *case








construct.






*TextDPI




PAIR(<xdpi>, <ydpi>), the




Any Resolution




Required. Note that *DPI







X and Y units of the text




options.




values must be a power of 2







resolution. Device fonts and





factor of *TextDPI values. For







vector graphics are printed





example, if *TextDPI is







in the text resolution.





(300,300), then *DPI: (75,75)









is valid, but *DPI: (100,100) is









not since 300/100=3 which is









not a power of 2.






*PinsPerPhysPass




Integer, the number of




Any Resolution




Optional. If missing, assume 1.







scanlines printed when the




options, or







printhead moves across the




*switch/*case







page. It must be 1 if




construct.







*OutputDataFormat (defined







in Section 5.2.2) is







H_BYTE, or multiples of 8







if *OutputDataFormat is







V_BYTE.






*PinsPerLogPass




Integer, the number of




Same as above.




Optional. If missing, assume 1.







scanlines printed in one





By definition, *PinsPerLogPass







logical pass. On some serial





must be in multiples of







printers, scanlines are





*PinsPerPhysPass value.







interlaced to increase the







printing resolution.






*RedDeviceGamma




Integer, red gamma to be




Same as above




Optional. If missing, assume -







applied to correct for device





1 to use internal default.







color. This is only valid





Specify value as gamma value







when ICM is disabled.





* 1000 with a valid range of 0









to 65535.






*GreenDeviceGamma




Integer, green gamma to be




Same as above




Optional. If missing, assume -







applied to correct for device





1 to use internal default.







color. This is only valid





Specify value as gamma value







when ICM is disabled.





* 1000 with a valid range of 0









to 65535.






*BlueDeviceGamma




Integer, blue gamma to be




Same as above




Optional. If missing, assume -







applied to correct for device





1 to use internal default.







color. This is only valid





Specify value as gamma value







when ICM is disabled.





* 1000 with a valid range of 0









to 65535.






*RequireUniDir?




Boolean, whether this




Same as above




Optional. If missing, assume







resolution requires uni-





FALSE. This is used only by







directional printing be





some dot-matrix printers.







turned on before sending







raster data.






*MinStripBlankPixels




Integer, the minimum




Same as above




Optional. If missing, assume 0.







threshold for stripping blank





Note that this value is used







pixels in the middle of





only if *StripBlanks (defined







scanlines. That is, it applies





later) lists ENCLOSED.







to stripping enclosing







blanks only. The







measurement is in bytes. If







stripping leading and trailing







blanks are requested, the







minimum threshold is







always 0.














The following are additional entries that can appear in any ColorMode option.

















Entry Name




Description




Comments











*Color?




Boolean, whether this




Optional. If missing,







mode produces color




assume TRUE if







(vs. monochrome)




*DrvBPP > 1. For gray-







output.




scaling on the printer, this








option should be set to








FALSE even though








*DevBPP is greater than 1.






*DevNumOfPlanes




Integer, the number of




Optional. If missing,







color planes in color




assume 1 plane. For color







data sent to the




devices, if this entry is 1,







printer.




we call it “pixel mode”.






*DevBPP




Integer, the number of




Optional. If missing,







bits per pixel in color




assume 1 bit per pixel. For







data sent to the




color devices, if this entry







printer.




is 1, we call it “planar








mode”.






*RasterMode




Constant(DIRECT,




Optional. If missing,







INDEXED), which




assume INDEXED, i.e. the







describes how the




color data sent to the printer







raster data will be




is dependent upon the







interpreted by the




printer's palette.







printer in this color







mode.






*ColorPlaneOrder




LIST(YELLOW,




Required if







MAGENTA, CYAN,




*DevNumOfPlanes is







BLACK, RED,




greater than 1.







GREEN, BLUE), the







order of sending color







plane raster data. A







color value may be re-







peated in the list.






*PaletteSize




Integer, the number of




Optional. If missing,







entries in the palette




assume 2.







defined by CmdSelect







of this ColorMode







option.






*PaletteProgram-




Boolean, whether the




Optional. If missing,






mable?




color palette is




assume FALSE.







programmable.




IF TRUE, Driver will








download the correct








palette, for INDEXED








RasterMode.






*DrvBPP




Integer, the number of




Optional. If missing,







bits per pixel for the




assume 1 bit per pixel. Note







driver's bitmap ren-




that the driver's rendering







dering buffer. The




format is always 1 plane.







legal values are: 1, 4,







8, 16, 24, 32. The bit-







map format is the







Windows DIB.






*IPCallbackID




Integer (positive), the




Optional. If missing,







callback id for calling




assume that there is no







OEMImageProcessing




additional OEM image pro-







after rendering is done




cessing on the banding







and before sending




bitmap buffer.







data to the printer.














Note that the Unidrv5 of the instant invention has built-in support for following color data formats (*DevNumOfPlanes/*DevBPP):




1 plane/1 bpp (B/W)




3 planes/1 bpp (either RGB or CMY)




4 planes/1 bpp (CMYK)




1 plane/8 bpp




1 plane/24 bpp




If other color data formats are specified, the callback function OEMImageProcessing must be provided.




The driver's bitmap rendering format can be “deeper” than the printer's color data format, which implies that the driver or the OEM-supplied DLL would need to halftone the image down to the format appropriate for the printer. For example, if one would want the driver to render in 24 bpp format but send YMCK data to the printer, one of the ColorMode option should be like:




















*Feature: ColorMode







{













. . .







*Option: 24toYMCK







{













*Name: “Photographic Quality”







*DrvBPP: 24







*DevNumOfPlanes: 4







*DevBPP: 1







. . .













}







. . .













}















There are two ways to describe possible memory configurations on a printer with the instant invention. First, one could enumerate each and every possible configuration using the standard *Option construct. Each option represents a possible configuration and the driver will display them as a drop-down combobox. Within a Memory option construct, the following entry must be used to describe the memory configuration:






*MemoryConfigKB: PAIR(<InstalledMemoryKB>, <AvailableMemoryKB>)






Note that amount of available memory must be smaller than the amount of installed memory. Second, one could use the shorthand representation and rely on the GPD parser to synthesize memory options. This is useful for high-end printers which can have many possible memory configurations. The shorthand is defined as follows:

















Entry Name




Description




Comments











*MemConfigKB




PAIR(<installedKB>,




If there are multiple







<availableKB>), a




*MemConfigKB entries,







memory configuration




each represents a possible







expressed in KB unit.




memory configuration and







The GPD parser will syn-




they are presented to the







thesize a name in the




user in the order listed in







form “<installedKB>




the GPD file. Note: if the







KB” for UI display. For




synthesized name is not







example, for PAIR(512,




appropriate due to localiza-







370), the parser creates




tion issues, then the options







the name “512KB”.




should be explicitly








enumerated using








*MemoryConfigKB.






*MemConfigMB




PAIR(<installedMB>,




Same as above.







<availableMB>), a




*MemConfigKB and







memory configuration




*MemConfigMB can be







expressed in MB unit.




used together in any







The GPD parser will syn-




order desired.







thesize a name in the







form “<installedMB>







MB” for UI display. For







example, for PAIR(16,







15), the parser creates







the name “16MB”.














The shorthand and longhand methods of specifying the memory configuration may be freely mixed within the Memory feature construct. The synthesized name is also the keyname of the option and may be referenced by the *DefaultOption keyword. The list of synthesized memory options are displayed in the UI along with the long hand options in the order they appear in the GPD file.




Halftoning is used to reduce the data depth. There are four types of Halftone options. First is the system-provided standard halftone options. They are identified by the standard option names in the GPD file. Second, there are the OEM-provided halftone patterns. These custom options need additional entries to describe the size and content of the pattern (see the table below). If these patterns are stored in the resource dll they can be either encrypted or unencrypted. If the patterns are not in the resource dll or they are encrypted, there must be a callback function to generate the halftone pattern. All OEM provided halftone patterns must have a size that is a multiple of dwords (evenly divisible by 4). If the custom pattern has three different patterns each individual pattern must be a multiple of dwords. Multiple pattern resources are assumed to be stored with the red pattern first, then green and finally blue. Third, are the OEM-provided callbacks for halftone. There can be multiple callback halftone methods and Unidrv5 will pass the symbolname of the selected halftone option when making the callback OEMImageProcessing. The callback halftoning is applied on the banding bitmap buffer after all rendering is done and before sending data to the printer. And finally, there is Halftoning on the printer. This is the only type of options that has *Command:CmdSelect{ } construct for selecting a particular halftone method on the printing.




The following are the standard halftone option names to utilize when the system provided halftone options are desired:




HT_PATSIZE





2×2, HT_PATSIZE





2×2_M




HT_PATSIZE





4×4, HT_PATSIZE





4×4_M




HT_PATSIZE





6×6, HT_PATSIZE





6×6_M




HT_PATSIZE





8×8, HT_PATSIZE





8×8_M




HT_PATSIZE





10×10, HT_PATSIZE





10×10_M




HT_PATSIZE





12×12, HT_PATSIZE





12×12_M




HT_PATSIZE





14×14, HT_PATSIZE





14×14_M




HT_PATSIZE





16×16, HT_PATSIZE





16×16_M




HT_PATSIZE_SUPERCELL, HT_PATSIZE_SUPERCELL_M




HT_PATSIZE_AUTO




The HT_PATSIZE_AUTO mode is recommended as the default and will be assumed if no halftone option exists. It allows the driver to select the optimum GDI standard halftone method based on the device resolution and color mode. The result will be that the user will be able to switch between color and monochrome or select different resolutions without having to know the optimum halftone method for that configuration. It is currently anticipated that HT_PATSIZE_SUPERCELL_M will be used for color while monochrome will utilize on of the standard HT_PATSIZE





6×6_M to HT_PATSIZE





16×16_M patterns based on the current resolution.




The following are additional entries for a Halftone option:


















Entry Name




Description




Location




Comments











*rcHTPatternID




Integer, the




OEM-




Required for







Windows




defined pat-




OEM-defined







RC_HTPATTERN




tern Halftone




halftone patterns







resource id for the




options




stored in the re-







halftone pattern data





source DLL. If







in the associated re-





missing default to







source DLL. Pre-





zero. If zero there







ferably all





must be a







RC_HTPATTERN





HTCallbackID







ID's in a resource





and callback







DLL be contiguous





function to gen-







and start from 1.





erate the halftone









pattern.






*HTpatternSize




PAIR(xSize, ySize),




Same as




Required for







the X and Y size, in




above




OEM-defined







pixels, of the half-





halftone patterns.







tone pattern.







Currently, xSize







and ySize must







equal.






*HTNumPatterns




Integer specifying




Same as




Optional. If miss-







the number of pat-




above




ing, assume 1







terns to use for color





pattern for all







halftoning which are





color planes. Cur-







in the associated





rently, 1 or 3 are







resource DLL or





the only valid







generated by the





entries.







OEM callback.






*HTCallbackID




Integer (positive),




Same as




Optional. If







the callback id for




above




missing, assume







calling





there is no OEM







OEMHalftonePat-





callback neces-







tern to generate or





sary to generate







decode a custom





this patterns.







halftone pattern. If







the callback







function







OEMHalftonePat-







tern generates more







than one possible







pattern, each pattern







must be assigned a







unique







HTCallbackID.














Halftone options are closely tied to ColorMode options. The following are three typical scenarios:




1. *DrvBPP is 4 and *DevNumOfPlanes is 4 (YMCK): in this case, halftoning is done during the rendering process and hence only the pattern halftoning options should be available. If the OEM wants special image processing on the final bitmap buffer, *IPCallbackID entry should be defined in the GPD file and OEMImageProcessing function should be exported in the render-mode OEM DLL.




2. *DrvBPP is 24 and *DevNumOfPlanes is 4 (YMCK): in this case, halftoning is done after rendering is completed and OEM must export the function OEMImageProcessing. *IPCallbackID entry must be defined in the GPD file. Only halftoning options performed in OEMImageProcessing should be made available to the user.




3. *DrvBPP is 24 and *DevBPP is 24: in this case, the printer is halftoning. All software halftoning options should be disabled. If the OEM wants special image processing performed on the final bitmap buffer, *IPCallbackID entry should be defined and the OEMImageProcessing function should be exported.




Dependencies between halftone options and color modes can be expressed via *Constraints.




Some printers have fonts resident on the device which speed up printing. A separate tool, IFI Font Editor, is provided for editing the font metrics and other related information. Each font is represented by one .IFI file and all .IFI files of a printer can be added to the resource DLL (*ResourceDLL) using the resource type RC_FONT. A GPD file can reference these fonts via RC_FONT resource ID's. A special keyword, *DeviceFonts, is defined for this purpose:






*DeviceFonts: LIST(fontID


1


, fontID


2


, . . . )






For example,




*% assume that RC_FONT_xxx id's are value macros defined by the GPD file creator.




*DeviceFonts: LIST(=RC_FONT_COURIER


10


, =RC_FONT_ARIALR, =RC FONT_ARIALI, +=RC_FONT_ARIALB, =RC_FONT_ARIALBI, =RC_FONT_TIMESNRR, =RC FONT_TIMESNRI, +=RC_FONT_TIMESNRB, =RC_FONT_TIMESNRBI)




Note that the continuation character, ‘+’, is used to concatenate multiple lines. If there are multiple *DeviceFonts entries, the individual lists will be merged together by the GPD parser. This is different from the default behavior where the last occurance of a *Keyword entry overwrites and redefines the value associated with the *Keyword. *DeviceFonts are assumed to be available in all printer configurations. If a certain sets of fonts are available only in a particular orientation (such as Portrait vs. Landscape), *switch/*case constructs can be used to express such dependency. If there is no fonts resident on the printer, there is no need to define *DeviceFonts entry in the GPD file.




For backward compatibility with GPC, GPD also supports default font cartridges. Each font cartridge is represented by one *FontCartridge construct.




















*FontCartridge: Z1A







{













<entries that describe the font cartridge>













}















The following entries can appear inside a *FontCartridge construct:

















Entry Name




Description




Comments











*rcCartridgeNameID




Integer, the Windows




Required, unless







string resource id for




*CartridgeName entry







the font cartridge




is specified.







name.






*CartridgeName




Quoted string, the font




Required if







cartridge name.




*rcCartridgeNameID








is not specified.






*Fonts




LIST(integers), the list




Required unless







of RC_FONT re-




*PortraitFonts and/or







source id's for




*LandscapeFonts are







cartridge fonts which




specified.







are available in both







Portrait and Land-







scape modes. Prefer-







ably all RC_FONT







ID's in a resource







DLL are contiguous







and start from 1.






*PortraitFonts




LIST(integers), the




Optional. If missing,







list of RC_FONT re-




assume none. If *Fonts is







source id's for the




specified, then the list of







Portrait mode fonts in




Portrait fonts is the union







this cartridge.




of both entries.






*LandscapeFonts




LIST(integers), the




Optional. If missing,







list of RC_FONT




assume none. If *Fonts is







resource id's for the




specified, then the list of







Landscape mode fonts




Landscape fonts is the







in this cartridge.




union of both entries.














Font substitution is a method of achieving balance between document portability and printing performance. Unidrv5 supports font substitution, i.e. substitute device fonts for TrueType fonts that need to be downloaded. This feature is invoked if the GPD file contains a default font substitution table which is comprised of one or more *TTFS constructs:




















*TTFS: <unique name>







{













*TTFontName: “<TT font name>”







*DevFontName: “<Substituted device font name>”













}















Each *TTFS construct defines one substitution preference. They are concatenated together for displaying in the UI. If two or more *TTFS constructs have the same symbolname, the last one overwrites the previous ones. The font name strings are specified either in UNICODE or in the code page specified by *CodePage.




Each TrueType font can be mapped to at most one device font. In addition, the substitution happens only if other attributes match, such as the character set, weight, italic, orientation. Typically, font substitution speeds up printing by reducing the amount of data sent to the printer (no font downloading) and reducing the usage of printer memory. Note that device TrueType fonts should be viewed as different fonts than the system TrueType fonts. For example, HP LaserJet 4 printer has Arial font on the printer, but it is different than the Arial font on the Windows systems both in terms of the font metrics and the set of glyphs contained in the font. However, for the same glyph index, the outline data is the same. So for better performance, its GPD file can define a default substitution table:




















*TTFS: Arial







{













*TTFontName: “Arial”







*DevFontName: “Arial”













}







*TTFS: TNR







{













*TTFontName: “Times New Roman”







*DevFontName: “Times New Roman”













}







*TTFS: CourierNew







{













*TTFontName: “Courier New”







*DevFontName: “Courier New”













}







*TTFS: Wingdings







{













*TTFontName: “Wingdings”







*DevFontName: “Wingdings”













}















The user can modify the font substitution table through the driver UI. The GPD file can specify if TrueType font substitution should be used by default or not via the following entry:






*TTFSEnabled?: <Boolean>






If this value is FALSE, Unidrv5 will display the font substitution table but will not perform font substitution unless the user changes the setting manually. If there is no *TTFS entry at all in a GPD file, Unidrv5 will not invoke the font substitution functionality regardless of whether the *TTFSEnabled entry exists or not. If there are at least one *TTFS entry but no *TTFSEnabled entry, Unidrv5 assumes FALSE for the *TTFSEnabled value. Note that *TTFS entry cannot have any dependency on printer configurations, though *TTFSEnabled entry can. Note also that the keywords *rcTTFontNameID and *rcDevFontNameID can be used in place of *TTFontName, *DevFontName if it is desired to reference a string stored in a resource file instead of a string defined directly in the GPD file.




GPD feature and option selections are normally independent of each other. That is, whether option A is installed or selected has no impact on whether option B can be installed or selected. However, there are printers where 2 or more feature selections conflict or constrain each other. One common case is that if the envelope feeder is selected, then regular paper sizes, such as Letter and A4, cannot be selected. This section defines ways to describe various types of constraints.




GPD defines *Constraints entry to express the mutually exclusive selection relationship between two options. For example, on an Epson Stylus color printer, the 720 dpi resolution cannot be selected if either Coated360 or Transparency media is selected:




















*Feature: Resolution







{













. . .







*Option: 720dpi







{













*DPI: PAIR(720,720)







*Constraints: MediaType.Coated360







*Constraints: MediaType.Transparency













}













}















Another way to look at it is that if 720 dpi resolution is selected, then neither Coated360 media nor Transparency media can be selected. Within the same *Feature or *Option construct, the relationship between multiple *Constraints entries is the logical OR.




The *Constraints definitions are reciprocal. That is, if A is constrained by B, then B is automatically constrained by A. In the above example, if 720 dpi resolution is selected, then the user cannot select either Coated360 paper or Transparency. On the other hand, if the current resolution is 360 dpi and the user has selected Coated360 or Transparency media, then the user can no longer select 720 dpi resolution. The location where the constraints are specified is up to the GPD creator. It is okay to define the constraints in both Resolution and MediaType constructs, but it is redundant.




When an option is associated with multiple constraints, GPD allows using the LIST value type to consolidate them. For example, the above constraints can be described in one entry:






*Constraints: LIST(MediaType.Coated360, MediaType.Transparency)






Here is the ENBF definition of *Constraints entry:






<ConstraintEntry>::=*Constraints: <ConstraintValue>








<ConstraintValue>::=<QualifiedName>|LIST(<QualifiedName>{,<QualifiedName>})








<QualifiedName>::=<FeatureName>.<OptionName>






Note that *Constraints definitions are not transitive, that is, if A is constrained by B, and B is constrained by C, then A is not automatically constrained by C. Obviously, *Constraints definitions must appear inside an *Option construct because the construct itself implies the one party of this mutually exclusive selection relationship.




Sometimes, the selection constraints involve more than two options. For example, on an Epson Stylus color printer, the CMYK color mode cannot be used with the plain paper in 720 dpi, but it can be used with Coated720 paper in 720 dpi or used with plain paper in 180 dpi. In addition, the plain paper and 720 dpi resolution are compatible if the B/W mode is selected. To describe such multiple-option constraints, GPD defines *InvalidCombination entry:




<InvalidCombinationEntry>::=*InvalidCombination: LIST(<QualifiedName>{,<QualifiedName>})




This entry must appear at the root level since it is symmetric with respect to each of the enumerated QualifiedNames. So the above example can be described as:






*InvalidCombination: LIST(Resolution.720 dpi, MediaType.Plain, ColorMode.CMYK)






For the expression






*InvalidCombination: LIST(option


1


, option


2


, option


3


, option


4


, . . . )






the logical meaning, in terms of option selection, is






!(option


1


&& option


2


&& option


3


&& option


4


&& . . . )






More than one *InvalidCombination entry may appear in the GPD file. Each *InvalidCombination entry defines a separate constraint. Each *InvalidCombination entry is independent of another and they may or may not have common options. *Constraints are a special case of *InvalidCombination involving only two options where one QualifiedName is implied from the location of the *Constraints entry within a particular *Feature/* Option construct. The above *Constraints example for 720 dpi resolution can also be described as:






*InvalidCombination: LIST(Resolution.720 dpi, MediaType.Coated360)








*InvalidCombination: LIST(Resolution.720 dpi, MediaType.Transparency)






Because they are more symmetric, *InvalidCombination entries tend to be more efficient to evaluate than *Constraints.




Most printers have two types of options: baseline and installable. The most common installable options are additional input bins and the duplexing unit. Occasionally, the option installations are mutually exclusive. For example, if the optional envelope feeder is installed, then the duplexing unit cannot be installed, and vice versa. Both *Constraints and *InvalidCombination deal with impossible combinations of explicitly specified option selections. Features synthesized by the *Installable keyword are not affected by *Constraints and *InvalidCombination since they have no QualifiedName. So GPD defines an entry, *InvalidInstallableCombination, to express constraints involving 2 or more Synthesized Features.






<InvalidInstComb>::=*InvalidInstallableCombination: LIST(<QualifiedName>{,<QualifiedName>})






Note that each qualified name in the list must be an installable option or feature, i.e. the corresponding *Option or *Feature construct must contain the following entry:






*Installable?: TRUE






The *InvalidInstallableCombination keyword means the Synthesized Features hosted by the Installable Features or Options enumerated in the QualifiedNames cannot all be set to the “Installed” option. If the QualifiedName refers to an installable Feature, there is obviously no option qualifier so in this case:






<QualifiedName>::=<FeatureName>






An installable feature means that all options of the feature are installable except the first option. Just like *InvalidCombination, each *InvalidInstallableCombination entry is independent of another. The exclusive installation relationship is symmetric among the synthesized features implied in the list. Note: the *InvalidInstallableCombination keyword can only be used if the *Installable? Keyword is present in the GPD file.




There is the implicit constraint that if an option is not installed, then it cannot be selected. It is also possible to have constraints between one option being installed and a different option being selected, such as if A is not installed, then B cannot be selected; or if A is installed, then B cannot be selected. For example, if LargeFmt tray is not installed, then Tabloid paper cannot be selected. GPD treats these types of installation-constraints-on-selection as attributes of an installable option or feature. It defines following new entries:






<NotInstalledConstraintsEntry>::=*NotInstalledConstraints: <ConstraintValue>








<InstalledConstraintsEntry>::=*InstalledConstraints: <ConstraintValue>






where <ConstraintValue> is the same as defined in Section 2.6.1 for a *Constraints entry. As their names imply, these entries must appear inside an installable option or feature construct (i.e. the *Option or *Feature construct which contains the *Installable: TRUE entry). Just like *Constraints, the relationship between multiple *NotInstalledConstraints entries and multiple items in the list is the logical OR. The implied member of this constraint relationship is the synthesized Feature created for each *Installable option or feature. For *NotInstalledConstraints, the implied member is <SynthesizedFeature.NotInstalled>, for *InstalledConstraints, the implied member is <SynthesizedFeature.Installed>. These keywords are unnecessary if there are no synthesized Features present since the *Constraints keyword can then explicitly refer to all the features.




The following table summarizes various types of constraints:



















then B cannot be installed




then B cannot be selected


























If A is not




N/A




*NotInstalledConstraints






installed,






If A is in-




*InvalidInstallableCombination




*InstalledConstraints






stalled but






not selected,






If A is




this is equivalent to the case




*Constraints, or






selected,




where “if B is installed, then A




*InvalidCombination







cannot be selected”, i.e., using







*InstalledConstraints inside B's







construct.














GPD defines the *switch and *case constructs for expressing dependencies between entry values and specific printer configurations. The *switch and *case constructs are similar to the switch and case statements in C programming language. It should be noted that although the documentation refers only to the lowercase version, the Parser will also accept *Switch and *Case. The *switch construct names the dependent feature and the *case construct names the specific option of that feature. For example, on HP LaserJet 4L printer, the *PrintableArea, *PrintableOrigin and *CursorOrigin attributes, which are members of the PaperSize option construct, also depend on the logical orientation:




















*% All numbers are expressed in 600dpi unit.







*Feature: Orientation







{













*DefaultOption: Portrait







*Option: Portrait







{













*Name: “Portrait”







*rcIconID: =RC_ICON_PORTRAIT













}







*Option: Landscape_CC90







{













*Name: “Landscape”







*rcIconID: =RC_ICON_LANDSCAPE













}













}







*Feature: PaperSize







{













*DefaultOption: Letter







*Option: Letter







{













*Name: “Letter 8½ × 11 inch”







*switch: Orientation







{













*case: Portrait







{













*PrintableArea: PAIR(4800, 6324)







*PrintableOrigin: PAIR(150, 150)







*CursorOrigin: PAIR(150,100)













}







*case: Landscape_CC90







{













*PrintableArea: PAIR(4860, 6360)







*PrintableOrigin: PAIR(120, 120)







*CursorOrigin: PAIR(100,6480)













}













}













}







. . .













}















Entries that can appear inside *switch and *case constructs are called relocateable entries. They include all global entries unless explicitly specified otherwise. Examples include: *DeviceFonts, *TTFSEnabled. They also include most entries within a *Feature construct or within a *case construct. The designation is based on whether it is applicable or not, and it is enforced by the GPD parser. For example, *Constraints entry is not relocateable. Additionally, *FontCartridge, *Command constructs are relocateable. The *switch and *case constructs nested inside an *Option construct defines the additional dependency on top of the implicit dependency. Each *switch construct specifies one dependent feature. The only legal entry within a *switch construct is *case construct type. It is not required to have one *case construct for every option of the dependent feature. The overwriting rule may be used when applicable. Within a *case construct, there can be nested *switch constructs for expressing multiple dependencies.




Just like C language, GPD defines a special *case option, called *default, for expressing all other valid options not explicitly mentioned. An option is valid if it is not constrained by the current installations and selections. That means the set of valid options may change depending on the specific printer configuration. If a *default case is not present, either all possible options have been explicitly enumerated or the value has been initialized before the *switch/*case constructs.




Global entries can take advantage of the implicit dependency imposed by the *Feature and *Option structures. But when a global entry is used within an *Option construct, its name must be prefixed by the reserved word EXTERN_GLOBAL: to distinguish it from native members of that construct.




For example:




















*Option: UPPERBIN







{













Name: “Upper OutputBin”













EXTERN_GLOBAL: *OutputOrderReversed?: TRUE













}















Note that *DefaultOption entry can also appear inside a *switch/*case construct, but there cannot be any loop in the dependency chain. For example, if the default option of Feature A depends on Feature B, then the default option of Feature B cannot depend on Feature A. There can be multiple features on the dependency chain, but the default option of the last one on the chain cannot depend on any other feature.




When specifying the dependency of an attribute, it must be done consistently. When there are multiple levels of dependency, the same feature can appear only once at only one level. That is if an attribute is defined to be dependent on Feature A at the first level, it cannot have a dependency on Feature A at any other level. For example say the attribute represented by the *DeviceFonts keyword had dependencies on Orientation and Resolution. The following would be an inconsistent (nonsensical) way of expressing this dependency.

















*switch: Orientation






{













*case: PORTRAIT







{













*switch: Resolution







{













*case: 300dpi







{













*switch: Orientation *% Orientation appears at 2













*% nesting levels - inconsistent and







meaningless!













{













*case: LANDSCAPE_CC90







{













*DeviceFonts: 1













}













}













}













*case: 600dpi







{













*DeviceFonts: 2













}


























}







*case: LANDSCAPE_CC90







{













*DeviceFonts: 3













}











}














If any attribute is defined multiple times within the GPD file, all of the definitions must express dependencies on the same Features at each nesting level. For example, if an attribute is initially defined to have a dependency on Orientation at the first level and Resolution at the second level, a subsequent definition of that attribute cannot specify a dependency on Papersize at the first level and Orientation at the second level. However, more dependency levels can be added in subsequent definitions of that attribute as long as the existing levels remain consistent with the previous definitions. One may think of each attribute being represented by a multi-level tree. The initial definition may define the trunk and lower branches, subsequent definitions may add more lower branches or define smaller branches off the existing branches, but may not redefine the branching structure that has already been defined. One may however redefine the value of the attribute (the leaves of the tree). Note there is no requirement that the tree be symmetric. If an attribute has further dependencies on resolution for landscape orientations but none for portrait, there is no need to add more *switch/*case constructs into the portrait branch simply because the landscape branch needs them.




A GPD writer may want to implement an ease-of-use UI feature which in its current implementation presents 3 radio buttons that allow the user to control the quality of the printed output without having to specify all of the options which affect the output quality. The three buttons allow the user to select a “draft quality” when speed of output is more important than quality, a “Better quality”, and a “Best quality”. The quality macro keywords allow the GPD writer to associate one or more Feature settings with each of these UI buttons. When the user presses one of the quality buttons, each of the Features associated with this button are set to the option specified in the GPD without further user intervention. The quality macro keywords are:






*DraftQualitySettings: LIST(qualifiedname


1


, qualifiedname2, . . . )








*BetterQualitySettings: LIST(qualifiedname


1


, qualifiedname2, . . . )








*BestQualitySettings: LIST(qualifiedname


1


, qualifiedname2, . . . )








*DefaultQuality: one of the following: {“DRAFTQUALITY”, “BETTERQUALITY”, “BESTQUALITY”}






As defined previously a Qualifiedname is defined to be of the form






<QualifiedName>::=<FeatureName>.<OptionName






for example RET.OFF or PaperSize.LEGAL or Resolution.300 dpi.




Each of these keywords is a relocatable global and may be placed within switch/case constructs. Currently, the UI allows a different set of quality macros to be used for each combination of MediaType and ColorMode. To make each macro setting dependent on MediaType and colormode use switch/case constructs, for example:

















*Switch: ColorMode






{













*case: 24bit







{













*switch: MediaType







{













*case: CLAYCOATED







{













*DraftQualitySettings: LIST(qualifiedname1,







qualifiedname2, . . . )







*BetterQualitySettings: LIST(qualifiedname1,







qualifiedname2, . . . )







*BestQualitySettings: LIST(qualifiedname1,







qualifiedname2, . . . )







*DefaultQuality: BESTQUALITY













}







*case: GLOSSY







{













*DraftQualitySettings: LIST(qualifiedname1,







qualifiedname2, . . . )







*BetterQualitySettings: LIST(qualifiedname1,







qualifiedname2, . . . )







*BestQualitySettings: LIST(qualifiedname1,







qualifiedname2, . . . )







*DefaultQuality: BETTERQUALITY













}







*default:







{













*DraftQualitySettings: LIST(qualifiedname1,







qualifiedname2, . . . )







*BetterQualitySettings: LIST(qualifiedname1,







qualifiedname2, . . . )







*BestQualitySettings: LIST(qualifiedname1,







qualifiedname2, . . . )







*DefaultQuality: DRAFTQUALITY













}













}













}







*default:







{













*DraftQualitySettings: LIST(qualifiedname1, qualifiedname2,







. . . )







*BetterQualitySettings: LIST(qualifiedname1, qualifiedname2,







. . . )







*BestQualitySettings: LIST(qualifiedname1, qualifiedname2,







. . . )







*DefaultQuality: DRAFTQUALITY













}











}














Note: to prevent inconsistent (bizzare) UI behavior, the quality macros should be defined so the execution of that macro will not have the side effect of changing either the MediaType or the Color Appearance settings. It is acceptable to have a macro change the color mode option—for example If Color Appearance=Color, the Best Quality macro may set ColorMode=24 bpp, the BetterQuality macro may set ColorMode=8 bpp and the DraftQuality macro may set ColorMode=4 bpp, but it would not make sense to set ColorMode=1 bpp (Mono). The feature settings defined for a quality macro should obviously be compatible with each other and not violate a *Constraints or *InvalidCombination statement. If quality macros are used, all three macros and the DefaultQuality keyword should be defined. If the GPD writer does not want to implement one of the macros, for one or more combinations of MediaType or ColorMode, he should explicitly define that unused macro by an empty list: LIST( ). Simply omitting one of the QualityMacro entries may lead to unanticipated behavior, (the parser's idea of the default value for the undefined macro may not agree with the GPD writee's idea of the default value). The GPD writer should also ensure all 4 keywords are defined for all combinations of ColorMode and MediaType to prevent UI inconsistencies. Use the *default: keyword within a *switch construct as shown above to ensure a definition always exists.




*Command is a grouping construct used to describe printer commands such as ejecting the page or selecting a font. The following are the legal entries within a *Command construct. Note that none of them can appear directly inside *case constructs.


















Entry Name




Description




Location




Comments











*Cmd




Quoted string, the command string




Any *Command




Required, unless *CallbackID







for this command




construct




entry is defined.






*CallbackID




Integer (positive), the unique




Same as above.




Required, unless *Cmd entry







callback id for this command.





is defined.






*Params




LIST(<StandardVariableNames>).




Same as above.




Optional. This entry can be







The standard variable names are





used only with *CallbackID







defined above. This allows callback





together. *Cmd entry







commands to access certain cached





references the standard







values such as the current





variables directly in its







resolution.





command string.






*NoPageEject?




Identifies a subset of




Command constructs




Optional. Default is FALSE







DOC_SETUP commands which




with an *Order section =







have the property that when all of




DOC_SETUP







the commands in the subset are




Currently used only







emitted in the specified order, the




if the printer







state of the printer will change as




supports Duplexing.







directed. This subset of







commands when emitted does not







have side-effects, they do not







change/reset any other







configuration of the printer that is







not explicitly specified in the







subset of commands. (they form







a sub-group). Also these







commands have the property that







when the entire subset is emitted







between the first and second







pages when printing in Duplex







mode, no page ejection occurs.






*Order




<section>.<number>, the ordering




Same as above.




Required for printer







information of this command.





configuration commands and









option selection commands.














A printer command in GPD can be used to configure the printer, change the printer state during printing such as moving the cursor, and select printer options such as Portrait orientation or Letter paper size. For the first two types, each command has a unique symbolname and all symbolnames are pre-defined. These *Command constructs must appear at the root level or inside *case constructs. But for selecting printer options, the *Command construct must have the symbolname CmdSelect and the construct must appear inside the corresponding *Option construct.




For simple commands that require only the command string, GPD provides a special shorthand syntax:




 *Command:<CommandName>:<CommandString>




For example,






*Command: CmdXMoveAbsolute: “escape for moving cursor horizontally to an absolute position”






is equivalent to:

















*Command: CmdXMoveAbsolute






{













*Cmd: “escape for moving cursor horizontally to an absolute position”











}














To configure and control a printer properly, the commands must be sent in the correct order. The ordering information has two parts: the job section name and the sequence number within a section.






<OrderEntry>*Order: <section>.<number>






GPD identifies six sections in a job stream. JOB_SETUP section is sent before anything is sent to the printer. It is sent only once per job right after the driver calls OpenJob. Note that printer settings that are controlled by commands in this section cannot be changed by ResetDC (a.k.a. within a job). DOC_SETUP section is sent at the beginning of the first page and the page following a ResetDC which can change printer settings within a job. Note that commands to be sent in the DOC_SETUP section must not cause the printer to reset and lose information such as the downloaded soft fonts and patterns. PAGE_SETUP section is sent at the beginning of every page before any drawing is done. PAGE_FINISH section is sent at the end of every page after all drawings are done. It is paired with PAGE_SETUP. DOC_FINISH section is sent when Unidrv5 gets the EndDoc call. It is paired with DOC_SETUP. JOB_FINISH section is sent right before calling EndJob. It is paired with JOB_SETUP.




Within a section, the commands are sent out in the increasing order of the sequence numbers. The numbers do not have to be consecutive, but they must be unique within a section. For example, on Canon BJC-600, the feature selection commands should be emitted in the order of InputBin, PaperSize, Resolution:




















*Feature: InputBin







{













*DefaultOption: Auto







*Option: Auto







{













*Name: “Auto Tray”







*Command: CmdSelect







{













*Order: DOC_SETUP.50







*Cmd: “<1B>(1<010014>”













}













}







. . .













}







*Feature: PaperSize







{













*DefaultOption: Letter







*Option: Letter







{













*Name: “Letter size”







*Command: CmdSelect







{













*Order: DOC_SETUP60







*Cmd: “<1B>(g<0300>n<01>r”













}













}







. . .













}







*Feature: Resolution







{













*DefaultOption: 360dpi







*Option: 360dpi







{













*Name: “360 dpi × 360dpi”







*Command: CmdSelect







{













*Order: DOC_SETUP.70







*Cmd: “<1B>(d<020001>”













}













}







. . .













}















Typically, the printer option selection commands are sent out intermixed with other printer configuration commands such as setting the copy count. A normal job stream would look like:




<JOB_SETUP commands>




<DOC_SETUP commands>




<PAGE_SETUP commands>




. . . page 1 data . . .




<PAGE_FINISH commands>




<PAGE_SETUP commands>




. . . page 2 data . . .




<PAGE_FINISH commands>




. . .




. . . more pages . . .




. . .




<DOC_FINISH commands>




<JOB_FINISH commands>




If ResetDC happens, say at the beginning of page 2, then the job stream would look like:




<JOB_SETUP commands>




<DOC_SETUP commands>




<PAGE_SETUP commands>




. . . page 1 data . . .




<PAGE_FINISH commands>




<DOC_FINISH commands>




<DOC_SETUP commands>




<PAGE_SETUP commands>




. . . page2 data . . .




<PAGE_FINISH commands>




. . .




. . .




<DOC_FINISH commands>




<JOB_FINISH commands>




The implications are that each section is self-contained in the sense that the above data stream structures will always configure the printer properly. A section can be null. When ResetDC happens, all commands in both DOC_FINSIH and DOC_SETUP sections are sent in the order specified. ResetDC can affect only the options that are changed by commands in DOC_SETUP section. In other words, if a ResetDC call changes the orientation but the orientation command is in JOB_SETUP section, then this ResetDC call has no effect. Essentially, the GPD file determines what can be changed by ResetDC.




One special category of commands that always require the ordering information is the printer configuration commands. They work together with the printer option selection commands to configure the printer. All of them are optional.
















Configuration







Command




Description











CmdStartJob




Initialize a job stream.






CmdStartDoc




Initialize a document.






CmdStartPage




Initialize a page for printing. This initialization







command should also set the printer's cursor posi-







tion to (0, 0) in cursor coordinates.






CmdEndPage




Finish a page after sending down all drawing objects






CmdEndDoc




Finish a document






CmdEndJob




Complete a job stream






CmdCopies




Set the count for multiple-copy printing






CmdSleepTimeOut




Set the number of minutes in idle mode before the







printer goes into sleep mode (i.e. power-save mode).














Take Canon BJC-600 for an example:

















*Command: CmdStartDoc






{













*Order: DOC_SETUP.10







*Cmd: “<1B>[K<0200000F1B>(a<0100011B>(c<030011>”











}














A GPD command string is a byte sequence which, when sent to the printer, performs a specific pre-defined function, such as selecting a paper size or positioning the print head. There is no restriction on the length of a command. It is basically a quoted string but with special provisions for specifying parameters. For example, an absolute-X-move command needs a parameter for specifying the target X position. A parameter must be specified outside of the pair of double quotes and is treated by the parser as a placeholder for one string segment (whose content will be determined when the command is actually emitted). I.e. all the string segments and parameter constructs are concatenated to form the InvocationString. At run-time, Unidrv5 evaluates the expressions defined in the parameter construct and emits the result in the specified format in place of the parameter construct.




The escape letter ‘%’ introduces a parameter segment. The letters immediately following ‘%’ specify the format of the parameter value. The following table lists the standard formats supported:




[digits]d: Parameter as signed ASCII decimal number.




[digits]D: Parameter as signed ASCII decimal number. + sign is printed if parameter is greater than 0.




C: Parameter as byte.




C: Parameter+‘0’ as byte.




f: Parameter as unsigned ASCII decimal number with the decimal point inserted before the second digit from right. For example, if the give value is 1225, the output should be “12.25”.




l: Parameter as word, LSB first




M: Parameter as word, MSB first.




Q: Qume hexadecimal ASCII number. (common on Toshiba/Qume devices)




G: 2*abs(Parameter)+is_negative(Parameter) as based 64 number, least significant digit to most significant digit. The most significant digit (0-63) is represented by the bytes 191-254. All other digits are represented by the bytes 63-126. “is_negative(Parameter)” is 1 if Parameter is negative, 0 otherwise.




N: Canon integer encoding. Outputs most significant byte to least significant byte encoding as follows. The least 4 significant bits are encoded as 001sbbbb, where s represents the sign of the integer (0 is negative, 1 is positive), and b represents a significant bit of the integer. The next most significant 6 bits are encoded as 01bbbbbb. So the integer 254 (11111110) would be represented as (01001111 00111110).




V: NEC VFU (Vertical Format Unit) encoding. The parameter specified by this format is divided by a ⅙ inch and VFU data will be sent to a printer same number of times as the quotient.




If a parameter value has limits (minimum and maximum), they can be expressed inside a pair of square brackets immediately following the format letters.




The parameter value is enclosed by a pair of curly brackets immediately following the limit specification (if any). There is a set of pre-defined values that GPD commands can reference at any time, such as the current resolution (xdpi, ydpi), the current paper width and height, etc. These values are expressed in the master units if applicable. A GPD command can use a restricted arithmetic expression (+, −, /, *, mod, max repeat, min, max) to express how to manipulate these values. All calculations are done in unsigned integers and intermediate results cannot overflow a DWORD (32-bit). Normally, if the result of evaluating the parameter expression is a value which exceeds the specified max limit, the command will be emitted once with the max specified value. The operator “max_repeat” modifies this behavior, causing the entire command invocation to be emitted repeatedly using the max allowed value until the accumulated value is equal to the evaluated value. Obviously, this is applicable only to single-parameter commands. Parenthesis can be used to impose precedence. Otherwise, it follows the C convention on the precedence of arithmetic operators. A parameter segment can cross line boundaries using the standard line continuation character ‘+’. Continuation linebreaks may only be inserted where whitespace is permitted. No whitespaces are permitted between the digits comprising an integer, the characters of a variable name, or other token like “max_repeat”.




The EBNF definition for a GPD command string is as follows (to avoid confusion, reserved letters are underlined and in bold, and reserved words are in bold).

















<SelectionCmd> ::= (<Segment> {<Segment>})






<Segment> ::=






 <QuotedStringSegment> | <Parameter> |


=


<ValueMacroName>






<QuotedStringSegment> ::=












{<readable ASCII character> | <hexSegment>}











<hexSegment> ::=


<


{<hexadecimals> | <WhiteSpaces>}


>








<hexadecimals> ::= {<HexDigit> <HexDigit>}






<HexDigit> ::=











0




|




1




|




2




|




3




|




4




|




5




|




6




|




7




|




8




|




9




|




A




|




B




|




C




|




D




|




E




|




F










<Parameter> ::= <Format>[<Limits>]<Value>






<Format> ::=











%




([<integer>]




d




| [<integer>]




D




|




c




|




C




|




l




|




m




|




q




|




g




|




n




|




v




)






<Limits> ::=


|


<Min>,<Max>


|








<Min> ::= <integer> |




*










<Max> ::= <integer> |




*










<Value> ::=


{


<Expression> |


max









repeat






(




<Expression>




)


}








<Expression> ::=















min






(




<Expression>




,




<Expression>




)




|









max






(




<Expression>




,




<Expression>




)




|











(




<Expression> <AddOperator> <Expression>




)




|











(




<Expression> <MulOperator> <Expression>




)




|







<integer> | <StdValues>











<AddOperator> ::=


+


|











<MulOperator> ::=




*




|




/




|


MOD
















Parenthesis are optional around expressions involving <Add or MulOperator>, if omitted the <MulOperators> will be evaluated before <AddOperators> left to right. Note that <Min> and <Max> are expressed in the unit that the actual parameter value is expressed in. When max_repeat is used, the command can have only one parameter. <StdValues> options are listed in the following table. They are of DWORD type unless specifically noted otherwise.

















Standard Variable Name




Description




Scope











NumOfDataBytes




number of data bytes




When the driver is sending








CmdSendBlockData or








CmdSendXXXData where XXX is








any of the 7 non-white primary








color. If there is compression, this is








the number of compressed data








bytes.






RasterDataWidthInBytes




the width of scanlines in bytes




When the driver is sending








CmdSendBlockData or








CmdSendXXXData where XXX is








any of the 7 non-white primary








color, or CmdSetSrcBmpWidth.








Compression has no impact.






RasterDataHeightInPixels




the height of the raster data block in




When the driver is sending







pixels.




CmdSendBlockData or








CmdSendXXXData where XXX is








any of the 7 non-white primary








color, or CmdSetSrcBmpHeight.






NumOfCopies




number of copies requested by the




When DrvEnablePDev and/or







user.




SETCOPYCOUNT escape is called.






PrintDirInCCDegrees




the requested rotation degrees




When the driver is sending







(counter-clockwise).




CmdSetSimpleRotation or








CmdSetAnyRotation command.






DestX




the destination X cursor position (in




When the driver is sending







master X unit) Relative to the cursor




CmdXMoveAbsolute or







origin X.




CmdYMoveAbsolute command.






DestY




the destination Y cursor position (in




Same as above.







master Y unit) Relative to the cursor







origin Y.






DestXRel




the destination X cursor position




When the driver is sending







relative to the current X cursor




CmdXMoveRelLeft or







position (in master X unit).




CmdXMoveRelRight command.






DestYRel




the desired Y cursor position relative




When the driver is sending







to the current Y cursor position (in




CmdYMoveRelUp or







master Y unit).




CmdYMoveRelDown command.






LinefeedSpacing




the amount of vertical spacing a




When the driver is sending







linefeed command (CmdLF) should




CmdSetLineSpacing command.







generate (in master Y unit).






RectXSize




the width of the rectangle in master X




When the driver is sending







unit.




CmdSetRectWidth command.






RectYSize




the height of the rectangle in master Y




When the driver is sending







unit.




CmdSetRectHeight command.






GrayPercentage




the gray level (in percentage) of the




When the driver is sending







rectangle.




CmdRectGrayFill command.






NextFontID




the unique number for the soft font to




When the driver is sending







be downloaded next.




CmdSetFontID command.






NextGlyph




the double-byte glyph code to be




When the driver is sending







down loaded next.




CmdSetCharCode command.






PhysPaperLength




the length of the physical paper in




When DrvEnablePDev is called.







master Y unit (in portrait orientation).






PhysPaperWidth




the width of the physical paper in




Same as above.







master X unit (in portrait orientation).






FontHeight




the height of the current device font in




When a font has been specified for a







the master Y unit.




text output call.






FontWidth




the width of the current device fixed-




Same as above.







pitch font in the master X unit.






FontIntLeading




the internal leading of the current




Same as above.







device font in the master Y unit.






FontBold




1 means the current device font is




Same as above.







bold and 0 means otherwise.






FontItalic




1 means the current device font is




Same as above.







italic and 0 means otherwise.






FontUnderline




1 means the current font style is




Same as above.







underlined and 0 means otherwise.






FontStrikeThru




1 means the current device font style




Same as above.







is strike-through and 0 means







otherwise






CurrentFontID




the downloading id of the current font




when a font has been specified for a








text output call and the font is a








downloaded font.






TextYRes




the current text Y resolution.




When the user has initiated a print








job.






TextXRes




the current text X resolution




Same as above.






GraphicsYRes




the current graphics Y resolution.




Same as above. (not implemented in








Beta 1)






GraphicsXRes




the current graphics X resolution.




Same as above. (not implemented in








Beta 1)






CursorOriginX




The X printing offset (in the current




When DrvEnablePDev is called.







orientation) in MasterUnits. The







printing offset is defined to be the







Imageable Origin - the Cursor Origin.






CursorOriginY




The Y printing offset.




When DrvEnablePDev is called.






Rop3




the current rop3 code




When the current DDI call supplies








the rop3 code.






RedValue




Red Value of the color for the palette




The scope of this variable is during







index being defined.




defining Palette using command








CmdDefinePaletteEntry.






GreenValue




Green Value of the Color.




Same as above.






BlueValue




Blue value of the color.




Same a above






PaletteIndexToProgram




The palette entry being programmed.




Same as above.






CurrentPaletteIndex




The index of the current palette entry




When the driver is sending







to be selected




CmdSelectPaletteEntry and any








other command which sets the








foreground brush color.






PatternBrushType




The type of pattern brush to be




When the driver is sending down a







downloaded. Predefined types:




pattern brush.







2 - Shading pattern







3 - Cross-hatch pattern







4 - User defined pattern






PatternBrushID




The ID of the downloaded pattern




When the driver selects a







brush.




downloaded pattern brush as the








current brush.






PatternBrushSize




The size in bytes of the pattern brush




When the driver is sending down a







to be downloaded.




pattern brush.














GPD has two types of macros: block macros and value macros. As their names imply, block macros are used to represent a sequence of GPD entries and constructs while value macros are used to represent all or parts of a value.




A block macro definition looks like a grouping construct:




















*BlockMacro: <BlockMacroName>







{







  <a sequence of entries and constructs>







}















A block macro can be referenced by the special *InsertBlock entry:






*InsertBlock: <BlockMacroNameRef>






Where <BlockMacroNameRef> is the <BlockMacroName> preceeded by the ‘equals’ character, without intervening whitespace. During GPD parsing, the above entry will be replaced, in place, by the body of the block macro definition without the curly brackets. For example, on HP LaserJet 5, all envelope paper sizes can not be used with the input bin Tray2 and Tray3, or in Duplex modes. A block macro can be defined to describe these common constraints and then use it in every envelope size option definition:

















*BlockMacro: PaperConstraints






{













*Constraints: InputBin.Tray2







*Constraints: InputBin.Tray3







*Constraints: Duplex











}






*Feature: PaperSize






{













. . .







*Option: Env10







{













*InsertBlock: =PaperConstraints







. . .













}







*Option: EnvMonarch







{













*InsertBlock: =PaperConstraints







. . .













}







*Option: EnvB5







{













*InsertBlock: =PaperConstraints







. . .













}







. . .











}














When the above Env


10


option definition is parsed, it is first expanded into:




















*Option: Env10







{













*Constraints: InputBin.Tray2







*Constraints: InputBin.Tray3







*Constraints: Duplex







. . .













}















Arbitrary white spaces are not allowed between the equals sign and the Macroname. If the definition of a block macro contains curly brackets, the brackets must appear in pairs and in the correct order of nesting. Block macro definitions may contain other Block macro or Value macro definitions (macros may be nested to arbitrary depth) and may reference other BlockMacros or ValueMacros.




A value macro definition is a simple <macroName>:<value> pair inside the special *Macros construct:




















*Macros: <GroupName>







{













ValueMacro1: <value>







ValueMacro2: <value>







. . .













}















A *Macros construct can contain any number of value macro definitions, and there can be multiple Macros constructs in a GPD file. The <GroupName> is optional and purely for better readability. The ValueMacro name is a <symbol type> and as such may not start with nor contain the ‘*’ character. Only ValueMacro definitions may appear within the *Macros construct.




The value portion of a value macro definition may consist of a combination of arbitrary character sequences <value fragments> and ValueMacro References. After all ValueMacro references (if any) are resolved, every value macro definition must itself represent a valid value type—for example an Integer, Quoted_String, Symbol, LIST etc. There are a few additional restrictions on the arbitrary character sequences. First, a <value fragment> may never contain the equals character since this introduces a ValueMacro reference. Second, if the Double Quote character appears within a <value fragment>, the entire sub string it introduces must also be present including the closing Double Quote. Finally, if the Percent character appears within a <value fragment> outside of a literal substring, the entire command parameter construct it introduces must also be present including the closing Curly Brace.




As with BlockMacro references, ValueMacro references are formed by prepending the equals character to the ValueMacro name. When the ValueMacro reference is resolved, this token is replaced by the fully resolved macro definition.




Here's an example featuring the HP LaserJet 4L printer:

















*Macros: HP4L






{













LetterCmdPrefix: “<1B>&12a8c1E<1B>*p0x0Y”







A4CmdPrefix: “<1B>&126a8c1E<1B>*p0x0Y”







Env10CmdPrefix: “<1B>&181a8c1E<1B>*p0x0Y”







Helvetica_ID: 23







Courier_ID: 24







. . .











}






*BlockMacro: PSOrder { *Order: DOC_SETUP.11 }






*DeviceFonts: LIST(=Helvetica_ID, =Courier_ID, . . .)






*Feature: PaperSize






{













*Name: “Paper Size”







*DefaultOption: Letter







*Option: Letter







{













*Name: “Letter 85 × 11 inch”







*PageProtectMem: 1028







*switch: Orientation














{




*case:Portrait








{













*Command: CmdSelect







{













*InsertBlock: =PSOrder







*Cmd: =LetterCmdPrefix “<1B>*c0t5760x7680Y”













}







*PrintableArea: PAIR(4800, 6324)







*PrintableOrigin: PAIR(150, 150)







*CursorOrigin: PAIR(150, 100)













}







*case:Landscape_CC90







{













*Command: CmdSelect







{













*InsertBlock: =PSOrder







*Cmd: =LetterCmdPrefix “<1B>*c0t7632x5880Y”













}







*PrintableArea: PAIR(4860, 6360)







*PrintableOrigin: PAIR(120, 120)












*CursorOrigin: PAIR(100, 6480)




}













}













}











}














The macros are provided for reducing text repetition in GPD files. For simplicity, no parameters are permitted for these macros. All macro references are resolved in a single pass using straightforward text substitution. Therefore, a macro must be defined before it can be referenced and a macro can not reference itself. All nested macro references are resolved at the time of parsing the macro definitions. If a macro is defined more than once, one definition lasts until it is overwritten by the next definition or its scope expires. A BlockMacro is considered defined when the closing curly brace of the *BlockMacro construct is parsed. At that time all macros defined within the BlockMacro are lost. The scope of a Macro definition is limited to the nesting level it was defined in. Macros defined within a nesting level can only be referenced within that nesting level (or levels contained within that nesting level). A macro defined at the Root level can be referenced throughout the GPD file. For example, if we have,

















*Macros: DefaultMargins






{













HWMargins: RECT(0,0,40,0)    *% definition #1











}






*Feature: PaperSize






{













*DefaultOption: Letter







*Option: Letter







{













*Name: “Letter 8½ × 11 inch”







*Margins: =HWMargins













}







*Option: A4







{













*Macros: DefaultMargins *% definition #2 for the same







value macro







{













HWMargins: RECT(0,0,50,0)













}







*Name: “A4 210 × 297 mm”







*Margins: =HWMargins













} *% this closing bracket un-defines the second definition.







*Option: Legal







{













*Name: “Legal 8½ × 14 inch”







*Margins: =HWMargins













}







. . .











}














The first definition (#1) is referenced by Letter and Legal options, and the second definition (#2) is used only by A4 option.




GPD defines a set of attributes and commands for describing how to compose the printer-ready output data. Attributes provide information about specific properties, such as where the cursor X is after sending a carriage return, or whether the printer can rotate raster graphics when printing in landscape orientation. Commands describe the specific printer escapes for a particular task, such as doing absolute X move, or sending a block of raster data to the printer. All commands are expressed via *Command construct or its short-hand representation if there is no command callback. There is no ordering information in any printing commands and Unidrv5 sends the appropriate commands when needed. It may cache certain settings (such as the current compression mode) to avoid repeatedly sending the same command.




For clarity, all command names start with Cmd prefix. All printing attributes appear at the root level unless there is dependency on printer configurations, in which case they are inside either the *case constructs or the appropriate *Option constructs (where their names must be preceded by EXTERN_GLOBAL: prefix).




GPD loosely divides all printing attributes and commands into four categories. First there is General Printing, which includes entries that affect all types of printing, such as cursor movements. Next is Raster Printing, which includes entries that are specific to raster graphics printing. Third is Text Printing, which includes entries that are specific to downloading fonts and device font printing.




The following defines the printing attributes and commands by category.




General Printing: Printer Capabilities

















Entry Name




Description




Comment











*RotateCoordinate?




Boolean, which describes whether the printer




Optional. If missing, assume







can rotate the coordinate system to fit the




FALSE, i.e. the printer cannot







logical orientation, i.e. whether it has




rotate the coordinate system to fit







command to set the logical orientation. Note




the logical orientation, such as all







that if the printer has both LANDSCAPE_90




dot-matrix printers.







and LANDSCAPE_270 orientations, then the







value of this entry applies to both landscape







orientations. It cannot appear inside







*switch/*case constructs.






*RotateRaster?




Boolean, which describes whether the printer




Optional. If missing, assume







can automatically rotate the raster data to fit




FALSE, such as for all dot-matrix







the logical orientation. If *RotateCoordinate?




printers.







entry is FALSE, this entry must be FALSE







too. Note that if the printer has both







LANDSCAPE_90 and LANDSCAPE_270







orientations, then the value of this entry







applies to both landscape orientations.






*TextCaps




LIST(TC_OP_CHARACTER,




Optional. If missing, assume empty







TC_OP_STROKE, TC_CP_STROKE,




list. Only 90-degree rotation is







TC_CR_90, , TC_CR_SF_X_YINDEP,




supported for device fonts.







TC_SA_DOUBLE, TC_SA_INTEGER,







TC_SA_CONTIN, TC_EA_DOUBLE,







TC_IA_ABLE, TC_UA_ABLE,







TC_SO_ABLE, TC_RA_ABLE,







TC_VA_ABLE), list of the printer's text







capabilities. These constants map directly to







the capability flags defined by Windows.






*RotateFont?




Boolean, which describes whether the printer




Optional. If missing, assume







can automatically rotate fonts to fit the logical




FALSE, such as for all dot-matrix







orientation. If *RotateCoordinate? entry is




printers.







FALSE, this entry must be FALSE too. Note







that if the printer has both LANDSCAPE_90







and LANDSCAPE_270 orientations, then the







value of this entry applies to both landscape







orientations. It cannot appear inside







*switch/*case constructs.






*ReselectFont




LIST(AFTER_GRXDATA,




Optional: if missing assume fonts







AFTER_XMOVE, AFTER_FF) this keyword




do not need to be reselected.







allows you to specify which operations







require the driver to reselect the current font.







AFTER_GRXDATA means the driver must







reselect the font after graphic data is emitted







using any of the CmdSendxxxData







commands. AFTER_XMOVE means the







font must be reselected after X movement







commmands. AFTER_FF means the font







must be reselected after CmdFF (formfeed).






*MemoryUsage




LIST(FONT, RASTER, VECTOR), which




Required if Memory feature is







lists what types of items consume printer




defined.







memory defined in the Memory feature. If a







listed type is not applicable, it is ignored. For







example, if LIST(FONT, RASTER,







VECTOR) is specified and the printer does







not support vector graphics, then it is







equivalent to LIST(FONT, RASTER).














General Printing: Cursor Control

















Entry Name




Description




Comment











*CursorXAfterCR




Constant




Optional. If missing, assume







(AT_PRINTABLE_X_ORIGIN, or




AT_CURSOR_X_ORIGIN, i.e., CmdCR







AT_CURSOR_X_ORIGIN), the




will move the cursor X to the physical 0







cursor X position after sending a




position.







carriage return.






*BadCursorMoveInGrxMode




LIST(X_PORTRAIT,




Optional. If missing, assume empty list,







X_LANDSCAPE, Y_PORTRAIT,




i.e no restriction.







Y_LANDSCAPE), the list of illegal







cursor movements in raster graphics







mode. For example, X_PORTRAIT







means X movement is not allowed in







raster mode at Portrait orientation.






*YMoveAttributes




LIST(FAVOR_LF,




Optional. If missing, assume empty list.







SEND_CR_FIRST), the list of







special attributes pertaining to Y-







move commands.






*UseSpaceForXMove?




Boolean, can space characters be




Optional. If missing, assume TRUE. If







used to perform X movements? If




TRUE the driver will use SPACES for







FALSE, only NULL characters are




coarse moves and NULLs for fine







used.




moves.






*MaxLineSpacing




Integer, the maximum line spacing




Optional. If missing, assume Infinite,







value (in master Y unit).




i.e. there is no limit.






*EjectPageWithFF?




Boolean, whether the printer uses




Optional. If missing, assume FALSE.







FormFeed to eject a page.






*XMoveThreshold




Integer (positive), the threshold (in X




Optional. If missing, assume 0







master unit) above which




threshold, i.e. CmdXMoveAbsolute is







CmdXMoveAbsolute is used instead




always used. The special value, *, can







ofCmdXMoveRelLeft or




be used to specify preference for relative







CmdXMoveRelRight. This is




X-move commands.







applicable only if both absolute and







relative X-move commands are







specified.






*YMoveThreshold




Same as above except substituting




Same as above except substituting “Y”







“Y” for “X”.




for “X”.






*XMoveUnit




Integer (positive). The unit is




Required if there is any X-move







expressed in dots per inch. For




commands (either absolute or relative).







example, if the printer's X-move unit







is 1/60”, then this entry should be 60.







Note that the X movement unit must







factor evenly into the master X unit.






*YMoveUnit




Same as above except substituting




Same as above except substituting “Y”







“Y” for “X”.




for “X”.






CmdXMoveAbsolute




Quoted string, the command to move




Optional. This command can have only







to an absolute X position.




one parameter which specifies the








movement amount.






CmdXMoveRelLeft




Quoted string, the command to move




Same as above.







left relative to the current cursor X







position.






CmdXMoveRelRight




Quoted string, the command to move




Same as above.







right relative to the current cursor X







position.






CmdYMoveAbsolute




Quoted string, the command to move




Same as above.







to an absolute Y position.






CmdYMoveRelUp




Quoted string, the command to move




Same as above.







up relative to the current cursor Y







position.






CmdYMoveRelDown




Quoted string, the command to move




Same as above.







down relative to the current cursor Y







position.






CmdSetLineSpacing




Quoted string, the command to set




Optional.







the distance of a line spacing







command.






CmdCR




Quoted string, the command to return




Required.







the cursor X to the leftmost position







(carriage-return).






CmdLF




Quoted string, the command to move




Required.







the cursor Y to the next line (line-







feed). The amount of movement is







determined by the current line







spacing value.






CmdFF




Quoted string, the command for




Required.







ejecting a page (form-feed).






CmdSetSimpleRotation




Quoted string, the command to set




Optional. This command can be







the rotation angle in multiples of 90




superseded by CmdSetAnyRotation if







degrees (counter-clockwise).




the printer supports arbitrary-degree








rotation.






CmdSetAnyRotation




Quoted string, the command to set




optional. If missing, assume the printer







the rotation angle in counter-




does not support arbitrary angle rotation







clockwise direction






CmdUniDirectionOn




Quoted string, the command to




Optional. If missing, always use the







enable uni-directional printing.




default printing mode.






CmdUniDirectionOff




Quoted string, the command to







disable uni-directional printing.






CmdPushCursor




Quoted string, the command to push




Optional.







the current cursor position onto the







stack for later retrieval.






CmdPopCursor




Quoted string, the command to pop




Optional.







the last cursor position on the stack







and restore it as the current cursor







position.






CmdBackSpace




Quoted string, the command to




Optional. This is used only for printing







backspace a single character width.




over-strike characters.







The printer must be able to move the







cursor back the width of the last







printed character with this command.














General Printing: Color

















Entry Name




Description




Comment











*EnableGDIColorMapping?




Boolean, shall GDI perform gamut




Optional. If missing, assume FALSE.







mapping from display to printer




This keyword sets the







colorspace? The printer colorspace is




HT_FLAG_DO_DEVCLR_XFORM







defined by the COLORINFO




flag in GDIINFO.







structure and some GPD keywords.






*ChangeColorModeOnPage?




Boolean, whether a color printer can




Optional. If missing, assume FALSE,







change the color mode (such as




i.e. the driver cannot change the color







monochrome vs. CMYK, or CMY




printing mode within a page. This is







vs. 24bpp) on a page without other




used to optimize printing speed.







side effects such as page ejection.






*ChangeColorModeOnDoc?




Boolean, whether a color printer can




Optional. If missing, assume TRUE.







change the color mode from one page







to another page within one document







without other side effects.






*MagentaInCyanDye




Integer (0-1000), ink impurity




Optional. If missing, assume −1 to







adjustment to specify magenta




utilize internal defaults. Specify value







contamination in cyan dye.




as 100 * percent contamination (i.e.








8.4% as 840).






*YellowInCyanDye




Integer (0-1000), ink impurity




Same as above.







adjustment to specify yellow







contamination in cyan dye.






*CyanInMagentaDye




Integer (0-1000), ink impurity




Same as above.







adjustment to specify cyan







contamination in magenta dye.






*YellowInMagentaDye




Integer (0-1000), ink impurity




Same as above.







adjustment to specify yellow







contamination in magenta dye.






*CyanInYellowDye




Integer (0-1000), ink impurity




Same as above.







adjustment to specify cyan







contamination in yellow dye.






*MagentaInYellowDye




Integer (0-1000), ink impurity




Same as above.







adjustment to specify magenta







contamination in yellow dye.






CmdSelectBlackColor




Quoted string, command to select




Optional. This set of 8 primary color







black color for the foreground. The




selection commands are used by planar







foreground color is used to print text




color printers (such as dot-matrix







and vector graphics (if available).




printers) and palette color printers








which does not support programmable








color palettes (such as early ink jet








printers).






CmdSelectRedColor




Quoted string, command to select red




Same as above.







color for the foreground.






CmdSelectGreenColor




Quoted string, command to select




Same as above.







green color for the foreground.






CmdSelectYellowColor




Quoted string, command to select




Same as above.







yellow color for the foreground.






CmdSelectBlueColor




Quoted string, command to select




Same as above.







blue color for the foreground.






CmdSelectMagentaColor




Quoted string, command to select




Same as above.







magenta color for the foreground.






CmdSelectCyanColor




Quoted string, command to select




Same as above.







cyan color for the foreground.






CmdSelectWhiteColor




Quoted string, command to select




Same as above.







white color for the foreground.






CmdBeginPaletteDef




Quoted string, the command to




Optional. For palette printing modes,







initialize color palette definition.




if this entry is missing, it means there is








no required initialization.








This set of palette commands are used








by color printers which supports








programmable palettes that can be used








for both the foreground (i.e. text and








vector graphics) and raster printing.






CmdEndPaletteDef




Quoted string, the command to finish




Optional. For palette printing modes,







color palette definition.




if it is missing, it means there is








nothing to be done.






CmdDefinePaletteEntry




Quoted string, the command to define




Optional, but required for palette







a color palette entry.




printing modes.






CmdSelectPaletteEntry




Quoted string, the command to select




Optional, but required for palette







a color palette entry as the current




printing modes.







color.






CmdSelectBlackBrush




Quoted string, the command to select




Required.







a solid black brush as the current







brush.






CmdSelectWhiteBrush




Quoted string, the command to select




Optional. For devices that supponts







a solid white brush as the current




white solid brush.







brush.






CmdDownloadPattern




Quoted string, the command to




Optional. If defined, CmdSelectPattern







download a pattern brush to the




must also be defined.







device.






CmdSelectPattern




Quoted string, the command to select




Optional. If defined,







a downloaded pattern brush as the




CmdDownloadPattern must also be







current brush.




defined.














General Printing: Overlay




Some printers support overlays (a.k.a. watermarks) which should be treated like fonts in the sense that it is a type of resources that can be downloaded once to the printer and then referenced many times. Only one overlay pattern can be selected at the beginning of each page. Here are the attributes and commands associated with printing overlays:

















Entry Name




Description




Comment











*MinOverlayID




integer, minimum id for




Optional. If missing, assume 1.







downloading an overlay pattern.






*MaxOverlayID




integer, maximum id for




Optional. If missing, assume no limit.







downloading an overlay pattern.






CmdOverlayRegStart




quoted string, command for




Optional. If missing, assume no support







starting the overlay registration.




for overlays.







Typically, it sets the overlay id.







The overlay pattern data are







downloaded next.






CmdOverlayRegEnd




quoted string, command for




Optional. If missing, assume no support







ending the overlay registration.




for overlays.







This is sent right after the overlay







pattern data.






CmdEnableOverlay




quoted string, command for




Optional. If missing, assume no support







selecting a downloaded overlay




for overlays.







pattern (typically via id). This







command should be sent at the







beginning of a page.






CmdDisableOverlay




quoted string, command for




Optional. If missing, assume no support







disabling the use of any overlay.




for overlays.







This command should be sent at







the beginning of a page.














Just like font installers, there should be an overlay manager which provides the user interface to create, locate and install overlay pattern files. The driver would copy the content of this file after sending the command CmdSetOverlayID.




Raster Printing: Data Compression




Unidrv5 assumes that the printer's raster data compression mode can be turned on or off independently of other raster commands, such as CmdSendBlockData. The current compression method is part of the printer's global state information. It is also assumed that once a compression method is selected, it remains in effective until another method is selected or the compression is disabled.




Unidrv5 supports a set of standard raster data compression algorithms. They preferably include TIFF4.0 and Delta-Row Compression (DRC) as defined in HP/PCL reference manual as well as Far East run length encoding (FERLE). These methods as well as OEM supplied compression can be intermixed on a per scanline basis. The GPD allows OEM's to define custom compression algorithms via the OEMCompression callback. At most one custom compression method can be specified per printer configuration. When a custom method is used, Unidrv5 would utilize the OEMCompression callback to compress the raster data and then compare it against the compressed size of any other active compression mode and use the most efficient method.

















Entry Name




Description




Comments











CmdEnableTIFF4




Quoted string, command to select




Optional. If missing, Unidrv5 will not







TIFF4.0 raster data compression.




attempt TIFF4.0 compression.






CmdEnableDRC




Quoted string, command to select




Optional. If missing, Unidrv5 will not







delta-row raster data compression.




attempt DRC. If both TIFF4 and DRC








commands are listed, Unidrv5 will








choose the optimal compression on per








scanline basis.






CmdEnableFE_RLE




Quoted string, command to select FE-




Optional. If missing, Unidrv5 will not







RLE raster data compression.




use FE-RLE compression.






CmdEnableOEMComp




Quoted string, command to select an




Optional. Note that it does not make







OEM defined raster data compression




sense for this command to co-exist with







algorithm.




the standard TIFF4 or DRC command








for any printer configuration.






CmdDisableCompression




Quoted string, command to disable any




Optional.







raster data compression, including both







standard and custom methods.














When CmdEnableOEMComp is specified, Unidrv5 expects the OEM DLL to provide the following callback function:




DWORD OEMCompression(




PBYTE pInBuf, //pointer to the input buffer containing the original raster data




PBYTE pOutBuf, //pointer to the output buffer for the compressed data




DWORD dwInLen, //the length of the input data to compress




DWORD dwOutLen, //the size of the output buffer (in bytes)




)




The return value is the length of the compressed data in bytes. This function should return zero if the output buffer is not big enough to hold the compressed data. Typically, Unidrv5 would start with an output buffer the same size as the input buffer. If the return value is greater than the input buffer size, Unidrv5 would issue the command CmdDisableCompression and send the uncompressed data. When there are multiple compression methods specified (treating no-compression as a special compression method), the most compressed method is used on per scanline/block basis.




On some FE printers, the compression selection is mingled with sending data. In that case, only one compression method can be used. The compression selection should be hardcoded in CmdSendBlockData or other similar data emission commands. The corresponding compression selection command should be an empty quoted string. There should be no *CmdDisableCompression entry because there is no way to turn off compression.




Raster Printing: Raster Data Emission

















Entry Name




Description




Comments











*OutputDataFormat




Constant(H_BYTE or V_BYTE), the




Optional. If missing, assume







output data direction, i.e. whether the




H_BYTE. For example, all page







bits in a data byte are mapped to




printers use H_BYTE format.







horizontal pixels or vertical pixels.






*OptimizeLeftBound?




Boolean, whether to remove blanks at




Optional. If missing, assume no







the left bound of a band.




optimization.






*StripBlanks




LIST(LEADING, ENCLOSED,




Optional. If missing, assume empty







TRAILING), the ways to strip blanks




list, i.e. no blank stripping. Note







in a raster data block.




that if any compression (such as








TIFF4) is specified, it's usually more








efficient not to request stripping








enclosed blanks.






*RasterSendAllData?




Boolean, whether the driver should




Optional. If missing, Unidrv5







send all color plane raster data




assumes FALSE.







regardless of blank scanlines or blanks







within a scanline.






*MirrorRasterByte?




Boolean, whether the driver mirrors a




Optional. If missing, Unidrv5







raster image per 8 bits.




assumes FALSE.






*CursorXAfterSendBlockData




Constant (AT_GRXDATA_END,




Optional. If missing, assume







AT_GRXDATA_ORIGIN, or




AT_GRXDATA_END, i.e. the







AT_CURSOR_X_ORIGIN), the




cursor X moves to the pixel after the







cursor X position after sending a block




last pixel of the graphics block.







of raster graphics data.






*CursorYAfterSendBlockData




Constant (NO_MOVE,




optional. If missing, assume







AUTO_INCREMENT), the cursor Y




NO_MOVE, i.e. the cursor Y stays







position after sending a block of raster




at the original position.







data.






*UseExpColorSelectCmd?




Boolean, whether color selection




Optional. If missing, assume







commands are separate from the




FALSE. For all dot-matrix printers,







commands to send color raster data.




this field is TRUE.






*MoveToX0BeforeSetColor?




Boolean, whether moving to the




Optional. If missing, assume







physical X=0 before sending the




FALSE. This field makes sense only







explicit color selection command.




if*UseExpColorSelectCmd? is








TRUE.






CmdBeginRaster




Quoted string, the command to




optional. If missing, it implies that







initialize raster data transfer.




no initialization is needed.






CmdEndRaster




Quoted string, the command to finish




optional. If missing, it means there is







raster data transfer. It is used in pairs




nothing to be done when raster data







with *CmdBeginRaster




transfer is completed.






CmdSetDestBmpWidth




Quoted string, command to set the




Applicable only to printers which can







destination bitmap width.




scale raster graphics.






CmdSetDestBmpHeight




Quoted string, command to set the




Same as above.







destination bitmap height.






CmdSetSrcBmpWidth




Quoted string, command to set the




Same as above.







source bitmap width






CmdSetSrcBmpHeight




Quoted string, command to set the




Same as above.







source bitmap height.






CmdSendBlockData




Quoted string, the command to send




Required unless the printer type is







one block of data to the printer. One




TTY (text only).







block of data fills one physical pass of







the print head. For V_BYTE type







printers, one block has







*PinsPerPhysPass number of







scanlines. For H_BYTE type printers,







one block has *PinsPerLogPass







number of scanlines.






CmdEndBlockData




Quoted string, the command to end




Optional. If missing, assume NULL.







sending one block of data to the







printer. This command is sent after the







raster data. This is used on some dot-







matrix printers.






*SendMultipleRows?




Boolean, whether CmdSendBlockData




Optional. If missing, assume







can send multiple blocks in one shot.




FALSE.







This is used only by H_BYTE type







printers.






CmdSendRedData




Quoted string, the command to send




Required if planar color printing is







red plane data.




used.






CmdSendGreenData




Quoted string, the command to send




Same as above.







green plane data.






CmdSendBlueData




Quoted string, the command to send




Same as above.







blue plane data.






CmdSendCyanData




Quoted string, the command to send




Same as above.







cyan plane data.






CmdSendMagentaData




Quoted string, the command to send




Same as above.







magenta plane data.






CmdSendYellowData




Quoted string, the command to send




Same as above.







yellow plane data.






CmdSendBlackData




Quoted string, the command to send




Same as above.







black plane data.














Text Printing: Device Fonts

















Entry Name




Description




Comments











*DefaultFont




Integer, the Windows RC_FONT




Required, if the printer supports any







resource id of the default font.




device fonts.






*MaxFontUsePerPage




Integer, the limit on the number of fonts




Optional. If missing, assume no limit.







(resident or downloaded) that the printer







can use on a page.






*DefaultCTT




Integer, the Windows RC_CTT resource




Optional. If missing, assume 0, i.e. no







id of the default character translation




translation.







table. This entry is provided only for







backward compatibility with GPC.






*LookaAheadRegion




Integer, the number of pixels (in master




Optional. If missing, assume 0.







Y unit) that the driver needs to look







ahead when determining whether it







should emit text. This is applicable only







to serial printers, inkjet printers in







particular.






*TextYOffset




Integer, the Y distance (in master Y




Optional. If missing, assume 0.







unit) by which to reposition printer-







resident fonts in order to align correctly







with baselines of bitmap fonts. This is







used on some dot-matrix printers.






*CharPosition




Constant (UPPERLEFT, BASELINE),




Optional. If missing, assume







where the print head should be




UPPERLEFT, i.e. Unidrv5 would







positioned before printing a character.




position the print head at the upper left








corner of the character bounding box








before printing it.














Text Printing: Font Downloading

















Entry Name




Description




Comments











*MinFontID




<integer>, the minimum id for soft




Optional. If missing, assume 1.







fonts.






*MaxFontID




<integer>, the maximum id for soft




Optional. If missing, assume 65535.







fonts.






*MaxNumDownFonts




Integer, the maximum number of




Optional. If missing, assume no limit.







downloaded soft fonts that can be







stored on the printer at any time.






*DLSymbolSet




Constant(PC_8, ROMAN_8), the




Optional. If missing, assume the glyph id







symbol set to be used when




range is contiguous as specified by







downloading TrueType fonts.




*MinGlyphID and *MaxGlyphID.






*MinGlyphID




<integer>, the minimum id for




Optional. If missing, assume 32 if







downloaded font glyphs.




*DLSymbolSet is missing. Ignored if








DLSymbolSet is defined.






*MaxGlyphID




<integer>, the maximum id for




Optional. If missing, assume 255 if







downloaded font glyphs.




*DLSymbolSet is missing. Ignored if








DLSymbolSet is defined.






CmdSetFontID




Quoted string, the command to set the




Optional. If missing, assume that there is







current font id.




no font downloading support on the








printer.






CmdDeselectFontID




Quoted string, the command to




Optional, If missing assume that the







deselect a font id, i.e. make that font




current font need not be deselected when







inactive.




selecting a new font.






CmdSelectFontID




Quoted string, the command to select a




Optional. If missing, assume that there is







font id, i.e. make that font active.




no font downloading support on the








printer.






CmdSetCharCode




Quoted string, the command to set the




Same as above CmdSetFontID,







current character code whose data will




CmdSelectFontID and CmdSetCharCode







be sent immediately after.




are bounded as a group, i.e. they must all








exist or none at all.






CmdSelectFontHeight




Quoted string, the command to select




Optional, If missing assume that printer







font height.




does not support scaleable, downloadable








True Type outline fonts. This command








is needed for HPPCL_OUTLINE format.






CmdSelectFontWidth




Quoted string, the command to select




Optional, If missing assume that width of







font Width.




downloaded font is scaled proportionally








to the font height.






*FontFormat




Constant (HPPCL, HPPCL_RES,




Required if the printer supports font







HPPCL_OUTLINE,




downloading. If OEM_CALLBACK is







OEM_CALLBACK), the font




specified, the corresponding callback







downloading format.




functions must be provided in the OEM








extension dll.






CmdDeleteFont




Quoted string, the command to delete




Optional. If this entry is specified,







a temporary soft font by id.




Unidrv5 assumes that when a font is








deleted, its memory can be reclaimed








immediately. Otherwise, this entry should








not be defined.














Font Printing: Font Simulation

















Entry Name




Description




Comments











CmdSetFontSim




Quoted string, the command to set




Optional. If present, Unidrv5 assumes







italic/bold/underline/strike-through




that the printer cannot remember any







simulation in one shot.




attribute state information and must be








set each time a font is used.






CmdClearAllFontAttribs




Quoted string, one command that will




If the printer supports Bold, Italic or







set all Bold, Italic and Underline




Underlining, but does not support the







attributes OFF.




commands to turn individual attributes








off, this command may be defined in








place of the individual commands








CmdBoldOff, CmdItalicOff,








CmdUnderlineOff.






CmdBoldOn




Quoted string, the command to set bold




Optional. If present, Unidrv5 assumes







attribute ON.




that the printer can set bold attribute








independently and that once it is set, it








remains effective until the opposite








command (i.e. CmdBoldOff) is sent








to change the state.






CmdBoldOff




Quoted string, the command to set bold




Optional, but it must be paired with







attribute OFF.




CmdBoldOn command.






CmdItalicOn




Quoted string, the command to set




Similar to CmdBoldOn.







italic attribute ON.






CmdItalicOff




Quoted string, the command to set




Similar to CmdBoldOff.







italic attribute OFF.






CmdUnderlineOn




Quoted string, the command to set




Similar to CmdBoldOn.







underline attribute ON.






CmdUnderlineOff




Quoted string, the command to set




Similar to CmdBoldOff.







underline attribute OFF.






CmdStrikeThruOn




Quoted string, the command to set




Similar to CmdBoldOn.







strike-through attribute ON.






CmdStrikeThruOff




Quoted string, the command to set




Similar to CmdBoldOff.







strike-through attribute OFF.






CmdWhiteTextOn




Quoted string, the command to enable




Optional. This is for backward







white text printing.




compatibility with GPC 3.0.






CmdWhiteTextOff




Quoted string, the command to disable




Optional, but it must be paired with







white text printing.




CmdWhiteTextOff.






CmdSelectSingleByteMode




Quoted string, the command to select




Optional. If missing, assume there is







single-byte printing mode. This is used




no mode switching for text printing.







on FE printers.






CmdSelectDoubleByteMode




Quoted string, the command to select




Optional, but it must be paired with







double-byte printing mode. This is




CmdSelectSingleByteMode.







used on FE printers.






*DiffFontsPerByteMode?




Boolean, whether the single-byte mode




Optional. If missing, assume FALSE.







and the double-byte mode maintain







separate states regarding the current







font and current font simulation







attributes.






CmdVerticalPrintingOn




Quoted string, the command to enable




Optional. If missing, assume that the







vertical printing mode. This is used on




vertical printing is not supported on







FE printers.




the printer.






CmdVerticalPrintingOff




Quoted string, the command to disable




Optional, but it must be paired with







vertical printing mode. This is used on




CmdVerticalPrintingOff.







FE printers






CmdBoldOff




Quoted string, the command to set bold




Optional, but it must be paired with







attribute OFF.




CmdBoldOn command.






CmdItalicOn




Quoted string, the command to set




Similar to CmdBoldOn.







italic attribute ON.






CmdItalicOff




Quoted string, the command to set




Similar to CmdBoldOff.







italic attribute OFF.






CmdUnderlineOn




Quoted string, the command to set




Similar to CmdBoldOn.







underline attribute ON.






CmdUnderlineOff




Quoted string, the command to set




Similar to CmdBoldOff.







underline attribute OFF.






CmdStrikeThruOn




Quoted string, the command to set




Similar to CmdBoldOn.







strike-through attribute ON.






CmdStrikeThruOff




Quoted string, the command to set




Similar to CmdBoldOff.







strike-through attribute OFF.






CmdWhiteTextOn




Quoted string, the command to enable




Optional. This is for backward







white text printing.




compatibility with GPC 3.0






CmdWhiteTextOff




Quoted string, the command to disable




Optional, but it must be paired with







white text printing.




CmdWhiteTextOff.






CmdSelectSingleByteMode




Quoted string, the command to select




Optional. If missing, assume there is







single-byte printing mode. This is used




no mode switching for text printing.







on FE printers.






CmdSelectDoubleByteMode




Quoted string, the command to select




Optional, but it must be paired with







double-byte printing mode. This is




CmdSelectSingleByteMode.







used on FE printers.






*DiffFontsPerByteMode?




Boolean, whether the single-byte mode




Optional. If missing, assume FALSE.







and the double-byte mode maintain







separate states regarding the current







font and current font simulation







attributes.






CmdVerticalPrintingOn




Quoted string, the command to enable




Optional. If missing, assume that the







vertical printing mode. This is used on




vertical printing is not supported on







FE printers.




the printer.






CmdVerticalPrintingOff




Quoted string, the command to disable




Optional, but it must be paired with







vertical printing mode. This is used on




CmdverticalPrintingOff.







FE printers.














Numerous modifications and alternative embodiments of the invention will be apparent to those skilled in the art in view of the foregoing description. Accordingly, this description is to be construed as illustrative only and is for the purpose of teaching those skilled in the art the best mode for carrying out the invention. Details of the structure and implementation of the various components described above can be varied substantially without departing from the spirit of the invention, and exclusive use of all modifications that come within the scope of the appended claims is reserved.



Claims
  • 1. A computer system for outputting data to an output device, comprising:an application program for invoking a plurality of graphics device interface functions to control the sending of data to the output device; a graphics device interface for invoking a plurality of device driver functions for controlling the outputting of data in response to the invocation of the plurality of graphics device interface functions; a text based minidriver containing a text based characterization of the output device, the text based characterization containing an implementation of device specific device driver functions invoked by the graphic device interface, the text based minidriver including means for outputting the text based characterization; and a modular universal driver which incorporates the text based characterization passed by the text based minidriver, the modular universal driver implementing the device specific driver functions to control the outputting of data to the output device in accordance with the incorporated text based characterization.
  • 2. The computer system of claim 1, wherein the modular universal driver provides a standard user interface for user selection and control of device specific driver functions, wherein the text based minidriver provides output device specific user interface information relating to device specific device driver functions, and wherein the universal driver incorporates the output device specific user interface information in the standard user interface provided thereby.
  • 3. The computer system of claim 1, wherein the output device specific user interface information contains information for generating a separate user interface page, and wherein the universal driver adds the separate user interface page to the standard user interface provided thereby.
  • 4. The computer system of claim 1, wherein the modular universal driver provides a standard user interface for user selection and control of device specific driver functions, and wherein the text based minidriver provides output device specific user interface information relating to device specific device driver functions, and wherein the universal driver replaces the standard user interface with a device specific user interface generated from the output device specific user interface information.
  • 5. A computer system for outputting data to an output device, comprising:an application program for invoking a plurality of graphics device interface functions to control the sending of data to the output device; a graphics device interface for invoking a plurality of device driver functions for controlling the outputting of data in response to the invocation of the plurality of graphics device interface functions; a text based minidriver containing a text based characterization of the output device, the text based characterization containing an implementation of device specific device driver functions invoked by the graphic device interface, the text based minidriver including means for outputting the text based characterization; a modular universal driver which incorporates the text based characterization passed by the text based minidriver, the modular universal driver implementing the device specific driver functions to control the outputting of data to the output device in accordance with the incorporated text based characterization; and wherein the text based minidriver contains at least one installable device specific device driver function, and wherein the text based minidriver provides output device specific user interface information relating to installed device specific device driver functions, and wherein the universal driver utilizes the information relating to installed device specific device driver functions to display only installed device specific device driver functions on the user interface.
  • 6. The computer system of claim 1, wherein the text based minidriver further includes at least one function rendering module for implementing certain device specific driver functions to control the outputting of data to the output device, and wherein the modular universal driver allows the function rendering module to control the outputting of data to the output device for the certain device specific driver functions.
  • 7. The computer system of claim 1, wherein the text based minidriver further includes at least one function rendering module, and wherein the modular universal driver incorporates the function rendering module to modify the implementation of certain device specific driver functions to control the outputting of data to the output device.
  • 8. The computer system of claim 1, wherein the text based minidriver further includes a function rendering module, and wherein the modular universal driver incorporates the function rendering module to replace the implementation of the device specific driver functions provided by the universal driver to control the outputting of data to the output device.
  • 9. The computer system of claim 1, wherein the text based characterization includes dependencies between certain device specific device driver functions.
  • 10. The computer system of claim 1, wherein the text based characterization includes constraints on certain device specific device driver functions.
  • 11. A computer-readable medium having computer-executable modules comprising:a minidriver rendering module containing a text based characterization of an output device, the text based characterization containing an implementation of device specific device driver functions invoked by a graphic device interface; and a unidriver rendering module for implementing the device specific driver functions to control the outputting of data to the output device in accordance with the text based characterization.
  • 12. The computer-readable medium of claim 11, wherein the minidriver rendering module contains data for implementing certain device specific driver functions to control the outputting of data to the output device, and wherein the unidriver rendering module allows the minidriver rendering module to control the outputting of data to the output device for the certain device specific driver functions.
  • 13. The computer-readable medium of claim 11, wherein the minidriver rendering module contains data for implementing certain device specific driver functions to control the outputting of data to the output device, and wherein the unidriver rendering module incorporates the data from the minidriver rendering module to modify the implementation of certain device specific driver functions to control the outputting of data to the output device.
  • 14. The computer-readable medium of claim 11, wherein the minidriver rendering module contains data for implementing device specific driver functions to control the outputting of data to the output device, and wherein the unidriver rendering module incorporates the function rendering module to replace the implementation of the device specific driver functions provided by the unidriver rendering module to control the outputting of data to the output device.
  • 15. The computer-readable medium of claim 11, further comprising:a minidriver user interface module for providing output device specific user interface information relating to device specific device driver functions; and a unidriver user interface module for providing a standard user interface for user selection and control of device specific driver functions, the unidriver user interface module incorporating the output device specific user interface information in the standard user interface provided thereby.
  • 16. The computer-readable medium of claim 15, wherein the output device specific user interface information contains information for generating a separate user interface page, and wherein the unidriver user interface module adds the separate user interface page to the standard user interface provided thereby.
  • 17. The computer-readable medium of claim 11, further comprising:a minidriver user interface module for providing output device specific user interface information relating to device specific device driver functions; and a unidriver user interface module for providing a standard user interface for user selection and control of device specific driver functions, the unidriver user interface module replacing the standard user interface with the output device specific user interface information provided by the minidriver user interface module.
  • 18. A method of characterizing a printer device to allow its inclusion in a computer system having an application program which invokes graphic device interface functions to control the outputting of printable data, and an universal driver for implementing device specific functions based on characterization information for the particular printer device, the device specific functions controlling the outputting of data in accordance with the characterization information to allow proper printing and control of the printer device, the method comprising the steps of:opening a text editor; creating a text based minidriver using the text editor, the text based minidriver containing a text based characterization of the printer device, the text based characterization containing an implementation of printer device specific device driver functions invoked by the graphic device interface, the text based minidriver including means for outputting the text based characterization to the universal driver; and installing the text based minidriver.
  • 19. The method of claim 18, wherein the step of creating a text based minidriver comprises the steps of:creating a text based rendering module including implementations of printer device specific device driver functions; and creating a text based user interface module including output device specific user interface information relating to printer device specific device driver functions.
  • 20. A method of modifying a printer minidriver characterizing a printer device to allow its inclusion in a computer system having an application program which invokes graphic device interface functions to control the outputting of printable data, and an universal driver for implementing device specific functions based on characterization information for the particular printer device provided by the minidriver, the device specific functions controlling the outputting of data in accordance with the characterization information to allow proper printing and control of the printer device, the method comprising the steps of:opening the minidriver in a text editor; modifying the minidriver; saving the minidriver in the text editor; and installing the minidriver.
  • 21. The method of claim 20, wherein the step of modifying the minidriver comprises the step of adding a new feature to the printer characterization.
  • 22. The method of claim 20, wherein the step of modifying the minidriver comprises the step of specifying a dependency between printer settings.
US Referenced Citations (2)
Number Name Date Kind
5604843 Shaw et al. Feb 1997 A
5619635 Millman et al. Apr 1997 A
Non-Patent Literature Citations (1)
Entry
The Unicode Standard Version 2.0, The Unicode Consortium, Addison-Wesley Press, 1997.