GDI begins with a handle to a device context (hDC) to try to find a matching ICC color profile. GDI opens the ICM\prtr key in the registry (for a discussion of the registry, see a later section) to enumerate all of the printer manufacturers that have currently installed profiles. GDI must next obtain the 4-byte manufacturer identifier and 4-byte model identifier from the printer driver by using one of the two methods listed below. Windows 95 device driver developers are encouraged to support the new DeviceCapabilities indices used by the second method given below.
If the driver does not return the manufacturer and model identifier to the DeviceCapabilities call, GDI constructs these from the (unfriendly) printer name (for example, the default printer name listed in the INF or the original dmDeviceName member of the DEVMODE structure, which the user may later change to a friendly name). The first four letters become the manufacturer identifier (that is, the icHeader.manufacturer tag). Spaces and hyphens are converted to spaces, and spaces are used to fill in afterward, if necessary. For example, "HP LaserJet" is read as "HP L" (0x48 0x50 0x32 0x4C), which is then converted to "HP " (0x48 0x50 0x32 0x32).
A CRC is applied to the whole name to get the model identifier (that is, the. icHeader.model tag). The CRC is given by the algorithm described at the end of this paper (which is actually the same algorithm used to construct parallel attached Plug and Play identifier values).
If the driver does return the manufacturer and model to the DeviceCapabilities call, GDI simply takes those values and then proceeds, following these steps:
1. Selecting the Manufacturer and Model registry keys to use.
Using the manufacturer and model identifiers for the driver, GDI attempts to open the manufacturer key and then the model key as a subkey of the manufacturer key. If these keys do not exist, the substitution lists described in the following section are searched next. If there are no substitutions for the manufacturer/model pair, there is no match and GDI fails to find the color profile required to perform image color matching.
2. Selecting the best profile defined for the current printer driver settings and the selected Manufacturer and Model registry keys.
GDI looks in the current DEVMODE structure for the hDC and uses the dmMediaType member value to open the associated key as a subkey of the model key. If the key does not exist, GDI calls the RegEnumKey function to find any media type and opens the first key enumerated. Note that in this scenario, where insufficient information is given to provide the optimally desired match, the decision to arbitrarily choose the first media type listed (which is purely installation-order dependent) is the only available option given the lack of any "gracefully failing" mapping schemes.
GDI looks in the DEVMODE structure next for the dmDitherType member and tries to open the associated key as a subkey of the media key. If the key does not exist, GDI calls the RegEnumKey function to find any dither type and opens the first key enumerated. GDI then looks in the DEVMODE structure for the dmPrintQuality and dmYResolution members and tries to open the associated key as a subkey of the dither key. If the key does not exist, GDI calls the RegEnumKey function to find any resolution and opens the first key enumerated. At this point, GDI is at the level of the registry hierarchy where profiles names are stored. GDI first looks for the "default" value; if that value does not exist, it starts looking for values of the form profile00 to profile99. GDI uses the first profile it finds.
The logic of the two steps described above is shown with the following pseudocode.
// search for appropriate manufacturer/model key in registry from which to get // identity of color profile to use if driver doesn't provides identifiers from new DeviceCapabilities call then get identifiers via checksum algorithm if manufacturer/model registry key and driver manufacturer/model match then break; if GDI substitution list match found then locate manufacturer/model key for substitute driver break; if registry substitution list match found then locate manufacturer/model key for substitute driver break; end; // no ICM possible because no appropriate // manufacturer/model key found end if end if end if // use hDC to read current configuration values from DEVMODE structure for the // printer driver and search prtr subkey branch of the found manufacturer/model // key for color profile that matches that current configuration. // example prtr subkey branch looks like this: // \prtr\EPSO\788D\107\ErrorDiffusion\00360x00360\profile00=epsonsty.icm \HP \7645\MediaUnknown\DitherUnknown\ResolutionUnknown\profile00=hp.icm if DEVMODE.dmMediaType value matches a value in a media subkey then look at dither subkeys on that branch else call EnumRegType to enumerate media types and look at dither subkeys on branch of first media type found end if if DEVMODE.dmDitherType value matches a value in a dither subkey then look at the resolution subkeys in that branch else call EnumRegType to enumerate dither types and look at resolution subkeys on branch of first dither type found end if if DEVMODE.dmPrintQuality and DEVNODE.dmYResolution values match a subkey then look at color profile identifier subkeys in that branch else call EnumRegType to enumerate resolution types and look at color profile identifier subkeys on branch of first resolution found end if // at this point, one or more color profile identifier keys are being looked at if key is DEFAULT then use value of that key as the color profile identifier else // keys are of form PROFILEnn, where nn = 00, 01, ... 99 use value of key with smallest "nn" (use 00 in preference to 01, etc.) as the color profile identifier end if