home *** CD-ROM | disk | FTP | other *** search
- program HPGLVIEW;
- {-----------------------------------------------------------------------------}
- (* An HPGL viewer
-
- The viewer takes a file of HPGL commands and displays the plot commands
- on the screen.
-
- It always represents the page (A3 or A4) lying sideways on the
- screen, to preserve the maximum resolution, and ignores the aspect ratio
- of the screen for the same reason.
-
- Its designed to show you what the plot looks like on the page not be
- an absolute mimic of a plot. If you need absolute precision, plot it.
-
- -------------------------------------------------------------------------------
- HPGLVIEW - a on-screen Previewer for HPGL files
-
- Copyright (C) 1991 Giovanni S. Moretti
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- -----------------------------------------------------------------------------
- Giovanni Moretti | EMAIL: G.Moretti@massey.ac.nz
- Computer Centre, Massey University |
- Palmerston North, New Zealand |
- -----------------------------------------------------------------------------
-
- Please send me a copy of any major hacks/improvements so I can coordinate
- any new releases.
-
- HP-GL is (probably) a trademark of Hewlett-Packard Company.
-
- *)
- {-----------------------------------------------------------------------------}
- { RCS Control Information
- $Author: Giovanni_Moretti $
- $Date: 91/04/18 15:57:59 $
- $Revision: 1.1 $
- $Log: hpglview.pas $
- Revision 1.1 91/04/18 15:57:59 ROOT_DOS
- Initial revision
-
- }
- uses graph, dos, crt, smalfont, { Like FONTS.PAS with only SMALLFONT left}
- drivers;
-
- const A3_char_width = 0.285; {cm}
- A3_char_height = 0.375;
-
- A4_char_width = 0.187;
- A4_char_height = 0.269;
-
- unknown_max = 100;
-
- var pen_down : boolean;
- cmd : string; {Current HPGL command being done}
- x, y, x1,y1 : real; {and the numeric arguments to this cmd}
- lbl : string; {or a character string arg for LB cmd }
-
- filename : string;
- inf : text; {Input file}
-
- screen_max_X : integer; {No of dots across screen -1}
- screen_max_Y : integer; {and number down }
-
- Graphics_Driver : integer; { for BGI - may be set manually with /G }
- Graphics_mode : integer; { for BGI - may be set manually with /G }
- {-----------------------------------------------------------------------------}
- use_plotter_units : boolean; {If TRUE => NO Scaling, FALSE => Scale}
-
- x_max : real; {Maximum and Minimum values as defined}
- x_min : real; {by the SC (Scale) command }
- y_max : real;
- y_min : real;
-
- x_p1, y_p1 : integer;
- x_p2, y_p2 : integer;
- {-----------------------------------------------------------------------------}
- Paper_size : integer; {Either a 3 or 4 (A3 or A4) }
- X_plot_area_mm : integer;
- Y_plot_area_mm : integer;
- args : boolean;
- hard_clip_X : integer;
- hard_clip_Y : integer;
-
- colour : integer; {Current colour from video palette}
- {-----------------------------------------------------------------------------}
- char_height : real; {Currently set Character Height and Width}
- char_width : real; {Always defined - used by SI and DI cmds }
-
- text_direction : word; {Used by DI cmd }
- {-----------------------------------------------------------------------------}
- symbol_mode : boolean; {Whether a symbol is drawn on a PA or PR }
- symbol_char : char; {command - used by the SM instruction }
- {-----------------------------------------------------------------------------}
- {Remember unimplemented commands in this array for later }
-
- unknown_cmds : array [1..unknown_max] of string;
- unknown_count : integer;
-
- cnt : integer;
- pause : char;
-
- ch : char;
- debug : boolean;
- digits : set of char;
- i : integer; {General Purpose Integer}
- finished : boolean;
-
- initialise_cmd_count : integer; {Used to pause on 2nd, 3rd ... IN cmd}
- IP_cmd_count : integer; {Used to change colours on 2nd .. IP cmd}
- auto_detect_graphics : boolean; {altered be /G command line option }
- {-----------------------------------------------------------------------------}
-
- procedure SET_DEFAULT_TEXT_DIRECTION;
- begin
- text_Direction:= HorizDir;
- SetTextJustify(LeftText, BottomText);
- end;
-
- {-----------------------------------------------------------------------------}
- { Set up the appropriate scaling factors to draw text of the size defined by
- HEIGHT and WIDTH.
-
- HEIGHT and WIDTH are remembered in CHAR_HEIGHT and CHAR_WIDTH so
- this procedure can be reused if TEXT_DIRECTION is redefined.
-
- This procedure is used whenever it is necessary to change either
- text size or direction.
- }
-
- procedure SET_TEXT_SIZE (width, height : real); {Arguments are in Centimetres}
-
- var x_top, x_bottom, y_top, y_bottom : integer;
- width_in_mm, height_in_mm : real;
- scale_x, scale_y : real;
- letter_height, letter_width : integer;
-
- begin
- {Scale ratios by 100 so as not to lose too much precision on ROUND()}
- x_top:= 100; x_bottom:= 100; y_top:= 100; y_bottom:= 100;
-
- {This Section Gives "Approximately" the correct size lettering }
- SetTextStyle(SmallFont, HorizDir, 2);
- letter_height:= TextHeight('M'); {Remember Size of Standard Characters}
- letter_width := TextWidth('M');
-
- width_in_mm := letter_width / screen_max_X * X_plot_area_mm;
- scale_x:= (width*10) / width_in_mm; { *10 as SI args are in cm}
- if scale_x > 10 then scale_x:= 10;
- if scale_X > 1 then x_top := round(scale_x *100)
- else x_bottom:= round(1/scale_X *100);
-
- height_in_mm:= Letter_Height / screen_max_Y * Y_plot_area_mm;
- scale_y:= (height*10) / height_in_mm; { *10 as SI args are in cm}
- if scale_y > 10 then scale_y:= 10;
- if scale_y > 1 then Y_top := round(scale_Y *100)
- else Y_bottom:= round(1/scale_Y *100);
-
- SetUserCharSize(x_top, x_bottom, y_top, y_bottom);
- SetTextStyle(smallFont, text_direction, UserCharSize);
- end;
-
- {-----------------------------------------------------------------------------}
-
- procedure SET_DEFAULT_TEXT_SIZE;
- begin
- if paper_size = 4 then { A4 Paper }
- begin
- char_height := A4_char_height;
- char_width := A4_char_width;
- end
- else { A3 Paper }
- begin
- char_width := A3_char_width;
- char_height := A3_char_height;
- end;
- set_text_size(char_width, char_height);
- end;
- {-----------------------------------------------------------------------------}
-
- procedure SET_P1_P2 (x, y, x1, y1 : integer);
- begin
- x_p1:= x;
- y_p1:= y;
- x_p2:= x1;
- y_p2:= y1;
- end;
- {-----------------------------------------------------------------------------}
-
- procedure SET_DEFAULT_P1_P2;
- begin
- if paper_size = 4 then { A4 Paper }
- begin
- x_p2 := 10430;
- x_p1 := 430;
- y_p2 := 7400;
- y_p1 := 200;
- end
- else { A3 Paper }
- begin
- x_p2 := 15580;
- x_p1 := 380;
- y_p2 := 10430;
- y_p1 := 430;
- end;
- end;
- {-----------------------------------------------------------------------------}
-
- procedure SET_PAPER_SIZE ( default : integer);
- begin
- if default <> 0 then paper_size:= default
- else
- repeat
- write('A4 or A3 paper (3/4) : ');
- readln(paper_size);
- until paper_size in [3,4];
-
- if paper_size = 4 then
- begin { A4 Paper }
- X_plot_area_mm:= 270;
- Y_plot_area_mm:= 190;
- hard_clip_X := 10870;
- hard_clip_Y := 7600;
- end
- else { A3 Paper }
- begin
- X_plot_area_mm:= 399;
- Y_plot_area_mm:= 271;
- hard_clip_X := 15970;
- hard_clip_Y := 10870;
- end;
- end;
-
- {-----------------------------------------------------------------------------}
- {Search the list of already Unknown Commands to see if the current one has
- already been added to the list
- }
-
- function SEEN_BEFORE (cmd : string) : boolean;
- var i : integer;
- found : boolean;
- begin
- i:= 0;
- found:= false;
- while (i < unknown_count) and not found do
- begin
- i:= i+1;
- if unknown_cmds[i] = cmd then found:= true;
- end;
- seen_before:= found;
- end;
- {-----------------------------------------------------------------------------}
-
- { READARG - a version of READ-A-NUMBER that will handle numbers that start
- with a decimal point (no leading digit)
-
- On exit skip past any trailing terminators/separators
- }
-
- procedure READARG (var num: real);
- label 99;
- var seen_point : boolean;
- divisor : integer;
- is_negative: boolean;
- begin
- while not eof (inf) and not (ch in digits+['-']) do
- read(inf, ch); {Just in Case}
-
- if eof(inf) then goto 99;
-
- num:= 0;
- seen_point := false;
- divisor := 1;
- is_negative:= false;
-
- if ch = '-' then begin is_negative:= true; read(inf, ch); end;
-
- while ch in digits do
- begin
- if ch = '.' then seen_point:= true
- else
- begin
- if seen_point then divisor:= divisor * 10;
- num:= num*10 + (ord(ch)-ord('0'));
- end;
- read(inf, ch);
- end;
-
- if seen_point then num:= num / divisor;
-
- if is_negative then num:= -num;
-
- (* if ch in [',',';'] then read(inf, ch); {Skip past terminator/separator}*)
- 99:
- end;
- {-----------------------------------------------------------------------------}
- { GET THE NEXT HPGL COMMAND into "cmd" }
-
- { On EXIT: "cmd" - contains HPGL command }
-
- procedure GET_CMD;
- label 99;
- begin
-
- { Skip past any non-alphabetic characters }
-
- while not eof(inf) and not (ch in ['A'..'Z','a'..'z']) do
- read(inf, ch); {Skip junk}
-
- if eof(inf) then begin cmd:= 'ZZ'; goto 99; end;
-
- cmd := '';
- cmd:= concat(cmd, upcase(ch));
- read(inf, ch);
- if ch <> ';' then
- begin
- cmd:= concat(cmd, upcase(ch));
- read(inf, ch);
- end;
- 99:
- end;
- {-----------------------------------------------------------------------------}
- procedure READ_OR_RESET_ARGS (num_of_args : integer);
- begin
- if ch = ';' then args:= false
- else
- begin
- readarg(x);
- if num_of_args >= 2 then readarg(y);
- if num_of_args >= 3 then readarg(x1);
- if num_of_args = 4 then readarg(y1);
- args:= true;
- end
- end;
-
- {-----------------------------------------------------------------------------}
-
- { SCALE THE PARAMETERS X & Y INTO SCREEN UNITS }
-
- {If scaling is active the incoming values should be between:
-
- X_min .. X_max which is scaled to fit between x_p1 .. x_p2 and ditto for Y
-
- If not, then use plotter units and scale these to fit onto the screen
- }
-
- procedure SCALE (var x, y : integer);
- begin
- if use_plotter_units then
- begin
- x:= round( x/(hard_clip_X) * screen_max_X);
- y:= screen_max_y - round( y/(hard_clip_y) * screen_max_Y);
- end
- else {Scaling is Active - Fit plot Using Coords P1 and P2 - defined in IP cmd}
- begin
- x:= round((((x-x_min)/(x_max-x_min)) * (x_p2-X_p1) + x_p1)/Hard_clip_X * Screen_max_X);
- y:= round((((y-y_min)/(y_max-y_min)) * (y_p2-y_p1) + y_p1)/Hard_clip_Y * Screen_max_Y);
- y:= screen_max_y - y;
- end;
- end;
-
- {-----------------------------------------------------------------------------}
- {PU - PEN UP - Set Current co-ord if any arguments}
-
- procedure do_PU_cmd;
-
- var x_int, y_int: integer;
- begin
- read_or_reset_args(2);
- if args then
- begin
- x_int:= round(x);
- y_int:= round(y);
- scale(x_int, y_int);
- moveTo(x_int, y_int);
- end;
- pen_down:= false;
- end;
- {----------------------------------------------------------------------------}
-
- {PD - PEN DOWN - Move to and Draw if a co-ord present }
-
- procedure do_PD_cmd;
-
- var x_int, y_int: integer;
- begin
- read_or_reset_args(2);
- if args then
- begin
- x_int:= round(x);
- y_int:= round(y);
- scale(x_int, y_int);
- lineto(x_int,y_int);
- end;
- pen_down:= true;
- end;
-
-
- {-----------------------------------------------------------------------------}
-
- { PA - POINT ABSOLUTE - Move to x,y, Drawing if PEN DOWN}
-
- procedure do_PA_cmd;
-
- var x_int, y_int: integer;
- save_x, save_y : integer;
- begin
- read_or_reset_args(2);
- if args then
- begin
- x_int:= round(x);
- y_int:= round(y);
- scale(x_int, y_int);
- if pen_down then lineto(x_int,y_int)
- else moveto(x_int,y_int);
- if symbol_mode then {If symbol-mode then PLOT symbol Char at Destination}
- begin
- save_x:= getX; save_y:= getY;
- outtext(symbol_char);
- moveto(save_x, save_y); {Ensure current point doesn't change}
- end;
- end;
- end;
-
-
- {-----------------------------------------------------------------------------}
-
- { PR - POINT RELATIVE - Moveto or Draw relative to Last position}
-
- procedure do_PR_cmd;
-
- var x_int, y_int: integer;
- save_x, save_y : integer;
- begin
- read_or_reset_args(2);
- if args then
- begin
- x_int:= round(x);
- y_int:= round(y);
- scale(x_int, y_int);
- x:= getX;
- y:= GetY;
- if pen_down then lineto(GetX+x_int, GetY+y_int)
- else moveto(GetX+x_int, GetY+y_int);
- if symbol_mode then {Plot symbol character at endpoint}
- begin
- save_x:= getX; save_y:= getY;
- outtext(symbol_char);
- moveto(save_x, save_y);
- end;
- end;
- end;
-
- {-----------------------------------------------------------------------------}
-
- { LB - LABEL - Output text in current SIze and DIrection}
-
- procedure do_LB_cmd;
- begin
- lbl:= '';
- while ch <> #03 do
- begin
- lbl:= concat(lbl, ch);
- read(inf, ch);
- end;
- read(inf, ch); {skip past ";"}
- outtext(lbl);
- end;
-
- {-----------------------------------------------------------------------------}
-
- { CI - DRAW CIRCLE - centred at current point }
-
- { This should really take into account the current scaling so you can draw
- elipses (I think). At the moment it always draws perfect circles, using the
- X size as its Radius
- }
-
- procedure do_CI_cmd;
-
- begin
- read_or_reset_args(1); { read Radius }
- x:= x/(hard_clip_X) * screen_max_X;
- circle(getX, getY, round(x));
- end;
-
- {-----------------------------------------------------------------------------}
- { IP - Set the Initial Points for use by the SCale command }
-
- { To display Concatenated Plots in a different colour, it swaps colours, if
- available on each IP cmd. This is useful for viewing different layers of
- a printed circuit layout
- }
-
- procedure do_IP_cmd;
- begin
- read_or_reset_args(4);
- if not args then set_default_P1_P2
- else
- begin
- set_P1_P2(round(x), round(y), round(x1), round(y1));
- colour:= colour - 1;
- if colour = 0 then colour:= GetMaxColor;
- setcolor(colour);
- end;
- end;
-
- {-----------------------------------------------------------------------------}
-
- { SC - Define Coordinate Scale }
-
- { If there are arguments, scale all following coordinates so that the
- ranges defined by the SCALE command lies within the PLOT AREA defined
- by the IP command coordinates.
-
- If no arguments the revert to using absolute plotter coordinates.
- }
-
- procedure do_SC_cmd;
- begin
- if ch = ';' then args:= false
- else
- begin {Don't use READ_AND_RESET as args in wrong order (x,x1,y,y1) }
- readarg(x); readarg(x1); readarg(y); readarg(y1);
- end;
- if args = false then use_plotter_units:= true
- else
- begin {Scale Command - from now on coords will arrive }
- x_min:= x; { scaled between Xmin-Xmax, Ymin-max}
- y_min:= y;
- x_max:= x1;
- y_max:= y1;
- use_plotter_units:= false;
- end;
- end;
-
- {-----------------------------------------------------------------------------}
- { IN - INITIALISE - Beep and wait for a keypress}
-
- procedure do_IN_cmd;
- begin
- set_default_P1_P2;
- pen_down:= false;
- if initialise_cmd_count > 0 then
- begin
- write(#7);
- pause:= readkey;
- end;
- initialise_cmd_count:= initialise_cmd_count+1;
- end;
-
- {-----------------------------------------------------------------------------}
-
- { SP - SET PEN - Usually used to change PEN Colour}
-
- procedure do_SP_cmd;
- begin
- read_or_reset_args(1);
- if args then {Display in a different colour if possible}
- if trunc(x) in [1..GetMaxColor] then
- setcolor(GetMaxColor - round(x) + 1)
- else
- begin
- colour:= colour-1;
- if colour = 0 then colour:= GetMaxColor;
- SetColor(Colour);
- end;
- end;
-
- {-----------------------------------------------------------------------------}
- { SI - Define TEXT SIZE in Centimetres, or reset it to the Default size }
-
- procedure do_SI_cmd;
- begin
- read_or_reset_args(2);
- if args = false then set_default_text_size
- else
- begin
- set_text_size(x,y);
- {Now to remember for later - for use by DI instruction}
- char_width := x;
- char_height:= y;
- end;
- end;
-
- {-----------------------------------------------------------------------------}
- { SR - Set Text Size - Relative to Scaling Points }
-
- { This bit has only been loosely tested (ie once) }
-
- procedure do_SR_cmd;
-
- var actual_width, actual_height : real; {for SR cmd}
- begin
- read_or_reset_args(2);
- if args = false then set_default_text_size
- else
- begin
- actual_width := x/100 * (x_p2 - x_p1) * 0.0025; {cm}
- actual_height:= y/100 * (y_p2 - y_p1) * 0.0025; {cm}
- set_text_size(actual_width, actual_height);
- {Now to remember for later - for use by DI instruction}
- char_width := actual_width;
- char_height:= actual_height;
- end;
- end;
-
- {-----------------------------------------------------------------------------}
- { SM - SYMBOL MODE - Plot a symbol after each plot/move}
-
- procedure do_SM_cmd;
- begin
- if ch = ';' then symbol_mode:= false
- else
- begin
- symbol_mode:= true;
- symbol_char:= ch;
- end;
- read(inf, ch);
- end;
-
- {-----------------------------------------------------------------------------}
- { DI/DR - Set Orientation to display following Text }
-
- { Ideally we should be able to Rotate the direction of the text
- (ie horizontal but upside down, but Turbo's toolbox doesn't handle this
- Instead we'll use the SetTextJustify to do it in 90 degree increments
- }
-
- procedure do_DI_or_DR_cmd;
- begin
- read_or_reset_args(2);
- if not args then set_Default_Text_direction {set to Defaults}
- else
- begin
- if abs(x) >= abs(y) then {RUN > RISE}
- begin
- text_Direction:= HorizDir;
- if x > 0 then SetTextJustify(LeftText, BottomText) { 0 degrees}
- else SetTextJustify(RightText, TopText); {180 degrees}
- end
- else
- begin
- text_direction:= VertDir;
- if y >= 0 then SetTextJustify(RightText, BottomText) { 90 degrees}
- else SetTextJustify(LeftText, TopText); {270 degrees}
- end;
-
- {Now call SET_TEXT_SIZE to alter TextDirection, using prev WIDTH&HEIGHT}
- set_text_size(char_width, char_height); {Either Default or Set by SI instr}
- end;
- end;
-
- {-----------------------------------------------------------------------------}
- {DF - Default - Reset various parameters to known state }
-
- procedure do_DF_cmd;
- begin
- set_default_text_direction;
- symbol_mode:= false;
- use_plotter_units:= true; {Turn off scaling}
- end;
- {-----------------------------------------------------------------------------}
-
- { DECODE and EXECUTE the HPGL command in "cmd" }
-
-
- procedure DECODE_and_EXECUTE_HPGL_COMMAND;
- begin
-
- if cmd = 'PU' then do_PU_cmd
- else if cmd = 'PD' then do_PD_cmd
- else if cmd = 'PA' then do_PA_cmd
- else if cmd = 'PR' then do_PR_cmd
- else if cmd = 'LB' then do_LB_cmd
- else if cmd = 'CI' then do_CI_cmd
- else if cmd = 'IP' then do_IP_cmd
- else if cmd = 'SC' then do_SC_cmd
- else if cmd = 'IN' then do_IN_cmd
- else if cmd = 'SP' then do_SP_cmd
- else if cmd = 'SI' then do_SI_cmd
- else if cmd = 'SR' then do_SR_cmd
- else if cmd = 'SM' then do_SM_cmd
- else if cmd = 'DF' then do_DF_cmd
- else if cmd = 'DI' then do_DI_or_DR_cmd
- else if cmd = 'DR' then do_DI_or_DR_cmd
- else if cmd = 'VS' then read_or_reset_args(1) {VELOCITY SET (of Pen) - Ignore}
- else if cmd = 'ZZ' then {End of file Sentinel - ignore this cmd}
- else {UNIMPLEMENTED COMMAND}
- if unknown_count = unknown_max then finished:= true {abort}
- else
- begin {Add Unknown Command to list of unknowns}
- unknown_count:= unknown_count+1;
-
- while (ch <> ';') and (not eof(inf)) do
- begin
- if (length(cmd) < 78) then cmd:= concat(cmd, ch);
- read(inf, ch);
- end;
- unknown_cmds[unknown_count]:= cmd;
- end;
- end;
- {-----------------------------------------------------------------------------}
-
- procedure VIEW_UNKNOWN_COMMANDS;
- var i : integer;
- ch : char;
- begin
- clrscr;
- if unknown_count = 0 then Writeln('No unimplemented HPGL commands encountered')
- else
- begin
- writeln(' UNIMPLEMENTED HPGL COMMANDS');
- writeln;
- for i:= 1 to unknown_count do
- begin
- writeln(unknown_cmds[i]);
- if (unknown_count mod 20 ) = 0 then
- begin
- write('Press any key : '); ch:= readkey;
- end;
- end;
- writeln;
- end;
- ch:= readkey;
- end;
- {-----------------------------------------------------------------------------}
-
- procedure Graphics_Error(error: string);
- begin
- Writeln(error, ': ', GraphErrorMsg(GraphResult));
- Halt(1);
- end;
-
-
- procedure REGISTER_GRAPHICS_BITS;
- begin
- { Register all the drivers }
- if RegisterBGIdriver(@CGADriverProc) < 0 then graphics_error('CGA');
- if RegisterBGIdriver(@EGAVGADriverProc) < 0 then graphics_error('EGA/VGA');
- if RegisterBGIdriver(@HercDriverProc) < 0 then graphics_error('Herc');
- if RegisterBGIdriver(@ATTDriverProc) < 0 then graphics_error('AT&T');
- if RegisterBGIdriver(@PC3270DriverProc) < 0 then graphics_error('PC 3270');
-
-
- { Register SMALL Font - only one used }
- if RegisterBGIfont(@SmallFontProc) < 0 then graphics_error('Small Font');
-
- if auto_detect_graphics then
- Graphics_Driver := Detect; { autodetect the hardware }
-
- InitGraph(Graphics_Driver, Graphics_Mode, ''); { activate graphics }
- if GraphResult <> grOk then { any errors? }
- begin
- Writeln('Graphics init error: ', GraphErrorMsg(Graphics_Driver));
- Halt(1);
- end;
- end;
-
- procedure OPTIONS_ERROR (msg : string);
- begin
- writeln(msg);
- writeln('Type ');
- writeln(' HPGLVIEW ? ');
- writeln('for a list of valid options');
- writeln;
- halt(1);
- end;
- {-----------------------------------------------------------------------------}
- {SET THE GRAPHICS DRIVER and MODE accordin to the Supplied arguments }
-
- { Graphics Driver and Mode are set up via a command line option of the form:
-
- /G graphics-driver graphics-mode
-
- Check that the mode is valid for the indicated driver, ABORT if it isn't.
- }
-
- procedure MANUAL_GRAPHICS_SETUP (driver_no, mode_no : integer);
- var status : integer;
- begin
- if paramcount < mode_no then options_error ('Must define Graphics Driver & Mode')
- else
- begin
- val(paramstr(driver_no), graphics_driver, status);
- if status <> 0 then options_error('Graphics driver must be integer');
-
- if not (graphics_driver in [1..10]) then
- options_error(concat('Invalid Graphics Driver : ', paramstr(driver_no)));
-
- val(paramstr(mode_no), graphics_mode, status);
- if status <> 0 then
- options_error(concat('Graphics mode must be integer : ',paramstr(mode_no)));
-
- {Check the Specified Mode is valid for Defined Driver}
- case graphics_driver of
- {CGA} 1 :if not (graphics_mode in [0..4]) then options_error('Graphics mode for CGA must be 0..4');
- {MCGA} 2 :if not (graphics_mode in [0..5]) then options_error('Graphics mode for MCGA must be 0..5');
- {EGA } 3 :if not (graphics_mode in [0..1]) then options_error('Graphics mode for EGA must be 0..1');
- {EGA64} 4 :if not (graphics_mode in [0..1]) then options_error('Graphics mode for EGA64 must be 0..1');
- {EGAMono} 5 :if not (graphics_mode in [3 ]) then options_error('Graphics mode for EGAMono must be 3');
- {IBM8514} 6 :if not (graphics_mode in [0 ]) then options_error('Graphics mode for IBM8514 must be 0');
- {HercMono} 7 :if not (graphics_mode in [0 ]) then options_error('Graphics mode for HercMono must be 0');
- {ATT400} 8 :if not (graphics_mode in [0..5]) then options_error('Graphics mode for ATT400 must be 0..5');
- {VGA} 9 :if not (graphics_mode in [0..2]) then options_error('Graphics mode for VGA must be 0..2');
- {PC3270} 10 :if not (graphics_mode in [0 ]) then options_error('Graphics mode for PC3270 must be 0');
- end; {case}
- end;
- end;
-
- procedure display_licence;
- begin
- clrscr;
- writeln(' HPGLVIEW - a on-screen Previewer for HPGL files');
- writeln(' Copyright (C) 1991 Giovanni S. Moretti');
- writeln('');
- writeln(' This program is free software; you can redistribute it and/or modify');
- writeln(' it under the terms of the GNU General Public License as published by');
- writeln(' the Free Software Foundation; either version 1, or (at your option)');
- writeln(' any later version.');
- writeln('');
- writeln(' This program is distributed in the hope that it will be useful,');
- writeln(' but WITHOUT ANY WARRANTY; without even the implied warranty of');
- writeln(' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the');
- writeln(' GNU General Public License for more details.');
- writeln('');
- writeln(' You should have received a copy of the GNU General Public License');
- writeln(' along with this program; if not, write to the Free Software');
- writeln(' Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.');
- writeln('-----------------------------------------------------------------------------');
- writeln(' Giovanni Moretti | EMAIL: G.Moretti@massey.ac.nz');
- writeln(' Computer Centre, Massey University | ');
- writeln(' Palmerston North, New Zealand |');
- writeln('-----------------------------------------------------------------------------');
- writeln('Please send me copies of any major improvements so I can coordinate new');
- writeln('versions.');
- writeln;
- write('Press any key for help screen : '); ch:= readkey;
- end;
- {-----------------------------------------------------------------------------}
- procedure QUICK_HELP;
- begin
- display_licence;
- clrscr;
- writeln(' ********* HPGLVIEW v1.0 - A Screen Previewer for HPGL files *********');
- writeln('');
- writeln('This program will display the contents of an HPGL file, normally intended for');
- writeln('a plotter, on the PC''s screen. The screen is treated as an A3 or A4 page and');
- writeln('aspect ratio effects are ignored to maximise the available resolution.');
- writeln('');
- writeln(' HPGLVIEW <filename> [/A3 | /A4 ] [/G graphics-driver graphics-mode ] [/D]');
- writeln('');
- writeln(' Options : /A3 /A4 - Paper size, /G - Graphics Mode, /D Show unknown HPGL cmds');
- writeln(' Defaults: A4 page, Autodetect graphics driver, Ignore unknown cmds');
- writeln;
- writeln('GRAPHICS DRIVERS AND (VALID MODES): Try mode 0 if unsure.');
- writeln('CGA : 1(0-4) CGA : 2(0-5) EGA: 3(0-1) EGA64: 4(0-1) EGAmono: 5(3)');
- writeln('IBM8514: 6(0) HercMono: 7(0) ATT400: 8(0-5) VGA: 9(0-2) PC3270: 10(0)');
- writeln('');
- writeln('Recognised HPGL Commands');
- writeln(' PA, PU, PD, PR, LB, CI, VS, SP, IP, SC, SM, SI, DI, IN, DR, SR, DF');
- writeln('');
- writeln('Plotter Limits: A4 - Plot area 270x190mm, Hard limits X/Y = 10870x 7600');
- writeln(' A3 399x271mm 15970x10870');
- writeln;
- writeln('written by Giovanni Moretti Email: G.Moretti@massey.ac.nz');
- writeln;
- halt(1);
- end;
-
- {----------------------------------------------------------------------------}
- { Decode in execute the command line options (if any ) }
-
- procedure SET_OPTIONS;
- var next : integer;
- begin
- debug:= false;
- paper_size:= 4;
- auto_detect_graphics:= true;
-
- next:= 2;
- while next <= paramcount do
- begin
- if (paramstr(next) = '/h') or (paramstr(next) = '/H') then quick_help
- else
- if (paramstr(next) = '/a3') or (paramstr(next) = '/A3') then
- paper_size:= 3
- else
- if (paramstr(next) = '/a4') or (paramstr(next) = '/A4') then
- paper_size:= 4
- else
- if (paramstr(next) = '/d') or (paramstr(next) = '/D') then debug:= true
- else
- if (paramstr(next) = '/g') or (paramstr(next) = '/G') then
- begin
- auto_detect_graphics:= false;
- manual_graphics_setup(next + 1, next+2);
- next:= next+2;
- end
- else options_error(concat('Unknown Option : ',paramstr(next)));
- next:= next+1;
- end;
- set_paper_size(paper_size);
- end; {set_options}
- {----------------------------------------------------------------------------}
- { MAINLINE }
- begin
- digits:= ['0'..'9','.'];
-
- unknown_count := 0;
- for i:= 1 to unknown_max do unknown_cmds[i]:= '';
-
- ch:= ' ';
- debug:= false;
- if paramcount = 0 then quick_help;
-
- filename:= paramstr(1);
- if filename[1] in [ '/', '?'] then quick_help;
-
- assign(inf, filename);
- {$I-} reset(inf); {$I+}
- if ioresult <> 0 then begin writeln('HPGLVIEW: ', filename, ' not found'); halt; end;
-
- {GOT A VALID FILENAME}
-
- set_paper_size(4);
-
- if paramcount > 1 then set_options;
-
- cnt:= 0;
- clrscr;
- {---------------------------------------------------------------------------}
- { Set up graphics and display Boarder }
-
- register_graphics_bits; {Load appropriate graphics driver and Font }
-
- { Draw the Border Representing the Printed Page }
- screen_max_X:= getMaxX;
- screen_max_Y:= getMaxY;
- moveto(0,0);
- lineto(screen_max_x,0);
- lineto(screen_max_x, screen_max_y);
- lineto(0, screen_max_y);
- lineto(0,0);
-
- { Display File title at top of page }
- SetColor(GetMaxColor);
- colour:= GetmaxColor;
- SetTextStyle(smallfont,horizdir,6);
- SetTextJustify(CenterText,TopText);
- OutTextXY(screen_max_x div 2, 0, concat(' *** ', filename, ' *** '));
- {----------------------------------------------------------------------------}
-
- { Set up HPGL Defaults related to Paper Size }
-
- text_direction := horizDir;
- use_plotter_units := true; {Can be changed with SCALE command }
- symbol_mode := false;
- initialise_cmd_count:= 0;
- IP_cmd_count := 0;
-
- set_default_P1_P2; {Define initial Scaling Points for this paper size}
- set_default_text_direction;
- set_default_text_size; {As defined in HPGL manual}
-
- {------------------------------ Main Loop --------------------------------}
-
- finished:= false;
- while not eof(inf) and not finished do
- begin
- if keypressed then {If ESC pressed then abort immediately }
- begin
- ch:= readkey;
- if ch = #$1B {ESC} then finished:= true;
- end;
- if not finished and not eof(inf) then
- begin
- get_cmd;
- decode_and_execute_HPGL_command;
- end;
- end;
- if not finished then begin write(chr(7)); pause:= readkey; end;
- closegraph;
- if debug then view_unknown_commands;
- end.