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.
713 lines
16 KiB
713 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1990-2003 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
readgpc.c
|
|
|
|
|
|
Abstract:
|
|
|
|
This module contain functions to read the PLOTGPC data file
|
|
|
|
|
|
|
|
Development History:
|
|
|
|
15-Nov-1993 Mon 10:00:01 created
|
|
|
|
|
|
[Environment:]
|
|
|
|
GDI Device Driver - Plotter.
|
|
|
|
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
extern DEVHTINFO DefDevHTInfo;
|
|
|
|
|
|
|
|
BOOL
|
|
ValidateFormSrc(
|
|
PGPCVARSIZE pFormGPC,
|
|
SIZEL DeviceSize,
|
|
BOOL DevRollFeed
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function validate if FORMSRC has valid filed in it
|
|
|
|
Arguments:
|
|
|
|
pFormGPC - pointer to the GPCVARSIZE for the form data.
|
|
|
|
DeviceSize - Device size to check against,
|
|
|
|
DevRollFeed - TRUE if device can do roll feed
|
|
|
|
|
|
Return Value:
|
|
|
|
BOOL return value, the fields already verified and corrected.
|
|
|
|
|
|
|
|
Development History:
|
|
|
|
15-Nov-1993 Mon 10:34:29 created
|
|
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PFORMSRC pFS;
|
|
LONG cy;
|
|
UINT Count;
|
|
BOOL InvalidFS;
|
|
BOOL Ok = TRUE;
|
|
|
|
|
|
|
|
pFS = (PFORMSRC)pFormGPC->pData;
|
|
Count = (UINT)pFormGPC->Count;
|
|
|
|
while (Count--) {
|
|
|
|
InvalidFS = FALSE;
|
|
|
|
//
|
|
// Make sure that imageable area is less or eqaul to the size
|
|
//
|
|
|
|
if (pFS->Size.cy) {
|
|
|
|
if (pFS->Size.cy < MIN_PLOTGPC_FORM_CY) {
|
|
|
|
//
|
|
// Make it as variable length paper
|
|
//
|
|
|
|
PLOTERR(("Invalid Form CY, make it as variable length (%ld)",
|
|
pFS->Size.cy));
|
|
|
|
pFS->Size.cy = 0;
|
|
}
|
|
}
|
|
|
|
if (!(cy = pFS->Size.cy)) {
|
|
|
|
cy = DeviceSize.cy;
|
|
}
|
|
|
|
if (((pFS->Size.cx <= DeviceSize.cx) &&
|
|
(pFS->Size.cy <= cy)) ||
|
|
((pFS->Size.cy <= DeviceSize.cx) &&
|
|
(pFS->Size.cx <= cy))) {
|
|
|
|
NULL;
|
|
|
|
} else {
|
|
|
|
PLOTERR(("Invalid Form Size, too big for device to handle"));
|
|
InvalidFS = TRUE;
|
|
}
|
|
|
|
if ((pFS->Size.cy) &&
|
|
((pFS->Size.cy - pFS->Margin.top - pFS->Margin.bottom) <
|
|
MIN_PLOTGPC_FORM_CY)) {
|
|
|
|
PLOTERR(("Invalid Form CY or top/bottom margins"));
|
|
|
|
InvalidFS = TRUE;
|
|
}
|
|
|
|
if ((pFS->Size.cx < MIN_PLOTGPC_FORM_CX) ||
|
|
((pFS->Size.cx - pFS->Margin.left - pFS->Margin.right) <
|
|
MIN_PLOTGPC_FORM_CX)) {
|
|
|
|
PLOTERR(("Invalid Form CX or left/right margins"));
|
|
|
|
InvalidFS = TRUE;
|
|
}
|
|
|
|
if ((!DevRollFeed) && (pFS->Size.cy == 0)) {
|
|
|
|
InvalidFS = TRUE;
|
|
PLOTERR(("The device cannot handle roll paper %hs", pFS->Name));
|
|
}
|
|
|
|
|
|
if (InvalidFS) {
|
|
|
|
PLOTERR(("ValidateFormSrc: invalid form data, (removed it)"));
|
|
|
|
Ok = FALSE;
|
|
|
|
if (Count) {
|
|
|
|
CopyMemory(pFS, pFS + 1, sizeof(FORMSRC));
|
|
}
|
|
|
|
pFormGPC->Count -= 1;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Make sure ansi ascii end with a NULL
|
|
//
|
|
|
|
pFS->Name[sizeof(pFS->Name) - 1] = '\0';
|
|
|
|
++pFS;
|
|
}
|
|
}
|
|
|
|
if (!pFormGPC->Count) {
|
|
|
|
PLOTERR(("ValidateFormSrc: NO form are valid, count = 0"));
|
|
|
|
ZeroMemory(pFormGPC, sizeof(GPCVARSIZE));
|
|
}
|
|
|
|
return(Ok);
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD
|
|
PickDefaultHTPatSize(
|
|
WORD xDPI,
|
|
WORD yDPI,
|
|
BOOL HTFormat8BPP
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function return default halftone pattern size used for a particular
|
|
device resolution
|
|
|
|
Arguments:
|
|
|
|
xDPI - Device LOGPIXELS X
|
|
|
|
yDPI - Device LOGPIXELS Y
|
|
|
|
8BitHalftone - If a 8-bit halftone will be used
|
|
|
|
|
|
Return Value:
|
|
|
|
DWORD HT_PATSIZE_xxxx
|
|
|
|
|
|
|
|
Development History:
|
|
|
|
29-Jun-1993 Tue 14:46:49 created
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD HTPatSize;
|
|
|
|
//
|
|
// use the smaller resolution as the pattern guide
|
|
//
|
|
|
|
if (xDPI > yDPI) {
|
|
|
|
xDPI = yDPI;
|
|
}
|
|
|
|
if (xDPI >= 2400) {
|
|
|
|
HTPatSize = HT_PATSIZE_16x16_M;
|
|
|
|
} else if (xDPI >= 1800) {
|
|
|
|
HTPatSize = HT_PATSIZE_14x14_M;
|
|
|
|
} else if (xDPI >= 1200) {
|
|
|
|
HTPatSize = HT_PATSIZE_12x12_M;
|
|
|
|
} else if (xDPI >= 900) {
|
|
|
|
HTPatSize = HT_PATSIZE_10x10_M;
|
|
|
|
} else if (xDPI >= 400) {
|
|
|
|
HTPatSize = HT_PATSIZE_8x8_M;
|
|
|
|
} else if (xDPI >= 180) {
|
|
|
|
HTPatSize = HT_PATSIZE_6x6_M;
|
|
|
|
} else {
|
|
|
|
HTPatSize = HT_PATSIZE_4x4_M;
|
|
}
|
|
|
|
if (HTFormat8BPP) {
|
|
|
|
HTPatSize -= 2;
|
|
}
|
|
|
|
return(HTPatSize);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
ValidatePlotGPC(
|
|
PPLOTGPC pPlotGPC
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function validate a PLOTGPC data structure
|
|
|
|
|
|
Arguments:
|
|
|
|
pPlotGPC
|
|
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
|
|
|
|
Development History:
|
|
|
|
15-Feb-1994 Tue 22:49:40 updated
|
|
Update the pen plotter validation for the bitmap font and color
|
|
|
|
15-Nov-1993 Mon 10:11:58 created
|
|
|
|
|
|
Revision History:
|
|
|
|
02-Apr-1995 Sun 11:23:46 updated
|
|
Update the COLORINFO checking so it will make to NT3.51's default
|
|
and not compute the devpels on the spot.
|
|
|
|
--*/
|
|
|
|
{
|
|
if ((pPlotGPC->ID != PLOTGPC_ID) ||
|
|
(pPlotGPC->cjThis != sizeof(PLOTGPC))) {
|
|
|
|
PLOTERR(("ValidatePlotGPC: invalid PLOTGPC data (ID/Size)"));
|
|
return(FALSE);
|
|
}
|
|
|
|
pPlotGPC->DeviceName[sizeof(pPlotGPC->DeviceName) - 1] = '\0';
|
|
pPlotGPC->Flags &= PLOTF_ALL_FLAGS;
|
|
|
|
//
|
|
// Validate device size and its margin
|
|
//
|
|
|
|
if (pPlotGPC->DeviceSize.cx - (pPlotGPC->DeviceMargin.left +
|
|
pPlotGPC->DeviceMargin.right) < MIN_PLOTGPC_FORM_CX) {
|
|
|
|
PLOTERR(("Invalid Device CX (%ld) set to default",
|
|
pPlotGPC->DeviceSize.cx));
|
|
|
|
pPlotGPC->DeviceSize.cx = pPlotGPC->DeviceMargin.left +
|
|
pPlotGPC->DeviceMargin.right +
|
|
MIN_PLOTGPC_FORM_CX;
|
|
}
|
|
|
|
if (pPlotGPC->DeviceSize.cy < MIN_PLOTGPC_FORM_CY) {
|
|
|
|
PLOTERR(("Invalid Device CY (%ld) default to 50' long",
|
|
pPlotGPC->DeviceSize.cx));
|
|
|
|
pPlotGPC->DeviceSize.cy = 15240000;
|
|
}
|
|
|
|
if (pPlotGPC->DeviceSize.cy - (pPlotGPC->DeviceMargin.top +
|
|
pPlotGPC->DeviceMargin.bottom) < MIN_PLOTGPC_FORM_CY) {
|
|
|
|
PLOTERR(("Invalid Device CY (%ld) set to default",
|
|
pPlotGPC->DeviceSize.cy));
|
|
|
|
pPlotGPC->DeviceSize.cx = pPlotGPC->DeviceMargin.top +
|
|
pPlotGPC->DeviceMargin.bottom +
|
|
MIN_PLOTGPC_FORM_CY;
|
|
}
|
|
|
|
//
|
|
// For now we must have 1:1 ratio
|
|
//
|
|
|
|
if (pPlotGPC->PlotXDPI != pPlotGPC->PlotYDPI) {
|
|
|
|
pPlotGPC->PlotYDPI = pPlotGPC->PlotXDPI;
|
|
}
|
|
|
|
if (pPlotGPC->RasterXDPI != pPlotGPC->RasterYDPI) {
|
|
|
|
pPlotGPC->RasterYDPI = pPlotGPC->RasterXDPI;
|
|
}
|
|
|
|
if (pPlotGPC->ROPLevel > ROP_LEVEL_MAX) {
|
|
|
|
pPlotGPC->ROPLevel = ROP_LEVEL_MAX;
|
|
}
|
|
|
|
if (pPlotGPC->MaxScale > MAX_SCALE_MAX) {
|
|
|
|
pPlotGPC->MaxScale = MAX_SCALE_MAX;
|
|
}
|
|
|
|
if ((!(pPlotGPC->Flags & PLOTF_RASTER)) &&
|
|
(pPlotGPC->MaxPens > MAX_PENPLOTTER_PENS)) {
|
|
|
|
pPlotGPC->MaxPens = MAX_PENPLOTTER_PENS;
|
|
}
|
|
|
|
if (pPlotGPC->MaxPolygonPts < 3) { // minimum 3 points to make up a
|
|
// region
|
|
pPlotGPC->MaxPolygonPts = 0;
|
|
}
|
|
|
|
if (pPlotGPC->MaxQuality > MAX_QUALITY_MAX) {
|
|
|
|
pPlotGPC->MaxQuality = MAX_QUALITY_MAX;
|
|
}
|
|
|
|
if (pPlotGPC->Flags & PLOTF_PAPERTRAY) {
|
|
|
|
if ((pPlotGPC->PaperTraySize.cx != pPlotGPC->DeviceSize.cx) &&
|
|
(pPlotGPC->PaperTraySize.cy != pPlotGPC->DeviceSize.cx)) {
|
|
|
|
PLOTERR(("Invalid PaperTraySize (%ld x %ld), Make it as DeviceSize",
|
|
pPlotGPC->PaperTraySize.cx,
|
|
pPlotGPC->PaperTraySize.cy));
|
|
|
|
pPlotGPC->PaperTraySize.cx = pPlotGPC->DeviceSize.cx;
|
|
pPlotGPC->PaperTraySize.cy = pPlotGPC->DeviceSize.cy;
|
|
}
|
|
|
|
} else {
|
|
|
|
pPlotGPC->PaperTraySize.cx =
|
|
pPlotGPC->PaperTraySize.cy = 0;
|
|
}
|
|
|
|
if (!pPlotGPC->ci.Cyan.Y) {
|
|
|
|
//
|
|
// This is NT3.51 default
|
|
//
|
|
|
|
pPlotGPC->ci = DefDevHTInfo.ColorInfo;
|
|
pPlotGPC->DevicePelsDPI = 0;
|
|
|
|
} else if ((pPlotGPC->DevicePelsDPI < 30) ||
|
|
(pPlotGPC->DevicePelsDPI > pPlotGPC->RasterXDPI)) {
|
|
|
|
pPlotGPC->DevicePelsDPI = 0;
|
|
}
|
|
|
|
if (pPlotGPC->HTPatternSize > HT_PATSIZE_16x16_M) {
|
|
|
|
pPlotGPC->HTPatternSize = PickDefaultHTPatSize(pPlotGPC->RasterXDPI,
|
|
pPlotGPC->RasterYDPI,
|
|
FALSE);
|
|
}
|
|
|
|
if ((pPlotGPC->InitString.Count != 1) ||
|
|
(!pPlotGPC->InitString.SizeEach) ||
|
|
(!pPlotGPC->InitString.pData)) {
|
|
|
|
ZeroMemory(&(pPlotGPC->InitString), sizeof(GPCVARSIZE));
|
|
}
|
|
|
|
if ((pPlotGPC->Forms.Count) &&
|
|
(pPlotGPC->Forms.SizeEach == sizeof(FORMSRC)) &&
|
|
(pPlotGPC->Forms.pData)) {
|
|
|
|
ValidateFormSrc(&(pPlotGPC->Forms),
|
|
pPlotGPC->DeviceSize,
|
|
(pPlotGPC->Flags & PLOTF_ROLLFEED));
|
|
|
|
} else {
|
|
|
|
ZeroMemory(&(pPlotGPC->Forms), sizeof(GPCVARSIZE));
|
|
}
|
|
|
|
if (!(pPlotGPC->Flags & PLOTF_RASTER)) {
|
|
|
|
//
|
|
// PEN PLOTTER MUST COLOR and NO_BMP_FONT
|
|
//
|
|
|
|
pPlotGPC->Flags |= (PLOTF_NO_BMP_FONT | PLOTF_COLOR);
|
|
}
|
|
|
|
if ((!(pPlotGPC->Flags & PLOTF_RASTER)) &&
|
|
(pPlotGPC->Pens.Count) &&
|
|
(pPlotGPC->Pens.SizeEach == sizeof(PENDATA)) &&
|
|
(pPlotGPC->Pens.pData)) {
|
|
|
|
UINT i;
|
|
PPENDATA pPD;
|
|
|
|
|
|
pPD = (PPENDATA)pPlotGPC->Pens.pData;
|
|
|
|
for (i = 0; i < (UINT)pPlotGPC->MaxPens; i++, pPD++) {
|
|
|
|
if (pPD->ColorIdx > PC_IDX_LAST) {
|
|
|
|
PLOTERR(("Invalid ColorIndex (%ld), set to default",
|
|
pPD->ColorIdx));
|
|
|
|
pPD->ColorIdx = PC_IDX_FIRST;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
ZeroMemory(&(pPlotGPC->Pens), sizeof(GPCVARSIZE));
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
VOID
|
|
CopyPlotGPCFromPCD(
|
|
PPLOTGPC pPlotGPC,
|
|
PPLOTGPC_PCD pPlotGPC_PCD
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function copies a PLOTGPC_PCD structure into a PLOTGPC structure.
|
|
|
|
Arguments:
|
|
|
|
pPlotGPC - destination
|
|
pPlotGPC_PCD - source
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
|
|
Development History:
|
|
|
|
1 Feb 2000
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
{
|
|
// All the datatypes upto InitString are the same in both the structures.
|
|
CopyMemory(pPlotGPC,
|
|
pPlotGPC_PCD,
|
|
(LPBYTE)&(pPlotGPC_PCD->InitString) - (LPBYTE)pPlotGPC_PCD);
|
|
|
|
// We replace sizeof(PLOTGPC_PCD) with sizeof(PLOTGPC)
|
|
pPlotGPC->cjThis = sizeof(PLOTGPC);
|
|
|
|
pPlotGPC->InitString.Count = pPlotGPC_PCD->InitString.Count;
|
|
pPlotGPC->InitString.SizeEach = pPlotGPC_PCD->InitString.SizeEach;
|
|
if (pPlotGPC_PCD->InitString.pData) {
|
|
pPlotGPC->InitString.pData = (LPVOID)(pPlotGPC_PCD->InitString.pData
|
|
+ (sizeof(PLOTGPC) - sizeof(PLOTGPC_PCD)));
|
|
} else {
|
|
pPlotGPC->InitString.pData = NULL;
|
|
}
|
|
|
|
pPlotGPC->Forms.Count = pPlotGPC_PCD->Forms.Count;
|
|
pPlotGPC->Forms.SizeEach = pPlotGPC_PCD->Forms.SizeEach;
|
|
if (pPlotGPC_PCD->Forms.pData) {
|
|
pPlotGPC->Forms.pData = (LPVOID)(pPlotGPC_PCD->Forms.pData
|
|
+ (sizeof(PLOTGPC) - sizeof(PLOTGPC_PCD)));
|
|
} else {
|
|
pPlotGPC->Forms.pData = NULL;
|
|
}
|
|
|
|
pPlotGPC->Pens.Count = pPlotGPC_PCD->Pens.Count;
|
|
pPlotGPC->Pens.SizeEach = pPlotGPC_PCD->Pens.SizeEach;
|
|
if (pPlotGPC_PCD->Pens.pData) {
|
|
pPlotGPC->Pens.pData = (LPVOID)(pPlotGPC_PCD->Pens.pData
|
|
+ (sizeof(PLOTGPC) - sizeof(PLOTGPC_PCD)));
|
|
} else {
|
|
pPlotGPC->Pens.pData = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
PPLOTGPC
|
|
ReadPlotGPCFromFile(
|
|
PWSTR pwsDataFile
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function open/read the PlotGPC data file and validate them also
|
|
|
|
|
|
Arguments:
|
|
|
|
pwsDataFile - a pointer to full qualify path for the data file name
|
|
|
|
Return Value:
|
|
|
|
BOOL - to indicate state
|
|
|
|
|
|
|
|
Development History:
|
|
|
|
15-Nov-1993 Mon 10:01:17 created
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
HANDLE hFile;
|
|
DWORD dwSize;
|
|
PLOTGPC_PCD PlotGPC_PCD;
|
|
BOOL bSuccess = TRUE;
|
|
PPLOTGPC pPlotGPC = NULL;
|
|
|
|
if ((hFile = OpenPlotFile(pwsDataFile)) == (HANDLE)INVALID_HANDLE_VALUE) {
|
|
|
|
PLOTERR(("ReadPlotGPCFromFile: Open data file failed"));
|
|
return(NULL);
|
|
}
|
|
|
|
if ((ReadPlotFile(hFile, &PlotGPC_PCD, sizeof(PLOTGPC_PCD), &dwSize)) &&
|
|
(dwSize == sizeof(PLOTGPC_PCD))) {
|
|
|
|
if ((PlotGPC_PCD.ID != PLOTGPC_ID) ||
|
|
(PlotGPC_PCD.cjThis != sizeof(PLOTGPC_PCD))) {
|
|
|
|
bSuccess = FALSE;
|
|
PLOTERR(("ReadPlotGPCFromFile: invalid data file"));
|
|
}
|
|
|
|
} else {
|
|
|
|
bSuccess = FALSE;
|
|
PLOTERR(("ReadPlotGPCFromFile: Read data file failed"));
|
|
}
|
|
|
|
//
|
|
// if we have pPlotGPC_PCD == NULL then an error ocurred
|
|
//
|
|
|
|
if (bSuccess) {
|
|
|
|
dwSize = PlotGPC_PCD.SizeExtra + sizeof(PLOTGPC);
|
|
|
|
if (pPlotGPC = (PPLOTGPC)LocalAlloc(LPTR, dwSize)) {
|
|
|
|
CopyPlotGPCFromPCD(pPlotGPC, &PlotGPC_PCD);
|
|
|
|
if ((PlotGPC_PCD.SizeExtra) &&
|
|
(ReadPlotFile(hFile,
|
|
(LPBYTE)pPlotGPC + sizeof(PLOTGPC),
|
|
PlotGPC_PCD.SizeExtra,
|
|
&dwSize)) &&
|
|
(dwSize == PlotGPC_PCD.SizeExtra)) {
|
|
|
|
if ((pPlotGPC->InitString.Count == 1) &&
|
|
(pPlotGPC->InitString.SizeEach) &&
|
|
(pPlotGPC->InitString.pData)) {
|
|
|
|
(LPBYTE)pPlotGPC->InitString.pData += (ULONG_PTR)pPlotGPC;
|
|
|
|
} else {
|
|
|
|
ZeroMemory(&(pPlotGPC->InitString), sizeof(GPCVARSIZE));
|
|
}
|
|
|
|
if ((pPlotGPC->Forms.Count) &&
|
|
(pPlotGPC->Forms.SizeEach == sizeof(FORMSRC)) &&
|
|
(pPlotGPC->Forms.pData)) {
|
|
|
|
(LPBYTE)pPlotGPC->Forms.pData += (ULONG_PTR)pPlotGPC;
|
|
|
|
} else {
|
|
|
|
ZeroMemory(&(pPlotGPC->Forms), sizeof(GPCVARSIZE));
|
|
}
|
|
|
|
if ((pPlotGPC->Pens.Count) &&
|
|
(pPlotGPC->Pens.SizeEach == sizeof(PENDATA)) &&
|
|
(pPlotGPC->Pens.pData)) {
|
|
|
|
(LPBYTE)pPlotGPC->Pens.pData += (ULONG_PTR)pPlotGPC;
|
|
|
|
} else {
|
|
|
|
ZeroMemory(&(pPlotGPC->Pens), sizeof(GPCVARSIZE));
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// Failed to read, free the memory and return NULL
|
|
//
|
|
|
|
LocalFree((HLOCAL)pPlotGPC);
|
|
pPlotGPC = NULL;
|
|
|
|
PLOTERR(("ReadPlotGPCFromFile: read variable size data failed"));
|
|
}
|
|
|
|
} else {
|
|
|
|
PLOTERR(("ReadPlotGPCFromFile: allocate memory (%lu bytes) failed",
|
|
dwSize));
|
|
}
|
|
}
|
|
|
|
ClosePlotFile(hFile);
|
|
|
|
if (pPlotGPC) {
|
|
|
|
ValidatePlotGPC(pPlotGPC);
|
|
}
|
|
|
|
return(pPlotGPC);
|
|
}
|