Foreword.
The HPGL-2 component is a partial implementation of the second generation of
the Hewlett-Packard graphic language. I simply was too lazy to put it all
together.
Most of the language is implemented, missing parts are:

  - Bezier curves and wedges
  - Labels
  - 3 point arcs
  - Character fill mode

As far as RTL is concerned, most of it, described in the HP-GL/2 and HP RTL
reference guide, is also here. However, I have noticed, some of the Windows
printer drivers are using full set of the HP RTL. At the time of this writing
I was far from idea of full implementation of the HP RTL.

HPGL Properties and methods.
property Autopaint - to start drawing plot file automatically
property Aborted - to abort plot file reading/drawing
property Border - to draw a border around the HPGL window
property BorderColor - color of the border
property DataDone - number of bytes processed by the HPGL up to the moment, read-only
property DoZoom - enable/disable zoom/pan capabilities
property DoViewport - eneble/disable picture repainting
property FileName - name of the plot file to process
property Increment - frequency of the OnProgress reporting
property PaperColor - background color of the HPGL2 window
property PlotReady - True when plot file was processed, read-only
property ViewMode - current view mode vmZoom or vmPan
property UsedPens - boolean array of pens used in a plot file
property HpPens - array of the pen data defined in a plot file header
property HPPage - page width & height as defined in a plot file header
property PJLPage - ---"---"---"--- as defined by the PJL
property RTLPage - ---"---"---"--- as defined by the HP RTL
property RealPage - actual width & height of the plot file page

Events
property OnError - do you really need explanation?
property OnProgress - one more time...
property OnPlotReady - another one of those
property OnAfterPaint - will be called when painting is done

Methods
procedure Read - read the plot file
function  Extents : TRect - coordinated of the plot file corners
function  ElementType(Index : integer) : TElemType - pull an element from the list
function  ElementCount : integer - number of elements in the entire list
function  HPErrorMsg(Code: integer): string - convert error code to a string
procedure Print - print plot file using current printer

Code example
The following code is part out of the real life application.

//-----------------------------------------------------------------------
// The DPS HPGL/2 file viewer.
// Copyright c 1996-2000 Andrey Radchenko & Reprografia, Inc.
// All Rights Reserved.
//-----------------------------------------------------------------------
unit Srv40_Viewer1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, CoolCtrls, Buttons, hpgl_2, {$IFDEF SERVER86} Srv86_Pictures,
  {$ELSE} Srv40_Pictures, {$ENDIF} StdCtrls, RzBorder,
  RzLabel, Dps40_MainType;

type
  TfrmView40 = class(TForm)
    pnView: TCoolPanel;
    CoolPanel2: TCoolPanel;
    hpView: THPGL2;
    tbView: TSpeedButton;
    mtDone: TRzMeter;
    lblDone: TLabel;
    tmStart: TTimer;
    RzLabel1: TRzLabel;
    RzLabel2: TRzLabel;
    RzLabel3: TRzLabel;
    lblPage: TRzLabel;
    lblPlot: TRzLabel;
    lblStatus: TRzLabel;
    sbPan: TSpeedButton;
    sbZoom: TSpeedButton;
    pdPrinter: TPrinterSetupDialog;
    tbCancel: TCoolBtn;
    tbPrint: TCoolBtn;
    pnlPens: TCoolPanel;
    procedure tbCancelClick(Sender: TObject);
    procedure StartPlot(Sender: TObject);
    procedure hpViewError(Sender: TObject; Code: Integer;
                          MoreInfo: String);
    procedure hpViewProgress(Sender: TObject; Percent: Integer);
    procedure hpViewPlotReady(Sender: TObject);
    procedure tbViewClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure tbPrintClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    {}
  protected
    procedure StartSizing(var Msg : TMessage); message WM_ENTERSIZEMOVE;
    procedure EndSizing(var Msg : TMessage); message WM_EXITSIZEMOVE;
    procedure WM_SysCom(var Msg : TMessage); message WM_SYSCOMMAND;
    {}
  private
    HpError : integer;
    Sizing : boolean;
    procedure ResizeForm;
    {}
  public
    PlotFile : string;
    Creator  : hWnd;
  end;

uses
  Dps40_Common;
{$R *.DFM}

{ TfrmView }
{----------------------------------------------------}
procedure TfrmView40.ResizeForm;
var
  W : integer;
  A : integer;
begin
  W := Width;
  A := (W - (tbCancel.Width + tbPrint.Width + mtDone.Width + 44)) div 2;
  tbCancel.Left := A;
  tbPrint.Left := A + 100;
  mtDone.Left := A + 200;
  lblDone.Left := A + 384;
  tbView.Left := W - 44;
end;
{----------------------------------------------------}
procedure TfrmView40.tbCancelClick(Sender: TObject);
begin
  hpView.Aborted := True;
  lblStatus.Caption := 'User abort';
  if Creator = 0 then
    ModalResult := mrOk
  else
    PostMessage(Creator, WM_VIEWMSG, vw_Close, 0);
end;
{----------------------------------------------------}
procedure TfrmView40.StartPlot(Sender: TObject);
begin
  tmStart.Enabled := False;
  hpView.Autopaint := True;
  hpView.ViewMode := vmZoom;
  mtDone.Value := 0;
  lblDone.Caption := '0%';
  if PlotFile <> '' then
    begin
      lblStatus.Caption := 'Reading file';
      hpView.FileName := PlotFile;
      hpView.Read;
    end
  else
    ModalResult := mrCancel;
end;
{----------------------------------------------------}
procedure TfrmView40.hpViewError(Sender: TObject; Code: Integer;
                                 MoreInfo: String);
begin
  if Code <> errHpOk then
    begin
      lblStatus.Font.Color := clRed;
      lblStatus.Font.Style := [fsBold];
      lblStatus.Caption := hpView.HPErrorMsg(Code);
    end;
  lblDone.Caption := '0%';
  mtDone.Value := 0;
  HpError := Code;
end;
{----------------------------------------------------}
procedure TfrmView40.hpViewProgress(Sender: TObject; Percent: Integer);
begin
  lblDone.Caption := IntToStr(Percent) + '%';
  mtDone.Value := Percent;
end;
{----------------------------------------------------}
procedure TfrmView40.hpViewPlotReady(Sender: TObject);
var
  P : TPoint;
  Sh : TShape;
  Lbl : TLabel;
  I, T : integer;
begin
  lblDone.Caption := '0%';
  mtDone.Value := 0;
  tbPrint.Enabled := True;
  tbView.Enabled := True;
  tbCancel.Caption := '&Close';
  P := hpView.RealPage;
  lblPlot.Caption := IntToStr(P.X) + 'x' + IntToStr(P.Y);
  P := hpView.HPPage;
  lblPage.Caption := IntToStr(P.X) + 'x' + IntToStr(P.Y);
  if HpError = errHpOk then
    begin
      lblStatus.Caption := 'Viewing file';
      lblPage.Refresh;
      lblPlot.Refresh;
      T := 4;
      for I := 1 to hpMaxPens do
        if hpView.UsedPens[I] then
          begin
            Sh := TShape.Create(Self);
            Sh.Parent := pnlPens;
            Sh.Width := 12;
            Sh.Height := 12;
            Sh.Top := T;
            Sh.Left := 4;
            Sh.Brush.Color := hpView.HpPens[I].Color;
            Lbl := TLabel.Create(Self);
            Lbl.Parent := pnlPens;
            lbl.Transparent := True;
            Lbl.Top := T - 1;
            lbl.Left := 20;
            lbl.Caption := IntToStr(I);
            Inc(T, 14);
            if T > pnlPens.Height then
              Break;
          end;
    end;
end;
{----------------------------------------------------}
procedure TfrmView40.tbViewClick(Sender: TObject);
begin
  if tbView.Tag = 0 then
    begin
      tbView.Tag := 1;
      tbView.Glyph.Assign(sbPan.Glyph);
      hpView.ViewMode := vmPan;
      hpView.Cursor := cr_Pan;
    end
  else
    begin
      tbView.Tag := 0;
      tbView.Glyph.Assign(sbZoom.Glyph);
      hpView.ViewMode := vmZoom;
      hpView.Cursor := cr_Zoom;
    end
end;
{----------------------------------------------------}
procedure TfrmView40.EndSizing(var Msg: TMessage);
begin
  Sizing := False;
    ResizeForm;
      if hpView.PlotReady then
          Invalidate;
          end;
{----------------------------------------------------}
procedure TfrmView40.StartSizing(var Msg: TMessage);
begin
  Sizing := True;
end;
{----------------------------------------------------}
procedure TfrmView40.WM_SysCom(var Msg: TMessage);
begin
  if (Msg.WParam = SC_MAXIMIZE) or (Msg.WParam = SC_RESTORE) then
    begin
      ResizeForm;
      if hpView.PlotReady then
        Invalidate;
    end
  else
    inherited;
end;
{----------------------------------------------------}
procedure TfrmView40.FormShow(Sender: TObject);
begin
{$IFDEF SERVER}
  SetBitmaps(frmView40, ConfigData.BackSec, ConfigData.BtnSec);
{$ELSE}
  pnView.idWallPaper := 1;
  tbCancel.idWallpaper := 0;
  tbPrint.idWallPaper := 0;
{$ENDIF}
  Caption := 'Viewing ' + PlotFile;
  Sizing := False;
  Width := Screen.Width - 20;
  Height := Screen.Height - 20;
  Top := 10;
  Left := 10;
  ResizeForm;
  tmStart.Interval := 100;
  tmStart.Enabled := True;
  Screen.Cursors[Cr_Zoom] := LoadCursor(HInstance, 'CR_MGLASS');
  Screen.Cursors[Cr_Pan] := LoadCursor(HInstance, 'CR_PAN');
  hpView.Cursor :=  Cr_Zoom;
  HpError := errHpOk;
end;
{----------------------------------------------------}
procedure TfrmView40.FormPaint(Sender: TObject);
begin
  if Sizing then
    Exit;
end;
{----------------------------------------------------}
procedure TfrmView40.tbPrintClick(Sender: TObject);
begin
  if pdPrinter.Execute then
    hpView.Print;
end;
{----------------------------------------------------}
procedure TfrmView40.FormCreate(Sender: TObject);
begin
  Creator := 0;
end;
{----------------------------------------------------}
procedure TfrmView40.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Creator <> 0 then
    PostMessage(Creator, WM_VIEWMSG, vw_Close, 0);
end;
{----------------------------------------------------}
end.
