|
|
/*++
Copyright (c) 1990-2003 Microsoft Corporation
Module Name:
plotgpc.c
Abstract:
This module contains the function to generate plotter gpc data for NT 1.0a This module contains the functions required to generate a plotter gpc data file.
Development History:
15-Feb-1994 Tue 22:50:10 updated Add bitmap font caps
09-Nov-1993 Tue 09:23:48 created
18-Mar-1994 Fri 14:00:14 updated Adding PLOTF_RTL_NO_DPI_XY, PLOTF_RTLMONO_NO_CID and PLOTF_RTLMONO_FIXPAL flags
[Environment:]
GDI Device Driver - PLOTTER
[Notes:]
Revision History:
--*/
#if 0
; ; Plotter GPC data file format ; ; 1. All key value(s) for the keyword must be encloses by a {} brace pair. ; 2. Any Strings must be enclosed by quotes (""). ; 3. a ';' denotes a comment to the end of the current line. ; 4. Types ; a. FLAG - 1 or 0 ; b. WORD - 16 bit number ; c. DWORD - 32 bit number ; d. STRING - ANSI character string, maximum size depends on keyword ; e. FORMSRC - 1. 31 byte string for the name of the form (paper source) ; 2. 2 DWORDs: size width/height (SIZEL) 1/1000mm ; ** if height is <= 25400 (1 inch) or it greater ; then DeviceSize CY then it is assumed that ; the form is variable length and the height ; will be reset to zero (0) ; ; 3. 4 DWORDs: Left/Top/Right/Bottom margins in 1/1000mm ; ; f. CONSTANT - Pick from a set of predefined strings in the header file ; g. COLORINFO - Windows 2000, Windows XP and Windows Server 2003 DDI COLORINFO data structure (30 DWORDs) ; h. PENDATA - 1. One word that specifies the location in the carousel ; of this pen (1=slot 1, 2=slot 2). ; 2. constant which specifies the predefined pen color ; PC_IDX_xxxx can be one of: ; ; Index R G B ; ------------------------------ ; PC_IDX_WHITE 255 255 255 ; PC_IDX_BLACK 0 0 0 ; PC_IDX_RED 255 0 0 ; PC_IDX_GREEN 0 255 0 ; PC_IDX_YELLOW 255 255 0 ; PC_IDX_BLUE 0 0 255 ; PC_IDX_MAGENTA 255 0 255 ; PC_IDX_CYAN 0 255 255 ; PC_IDX_ORANGE 255 128 0 ; PC_IDX_BROWN 255 192 0 ; PC_IDX_VIOLET 128 0 255 ; ; i. ROPLEVEL - One of following levels: ; ; ROP_LEVEL_0 - No Rop support ; ROP_LEVEL_1 - ROP1 support (SRC) ; ROP_LEVEL_2 - ROP2 support (SRC/DEST) ; ROP_LEVEL_3 - ROP3 support (SRC/DEST/PAT) ; ; *** if DeviceSize' height is <= 25400 (1 inch) then it is assumed that the ; device can handle variable length paper and the height will be reset to ; zero (0) ; ; *** RasterDPI must be defined for both raster and pen plotters. For raster ; plotters this should be the raster resolution of the device. For pen ; plotters it should be the ideal resolution for the device that GDI ; will report back to the calling windows application. ; ; Keyword Type Count Range/Size ; ------------------------------------------------------------------------- ; DeviceName STRING 31 Device name as it appears in UI's ; DeviceSize DWORD 2 Device cx/cy in 1/1000mm ; DeviceMargin DWORD 4 Device L/T/R/B margin in 1/1000mm ; RasterCap Flag 1 0/1 (1=Raster Device, 2=Pen Device) ; ColorCap Flag 1 0/1 (1=Color Device, 2=Mono) ; BezierCap Flag 1 0/1 (1=Device supports HPGL2 ; Beziers extension) ; RasterByteAlign Flag 1 0/1 (1=Device must receive all ; raster data on byte alligned ; x coordinates) ; PushPopPal Flag 1 0/1 (1=Driver must push/pop ; pallete when switching ; between RTL / HPGL2) ; TransparentCap Flag 1 0/1 (1=Device supports transp. cmd) ; WindingFillCap Flag 1 0/1 (1=Device can do winding fills) ; RollFeedCap Flag 1 0/1 (1=Device has roll paper src) ; PaperTrayCap Flag 1 0/1 has a main paper tray? ; NoBitmapFont Flag 1 0/1 Do not do bitmap font ; RTLMonoEncode5 Flag 1 0/1 RTL Mono Compress Mode 5? ; RTLNoDPIxy Flag 1 0/1 NO RTL DPI X,Y Move command ; RTLMonoNoCID Flag 1 0/1 RTL Mono No CID command ; RTLMonoFixPal Flag 1 0/1 RTL Mono PAL ONLY 0=W, 1=K ; PlotDPI DWORD 2 Plotter UNIT X/Y Dots per Inch ; RasterDPI WORD 2 Raster (RTL) X/Y Dots per Inch ; ROPLevel DWORD 1 0/1/2/3 ; MaxScale WORD 1 0-10000 (100 times bigger) ; MaxPens WORD 1 Device max # of pens for pen plotter ; MaxCopies WORD 1 Device max # of copies of each ; page device can render by itself. ; MaxPolygonPts WORD 1 Device max # of points when defining ; a polygon to later be stroked or ; filled. ; MaxQuality WORD 1 Device maximum quality levels ; PaperTraySize DWORD 2 Paper Tray width/height in 1/1000mm ; COLORINFO DWORD 30 COLORINFO data structure ; DevicePelsDPI DWORD 1 Dots Per Inch ; HTPatternSize CONSTANT 1 HT_PATSIZE_xx ; InitString STRING 255 Standard string sent to device for ; initialization. ; PlotPenData PENDATA 32 (Max) Pen Plotter's carousel def. ; FormInfo FORMSRC 64 Device supported forms ; ; Following are example values for the PLOTTER characterization data: ;
DeviceName { "HP DesignJet 650C (C2859B)" }; Device Name DeviceSize { 914400, 15240000 } ; Device Size (36" x 50') DeviceMargin { 25400, 25400, 5000, 36000 } ; Device Margin (in 1/1000mm) RasterCap { 1 } ; Pen/Raster plotter (0/1) ColorCap { 1 } ; Color plotter (0/1) BezierCap { 1 } ; Can do bezier curves (0/1) RasterByteAlign { 0 } ; need to byte aligned (0/1) PushPopPal { 1 } ; need to push/pop palette (0/1) TransparentCap { 0 } ; Has transparent mode (0/1) WindingFillCap { 0 } ; Can do winding fills (0/1) RollFeedCap { 1 } ; Can do RollPaper feed (0/1) PaperTrayCap { 0 } ; Has paper input tray (0/1) NoBitmapFont { 0 } ; Do not do bitmap font RTLMonoEncode5 { 1 } ; RTL Mono Adapt Compression RTLNoDPIxy { 0 } ; Has RTL DPI XY move comand RTLMonoNoCID { 0 } ; Has RTL MONO CID Command RTLMonoFixPal { 0 } ; Can change RTL Palette 0/1 PlotDPI { 1016, 1016 } ; Pen Plotter X/Y DPI RasterDPI { 300, 300 } ; Raster Plotter X/Y DPI ROPLevel { ROP_LEVEL_2 } ; ROP levels (0/1/2/3) MaxScale { 1600 } ; Maximum allowed Scale % MaxPens { 256 } ; Maximum allowed pens MaxCopies { 1 } ; Maximum allowed copies MaxPolygonPts { 8192 } ; Maximum Polygon points MaxQuality { 3 } ; Maximum quality levels
; ; Only needed if PaperTrayCap = 1, ; PaperTraySize { 215900, 279400 } ; Letter size paper tray ;
COLORINFO { 6810, 3050, 0, ; xr, yr, Yr 2260, 6550, 0, ; xg, yg, Yg 1810, 500, 0, ; xb, yb, Yb 2000, 2450, 0, ; xc, yc, Yc 5210, 2100, 0, ; xm, ym, Ym 4750, 5100, 0, ; xy, yy, Yy 3324, 3474, 10000, ; xw, yw, Yw 10000, 10000, 10000, ; RGB gamma 1422, 952, 787, ; Dye correction datas 495, 324, 248 }
DevicePelsDPI { 0 } ; effective device DPI (default) HTPatternSize { HT_PATSIZE_6x6_M } ; GDI Halftone pattern size
InitString { "\033E" }
; ; Only allowed if RasterCap = 0, and must define all pens (MaxPens) ; ; PlotPenData { 1, PC_WHITE } ; PlotPenData { 2, PC_BLACK } ; PlotPenData { 3, PC_RED } ; PlotPenData { 4, PC_GREEN } ; PlotPenData { 5, PC_YELLOW } ; PlotPenData { 6, PC_BLUE } ; PlotPenData { 7, PC_MAGENTA } ; PlotPenData { 8, PC_CYAN } ; PlotPenData { 9, PC_ORANGE } ; PlotPenData { 10, PC_BROWN } ; PlotPenData { 11, PC_VIOLET } ;
FormInfo { "Roll Paper 24 in", 609600, 0, 0, 0, 0, 0 } FormInfo { "Roll Paper 36 in", 914400, 0, 0, 0, 0, 0 } FormInfo { "ANSI A 8.5 x 11 in", 215900, 279400, 0, 0, 0, 0 } FormInfo { "ANSI B 11 x 17 in", 279400, 431800, 0, 0, 0, 0 } FormInfo { "ANSI C 17 x 22 in", 431800, 558800, 0, 0, 0, 0 } FormInfo { "ANSI D 22 x 34 in", 558800, 863600, 0, 0, 0, 0 } FormInfo { "ANSI E 34 x 44 in", 863600, 1117600, 0, 0, 0, 0 } FormInfo { "ISO A4 210 x 297 mm", 210000, 297000, 0, 0, 0, 0 } FormInfo { "ISO A3 297 x 420 mm", 297000, 420000, 0, 0, 0, 0 } FormInfo { "ISO A2 420 x 594 mm", 420000, 594000, 0, 0, 0, 0 } FormInfo { "ISO A1 594 x 841 mm", 594000, 841000, 0, 0, 0, 0 } FormInfo { "ISO A0 841 x 1189 mm", 841000, 1189000, 0, 0, 0, 0 } FormInfo { "ISO OS A2 480 x 625 mm", 480000, 625000, 0, 0, 0, 0 } FormInfo { "ISO OS A1 625 x 900 mm", 625000, 900000, 0, 0, 0, 0 } FormInfo { "JIS B4 257 x 364 mm", 257000, 364000, 0, 0, 0, 0 } FormInfo { "JIS B3 364 x 515 mm", 364000, 515000, 0, 0, 0, 0 } FormInfo { "JIS B2 515 x 728 mm", 515000, 728000, 0, 0, 0, 0 } FormInfo { "JIS B1 728 x 1030 mm", 728000, 1030000, 0, 0, 0, 0 } FormInfo { "Arch A 9 x 12 in", 228600, 304800, 0, 0, 0, 0 } FormInfo { "Arch B 12 x 18 in", 304800, 457200, 0, 0, 0, 0 } FormInfo { "Arch C 18 x 24 in", 457200, 609600, 0, 0, 0, 0 } FormInfo { "Arch D 24 x 36 in", 609600, 914400, 0, 0, 0, 0 } FormInfo { "Arch E 36 x 48 in", 914400, 1219200, 0, 0, 0, 0 } FormInfo { "Arch E1 30 x 42 in", 762000, 1066800, 0, 0, 0, 0 }
#endif
#define DBG_PLOTFILENAME DbgPlotGPC
#include <stddef.h>
#include <windows.h>
#include <winddi.h>
#include <wingdi.h>
#include <winspool.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <strsafe.h>
#include <plotlib.h>
#define DBG_FORM 0x00000001
#define DBG_PAPERTRAY 0x00000002
#define DBG_FULLGPC 0x00000004
DEFINE_DBGVAR(0);
#if DBG
TCHAR DebugDLLName[] = TEXT("PLOTGPC"); #endif
#define SIZE_ARRAY(a) (sizeof((a)) / sizeof((a)[0]))
#define SIZE_COLORINFO (sizeof(COLORINFO) / sizeof(LDECI4))
#define PK_FLAG 0
#define PK_WORD 1
#define PK_DWORD 2
#define PK_STRING 3
#define PK_FORMSRC 4
#define PK_PENDATA 5
#define PKF_DEFINED 0x8000
#define PKF_REQ 0x0001
#define PKF_MUL_OK 0x0002
#define PKF_VARSIZE 0x0004
#define PKF_FS_VARLEN 0x0008
#define PKF_ALL 0x0010
#define PKF_REQALL (PKF_REQ | PKF_ALL)
#define PKF_ROLLPAPER (PKF_MUL_OK | PKF_VARSIZE | PKF_FS_VARLEN)
#define PKF_FORMINFO (PKF_MUL_OK | \
PKF_VARSIZE | \ PKF_REQ | \ PKF_FS_VARLEN) #define PKF_PENDATA (PKF_MUL_OK | PKF_VARSIZE)
#define PLOTOFF(a) (DWORD)FIELD_OFFSET(PLOTGPC, a)
#define GET_PLOTOFF(pPK) ((LPBYTE)&PlotGPC + pPK->Data)
#define ADD_PLOTOFF(p, pPK) ((LPBYTE)(p) + pPK->Data)
//
// The plotval is used to provide a name constant selection.
//
typedef struct _PLOTVAL { LPSTR pValName; DWORD Val; } PLOTVAL, *PPLOTVAL;
//
// The keyword parser structure
//
typedef struct _PLOTKEY { LPSTR pKeyword; // Keyword name
WORD KeywordLen; // Keyword length
WORD Flags; // PKF_xxxx
WORD Type; // PK_xxxx
SHORT Count; // maximum size allowed, < 0 if non-Zero string
DWORD Data; // data
LPVOID pInfo; // extra set of pointer data
} PLOTKEY, *PPLOTKEY;
//
// Local/Global variables
//
PLOTVAL PenColorVal[PC_IDX_TOTAL + 1] = {
{ "PC_WHITE", PC_IDX_WHITE }, { "PC_BLACK", PC_IDX_BLACK }, { "PC_RED", PC_IDX_RED }, { "PC_GREEN", PC_IDX_GREEN }, { "PC_YELLOW", PC_IDX_YELLOW }, { "PC_BLUE", PC_IDX_BLUE }, { "PC_MAGENTA", PC_IDX_MAGENTA }, { "PC_CYAN", PC_IDX_CYAN }, { "PC_ORANGE", PC_IDX_ORANGE }, { "PC_BROWN", PC_IDX_BROWN }, { "PC_VIOLET", PC_IDX_VIOLET }, { NULL, 0xffffffff } };
PLOTVAL ROPLevelVal[ROP_LEVEL_MAX + 2] = {
{ "ROP_LEVEL_0", ROP_LEVEL_0 }, { "ROP_LEVEL_1", ROP_LEVEL_1 }, { "ROP_LEVEL_2", ROP_LEVEL_2 }, { "ROP_LEVEL_3", ROP_LEVEL_3 }, { NULL, 0xffffffff } };
PLOTVAL HTPatSizeVal[] = {
{ "HT_PATSIZE_2x2", HT_PATSIZE_2x2 }, { "HT_PATSIZE_2x2_M", HT_PATSIZE_2x2_M }, { "HT_PATSIZE_4x4", HT_PATSIZE_4x4 }, { "HT_PATSIZE_4x4_M", HT_PATSIZE_4x4_M }, { "HT_PATSIZE_6x6", HT_PATSIZE_6x6 }, { "HT_PATSIZE_6x6_M", HT_PATSIZE_6x6_M }, { "HT_PATSIZE_8x8", HT_PATSIZE_8x8 }, { "HT_PATSIZE_8x8_M", HT_PATSIZE_8x8_M }, { "HT_PATSIZE_10x10", HT_PATSIZE_10x10 }, { "HT_PATSIZE_10x10_M", HT_PATSIZE_10x10_M }, { "HT_PATSIZE_12x12", HT_PATSIZE_12x12 }, { "HT_PATSIZE_12x12_M", HT_PATSIZE_12x12_M }, { "HT_PATSIZE_14x14", HT_PATSIZE_14x14 }, { "HT_PATSIZE_14x14_M", HT_PATSIZE_14x14_M }, { "HT_PATSIZE_16x16", HT_PATSIZE_16x16 }, { "HT_PATSIZE_16x16_M", HT_PATSIZE_16x16_M }, { NULL, 0xffffffff } };
BYTE InitString[512] = ""; FORMSRC AvaiForms[64]; PENDATA AvaiPenData[MAX_PENPLOTTER_PENS];
UINT MaxKeywordLen = 0; UINT MaxPCValLen = 0; CHAR szFormInfo[] = "FormInfo"; CHAR szPenData[] = "PlotPenData"; CHAR szPaperTrayCap[] = "PaperTrayCap"; CHAR szPaperTraySize[] = "PaperTraySize"; CHAR szNoBmpFont[] = "NoBitmapFont"; CHAR szRTLMonoEncode5[] = "RTLMonoEncode5"; CHAR szRTLNoDPIxy[] = "RTLNoDPIxy"; CHAR szRTLMonoNoCID[] = "RTLMonoNoCID"; CHAR szRTLMonoFixPal[] = "RTLMonoFixPal";
FILE *InFile; FILE *OutFile; UINT LineNo; CHAR InFileName[80];
//
// The keys to search / parse
//
PLOTKEY PlotKey[] = {
{ "DeviceName", 0,PKF_REQ, PK_STRING, (SHORT)CCHDEVICENAME, PLOTOFF(DeviceName), NULL }, { "DeviceSize", 0,PKF_REQALL, PK_DWORD, 2, PLOTOFF(DeviceSize), NULL }, { "DeviceMargin", 0,PKF_REQALL, PK_DWORD, 4, PLOTOFF(DeviceMargin), NULL }, { "RasterCap", 0,PKF_REQ, PK_FLAG, 1, PLOTF_RASTER, NULL }, { "ColorCap", 0,PKF_REQ, PK_FLAG, 1, PLOTF_COLOR, NULL }, { "BezierCap", 0,PKF_REQ, PK_FLAG, 1, PLOTF_BEZIER, NULL }, { "RasterByteAlign",0,PKF_REQ, PK_FLAG, 1, PLOTF_RASTERBYTEALIGN, NULL }, { "PushPopPal", 0,PKF_REQ, PK_FLAG, 1, PLOTF_PUSHPOPPAL, NULL }, { "TransparentCap", 0,PKF_REQ, PK_FLAG, 1, PLOTF_TRANSPARENT, NULL }, { "WindingFillCap", 0,PKF_REQ, PK_FLAG, 1, PLOTF_WINDINGFILL, NULL }, { "RollFeedCap", 0,PKF_REQ, PK_FLAG, 1, PLOTF_ROLLFEED, NULL }, { szPaperTrayCap, 0,PKF_REQ, PK_FLAG, 1, PLOTF_PAPERTRAY, NULL }, { szNoBmpFont, 0,0, PK_FLAG, 1, PLOTF_NO_BMP_FONT, NULL }, { szRTLMonoEncode5, 0,0, PK_FLAG, 1, PLOTF_RTLMONOENCODE_5, NULL }, { szRTLNoDPIxy, 0,0, PK_FLAG, 1, PLOTF_RTL_NO_DPI_XY, NULL }, { szRTLMonoNoCID, 0,0, PK_FLAG, 1, PLOTF_RTLMONO_NO_CID, NULL }, { szRTLMonoFixPal, 0,0, PK_FLAG, 1, PLOTF_RTLMONO_FIXPAL, NULL }, { "PlotDPI", 0,PKF_REQALL, PK_DWORD, 2, PLOTOFF(PlotXDPI), NULL }, { "RasterDPI", 0,PKF_REQALL, PK_WORD, 2, PLOTOFF(RasterXDPI), NULL }, { "ROPLevel", 0,0, PK_WORD, 1, PLOTOFF(ROPLevel), ROPLevelVal }, { "MaxScale", 0,0, PK_WORD, 1, PLOTOFF(MaxScale), NULL }, { "MaxPens", 0,PKF_REQ, PK_WORD, 1, PLOTOFF(MaxPens), NULL }, { "MaxCopies", 0,0, PK_WORD, 1, PLOTOFF(MaxCopies), NULL }, { "MaxPolygonPts", 0,PKF_REQ, PK_WORD, 1, PLOTOFF(MaxPolygonPts), NULL }, { "MaxQuality", 0,0, PK_WORD, 1, PLOTOFF(MaxQuality), NULL }, { szPaperTraySize, 0,PKF_ALL, PK_DWORD, 2, PLOTOFF(PaperTraySize), NULL }, { "COLORINFO", 0,0, PK_DWORD, (SHORT)SIZE_COLORINFO, PLOTOFF(ci), NULL }, { "DevicePelsDPI", 0,0, PK_DWORD, 1, PLOTOFF(DevicePelsDPI), NULL }, { "HTPatternSize", 0,0, PK_DWORD, 1, PLOTOFF(HTPatternSize), HTPatSizeVal }, { "InitString", 0,PKF_VARSIZE, PK_STRING, -(SHORT)SIZE_ARRAY(InitString),PLOTOFF(InitString), InitString }, { szPenData, 0,PKF_PENDATA, PK_PENDATA,(SHORT)SIZE_ARRAY(AvaiPenData),PLOTOFF(Pens), AvaiPenData }, { szFormInfo, 0,PKF_FORMINFO, PK_FORMSRC,(SHORT)SIZE_ARRAY(AvaiForms), PLOTOFF(Forms), AvaiForms }, { NULL, 0 } };
//
// Current default plotter's GPC
//
PLOTGPC PlotGPC = {
PLOTGPC_ID, // ID
PLOTGPC_VERSION, // Version
sizeof(PLOTGPC), // cjThis
0, // SizeExtra
"HPGL/2 Plotter", // DeviceName,
{ 215900, 279400 }, // DeviceSize
{ 5000, 5000, 5000, 36000 }, // DeviceMargin
0, // Flags
1016, // PlotXDPI
1016, // PlotYDPI
300, // RasterXDPI
300, // RasterYDPI
ROP_LEVEL_0, // ROPLevel
100, // MaxScale
8, // MaxPens
1, // MaxCopies
128, // MaxPolygonPts
4, // MaxQuality 100 levels
{ -1, -1 }, // PaperTraySize = 0
{ // ci
{ 6810, 3050, 0 }, // xr, yr, Yr
{ 2260, 6550, 0 }, // xg, yg, Yg
{ 1810, 500, 0 }, // xb, yb, Yb
{ 2000, 2450, 0 }, // xc, yc, Yc
{ 5210, 2100, 0 }, // xm, ym, Ym
{ 4750, 5100, 0 }, // xy, yy, Yy
{ 3324, 3474, 10000 }, // xw, yw, Yw
10000, 10000, 10000, // RGBB gamma
1422, 952, // M/C, Y/C
787, 495, // C/M, Y/M
324, 248 // C/Y, M/Y
},
0, // DevicePelsDPI
0xffffffff, // HTPatternSize
{ 0, 0, NULL }, // init string
{ 0, sizeof(FORMSRC), NULL }, // Forms
{ 0, sizeof(PENDATA), NULL } // Pens
};
VOID ShowUsage( VOID ) { fprintf(stderr, "\nPlotGPC [-?] InputDataFile [OutputPlotGPC]\n"); fprintf(stderr, "Build NT Plotter GPC data file\n\n"); fprintf(stderr, " -?: display this message.\n"); fprintf(stderr, " InputDataFile: input ASCII data file\n"); fprintf(stderr, " OutputPlotGPC: output binary plotter gpc data file\n");
}
VOID cdecl DispError( INT Level, LPSTR pStr, ... ) { va_list vaList;
if (Level) {
if (Level > 2) {
fprintf(stderr, "%s\n", InFileName);
} else {
fprintf(stderr, "\n%s(%u): ", InFileName, LineNo); }
if (Level < 0) {
fprintf(stderr, "INTERNAL ERROR: ");
} else if (Level == 1) {
fprintf(stderr, "warning: ");
} else if (Level >= 2) {
fprintf(stderr, "error: "); }
} else {
fprintf(stderr, "\n!!! "); }
va_start(vaList, pStr); vfprintf(stderr, pStr, vaList); va_end(vaList); }
VOID ShowSpaces( UINT Spaces ) { BYTE Buf[81];
while (Spaces) {
memset(Buf, ' ', sizeof(Buf));
if (Spaces > (sizeof(Buf) - 1)) {
Buf[sizeof(Buf) - 1] = '\0'; Spaces -= (sizeof(Buf) - 1);
} else {
Buf[Spaces] = '\0'; Spaces = 0; }
fprintf(stdout, "%s", Buf); } }
VOID ShowNumbers( LPBYTE pNum, PPLOTVAL pPV, WORD Type, UINT Count, UINT NumDigits, UINT NumPerLine )
/*++
Routine Description:
This function shows numbers in the passed format.
Arguments:
pNum - Points to the number
pPV - Point to the value constant key name to be displayed
Type - PK_xxx type
Count - Total numbers
NumDigits - Total digits per number
NumPerLine - Total number per line to display
Return Value:
VOID
Development History:
09-Nov-1993 Tue 19:45:13 created
Revision History:
--*/
{ DWORD *pdw; WORD *pw; DWORD dw; UINT Wrap; static BYTE DigitFormat[] = "%4lu";
if (NumDigits > 9) {
NumDigits = 9; }
DigitFormat[1] = (BYTE)(NumDigits + '0'); pdw = NULL; pw = NULL; Wrap = 0;
if (pPV) {
Count = 1; }
switch (Type) {
case PK_DWORD:
pdw = (DWORD *)pNum; break;
case PK_WORD:
pw = (WORD *)pNum; break;
default:
DispError(-1, "ShowNumbers only allowes PK_WORD, PK_DWORD"); return; }
while (Count--) {
if (pdw) {
dw = *pdw++;
} else {
dw = (DWORD)*pw++; }
if (pPV) {
pPV += dw;
fprintf(stdout, "%s", pPV->pValName);
} else {
fprintf(stdout, DigitFormat, dw); }
if (Count) {
fprintf(stdout, ", ");
if (++Wrap >= NumPerLine) {
fprintf(stdout, "\n"); ShowSpaces(MaxKeywordLen + 3); Wrap = 0; } } } }
UINT ShowString( LPBYTE pBuf, UINT cBuf )
/*++
Routine Description:
This function displays a formatted string
Arguments:
pBuf - points to the string buffer
cBuf - Size of the string pointed to by pBuf
Return Value:
UINT - total characters displayed
Development History:
14-Dec-1993 Tue 09:47:06 created
Revision History:
--*/
{ BYTE Ch; UINT i = 1;
if (!cBuf) {
cBuf = strlen(pBuf); }
fprintf(stdout, "\"");
while (cBuf--) {
Ch = *pBuf++; i += 2;
if ((Ch >= ' ') && (Ch <= 0x7f)) {
if (Ch == '\\') {
fprintf(stdout, "\\\\");
} else if (Ch == '\"') {
fprintf(stdout, "\\\"");
} else {
fprintf(stdout, "%c", Ch); --i; }
} else {
if (Ch == '\a') {
fprintf(stdout, "\\a");
} else if (Ch == '\b') {
fprintf(stdout, "\\b");
} else if (Ch == '\f') {
fprintf(stdout, "\\f");
} else if (Ch == '\n') {
fprintf(stdout, "\\n");
} else if (Ch == '\r') {
fprintf(stdout, "\\r");
} else if (Ch == '\t') {
fprintf(stdout, "\\t");
} else {
fprintf(stdout, "\\x%02x", Ch); ++i; } } }
fprintf(stdout, "\"");
return(++i); }
BOOL ShowOnePlotKey( PPLOTGPC pPlotGPC, PPLOTKEY pPK, UINT VarSizeIdx, UINT MaxLen )
/*++
Routine Description:
This function takes a PLOTKEY structure and displays its content
Arguments:
pPlotGPC - Points to the current PLOTGPC data structure
pPK - Points to the PLOTKEY data structure
VarSizeIdx - a variable size index, must be less then pVS->Count
MaxLen - The size to pack the output into
Return Value:
BOOL
Development History:
14-Dec-1993 Tue 09:48:13 created
Revision History:
--*/
{ PGPCVARSIZE pVS = NULL; LPBYTE pData; PFORMSRC pFS; PPENDATA pPD; UINT i; DWORD dw;
pData = ADD_PLOTOFF(pPlotGPC, pPK);
if (pPK->Flags & PKF_VARSIZE) {
pVS = (PGPCVARSIZE)pData;
if (VarSizeIdx >= pVS->Count) {
DispError(-1, "VarSizeIdx [%u] > GPCVarSize.Count [%u", VarSizeIdx, pVS->Count);
return(FALSE); }
pData = (LPBYTE)pPK->pInfo + (pVS->SizeEach * VarSizeIdx); }
fprintf(stdout, "\n%s", pPK->pKeyword); ShowSpaces(MaxKeywordLen - pPK->KeywordLen + 1); fprintf(stdout, "{ ");
switch (pPK->Type) {
case PK_FLAG:
fprintf(stdout, "%c", (pPlotGPC->Flags & pPK->Data) ? '1' : '0'); break;
case PK_WORD: case PK_DWORD:
ShowNumbers(pData, (PPLOTVAL)pPK->pInfo, pPK->Type, (UINT)pPK->Count, (pPK->Data == PLOTOFF(ci)) ? 5 : 0, (pPK->Data == PLOTOFF(ci)) ? 3 : 6);
break;
case PK_STRING:
if (pVS) {
ShowString(pData, pVS->SizeEach);
} else {
ShowString(pData, 0); }
break;
case PK_FORMSRC:
pFS = (PFORMSRC)pData; i = ShowString(pFS->Name, 0);
fprintf(stdout, ","); ShowSpaces(MaxLen + 2 - i); fprintf(stdout, "%7lu,%8lu,%5lu,%5lu,%5lu,%5lu", pFS->Size.cx, pFS->Size.cy, pFS->Margin.left, pFS->Margin.top, pFS->Margin.right, pFS->Margin.bottom); break;
case PK_PENDATA:
pPD = (PPENDATA)pData; dw = VarSizeIdx + 1;
ShowNumbers((LPBYTE)&dw, NULL, PK_DWORD, 1, 2, 1); fprintf(stdout, ", "); i = ShowString(PenColorVal[pPD->ColorIdx].pValName, 0); ShowSpaces(MaxLen + 2 - i); break; }
fprintf(stdout, " }");
return(TRUE); }
VOID ShowPlotGPC( PPLOTGPC pPlotGPC )
/*++
Routine Description:
This function show current settings of plotter GPC structure.
Arguments:
pPlotGPC - the GPC to be displayed
Return Value:
VOID
Development History:
09-Nov-1993 Tue 19:07:05 created
Revision History:
--*/
{ PGPCVARSIZE pVS; PFORMSRC pFS; PPLOTKEY pPK; PLOTKEY PK; UINT i; UINT Size; UINT Count; UINT MaxLen = 0;
fprintf(stdout, "\n\n;\n; '%s' plotter characterization data\n;\n", pPlotGPC->DeviceName);
pPK = &PlotKey[0];
while (pPK->pKeyword) {
PK = *pPK++;
if (PK.Flags & PKF_VARSIZE) {
pVS = (PGPCVARSIZE)ADD_PLOTOFF(pPlotGPC, (&PK)); Count = pVS->Count; PK.pInfo = pVS->pData;
} else {
Count = 1; }
if (PK.Type == PK_FORMSRC) {
if (PK.Flags & PKF_VARSIZE) {
pFS = (PFORMSRC)PK.pInfo;
} else {
pFS = (PFORMSRC)ADD_PLOTOFF(pPlotGPC, pPK); }
for (MaxLen = i = 0; i < Count; i++, pFS++) {
if ((Size = strlen(pFS->Name)) > MaxLen) {
MaxLen = Size; } } }
if (PK.Type == PK_PENDATA) {
MaxLen = MaxPCValLen; }
if (Count > 1) {
fprintf(stdout, "\n"); }
for (i = 0; i < Count; i++) {
ShowOnePlotKey(pPlotGPC, &PK, i, MaxLen); } }
fprintf(stdout, "\n\n"); }
#if 0
VOID ShowUndefined( VOID )
/*++
Routine Description:
This function displayes all undefined keywords
Arguments:
nono
Return Value:
VOID
Development History:
12-Nov-1993 Fri 17:20:24 created
Revision History:
--*/
{ PPLOTKEY pPK; BOOL Ok = TRUE;
pPK = (PPLOTKEY)&PlotKey[0];
while (pPK->pKeyword) {
if (!(pPK->Flags & PKF_DEFINED)) {
DispError(1, "keyword '%s' not defined.", pPK->pKeyword); Ok = FALSE; }
++pPK; }
if (!Ok) {
fprintf(stdout, "\n\n"); } }
#endif
LPBYTE GetOneLine( BOOL SkipFrontSpace )
/*++
Routine Description:
This function return the next line in the input file string
Arguments:
SkipFrontSpace - skip the white space in the begining of the line
Return Value:
pointer to the string, NULL if Error/EOF
Development History:
09-Nov-1993 Tue 10:39:31 created
Revision History:
--*/
{ LPBYTE pLine; static BYTE LineBuf[1024];
while (fgets(LineBuf, sizeof(LineBuf) - 1, InFile)) {
++LineNo;
//
// Skip End white spaces
//
pLine = &LineBuf[strlen(LineBuf)];
while ((pLine > LineBuf) && (isspace(*(pLine - 1)))) {
--pLine; }
*pLine = '\0';
//
// Skip Front white spaces
//
pLine = LineBuf;
if (SkipFrontSpace) {
while ((*pLine) && (isspace(*pLine))) {
++pLine; } }
if (*pLine) {
return(pLine); } }
return (NULL); }
LPBYTE ParseString( LPSTR pKeyword, LPBYTE *pLineLoc, LPBYTE pBuf, SHORT cBuf )
/*++
Routine Description:
This function takes a pBuf and parses a series of characters into a string, it may contain escape format characters, the string may or may not be NULL terminated
Arguments:
pKeyword - Current keyword name
pLineLoc - Pointer to pointer of buffer line location
pBuf - Pointer to the buffer
cBuf - size of output buffer, if negative then NULL is allowed in the string
Return Value:
LPBYTE points to the end of the string, NULL if failure.
Development History:
14-Dec-1993 Tue 09:52:07 created
Revision History:
--*/
{ #define STR_STATE_ERROR -1
#define STR_STATE_END 0
#define STR_STATE_BYTE 1
#define STR_STATE_BKSLASH 2
#define STR_STATE_HEX1 3
#define STR_STATE_HEX2 4
#define STR_STATE_OCT2 5
#define STR_STATE_OCT3 6
LPBYTE pLine; LPBYTE pStrBuf; LPBYTE pEnd; INT State; INT Number; BOOL Error = FALSE; BOOL szStr; BYTE Ch;
if (cBuf < 0) {
cBuf = -cBuf; szStr = FALSE;
} else {
szStr = TRUE; }
pLine = *pLineLoc; pStrBuf = pBuf; pEnd = pBuf + cBuf - 1; State = STR_STATE_BYTE;
while ((State != STR_STATE_ERROR) && (State != STR_STATE_END) && (pBuf <= pEnd) && (Ch = *pLine++)) {
switch (State) {
case STR_STATE_BYTE:
if (Ch == '\\') {
//
// Check if end of the line, if so read the next line in
// without stripping white space.
//
if (*pLine == '\0') {
if (!(pLine = GetOneLine(FALSE))) {
Ch = 0; State = STR_STATE_ERROR;
} else {
continue; }
} else {
State = STR_STATE_BKSLASH; }
} else if (Ch == '\"') {
State = STR_STATE_END; }
break;
case STR_STATE_BKSLASH:
State = STR_STATE_BYTE;
switch (Ch) {
case '0': //
case '1': // Maximum OCT number is 377
case '2': case '3':
Number = (INT)(Ch - '0'); State = STR_STATE_OCT2; break;
case 'x':
Number = 0; State = STR_STATE_HEX1; break;
case 'a':
Ch = '\a'; break;
case 'b':
Ch = '\b'; break;
case 'f':
Ch = '\f'; break;
case 'n':
Ch = '\n'; break;
case 'r':
Ch = '\r'; break;
case 't':
Ch = '\t'; break;
case '\\': case '\"':
break;
default:
DispError(2, "Invalid escape character '%c' (%s)", Ch, pKeyword); State = STR_STATE_ERROR; }
break;
case STR_STATE_OCT2: case STR_STATE_OCT3:
if ((Ch >= '0') && (Ch <= '7')) {
Number = (INT)((Number * 8) + (Ch - '0'));
if (State == STR_STATE_OCT2) {
State = STR_STATE_OCT3;
} else {
State = STR_STATE_BYTE; Ch = (BYTE)Number; }
} else {
DispError(2, "invalid digits for octal number '%c'", Ch); State = STR_STATE_ERROR; }
break;
case STR_STATE_HEX1: case STR_STATE_HEX2:
if ((Ch >= '0') && (Ch <= '9')) {
Number = (INT)((Number << 4) | (Ch - '0'));
} else if ((Ch >= 'a') && (Ch <= 'f')) {
Number = (INT)((Number << 4) | (Ch - 'a' + 10));
} else if ((Ch >= 'A') && (Ch <= 'F')) {
Number = (INT)((Number << 4) | (Ch - 'A' + 10));
} else if (State == STR_STATE_HEX1) {
DispError(2, "string hex escape must have at least one hex digit");
State = STR_STATE_ERROR;
} else {
--pLine; // re-process current one
}
if (State == STR_STATE_HEX1) {
State = STR_STATE_HEX2;
} else {
Ch = (BYTE)Number; State = STR_STATE_BYTE; } }
if (State == STR_STATE_BYTE) {
if ((szStr) && (!Ch)) {
//
// Do not allowe zero in the string
//
DispError(2, "CANNOT have NULL char. in the middle of '%s' string", pKeyword); State = STR_STATE_ERROR;
} else {
*pBuf++ = Ch; } } }
if (State != STR_STATE_END) {
Error = TRUE;
if (pBuf > pEnd) {
DispError(2, "string too big: maximum length is %u for '%s'.", cBuf - 1, pKeyword);
} else if (Ch == 0) {
DispError(2, "string must end with a '\"'"); } }
*pLineLoc = pLine;
if (Error) {
return(NULL);
} else {
*pBuf = '\0';
if (pStrBuf == pBuf) {
DispError(1, "NULL string is defined for '%s'", pKeyword); }
return(pBuf); }
#undef STR_STATE_ERROR
#undef STR_STATE_END
#undef STR_STATE_BYTE
#undef STR_STATE_BKSLASH
#undef STR_STATE_HEX1
#undef STR_STATE_HEX2
#undef STR_STATE_OCT2
#undef STR_STATE_OCT3
}
LPBYTE GetNextToken( LPSTR pKeyword, LPBYTE pBuf, SHORT cBuf )
/*++
Routine Description:
This function retrieves the next token from the input file
Arguments:
pKeyword - Current keyword name
pBuf - pointer to the string parsing output buffer, if not NULL
cBuf - size of pBuf
Return Value:
LPBYTE - a pointer to the output buffer or token string, NULL if failure
Development History:
09-Nov-1993 Tue 11:21:11 created
Revision History:
--*/
{ static LPBYTE pLine = NULL; static BYTE LastCh = '\0';
if (pLine == NULL) {
LineNo = 0; pLine = GetOneLine(TRUE); }
if (LastCh) {
*pLine = LastCh; LastCh = '\0'; }
LastCh = 0;
if (pBuf) {
if (!cBuf) {
return(pBuf); }
//
// reading a string section
//
while (pLine) {
while((*pLine) && ((isspace(*pLine)) || (*pLine == ','))) {
pLine++; }
if ((*pLine) && (*pLine != ';')) {
if (*pLine++ != '"') {
DispError(2, "string must enclosed by \" (Quote)"); return(NULL); }
return(ParseString(pKeyword, &pLine, pBuf, cBuf));
} else {
pLine = GetOneLine(TRUE); } }
} else {
while (pLine) {
while((*pLine) && ((isspace(*pLine)) || (*pLine == ','))) {
pLine++; }
if ((*pLine) && (*pLine != ';')) {
LPBYTE pLineRet = pLine;
while((*pLine) && (!isspace(*pLine)) && (*pLine != ',') && (*pLine != '{') && (*pLine != '}')) {
++pLine; }
if ((*pLine == '{') || (*pLine == '}')) {
if (pLine == pLineRet) {
++pLine; }
LastCh = *pLine; *pLine = '\0';
} else {
*pLine++ = '\0'; }
// fprintf(stderr, "\nTOKEN = '%s'", pLineRet);
return(pLineRet);
} else {
pLine = GetOneLine(TRUE); } } }
return(NULL); }
BOOL CheckSingleToken( BYTE Token )
/*++
Routine Description:
Check if a single character 'Token' exists
Arguments:
Token - Token to be checked
Return Value:
TRUE if found, FALSE otherwise
Development History:
09-Nov-1993 Tue 12:13:33 created
Revision History:
--*/
{ LPBYTE pToken;
if (!(pToken = GetNextToken(NULL, NULL, 0))) {
DispError(2, "Unexpected end of file."); return(FALSE); }
return(*pToken == Token); }
BOOL ConvertNumber( LPSTR pBuf, BOOL NegOk, LONG *pRetVal )
/*++
Routine Description:
Convert pBuf to a number based on the parameters passed
Arguments:
pBuf - Point to the string to be converted to a number
NegOk - TRUE if a negative number is allowed
pRetVal - Pointer to a LONG to return a converted number
Return Value:
TRUE if sucessful, FALSE if falied.
Development History:
09-Nov-1993 Tue 18:47:43 created
Revision History:
--*/
{ if ((*pRetVal = atol(pBuf)) < 0) {
if (!NegOk) {
DispError(2, "expect a positive number. [%s]", pBuf); return(FALSE); }
} else if (*pRetVal == 0) {
if (*pBuf != '0') {
DispError(2, "expect a number. [%s]", pBuf); return(FALSE); } }
return(TRUE);
}
INT ReadNumbers( LPSTR pKeyword, LPVOID pNumbers, PPLOTVAL pPlotVal, UINT Total, UINT Type, UINT Flags )
/*++
Routine Description:
This function reads the next token and returns a number, the number can be
1. '0x' prefixed for a hex type 2. normal for an integer type
Arguments:
pPK - Pointer to PLOTKEY
Return Value:
Expanded to DWORD, this function will only read positive numbers
Development History:
09-Nov-1993 Tue 11:03:36 created
Revision History:
--*/
{ PPLOTVAL pPV; LPBYTE pToken; UINT Count; DWORD SetBit; DWORD *pdw; WORD *pw;
pdw = NULL; pw = NULL;
switch (Type) {
case PK_WORD:
pw = (WORD *)pNumbers; break;
case PK_DWORD:
pdw = (DWORD *)pNumbers; break;
case PK_FLAG:
if (Total != 1) {
DispError(-1, "PK_FLAG has more than one count"); Total = 1; }
SetBit = *(DWORD *)pNumbers;
break;
default:
DispError(-1, "!!Unknow key type!!, internal error"); return(-1); }
for (Count = 0; Count < Total; Count++) {
LONG RetVal; BYTE Ch;
RetVal = 0;
if (pToken = GetNextToken(pKeyword, NULL, 0)) {
if (*pToken == '}') {
if (!Count) {
DispError(1, "%s none of %u numbers defined", pKeyword, Total);
} else {
DispError(1, "%s defined only %u of %u numbers", pKeyword, Count, Total); }
if (Flags & PKF_ALL) {
DispError(2, "All %u numbers in keyword '%s' must defined", Total, pKeyword); return(-1);
} else {
return(0x01); }
} else if (pPV = pPlotVal) {
while (pPV->pValName) {
if (!_stricmp(pToken, pPV->pValName)) {
break; }
++pPV; }
if (pPV->pValName) {
RetVal = pPV->Val;
} else {
DispError(2, "unknown key value '%s' for keyword '%s'", pToken, pKeyword); return(-1); }
} else if ((*pToken == '0') && ((*(pToken + 1) == 'x') || (*(pToken + 1) == 'X'))) {
//
// This is a Hex type format
//
pToken += 2;
while (Ch = *pToken++) {
if ((Ch >= '0') && (Ch <= '9')) {
Ch -= '0';
} else if ((Ch >= 'a') && (Ch <= 'f')) {
Ch = (Ch - 'a') + 10;
} else if ((Ch >= 'A') && (Ch <= 'F')) {
Ch = (Ch - 'A') + 10;
} else {
break; }
RetVal = (LONG)(((DWORD)RetVal << 4) | (DWORD)Ch); }
} else if (!ConvertNumber(pToken, Type == PK_FLAG, &RetVal)) {
DispError(2, "expect another %u numbers. [%s]", Total - Count, pToken); return(-1); }
if (pdw) {
*pdw++ = (DWORD)RetVal;
} else if (pw) {
*pw++ = (WORD)RetVal;
} else {
if (RetVal) {
PlotGPC.Flags |= SetBit;
} else {
PlotGPC.Flags &= ~SetBit; } }
} else {
DispError(2, "'%s' expect another %u numbers. [End Of File]", pKeyword, Total - Count); return(-1); } }
return(0); }
INT ReadString( PPLOTKEY pPK )
/*++
Routine Description:
This function reads in the string for the PK (plotkey)
Arguments:
pPK - Points to the PLOTKEY data structure
Return Value:
size of the string that was read.
Development History:
12-Nov-1993 Fri 12:25:50 created
Revision History:
--*/
{ LPBYTE pBuf; LPBYTE pEnd;
pBuf = (LPBYTE)((pPK->Flags & PKF_VARSIZE) ? pPK->pInfo : GET_PLOTOFF(pPK));
if (!(pPK->Flags & PKF_VARSIZE)) {
if (pPK->Count < 0) {
DispError(-1, "'%s' is a non-variable size string, it CANNOT have NULL char", pPK->pKeyword); return(-1); } }
if (pEnd = GetNextToken(pPK->pKeyword, pBuf, pPK->Count)) {
UINT Size = (UINT)(pEnd - pBuf);
if (pPK->Flags & PKF_VARSIZE) {
PGPCVARSIZE pVS;
pVS = (PGPCVARSIZE)GET_PLOTOFF(pPK);
if (Size) {
pVS->Count = 1; }
pVS->SizeEach = (WORD)Size; pVS->pData = NULL; }
return((pBuf[0] == '\0') ? 0x02 : 0x00); }
return(-1); }
BOOL CheckFormSrc( LPBYTE pKeyword, WORD Flags, SIZEL *pSize, RECTL *pMargin, LPSTR pFormName, INT ErrNo )
/*++
Routine Description:
Check if FORMSRC input is valid
Arguments:
pKeyword - Point to current keyword
Flags - PKF_xxxx
pSize - pointer to SIZEL for Form size
RECTL - Pointer to the RECTL for margins
pFormName - Name of the form
ErrNo - error number to send to DispError() if an error occurs
Return Value:
TRUE if OK, FALSE otherwise
Development History:
18-Nov-1993 Thu 00:04:12 created
Revision History:
--*/
{
if (pSize->cx < MIN_PLOTGPC_FORM_CX) {
DispError(ErrNo, "minimum height for '%s' (%s) must >= %lu", pFormName, pKeyword, MIN_PLOTGPC_FORM_CX); return(FALSE); }
if (pSize->cy < MIN_PLOTGPC_FORM_CY) {
if (Flags & PKF_FS_VARLEN) {
if (pSize->cy) {
pSize->cy = 0; DispError(1, "ASSUME variable length (set to 0) for '%s' (%s)", pFormName, pKeyword); }
} else {
DispError(ErrNo, "minimum height for '%s' (%s) must >= %lu", pFormName, pKeyword, MIN_PLOTGPC_FORM_CY); return(FALSE); } }
if ((pSize->cx - pMargin->left - pMargin->right) < MIN_PLOTGPC_FORM_CX) {
DispError(ErrNo, "invalid left/right margins for '%s' (%s)", pFormName, pKeyword); return(FALSE); }
if ((pSize->cy) && ((pSize->cx - pMargin->left - pMargin->right) < MIN_PLOTGPC_FORM_CY)) {
DispError(ErrNo, "invalid top/bottom margins for '%s' (%s)", pFormName, pKeyword); return(FALSE); }
return(TRUE); }
INT ReadFormSrc( PPLOTKEY pPK )
/*++
Routine Description:
Input a FORMSRC line from the input file.
Arguments:
pPK - Pointer to the PLOTKEY data structure
Return Value:
INT - >= 0 if OK, -1 if failure, a 0 return means no '}' end bracket is read a > 0 means '}' already read.
Development History:
12-Nov-1993 Fri 13:34:50 created
Revision History:
--*/
{ PGPCVARSIZE pVS; PFORMSRC pFS;
pVS = NULL; pFS = (PFORMSRC)GET_PLOTOFF(pPK);
if (pPK->Flags & PKF_VARSIZE) {
pVS = (PGPCVARSIZE)pFS; pFS = (PFORMSRC)pPK->pInfo;
if (pVS->Count >= pPK->Count) {
DispError(2, "too many '%s' defined, allowed only (%u)", pPK->pKeyword, pPK->Count); return(-1); }
pFS += pVS->Count; }
ZeroMemory(pFS, sizeof(FORMSRC));
if ((GetNextToken(pPK->pKeyword, pFS->Name, CCHFORMNAME)) && (pFS->Name[0]) && (ReadNumbers(pPK->pKeyword, (LPVOID)&pFS->Size, NULL, 6, PK_DWORD, PKF_REQ) >= 0) && (CheckFormSrc(pPK->pKeyword, pPK->Flags, &(pFS->Size), &(pFS->Margin), &(pFS->Name[0]), 2))) {
if (pVS) {
PFORMSRC pOrgFS = (PFORMSRC)pPK->pInfo; UINT i = pVS->Count;
while (i--) {
if (_stricmp(pFS->Name, pOrgFS->Name) == 0) {
DispError(2, "'%s' already defined in keyword '%s'", pOrgFS->Name, pPK->pKeyword); return(-1); }
pOrgFS++; }
pVS->Count += 1; pVS->SizeEach = sizeof(FORMSRC); pVS->pData = NULL;
}
return(0); }
return(-1); }
INT ReadPenData( PPLOTKEY pPK )
/*++
Routine Description:
Read a PENDATA structure
Arguments:
pPK - Pointer to the PLOTKEY data structure
Return Value:
INT - >= 0 if OK, -1 if failed, 0 if no '}' end bracket is definined, > 0 means '}' already read.
Development History:
12-Nov-1993 Fri 13:34:50 created
Revision History:
--*/
{ PGPCVARSIZE pVS; PPENDATA pPD; PENDATA PD; WORD IdxPen; INT Ret;
pVS = (PGPCVARSIZE)GET_PLOTOFF(pPK); pPD = (PPENDATA)pPK->pInfo;
if ((ReadNumbers(pPK->pKeyword, (LPVOID)&IdxPen, NULL, 1, PK_WORD, PKF_REQ) == 0) && ((Ret = ReadNumbers(pPK->pKeyword, (LPVOID)&PD.ColorIdx, PenColorVal, 1, PK_WORD, PKF_REQ)) >= 0)) {
if (IdxPen <= 0) {
DispError(2, "first pen number started at one (1), not zero (0)."); return(-1); }
if (IdxPen > MAX_PENPLOTTER_PENS) {
DispError(2, "maximum pen number is '%s'.", MAX_PENPLOTTER_PENS); return(-1); }
pPD += (IdxPen - 1);
if (pPD->ColorIdx != 0xffff) {
DispError(1, "redefined Pen #%d for '%s' keyword '%s'", IdxPen, pPK->pKeyword);
} else {
++pVS->Count; }
*pPD = PD;
pVS->SizeEach = sizeof(PENDATA); pVS->pData = NULL;
return(Ret); }
return(-1); }
PPLOTGPC GetFullPlotGPC( VOID )
/*++
Routine Description:
This function converts the current contents of PlotGPC to allocated memory so it has the entire PLOTGPC defined
Arguments:
VOID
Return Value:
PPLOTGPC, Pointer to the PLOTGPC packed and converted, NULL if failure
Development History:
17-Nov-1993 Wed 17:08:53 created
Revision History:
--*/
{ PPLOTGPC pPlotGPC; LPBYTE pData; DWORD InitStrSize[2]; DWORD FormsSize[2]; DWORD PlotPensSize[2]; DWORD SizeExtra;
if ((PlotGPC.InitString.Count == 1) || (PlotGPC.InitString.SizeEach)) {
//
// Include the NULL terminated character
//
InitStrSize[0] = PlotGPC.InitString.SizeEach + 1;
} else {
InitStrSize[0] = 0; ZeroMemory(&(PlotGPC.InitString), sizeof(GPCVARSIZE)); }
if ((PlotGPC.Forms.Count) && (PlotGPC.Forms.SizeEach == sizeof(FORMSRC))) {
FormsSize[0] = sizeof(FORMSRC) * PlotGPC.Forms.Count;
} else {
FormsSize[0] = 0; ZeroMemory(&(PlotGPC.Forms), sizeof(GPCVARSIZE)); }
if ((PlotGPC.Pens.Count) && (PlotGPC.Pens.SizeEach == sizeof(PENDATA))) {
PlotPensSize[0] = sizeof(PENDATA) * PlotGPC.Pens.Count;
} else {
PlotPensSize[0] = 0; ZeroMemory(&(PlotGPC.Pens), sizeof(GPCVARSIZE)); }
SizeExtra = (InitStrSize[1] = DWORD_ALIGNED(InitStrSize[0])) + (FormsSize[1] = DWORD_ALIGNED(FormsSize[0])) + (PlotPensSize[1] = DWORD_ALIGNED(PlotPensSize[0]));
PLOTDBG(DBG_FULLGPC, ("Size = PLOTGPC=%ld + SizeExtra=%ld = %ld", sizeof(PLOTGPC), SizeExtra, sizeof(PLOTGPC) + SizeExtra));
if (pPlotGPC = (PPLOTGPC)LocalAlloc(LPTR, sizeof(PLOTGPC) + SizeExtra)) {
PlotGPC.SizeExtra = (WORD)SizeExtra;
CopyMemory(pData = (LPBYTE)pPlotGPC, &PlotGPC, sizeof(PLOTGPC));
pData += sizeof(PLOTGPC);
if (InitStrSize[0]) {
CopyMemory(pData, InitString, InitStrSize[0]); pPlotGPC->InitString.pData = (LPVOID)pData; pData += InitStrSize[1]; }
if (FormsSize[0]) {
CopyMemory(pData, AvaiForms, FormsSize[0]); pPlotGPC->Forms.pData = (LPVOID)pData; pData += FormsSize[1]; }
if (PlotPensSize[0]) {
CopyMemory(pData, AvaiPenData, PlotPensSize[0]); pPlotGPC->Pens.pData = (LPVOID)pData; pData += PlotPensSize[1]; } }
return(pPlotGPC); }
INT ParsePlotGPC( VOID )
/*++
Routine Description:
This function parses a PlotGPC from a text file
Arguments:
VOID
Return Value:
INT, >= 0 means ok, -x if a failure occured.
Development History:
09-Nov-1993 Tue 12:19:20 created
Revision History:
--*/
{ LPBYTE pToken; PPLOTKEY pPK; INT Result; LONG cy; INT i;
while (pToken = GetNextToken(NULL, NULL, 0)) {
pPK = (PPLOTKEY)&PlotKey[0];
while (pPK->pKeyword) {
if (!_stricmp(pToken, pPK->pKeyword)) {
break; }
++pPK; }
if (pPK->pKeyword) {
// fprintf(stderr, "\nFound keyword '%s'", pToken);
if ((pPK->Flags & PKF_DEFINED) && (!(pPK->Flags & PKF_MUL_OK))) {
DispError(1, "keyword '%s' section redefined.", pToken); }
if (!CheckSingleToken('{')) {
DispError(2, "expect '{' after keyword '%s. key values must enclosed in {}", pPK->pKeyword); return(-1); }
switch (pPK->Type) {
case PK_FLAG:
Result = ReadNumbers(pPK->pKeyword, (LPVOID)&(pPK->Data), (PPLOTVAL)pPK->pInfo, pPK->Count, PK_FLAG, pPK->Flags); break;
case PK_WORD: case PK_DWORD:
Result = ReadNumbers(pPK->pKeyword, (LPVOID)GET_PLOTOFF(pPK), (PPLOTVAL)pPK->pInfo, pPK->Count, pPK->Type, pPK->Flags); break;
case PK_STRING:
Result = ReadString(pPK); break;
case PK_FORMSRC:
Result = ReadFormSrc(pPK); break;
case PK_PENDATA:
Result = ReadPenData(pPK); break;
default:
Result = -1; break; }
if (Result < 0) {
return(-1); }
if (!(Result & 0x01)) {
if (!CheckSingleToken('}')) {
DispError(2, "unbalanced braces, missing '}' at end of keyword '%s'", pPK->pKeyword); return(-1); } }
if (!(Result & 0x02)) {
pPK->Flags |= PKF_DEFINED; }
} else {
DispError(2, "Unknown keyword '%s'", pToken); return(-1); } }
if (PlotGPC.Flags & PLOTF_RASTER) {
if (PlotGPC.Flags & PLOTF_COLOR) {
PlotGPC.Flags &= ~PLOTF_RTLMONO_NO_CID; }
if ((pPK->pKeyword == szRTLMonoEncode5) && (!(pPK->Flags & PKF_DEFINED))) {
Result = -1; DispError(2, "Flag keyword '%s' must defined for RASTER Plotter.", pPK->pKeyword); }
} else {
PlotGPC.Flags |= (PLOTF_NO_BMP_FONT | PLOTF_RTL_NO_DPI_XY | PLOTF_RTLMONO_NO_CID | PLOTF_RTLMONO_FIXPAL); }
//
// Find out if a required keyword is missing
//
Result = 1; pPK = (PPLOTKEY)&PlotKey[0];
while (pPK->pKeyword) {
if ((PlotGPC.Flags & PLOTF_RASTER) && (pPK->pKeyword == szRTLMonoEncode5) && (!(pPK->Flags & PKF_DEFINED))) {
Result = -1; DispError(2, "Flag keyword '%s' must defined for RASTER Plotter.", pPK->pKeyword); }
if ((pPK->Flags & PKF_REQ) && (!(pPK->Flags & PKF_DEFINED))) {
Result = -1; DispError(2, "required keyword '%s' undefined", pPK->pKeyword); }
++pPK; }
//
// Validate DeviceSize/DeviceMargins
//
if (PlotGPC.DeviceSize.cx < MIN_PLOTGPC_FORM_CX) {
DispError(2, "Invalid DeviceSize CX = %ld", PlotGPC.DeviceSize.cx); Result = -1; }
if (PlotGPC.DeviceSize.cy < MIN_PLOTGPC_FORM_CY) {
if (PlotGPC.Flags & PLOTF_ROLLFEED) {
PlotGPC.DeviceSize.cy = 15240000; // default to 50' of length
DispError(1, "Assume device length can handle up to 50 feet of paper");
} else {
PlotGPC.DeviceSize.cy = 279400; // default to 11" of length
DispError(1, "Assume device length can handle up to 11 inch of paper"); } }
if (PlotGPC.DeviceSize.cx - (PlotGPC.DeviceMargin.left + PlotGPC.DeviceMargin.right) < MIN_PLOTGPC_FORM_CX) {
DispError(3, "Invalid DeviceMargin left/right (%ld/%ld", PlotGPC.DeviceMargin.left, PlotGPC.DeviceMargin.right); Result = -1; }
if (PlotGPC.DeviceSize.cy - (PlotGPC.DeviceMargin.top + PlotGPC.DeviceMargin.bottom) < MIN_PLOTGPC_FORM_CY) {
DispError(3, "Invalid DeviceMargin top/bottom (%ld/%ld", PlotGPC.DeviceMargin.top, PlotGPC.DeviceMargin.bottom); Result = -1; }
for (i = 0; i < (INT)PlotGPC.Forms.Count; i++) {
if ((!(PlotGPC.Flags & PLOTF_ROLLFEED)) && (AvaiForms[i].Size.cy == 0)) {
DispError(3, "%s '%s', the device CANNOT handle roll paper", szFormInfo, AvaiForms[i].Name);
Result = -1; }
if ((cy = AvaiForms[i].Size.cy) == 0) {
cy = PlotGPC.DeviceSize.cy; }
if (((AvaiForms[i].Size.cx <= PlotGPC.DeviceSize.cx) && (cy <= PlotGPC.DeviceSize.cy)) || ((AvaiForms[i].Size.cx <= PlotGPC.DeviceSize.cy) && (cy <= PlotGPC.DeviceSize.cx))) {
NULL;
} else {
DispError(3, "%s '%s' size too big for device to handle", szFormInfo, AvaiForms[i].Name);
Result = -1; } }
//
// Find out if pen data must be present
//
if (PlotGPC.Flags & PLOTF_RASTER) {
if (PlotGPC.Pens.Count) {
DispError(3, "CANNOT define Pen colors for a raster device"); Result = -1; }
} else {
if (!(PlotGPC.Flags & PLOTF_NO_BMP_FONT)) {
DispError(3, "PEN plotter MUST SET '%s' to 1", szNoBmpFont); Result = -1; }
if (!(PlotGPC.Flags & PLOTF_COLOR)) {
DispError(3, "PEN plotter must specify COLOR. (ColorCap {1})"); Result = -1; }
if (PlotGPC.MaxPens > MAX_PENPLOTTER_PENS) {
DispError(3, "maximum plotter Pens allowed are %ld, you defined %ld", MAX_PENPLOTTER_PENS, PlotGPC.MaxPens);
PlotGPC.MaxPens = MAX_PENPLOTTER_PENS; Result = -1; }
if (PlotGPC.Pens.Count < PlotGPC.MaxPens) {
DispError(3, "only %ld pens out of %ld pens defined", PlotGPC.Pens.Count, PlotGPC.MaxPens); Result = -1; }
if (PlotGPC.Pens.Count > PlotGPC.MaxPens) {
DispError(3, "too many pens (%ld) defined for '%s', Maximum is %ld", PlotGPC.Pens.Count, szPenData, PlotGPC.MaxPens); Result = -1; }
for (i = 0; i < PlotGPC.MaxPens; i++) {
if (AvaiPenData[i].ColorIdx == 0xffff) {
DispError(3, "'%s' Pen #%ld undefined", szPenData, i + 1); Result = -1; } } }
if (PlotGPC.Flags & PLOTF_PAPERTRAY) {
if ((PlotGPC.PaperTraySize.cx < 0) || (PlotGPC.PaperTraySize.cy < 0)) {
DispError(3, "'%s' defined, but '%s' not defined", szPaperTrayCap, szPaperTraySize);
Result = -1;
} else if ((PlotGPC.PaperTraySize.cx == 0) || (PlotGPC.PaperTraySize.cy == 0)) {
DispError(3, "'%s': Invalid Size (%ld x %ld), must have a size", szPaperTraySize, PlotGPC.PaperTraySize.cx, PlotGPC.PaperTraySize.cy); Result = -1;
} else if ((PlotGPC.PaperTraySize.cx != PlotGPC.DeviceSize.cx) && (PlotGPC.PaperTraySize.cy != PlotGPC.DeviceSize.cx)) {
DispError(3, "'%s': Invalid Size (%ld x %ld), one of width/height must eqaul device width (%ld)", szPaperTraySize, PlotGPC.PaperTraySize.cx, PlotGPC.PaperTraySize.cy, PlotGPC.DeviceSize.cx);
Result = -1; } }
return(Result); }
VOID CopyPlotGPCToPCD( PPLOTGPC_PCD pPlotGPC_PCD, PPLOTGPC pPlotGPC )
/*++
Routine Description:
This function copies a PLOTGPC structure into a PLOTGPC_GPC structure.
Arguments:
pPlotGPC_PCD - destination pPlotGPC - 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_PCD, pPlotGPC, (LPBYTE)&(pPlotGPC_PCD->InitString) - (LPBYTE)pPlotGPC_PCD);
// We need the size of PLOTGPC_PCD here, not the size of PLOTGPC
pPlotGPC_PCD->cjThis = sizeof(PLOTGPC_PCD); pPlotGPC_PCD->InitString.Count = pPlotGPC->InitString.Count; pPlotGPC_PCD->InitString.SizeEach = pPlotGPC->InitString.SizeEach; if (pPlotGPC->InitString.pData) { pPlotGPC_PCD->InitString.pData = (DWORD)(ULONG_PTR)(pPlotGPC->InitString.pData) - (sizeof(PLOTGPC) - sizeof(PLOTGPC_PCD)); } else { pPlotGPC_PCD->InitString.pData = 0; }
pPlotGPC_PCD->Forms.Count = pPlotGPC->Forms.Count; pPlotGPC_PCD->Forms.SizeEach = pPlotGPC->Forms.SizeEach; if (pPlotGPC->Forms.pData) { pPlotGPC_PCD->Forms.pData = (DWORD)(ULONG_PTR)(pPlotGPC->Forms.pData) - (sizeof(PLOTGPC) - sizeof(PLOTGPC_PCD)); } else { pPlotGPC_PCD->Forms.pData = 0; }
pPlotGPC_PCD->Pens.Count = pPlotGPC->Pens.Count; pPlotGPC_PCD->Pens.SizeEach = pPlotGPC->Pens.SizeEach; if (pPlotGPC->Pens.pData) { pPlotGPC_PCD->Pens.pData = (DWORD)(ULONG_PTR)(pPlotGPC->Pens.pData) - (sizeof(PLOTGPC) - sizeof(PLOTGPC_PCD)); } else { pPlotGPC_PCD->Pens.pData = 0; } }
VOID WritePlotGPCToFile( PPLOTGPC pPlotGPC )
/*++
Routine Description:
This routine writes out pPlotGPC into a .pcd file. A FILE* pointer to the file should be present in OutFile.
Arguments:
pPlotGPC - pointer to the PLOTGPC structure to be written. Some elements maybe modified in *pPlotGPC in this function.
Return Value:
None
Development History:
1 Feb 2000
Revision History:
--*/
{ PLOTGPC_PCD PlotGPC_PCD;
//
// make the references to offset
//
if (pPlotGPC->InitString.pData) {
(LPBYTE)pPlotGPC->InitString.pData -= (ULONG_PTR)pPlotGPC; }
if (pPlotGPC->Forms.pData) {
(LPBYTE)pPlotGPC->Forms.pData -= (ULONG_PTR)pPlotGPC; }
if (pPlotGPC->Pens.pData) {
(LPBYTE)pPlotGPC->Pens.pData -= (ULONG_PTR)pPlotGPC; }
CopyPlotGPCToPCD(&PlotGPC_PCD, pPlotGPC);
if (OutFile) {
fwrite(&PlotGPC_PCD, PlotGPC_PCD.cjThis, 1, OutFile);
fwrite((LPBYTE)pPlotGPC + pPlotGPC->cjThis, PlotGPC.SizeExtra, 1, OutFile); }
}
//
//***************************************************************************
// C main function entry point
//***************************************************************************
//
#define MAIN_SHOW_USAGE 0x0001
int __cdecl main( INT argc, CHAR **argv ) { PPLOTGPC pPlotGPC = NULL; INT RetVal = 1; UINT Flags = 0; UINT i; LPSTR pOutFile = NULL; PPLOTKEY pPK; PPLOTVAL pPV;
memset(AvaiPenData, 0xff, sizeof(AvaiPenData));
pPV = PenColorVal; MaxPCValLen = 0;
while (pPV->pValName) {
if ((i = (UINT)strlen(pPV->pValName)) > MaxPCValLen) {
MaxPCValLen = i; }
++pPV; }
pPK = &PlotKey[0]; MaxKeywordLen = 0;
while (pPK->pKeyword) {
if ((pPK->KeywordLen = (WORD)strlen(pPK->pKeyword)) > MaxKeywordLen) {
MaxKeywordLen = pPK->KeywordLen; }
++pPK; }
InFile = NULL; OutFile = NULL;
if (argc > 1) {
for (--argc, ++argv; argc > 0; --argc, ++argv) {
if (**argv == '-' ) {
switch (*(*argv + 1)) {
case '?': case 'h': case 'H':
Flags |= MAIN_SHOW_USAGE; RetVal = -1; break; }
} else if (InFile) {
if ((OutFile) && (OutFile != stdout)) {
DispError(0, "Unknown parameter '%s'", *argv); Flags |= MAIN_SHOW_USAGE; RetVal = 0;
} else if ((OutFile = fopen(pOutFile = *argv, "wb")) == NULL) {
DispError(0, "Cannot open output file '%s'\n", *argv); RetVal = 0; }
} else {
if (SUCCEEDED(StringCchCopyA(InFileName, CCHOF(InFileName), *argv))) {
if ((InFile = fopen(*argv, "rt" )) == NULL) {
DispError(0, "Cannot open input file '%s'\n", *argv); RetVal = -1; } } else { DispError(0, "Wrong filename '%s'\n", *argv); RetVal = -1; }
} }
} else {
Flags |= MAIN_SHOW_USAGE; RetVal = -1; }
if (Flags & MAIN_SHOW_USAGE) {
ShowUsage(); }
if ((RetVal >= 0) && (InFile)) {
RetVal = ParsePlotGPC(); }
if (RetVal >= 0) {
//
// if (InFile) {
//
// ShowUndefined();
// }
//
if (pPlotGPC = GetFullPlotGPC()) {
ValidatePlotGPC(pPlotGPC); ShowPlotGPC(pPlotGPC); WritePlotGPCToFile(pPlotGPC); }
} else {
fprintf(stdout, "\n"); }
if (InFile) {
fclose(InFile); }
if ((OutFile) && (OutFile != stdout)) {
fclose(OutFile); }
#if (DBG && GPC_READ_TEST)
if (pOutFile) {
LPWSTR pwStr = NULL; PPLOTGPC pReadPlotGPC; UINT Idx = 0;
pwStr = str2MemWstr(pOutFile);
if (pReadPlotGPC = ReadPlotGPCFromFile(pwStr)) {
ShowPlotGPC(pReadPlotGPC);
//
// make the references to offset
//
if (pReadPlotGPC->InitString.pData) {
(LPBYTE)pReadPlotGPC->InitString.pData -= (DWORD)pReadPlotGPC; }
if (pReadPlotGPC->Forms.pData) {
(LPBYTE)pReadPlotGPC->Forms.pData -= (DWORD)pReadPlotGPC; }
if (pReadPlotGPC->Pens.pData) {
(LPBYTE)pReadPlotGPC->Pens.pData -= (DWORD)pReadPlotGPC; }
if ((pPlotGPC->cjThis != pReadPlotGPC->cjThis) || (pPlotGPC->SizeExtra != pReadPlotGPC->SizeExtra)) {
DispError(-1, "Write / Read Size different");
} else {
UINT i; LPBYTE pP1; LPBYTE pP2;
pP1 = (LPBYTE)pPlotGPC; pP2 = (LPBYTE)pReadPlotGPC; Idx = pPlotGPC->cjThis + pPlotGPC->SizeExtra;
for (i = 0; i < Idx; i++) {
if (*pP1 != *pP2) {
fprintf(stdout, "\nOffset 0x%04x: Write = %02x, Read = %02x", i, *pP1, *pP2); }
++pP1; ++pP2; } }
LocalFree(pReadPlotGPC);
} else {
DispError(-1, "ReadPlotGPCFromFile(%s) failed", pOutFile); }
if (pwStr) {
LocalFree(pwStr); } } #endif
if (pPlotGPC) {
LocalFree((HLOCAL)pPlotGPC); }
return(RetVal); }
|