Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

410 lines
9.2 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
forms.c
Abstract:
Functions for manipulating forms
Environment:
PCL-XL driver, user and kernel mode
Revision History:
11/07/95 -davidx-
Created it.
mm/dd/yy -author-
description
--*/
#include "xllib.h"
BOOL
ValidDevmodeForm(
HANDLE hPrinter,
PDEVMODE pdm,
PFORM_INFO_1 pFormInfo,
PWSTR pFormName
)
/*++
Routine Description:
Validate the form specification in a devmode
Arguments:
hPrinter - Handle to the printer object
pdm - Pointer to the input devmode
pFormInfo - Pointer to a FORM_INFO_1 structure for returning
information about the logical form specified by the input devmode
pFormName - Buffer to storing form name and pFormInfo->pName is set to
this upon successful return
Return Value:
TRUE if the input devmode specifies a valid logical form
FALSE otherwise
--*/
{
PFORM_INFO_1 pForm, pFormDB;
DWORD cForms;
Assert(pFormInfo != NULL && pFormName != NULL);
//
// Get a list of forms in the system
//
if (! (pForm = pFormDB = GetFormsDatabase(hPrinter, &cForms))) {
Error(("Couldn't get system forms\n"));
return FALSE;
}
if (CustomDevmodeForm(pdm)) {
LONG width, height;
//
// Devmode is specifying a custom form whose width
// and height are measured in 0.1mm. Convert the unit to micron.
//
width = pdm->dmPaperWidth * 100;
height = pdm->dmPaperLength * 100;
//
// Go through the forms database and check if
// one of the forms has the same size as what's
// being requested. The tolerance is 1mm.
//
while ((cForms != 0) &&
(abs(width - pForm->Size.cx) > FORMSIZE_TOLERANCE ||
abs(height - pForm->Size.cy) > FORMSIZE_TOLERANCE))
{
cForms--;
pForm++;
}
//
// Custom size doesn't match that of any defined forms
//
if (cForms == 0) {
pFormInfo->Flags = 0;
pFormInfo->Size.cx = width;
pFormInfo->Size.cy = height;
pFormInfo->ImageableArea.left =
pFormInfo->ImageableArea.top = 0;
pFormInfo->ImageableArea.right = width;
pFormInfo->ImageableArea.bottom = height;
pFormInfo->pName = pFormName;
pFormName[0] = NUL;
MemFree(pFormDB);
return TRUE;
}
} else if (pdm->dmFields & DM_PAPERSIZE && pdm->dmPaperSize >= DMPAPER_FIRST) {
//
// Devmode is specifying a form using paper size index.
//
DWORD index = pdm->dmPaperSize - DMPAPER_FIRST;
if (index < cForms)
pForm = pFormDB + index;
} else if (pdm->dmFields & DM_FORMNAME) {
//
// Devmode is specifying a form using form name. Go through the forms database
// and check if the requested form name matches that of a form in the database.
//
while (cForms && wcscmp(pForm->pName, pdm->dmFormName) != EQUAL_STRING)
cForms--, pForm++;
if (cForms == 0)
pForm = NULL;
}
//
// If devmode is specifying a valid logical form, then return the form information
// in the provided buffer. Also update the devmode fields.
//
if (pForm != NULL) {
*pFormInfo = *pForm;
CopyStringW(pFormName, pForm->pName, CCHFORMNAME);
pFormInfo->pName = pFormName;
//
// Convert paper size unit from microns to 0.1mm
//
pdm->dmPaperWidth = pForm->Size.cx / 100;
pdm->dmPaperLength = pForm->Size.cy / 100;
pdm->dmPaperSize = (SHORT) (pForm - pFormDB);
pdm->dmFields |= DM_FORMNAME;
CopyStringW(pdm->dmFormName, pForm->pName, CCHFORMNAME);
}
MemFree(pFormDB);
return pForm != NULL;
}
BOOL
MapToPrinterForm(
PMPD pmpd,
PFORM_INFO_1 pFormInfo,
PPRINTERFORM pPrinterForm,
BOOL bStringent
)
/*++
Routine Description:
Map a logical form to a printer paper size
Arguments:
pmpd - Pointer to printer description data
pFormInfo - Pointer to logical form information
pPrinterForm - Pointer to a buffer for returning printer form information
bStringent - Whether to use more stringent criteria
Return Value:
TRUE if the logical form is supported on the printer
FALSE otherwise
--*/
{
LONG width, height;
WORD selection;
PFEATURE pFeature;
PPAPERSIZE pPaperSize, pNext;
width = pFormInfo->Size.cx;
height = pFormInfo->Size.cy;
//
// First check if the logical form name matches the name of a printer form.
//
Assert(pFormInfo->pName != NULL);
pFeature = MpdPaperSizes(pmpd);
Assert(pFeature->size == sizeof(PAPERSIZE));
pPaperSize = FindNamedSelection(pFeature, pFormInfo->pName, &selection);
if (pPaperSize == NULL && (!bStringent || IsUserDefinedForm(pFormInfo))) {
LONG dx, dy, minxy;
WORD index;
//
// There is no name match. Try to find out if there is a
// printer form whose size matches that of the logical form.
//
minxy = MAX_LONG;
for (index=0; index < pFeature->count; index++) {
pNext = FindIndexedSelection(pFeature, index);
//
// Compare the current size with the desired size.
//
dx = pNext->size.cx - width;
dy = pNext->size.cy - height;
//
// Check if we have an exact size match. Tolerance is 1mm.
//
if (abs(dx) <= FORMSIZE_TOLERANCE && abs(dy) <= FORMSIZE_TOLERANCE) {
selection = index;
pPaperSize = pNext;
break;
}
//
// Not an exact match, see if we could fit on this form.
//
if (dx >= 0 && dy >= 0) {
//
// Check to see if the current form is smaller than
// the smallest one we've found so far.
//
if (dx+dy < minxy) {
//
// Tentatively remember it as the smallest size.
//
selection = index;
pPaperSize = pNext;
minxy = dx + dy;
}
}
}
//
// If there is no exact size match and the printer supports
// custom paper size and the requested size is not too big,
// then go ahead and select custom paper size on the printer.
//
if (index == pFeature->count && SupportCustomSize(pmpd, width, height)) {
if (pPrinterForm) {
pPrinterForm->name[0] = NUL;
pPrinterForm->size = pFormInfo->Size;
pPrinterForm->imageableArea = pFormInfo->ImageableArea;
pPrinterForm->selection = SELIDX_ANY;
}
return TRUE;
}
}
//
// If the logical form is mapped to a printer paper size, then
// return information about the printer paper size to the caller
//
if (pPaperSize && pPrinterForm) {
pPrinterForm->imageableArea = pPaperSize->imageableArea;
RectIntersect(&pPrinterForm->imageableArea, &pFormInfo->ImageableArea);
pPrinterForm->size = pPaperSize->size;
pPrinterForm->selection = selection;
CopyStringW(pPrinterForm->name, pPaperSize->pName, CCHFORMNAME);
}
return (pPaperSize != NULL);
}
PFORM_INFO_1
GetFormsDatabase(
HANDLE hPrinter,
PDWORD pCount
)
/*++
Routine Description:
Return a collection of forms in the spooler database
Arguments:
hPrinter - Handle to a printer object
pCount - Points to a variable for returning total number of forms
Return Value:
Pointer to an array of FORM_INFO_1 structures if successful
NULL otherwise
--*/
{
PFORM_INFO_1 pFormDB = NULL;
DWORD cbNeeded;
if (!EnumForms(hPrinter, 1, NULL, 0, &cbNeeded, pCount) &&
GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
(pFormDB = MemAlloc(cbNeeded)) != NULL &&
EnumForms(hPrinter, 1, (PBYTE) pFormDB, cbNeeded, &cbNeeded, pCount))
{
return pFormDB;
}
MemFree(pFormDB);
return NULL;
}
VOID
FilterFormsDatabase(
PFORM_INFO_1 pFormDB,
DWORD cForms,
PMPD pmpd
)
/*++
Routine Description:
Determine which system forms are supported on the given printer
Arguments:
pFormDB - Points to a list of forms in the system
cForms - Number of forms
pmpd - Points to printer description data
Return Value:
NONE
--*/
{
PRINTERFORM printerForm;
while (cForms--) {
//
// Make sure the highest order bits are not used by the spooler
//
Assert(!IsSupportedForm(pFormDB));
if (MapToPrinterForm(pmpd, pFormDB, &printerForm, TRUE)) {
SetSupportedFormIndex(pFormDB, printerForm.selection);
}
pFormDB++;
}
}