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.
3235 lines
76 KiB
3235 lines
76 KiB
/*++
|
|
|
|
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);
|
|
}
|