home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / grafik / gp / gp.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-05-23  |  52.6 KB  |  1,855 lines

  1. UNIT GP;   { revision 5/17/94 }
  2.            { took scale from NxyPlot }
  3.  
  4. INTERFACE
  5.  
  6. USES Graph, BGIDriv, BGIFont,{ only SMALLFONT,CGA,HERC,EGAVGA LINKED }
  7.      Crt, GraphPrn, HpCopy, Powers, Mouse;
  8.  
  9. (* USE UNIT VESA16U in MAIN if wish DETECT to find VESA16,
  10.    driver 16, modes 0,1,2 *)
  11.  
  12. CONST  { included for reference and so GRAPH not necessarily needed }
  13.  
  14. { EGA VGA COLORS       DRIVERS            MODES FOR DRIVERS }
  15.   Black        =  0;   Detect   = 0;      CGAc0   = 0;   CGAc1 = 1; CGAc2 = 2;
  16.   Blue         =  1;   CGA      = 1;      CGAc3   = 3;   CGAhi = 4;
  17.   Green        =  2;
  18.   Cyan         =  3;   EGA      = 3;      EGALo   = 0;   EGAhi   = 1;
  19.   Red          =  4;   EGA64    = 4;      EGA64Lo = 0;   EGA64hi = 1;
  20.   Magenta      =  5;
  21.   Brown        =  6;
  22.   LightGray    =  7;   HercMono = 7;      HercMonoHi = 0;
  23.   DarkGray     =  8;
  24.   LightBlue    =  9;   VGA      = 9;      VGALo = 0; VGAmed = 1; VGAhi = 2;
  25.   LightGreen   =  10;
  26.   LightCyan    =  11;   { SEE Ref Guide GRAPH UNIT def's }
  27.   LightRed     =  12;
  28.   LightMagenta =  13;
  29.   Yellow       =  14;
  30.   White        =  15;
  31.  
  32. VAR    { GLOBALS FOR POSSIBLE USE BY MAIN }
  33.  
  34.   { graph driver and graph mode variables }
  35.       Gdrvr, Gmode : INTEGER;
  36.  
  37.   { current world values }
  38.       WorldXmin, WorldXmax, WorldYmin, WorldYmax : REAL;
  39.  
  40.   { current window values }
  41.       WindowXmin, WindowXmax, WindowYmin, WindowYmax : INTEGER;
  42.  
  43.   { values labeled at ends of axes created by MakeWorldAndAxes }
  44.       AxesXmin, AxesXmax, AxesYmin, AxesYmax : REAL;
  45.  
  46. PROCEDURE BeginGraphic(VAR Gdrvr, Gmode : INTEGER);
  47. PROCEDURE EndGraphic;
  48.  
  49. PROCEDURE GoGraphic;
  50. PROCEDURE GoText;
  51.  
  52. PROCEDURE DefineWorld(Num : INTEGER; Xmin, Xmax, Ymin, Ymax : REAL);
  53. PROCEDURE SelectWorld(Num : INTEGER);
  54. PROCEDURE BoxWorld(Color : WORD);
  55.  
  56. PROCEDURE DefineWindow(Num : INTEGER; Xmin, Xmax, Ymin, Ymax : REAL);
  57. PROCEDURE SelectWindow(Num : INTEGER);
  58. PROCEDURE ClearCurrentWindow;
  59.  
  60. PROCEDURE MakeWorldAndAxes(WindowNum,WorldNum:INTEGER;
  61.       Xmin, Xmax, Ymin, Ymax : REAL; AxesColor, BoxColor : WORD;
  62.       Xtitle : STRING; XtitleColor : WORD;
  63.       Ytitle : STRING; YtitleColor : WORD;
  64.       MainTitle : STRING; MainTitleColor : WORD);
  65.  
  66. FUNCTION XperPixel : REAL;
  67. FUNCTION YperPixel : REAL;
  68. FUNCTION NowX : REAL;
  69. FUNCTION NOWY : REAL;
  70. PROCEDURE GetXYfromPixels(VAR X,Y : REAL; Xpos, Ypos : INTEGER);
  71. FUNCTION XtoYAspFac : REAL;
  72.  
  73.  
  74.  
  75. PROCEDURE PlotPoint(X, Y : REAL; Color : WORD);
  76. FUNCTION  GetPoint(X, Y : REAL) : WORD;
  77.  
  78. PROCEDURE PlotTextXY(X, Y : REAL; TextString : STRING; Color : WORD);
  79. PROCEDURE PlotText(TextString : STRING; Color : WORD);
  80.  
  81. PROCEDURE PlotRealXY(LabelStr : STRING;
  82.            Value : REAL;W, d : INTEGER;X,Y : REAL;Color : WORD);
  83.                   { for X:w format type use d = -1 }
  84. PROCEDURE PlotReal(LabelStr : STRING;
  85.                      Value : REAL;W, d : INTEGER; Color : WORD);
  86.                      { for X:w format type use d = -1 }
  87.  
  88. PROCEDURE PlotIntegerXY(LabelStr : STRING; Value, w : INTEGER;
  89.                         X, Y : REAL; Color : WORD);
  90.  
  91. PROCEDURE PlotInteger(LabelStr : STRING; Value, w : INTEGER; Color : WORD);
  92.  
  93. PROCEDURE PlotLine(X1, Y1, X2, Y2 : REAL; Color : WORD);
  94. PROCEDURE PlotLineTo(X,Y : REAL; Color : WORD);
  95. PROCEDURE PlotLineRel(Dx,Dy : REAL; Color : WORD);
  96.  
  97. PROCEDURE PlotMoveTo(X,Y : REAL);
  98. PROCEDURE PlotMoveRel(Dx, Dy : REAL);
  99.  
  100. PROCEDURE PlotEllipse(Xmin, Xmax, Ymin, Ymax : REAL; Color : WORD);
  101. PROCEDURE PlotRect(Xmin, Xmax, Ymin, Ymax : REAL; Color : WORD);
  102. PROCEDURE PlotCircle(X, Y, R : REAL; Color : WORD);
  103. PROCEDURE Flood(x,y :REAL; FillColor,BorderColor : WORD);
  104.  
  105. PROCEDURE SaveImage(Num:INTEGER; Xmin,Xmax,Ymin,Ymax: REAL);
  106. PROCEDURE UnSaveImage(Num : INTEGER);
  107. PROCEDURE ClearImage(Num:INTEGER);
  108. PROCEDURE PlotImage(Num:INTEGER; Xlow,Yhi : REAL; PutType : WORD);
  109. PROCEDURE MoveImage(Num:INTEGER; Xlow, Yhi : REAL);
  110. PROCEDURE HeapImageToDisk(ImageNum : INTEGER; FileName : STRING);
  111. PROCEDURE DiskImageToHeap(FileName : STRING; ImageNum : INTEGER);
  112.  
  113. PROCEDURE CrossCursor(VAR CursorX, CursorY : REAL;
  114.                       ColorCursor:WORD;ShowXY:Boolean;
  115.                       Col, Row : INTEGER; ColorText : WORD);
  116. PROCEDURE BoxCursor(VAR BoxXmin, BoxXmax, BoxYmin, BoxYmax : REAL;
  117.                     ColorCursor : WORD; ShowXY : BOOLEAN;
  118.                     Col, Row : INTEGER; ColorText : WORD);
  119. PROCEDURE GetPixelArea(CurveColor, RefillColor : Word; VAR Area : REAL);
  120.  
  121. FUNCTION MouseOK : BOOLEAN;
  122. PROCEDURE RestrictMouseToWindow;
  123. PROCEDURE GetMouseXY(VAR X,Y:REAL);
  124. FUNCTION LeftMouseXY(VAR X, Y :REAL): BOOLEAN;
  125. FUNCTION LeftButtonClicked(VAR X, Y : REAL) : BOOLEAN;
  126. FUNCTION RightMouseXY(VAR X, Y :REAL): BOOLEAN;
  127. FUNCTION RightButtonClicked(VAR X, Y : REAL) : BOOLEAN;
  128.  
  129. PROCEDURE MousePointer(VAR X, Y : REAL; Show : BOOLEAN;
  130.                        Row, Col : INTEGER; Color : BYTE);
  131. PROCEDURE MouseRubberBox(VAR X1,X2,Y1,Y2:REAL;Color : Word;
  132.                          EraseBox : BOOLEAN);
  133. PROCEDURE MouseRubberLine(VAR X1, Y1, X2, Y2 : REAL; Color : WORD;
  134.                           EraseLine : Boolean);
  135. PROCEDURE MouseDraw(Color : WORD);
  136.  
  137. PROCEDURE CopyToEpson;
  138. PROCEDURE CopyToHPLaserJet;
  139.  
  140. (*************************************************************************)
  141.  
  142.  
  143. IMPLEMENTATION   { 4/26/91 : changed size of titles and axes labling }
  144.                  { Changed MakeWorldAndAxes to redefine window AND world }
  145. TYPE          { so that cannot plot over axes, may clear plot and not axes }
  146.   GraphicWorldRec = RECORD
  147.                       Xmn, Xmx, Ymn, Ymx : REAL;
  148.                     END;
  149.   GraphicWindowRec = RECORD
  150.                        Xmn, Xmx, Ymn, Ymx : REAL;
  151.                      END;
  152.   BoxRec = RECORD
  153.              Xmn,Ymx : REAL;
  154.            END;
  155. VAR
  156.   GraphicWorld : ARRAY[1..10] OF GraphicWorldRec;
  157.   CurrentWorld : GraphicWorldRec;
  158.   GraphicWindow : ARRAY[1..10] OF GraphicWindowRec;
  159.   Image : array[1..10] of pointer;
  160.   ImageValid : array[1..10] of Boolean;
  161.   SizeOfImage : array[1..10] of WORD;
  162.   Box: array[1..10] of BoxRec;
  163.   J : INTEGER;
  164.   OldDirectVideo : Boolean;
  165.   X, Y : REAL;
  166. (************************************************************************)
  167.  
  168.   PROCEDURE CopyToHPLaserjet;
  169.   BEGIN
  170.     HPHardCopy;
  171.   END;
  172.  
  173. (*************************************************************************)
  174.  
  175.   PROCEDURE CopyToEpson;
  176.   BEGIN
  177.     Hardcopy(6);
  178.     Write(Lst,^L);
  179.   END;
  180.  
  181. (*************************************************************************)
  182.  
  183.   FUNCTION XperPixel : REAL;
  184.   VAR
  185.     X,Y,Xpix2 : WORD;
  186.   BEGIN
  187.     X := GetX;
  188.     Y := GetY;
  189.     WITH CurrentWorld DO
  190.     BEGIN
  191.       PlotMoveTo(Xmx,Ymn);
  192.       Xpix2 := GetX;
  193.       XperPixel := (Xmx-Xmn)/Xpix2;
  194.     END;
  195.     MoveTo(X, Y);
  196.   END;
  197.  
  198.   (*************************************************************************)
  199.  
  200.   FUNCTION YperPixel : REAL;
  201.   VAR
  202.     X, Y, Ypix1, Ypix2 : WORD;
  203.   BEGIN
  204.     X := GetX;
  205.     Y := GetY;
  206.     WITH CurrentWorld DO
  207.     BEGIN
  208.       PlotMoveTo(Xmn,Ymn);
  209.       Ypix2 := GetY;
  210.       YperPixel := (Ymx-Ymn)/Ypix2;{ note reversal in denominator }
  211.     END;
  212.     MoveTo(X, Y);
  213.   END;
  214.  
  215.   (*************************************************************************)
  216.  
  217.   PROCEDURE BeginGraphic(VAR Gdrvr,Gmode : INTEGER);
  218.   VAR
  219.     ErrorCode : INTEGER;
  220.     PROCEDURE Abort(Msg : STRING);
  221.     BEGIN
  222.       WriteLn(Msg, ': ', GraphErrorMsg(GraphResult));
  223.       Halt(1);
  224.     END;
  225.   BEGIN
  226.     { Register all the drivers } {SEE UNIT BGIDRIV }
  227.     IF RegisterBGIdriver(@CGADriverProc) < 0 THEN
  228.       Abort('CGA');
  229.     IF RegisterBGIdriver(@EGAVGADriverProc) < 0 THEN
  230.       Abort('EGA/VGA');
  231.     IF RegisterBGIdriver(@HercDriverProc) < 0 THEN
  232.       Abort('Herc');
  233.   (*  IF RegisterBGIdriver(@ATTDriverProc) < 0 THEN
  234.       Abort('AT&T');
  235.     IF RegisterBGIdriver(@PC3270DriverProc) < 0 THEN
  236.       Abort('PC 3270');
  237.   *)
  238.     { Register all the fonts } {SEE UNIT BGIFONT }
  239. {    IF RegisterBGIfont(@BOLDFontProc) < 0 THEN
  240.       Abort('BOLD');
  241.     IF RegisterBGIfont(@EuroFontProc) < 0 THEN
  242.       Abort('EURO');
  243.     IF RegisterBGIfont(@GothicFontProc) < 0 THEN
  244.       Abort('Gothic');
  245.     IF RegisterBGIfont(@LcomFontProc) < 0 THEN
  246.       Abort('Lcom');
  247. }
  248.     IF RegisterBGIfont(@SmallFontProc) < 0 THEN
  249.       Abort('Small');
  250.  
  251. {    IF RegisterBGIfont(@SansSerifFontProc) < 0 THEN
  252.       Abort('SansSerif');
  253.  
  254.     IF RegisterBGIfont(@ScriFontProc) < 0 THEN
  255.       Abort('Scri');
  256.     IF RegisterBGIfont(@SimpFontProc) < 0 THEN
  257.       Abort('Simp');
  258.     IF RegisterBGIfont(@TriplexFontProc) < 0 THEN
  259.       Abort('Triplex');
  260.     IF RegisterBGIfont(@TscrFontProc) < 0 THEN
  261.       Abort('Tscr');
  262. }
  263.     InitGraph(Gdrvr, Gmode, '');
  264.     ErrorCode := GraphResult;
  265.     IF ErrorCode <> grOk THEN
  266.       BEGIN
  267.         WriteLn('(Graphics error:', GraphErrorMsg(ErrorCode));
  268.         Halt(1);
  269.       END;
  270.     SelectWindow(1); { sets WindowXmax etc }
  271.     SelectWorld(1);  { sets WorldXmax etc }
  272.     OldDirectVideo := DirectVideo;
  273.     DirectVideo := FALSE;
  274.   END;  { BeginGraphic }
  275.  
  276. (*************************************************************************)
  277.  
  278.   PROCEDURE EndGraphic;
  279.   BEGIN
  280.     For J := 1 to 10 DO
  281.     IF ImageValid[J] THEN
  282.       UnSaveImage(J);
  283.     DirectVideo := OldDirectVideo;
  284.     CloseGraph;
  285.   END;
  286.  
  287. (*************************************************************************)
  288.  
  289.   PROCEDURE DefineWorld(Num : INTEGER; Xmin, Xmax, Ymin, Ymax : REAL);
  290.   BEGIN
  291.     IF NOT (Num in [1..10] )
  292.     THEN
  293.       BEGIN
  294.         EndGraphic;
  295.         Writeln('DefineWorld was called with Num = ',Num);
  296.         Writeln('Max number of worlds is ten');
  297.         HALT;
  298.       END;
  299.     WITH GraphicWorld[Num] DO
  300.       BEGIN
  301.         IF (Xmin = 0) AND (Xmax = 0) THEN Xmax := 1.0
  302.         ELSE
  303.           IF Xmin = Xmax THEN Xmax := ABS(2.0*Xmin);
  304.         IF (Ymin = 0) AND (Ymax = 0) THEN Ymax := 1.0
  305.         ELSE
  306.           IF Ymin = Ymax THEN Ymax := ABS(2.0*Ymin);
  307.         Xmn := Xmin;
  308.         Ymn := Ymin;
  309.         Xmx := Xmax;
  310.         Ymx := Ymax;
  311.       END;
  312.   END;
  313.  
  314. (*************************************************************************)
  315.  
  316.   PROCEDURE DefineWindow(Num : INTEGER; Xmin, Xmax, Ymin, Ymax : REAL);
  317.  
  318.     { Xmin etc are real PERCENTS , LOWER LEFT screen is origin }
  319.     { pixel co-ords handled by SelectWindow }
  320.  
  321.   BEGIN
  322.     IF NOT (Num in [1..10])
  323.     THEN
  324.       BEGIN
  325.         EndGraphic;
  326.         Writeln('DefineWindow was called with Num = ',Num);
  327.         Writeln('Max number of windows is ten');
  328.         HALT;
  329.       END;
  330.     WITH GraphicWindow[Num] DO
  331.       BEGIN
  332.         IF Xmin < 0.0 THEN Xmin := 0.0;
  333.         IF Xmax > 100.0 THEN Xmax := 100.0;
  334.         IF Ymin < 0.0 THEN Ymin := 0.0;
  335.         IF Ymax > 100.0 THEN Ymax := 100.0;
  336.         Xmn := Xmin;
  337.         Ymn := Ymin;
  338.         Xmx := Xmax;
  339.         Ymx := Ymax;
  340.       END;
  341.   END;
  342.  
  343. (*************************************************************************)
  344.  
  345.   PROCEDURE SelectWorld(Num : INTEGER);
  346.   BEGIN
  347.     IF NOT (Num in [1..10])
  348.     THEN
  349.       BEGIN
  350.         EndGraphic;
  351.         Writeln('SelectWorld was called with Num = ',Num);
  352.         Writeln('Max number of worlds is ten');
  353.         HALT;
  354.       END;
  355.     CurrentWorld := GraphicWorld[Num];
  356.     With CurrentWorld DO
  357.     BEGIN
  358.       WorldXmin := Xmn;
  359.       WorldXmax := Xmx;
  360.       WorldYmin := Ymn;
  361.       WorldYmax := Ymx;
  362.     END;
  363.   END;
  364.  
  365. (*************************************************************************)
  366.  
  367.   PROCEDURE BoxWorld( Color : WORD);
  368.   BEGIN
  369.     WITH CurrentWorld DO
  370.       BEGIN
  371.         PlotMoveTo(Xmn, Ymn);
  372.         PlotLineTo(Xmn, Ymx, Color);
  373.         PlotLineTo(Xmx, Ymx, Color);
  374.         PlotLineTo(Xmx, Ymn, Color);
  375.         PlotLineTo(Xmn, Ymn, Color);
  376.       END;
  377.   END;
  378.  
  379. (*************************************************************************)
  380.  
  381.   PROCEDURE SelectWindow(Num : INTEGER);
  382.   VAR
  383.     X1, Y1, X2, Y2 : INTEGER;
  384.   BEGIN
  385.     IF NOT (Num in [1..10])
  386.     THEN
  387.       BEGIN
  388.         EndGraphic;
  389.         Writeln('SelectWindow was called with Num = ',Num);
  390.         Writeln('Max number of windows is ten');
  391.         HALT;
  392.       END;
  393.     WITH GraphicWindow[Num] DO
  394.       BEGIN
  395.         X1 := Trunc(0.01*GetMaxX*Xmn);
  396.         X2 := Trunc(0.01*GetMaxX*Xmx);
  397.         Y2 := Trunc(0.01*GetMaxY*(100-Ymn));
  398.         Y1 := Trunc(0.01*GetMaxY*(100-Ymx));
  399.       END;
  400.     WindowXmin := X1;  { Across and DOWN pixel count }
  401.     WindowXmax := X2;
  402.     WindowYmin := Y1;
  403.     WindowYmax := Y2;
  404.     SetViewPort(X1, Y1, X2, Y2, ClipOn);
  405.   END;
  406.  
  407. (*************************************************************************)
  408.  
  409. PROCEDURE MakeWindow(Num : Integer; Xmin, Xmax, Ymin, Ymax : REAL);
  410. VAR                         { use to define a window inside a window }
  411.   X1, X2, Y1, Y2 : REAL; { to be able to clear plot INSIDE axes }
  412. BEGIN
  413.   PlotMoveTo(Xmin+2.0*XperPixel,Ymin+YperPixel);
  414.   X1:= (100.0*(WindowXmin+GetX)/GetMaxX);
  415.   Y1 :=(100.0*(GetMaxY-WindowYmin-GetY)/GetMaxY);
  416.   PlotMoveTo(Xmax,Ymax);
  417.   X2 :=(100.0*(WindowXmin+GetX)/GetMaxX);
  418.   Y2 :=(100.0*(GetMaxY-WindowYmin-GetY)/GetMaxY);
  419.   DefineWindow(Num,X1,X2,Y1,Y2);
  420. END;
  421.  
  422. (*************************************************************************)
  423.  
  424.   PROCEDURE GoGraphic;
  425.   BEGIN
  426.     SetGraphMode(GetGraphMode);
  427.     DirectVideo := FALSE;
  428.   END;
  429.  
  430. (*************************************************************************)
  431.  
  432.   PROCEDURE GoText;
  433.   BEGIN
  434.     RestoreCrtMode;
  435.     DirectVideo := OldDirectVideo;
  436.   END;
  437.  
  438. (*************************************************************************)
  439.  
  440.   FUNCTION XpixelRel(X : REAL) : INTEGER;
  441.   VAR
  442.     ViewPort : ViewPortType;
  443.     Xtemp : REAL;
  444.   BEGIN
  445.     GetViewSettings(ViewPort);
  446.     WITH ViewPort DO
  447.       BEGIN
  448.         WITH CurrentWorld DO
  449.           BEGIN
  450.             Xtemp := (X2-X1)*(X-Xmn)/(Xmx-Xmn);
  451.             IF Xtemp > MaxInt
  452.             THEN
  453.               XpixelRel := MaxInt
  454.             ELSE
  455.               IF Xtemp < - MaxInt
  456.               THEN
  457.                 XpixelRel := - MaxInt
  458.               ELSE
  459.                 XpixelRel := Round(Xtemp);
  460.           END;
  461.       END;
  462.   END;
  463.  
  464. (*************************************************************************)
  465.  
  466.   FUNCTION YpixelRel(Y : REAL) : INTEGER;
  467.   VAR
  468.     ViewPort : ViewPortType;
  469.     Ytemp : REAL;
  470.   BEGIN
  471.     GetViewSettings(ViewPort);
  472.     WITH ViewPort DO
  473.       BEGIN
  474.         WITH CurrentWorld DO
  475.           BEGIN
  476.             Ytemp := (Y2-Y1)*(1.0 - (Y-Ymn)/(Ymx-Ymn));
  477.             IF Ytemp > MaxInt
  478.             THEN
  479.               YpixelRel := MaxInt
  480.             ELSE
  481.               IF Ytemp < -MaxInt
  482.               THEN
  483.                 YpixelRel := -MaxInt
  484.               ELSE
  485.                 YpixelRel := Round(Ytemp);
  486.           END;
  487.       END;
  488.   END;
  489.  
  490. (*************************************************************************)
  491.  
  492.   PROCEDURE PlotPoint(X, Y : REAL; Color : WORD);
  493.   BEGIN
  494.     PutPixel(XpixelRel(X), YpixelRel(Y), Color);
  495.   END;
  496.  
  497. (*************************************************************************)
  498.  
  499.   FUNCTION GetPoint(X, Y : REAL) : WORD;
  500.   BEGIN
  501.     GetPoint := GetPixel(XpixelRel(X), YpixelRel(Y));
  502.   END;
  503.  
  504. (*************************************************************************)
  505.  
  506.   PROCEDURE PlotLine(X1, Y1, X2, Y2 : REAL; Color : WORD);
  507.   VAR
  508.     OldColor : WORD;
  509.   BEGIN
  510.     OldColor := GetColor;
  511.     SetColor(Color);
  512.     Line(XpixelRel(X1), YpixelRel(Y1), XpixelRel(X2), YpixelRel(Y2));
  513.     SetColor(OldColor);
  514.   END;
  515.  
  516. (*************************************************************************)
  517.  
  518.   PROCEDURE PlotLineTo(X,Y : REAL; Color : WORD);
  519.   VAR
  520.     OldColor : WORD;
  521.   BEGIN
  522.     OldColor := GetColor;
  523.     SetColor(Color);
  524.     LineTo(XpixelRel(X),YpixelRel(Y));
  525.     SetColor(OldColor);
  526.   END;
  527.  
  528. (*************************************************************************)
  529.  
  530.   PROCEDURE PlotLineRel(Dx,Dy : REAL; Color : WORD);
  531.   VAR
  532.     OldColor : WORD;
  533.     Xav, Yav : REAL;
  534.     tdx,tdy,tx,ty :REAL; zx,zy : integer;
  535.   BEGIN
  536.     Xav := 0.5*(WorldXmax + WorldXmin);
  537.     Yav := 0.5*(WorldYmax + WorldYmin);
  538.     OldColor := GetColor;
  539.     SetColor(Color);
  540.     LineRel(Round(Dx/XperPixel), -Round(Dy/YperPixel));
  541.     SetColor(OldColor);
  542.   END;
  543.  
  544. (*************************************************************************)
  545.  
  546.   PROCEDURE PlotMoveTo(X,Y : REAL);
  547.   BEGIN
  548.     MoveTo(XpixelRel(X),YpixelRel(Y));
  549.   END;
  550.  
  551. (*************************************************************************)
  552.  
  553.   PROCEDURE PlotMoveRel(Dx, Dy : REAL);
  554.   BEGIN
  555.     MoveRel(XpixelRel(2.0*Dx)-XpixelRel(Dx),YpixelRel(2.0*Dy)-YpixelRel(Dy));
  556.   END;
  557.  
  558. (*************************************************************************)
  559.  
  560.   PROCEDURE ClearCurrentWindow;
  561.   BEGIN
  562.     ClearViewPort;
  563.   END;
  564.  
  565. (*************************************************************************)
  566.  
  567.   PROCEDURE PlotTextXY(X, Y : REAL; TextString : STRING; Color : WORD);
  568.   VAR
  569.     OldColor : WORD;
  570.   BEGIN
  571.     OldColor := GetColor;
  572.     SetColor(Color);
  573.     OutTextXY(XpixelRel(X), YpixelRel(Y), TextString);
  574.     SetColor(OldColor);
  575.   END;
  576.  
  577. (*************************************************************************)
  578.  
  579.   PROCEDURE PlotRealXY(LabelStr : STRING;
  580.            Value : REAL;W, d : INTEGER;X,Y : REAL;Color : WORD);
  581.                      { for X:w format type use d = -1 }
  582.   VAR
  583.     Tstr : STRING;
  584.     OldColor : WORD;
  585.   BEGIN
  586.     OldColor := GetColor;
  587.     SetColor(Color);
  588.     Str(Value:w:d,Tstr);
  589.     PlotMoveTo(X,Y);
  590.     OutText(LabelStr + Tstr);
  591.     SetColor(OldColor);
  592.   END;
  593.  
  594. (*************************************************************************)
  595.  
  596.   PROCEDURE PlotIntegerXY(LabelStr : STRING; Value, w : INTEGER;
  597.                                    X, Y : REAL; Color : WORD);
  598.   VAR
  599.     OldColor : WORD;
  600.     Tstr : STRING;
  601.   BEGIN
  602.     OldColor := GetColor;
  603.     SetColor(Color);
  604.     Str(Value:w,Tstr);
  605.     PlotMoveTo(X, Y);
  606.     OutText(LabelStr + Tstr);
  607.     SetColor(OldColor);
  608.   END;
  609.  
  610. (*************************************************************************)
  611.  
  612.   PROCEDURE PlotText(TextString : STRING; Color : WORD);
  613.   VAR
  614.     OldColor : WORD;
  615.   BEGIN
  616.     OldColor := GetColor;
  617.     SetColor(Color);
  618.     OutText(TextString);
  619.     SetColor(OldColor);
  620.   END;
  621.  
  622. (*************************************************************************)
  623.  
  624.   PROCEDURE PlotReal(LabelStr : STRING;
  625.                      Value : REAL;W, d : INTEGER; Color : WORD);
  626.                      { for X:w format type use d = -1 }
  627.   VAR
  628.     Tstr : STRING;
  629.     OldColor : WORD;
  630.   BEGIN
  631.     OldColor := GetColor;
  632.     SetColor(Color);
  633.     Str(Value:w:d,Tstr);
  634.     OutText(LabelStr + Tstr);
  635.     SetColor(OldColor);
  636.   END;
  637.  
  638. (*************************************************************************)
  639.  
  640.   PROCEDURE PlotInteger(LabelStr : STRING; Value, w : INTEGER; Color : WORD);
  641.   VAR
  642.     OldColor : WORD;
  643.     Tstr : STRING;
  644.   BEGIN
  645.     OldColor := GetColor;
  646.     SetColor(Color);
  647.     Str(Value:w,Tstr);
  648.     OutText(LabelStr + Tstr);
  649.     SetColor(OldColor);
  650.   END;
  651.  
  652. (*************************************************************************)
  653.  
  654.   PROCEDURE PlotEllipse(Xmin, Xmax, Ymin, Ymax : REAL; Color : WORD);
  655.   VAR
  656.     X, Y, Xr, Yr : INTEGER;
  657.     OldColor : WORD;
  658.   BEGIN
  659.     OldColor := GetColor;
  660.     SetColor(Color);
  661.     X := XpixelRel(0.5*(Xmax+Xmin)); { center co-ords }
  662.     Y := YpixelRel(0.5*(Ymax+Ymin));
  663.     Xr := (XpixelRel(Xmax)-XpixelRel(Xmin)) DIV 2;
  664.     Yr := (YpixelRel(Ymin)-YpixelRel(Ymax)) DIV 2;
  665.     Ellipse(X, Y, 0, 360, Xr, Yr);
  666.     SetColor(OldColor);
  667.   END;
  668.  
  669. (*************************************************************************)
  670.  
  671.   PROCEDURE PlotCircle(X, Y, R : REAL; Color : WORD);
  672.   VAR
  673.     OldColor : WORD;
  674.   BEGIN
  675.     OldColor := GetColor;
  676.     SetColor(Color);
  677.     Circle(XpixelRel(X), YpixelRel(Y),Round(R/XperPixel));
  678.     SetColor(OldColor);
  679.   END;
  680.  
  681. (*************************************************************************)
  682.  
  683.   PROCEDURE PlotRect(Xmin, Xmax, Ymin, Ymax : REAL; Color : WORD);
  684.   VAR
  685.     OldColor : WORD;
  686.   BEGIN
  687.     OldColor := GetColor;
  688.     SetColor(Color);
  689.     Rectangle(XpixelRel(Xmin), YpixelRel(Ymax), XpixelRel(Xmax),
  690.               YpixelRel(Ymin));
  691.     SetColor(OldColor);
  692.   END;
  693.  
  694. (*************************************************************************)
  695.  
  696. PROCEDURE FLOOD(x,y :REAL; FillColor,BorderColor : WORD);
  697. BEGIN
  698.   SetFillStyle(SolidFill,FillColor);
  699.   FloodFill(XpixelRel(x),YpixelRel(y),BorderColor);
  700. END;
  701.  
  702. (*************************************************************************)
  703.  
  704. PROCEDURE SaveImage(Num:INTEGER; Xmin,Xmax,Ymin,Ymax: REAL);
  705. VAR
  706.   Size, x1,x2,y1,y2 : WORD;
  707.   Temp : REAL;
  708. BEGIN
  709.   IF NOT ( Num in [1..10])
  710.   THEN
  711.     BEGIN
  712.       EndGraphic;
  713.       WriteLn('SaveImage called with num = ',num);
  714.       Writeln('Only ten images may be saved');
  715.       HALT;
  716.     END;
  717.     IF Xmax < Xmin THEN
  718.     BEGIN
  719.       Temp := Xmin;
  720.       Xmin := Xmax;
  721.       Xmax := Temp;
  722.     END;
  723.     IF Ymax < Ymin THEN
  724.     BEGIN
  725.       Temp := Ymin;
  726.       Ymin := Ymax;
  727.       Ymax := Temp;
  728.     END;
  729.   x1:=XpixelRel(Xmin);
  730.   x2:=XpixelRel(Xmax);
  731.   y1:=YpixelRel(Ymax);{ note Ymax and Ymin reversed as required by ImageSize }
  732.   y2:=YpixelRel(Ymin);{ and GetImage }
  733.   Size:=ImageSize(x1,y1,x2,y2);
  734.   IF Size = 0 THEN
  735.     BEGIN
  736.       EndGraphic;
  737.       Writeln('IMAGE ',Num,' TOO LARGE TO SAVE');
  738.       HALT;
  739.     END;
  740.   IF MemAvail < Size THEN
  741.     BEGIN
  742.       EndGraphic;
  743.       Writeln('Insufficient Heap Memory available for call to SaveImage(',
  744.       Num,')');
  745.       HALT;
  746.     END;
  747.   GetMem(Image[Num],Size);
  748.   SizeOfImage[Num] := Size;
  749.   GetImage(x1,y1,x2,y2,Image[Num]^);
  750.   ImageValid[Num] := TRUE;
  751.   With Box[Num] DO
  752.   Begin
  753.     Xmn:=Xmin;       { Only Upper Left Corner Needed }
  754.     Ymx:=Ymax;
  755.   end;
  756. end;
  757.  
  758. (*************************************************************************)
  759.  
  760. PROCEDURE UnSaveImage(Num : INTEGER);
  761. BEGIN
  762.   IF NOT ( Num in [1..10])
  763.   THEN
  764.     BEGIN
  765.       EndGraphic;
  766.       WriteLn('UnSaveImage called with num = ',num);
  767.       Writeln('Only ten images may be saved');
  768.       HALT;
  769.     END;
  770.   IF ImageValid[Num] = FALSE
  771.   THEN
  772.     BEGIN
  773.       EndGraphic;
  774.       WriteLn('Attempt to UnSave image number ',num);
  775.       Writeln('This image has not been saved');
  776.       HALT;
  777.     END;
  778.   FreeMem(Image[Num],SizeOfImage[Num]);
  779.   ImageValid[Num] := FALSE;
  780. END;
  781.  
  782. (*************************************************************************)
  783.  
  784. PROCEDURE PlotImage(Num:INTEGER; Xlow,Yhi : REAL; PutType : WORD);
  785. VAR
  786.   x,y:INTEGER;
  787. Begin
  788.   IF NOT ( Num in [1..10])
  789.   THEN
  790.     BEGIN
  791.       EndGraphic;
  792.       WriteLn('PlotImage called with num = ',num);
  793.       Writeln('Only ten images may be manipulated');
  794.       HALT;
  795.     END;
  796.   IF ImageValid[Num] = FALSE
  797.   THEN
  798.     BEGIN
  799.       EndGraphic;
  800.       Writeln('Attempt to PlotImage number ',num);
  801.       WriteLn('This image has not been saved');
  802.       HALT;
  803.     END;
  804.   WITH Box[Num] DO
  805.   begin
  806.     x:=XpixelRel(Xlow);
  807.     y:=YpixelRel(Yhi);
  808.     PutImage(x,y,Image[Num]^,PutType);  { uses upper left corner }
  809.     Xmn:=Xlow;
  810.     Ymx:=Yhi;
  811.   end;
  812. end;
  813.  
  814. (*************************************************************************)
  815.  
  816. PROCEDURE ClearImage(Num:INTEGER);
  817. VAR
  818.   x,y:INTEGER;
  819. BEGIN
  820.   IF NOT ( Num in [1..10])
  821.   THEN
  822.     BEGIN
  823.       EndGraphic;
  824.       WriteLn('ClearImage called with num = ',num);
  825.       Writeln('Only ten images may be manipulated');
  826.       HALT;
  827.     END;
  828.   IF ImageValid[Num] = FALSE
  829.   THEN
  830.     BEGIN
  831.       EndGraphic;
  832.       Writeln('Attempt to clear image number ',num);
  833.       Writeln('This image not saved');
  834.       HALT;
  835.     END;
  836.   WITH Box[Num] DO
  837.   Begin
  838.     x:=XpixelRel(Xmn);
  839.     y:=YpixelRel(Ymx);
  840.   end;
  841.   PutImage(x,y,Image[Num]^,XorPut);
  842. END;
  843.  
  844. (*************************************************************************)
  845.  
  846. PROCEDURE MoveImage(Num:INTEGER; Xlow, Yhi : REAL);
  847. Begin
  848.   IF NOT ( Num in [1..10])
  849.   THEN
  850.     BEGIN
  851.       EndGraphic;
  852.       WriteLn('MoveImage called with num = ',num);
  853.       Writeln('Only ten images may be manipulated');
  854.       HALT;
  855.     END;
  856.   IF ImageValid[Num] = FALSE
  857.   THEN
  858.     BEGIN
  859.       WriteLn('Attempt to move image number ',num);
  860.       Writeln('This image has not been saved');
  861.       HALT;
  862.     END;
  863.   ClearImage(Num);
  864.   PlotImage(Num,Xlow,Yhi, XORPut);
  865. end;
  866.  
  867. (*************************************************************************)
  868.  
  869. PROCEDURE HeapImageToDisk(ImageNum : Integer; FileName : String);
  870. VAR
  871.   ImageFile : File;
  872.   NumToWrite, Count : Word;
  873. Begin
  874.   IF (ImageValid[ImageNum] = FALSE) THEN
  875.     BEGIN
  876.       EndGraphic;
  877.       writeln('HeapImageToDisk called with INVALID Image Number ',
  878.              ImageNum, '.  Referenced FileName ',FileName);
  879.       Halt;
  880.     END
  881.   ELSE
  882.     BEGIN
  883.       Assign(ImageFile,FileName);
  884.       ReWrite(ImageFile,1);
  885.       NumToWrite := SizeOfImage[ImageNum];
  886.       BlockWrite(ImageFile,Image[ImageNum]^, NumToWrite,Count);
  887.       Close(ImageFile);
  888.       IF ( NumToWrite <> Count ) THEN
  889.         BEGIN
  890.           EndGraphic;
  891.           writeln('Disk full during write to '+Filename,' by HeapImageToDisk');
  892.           writeln('using Image Number ',ImageNum);
  893.           Halt;
  894.         END;
  895.     END;
  896. END;  { HeapImageToDisk }
  897.  
  898. (*************************************************************************)
  899.  
  900. PROCEDURE DiskImageToHeap(FileName : String; ImageNum : Integer);
  901. VAR
  902.   ImageFile : File;
  903.   NumRead, Size : Word;
  904. BEGIN
  905.   IF ( ImageValid[ImageNum] = TRUE ) THEN
  906.     UnSaveImage(ImageNum);
  907.   Assign(ImageFile, FileName);
  908.   ReSet(ImageFile,1);
  909.   Size := FileSize(ImageFile);
  910.   GetMem(Image[ImageNum],Size);
  911.   BlockRead(ImageFile, Image[ImageNum]^, Size, NumRead);
  912.   Close(ImageFile);
  913.   IF (NumRead <> Size) THEN
  914.     BEGIN
  915.       EndGraphic;
  916.       WriteLn('Incorrect number of bytes read from '+FileName + ' during');
  917.       writeln('DiskImageToHeap with Image Number ',ImageNum);
  918.       Halt;
  919.     END;
  920.   ImageValid[ImageNum] := TRUE;
  921.   SizeOfImage[ImageNum] := Size;
  922. END;  { DiskImageToHeap }
  923.  
  924. (*************************************************************************)
  925.  
  926. PROCEDURE MakeWorldAndAxes(WindowNum,WorldNum:INTEGER;
  927.       Xmin, Xmax, Ymin, Ymax : REAL; AxesColor, BoxColor : WORD;
  928.       Xtitle : STRING; XtitleColor : WORD;
  929.       Ytitle : STRING; YtitleColor : WORD;
  930.       MainTitle : STRING; MainTitleColor : WORD);
  931. VAR
  932.   X1, X2, Y1, Y2, Dx, Dy, TenXpwr, TenYpwr : REAL;
  933.   Xdivs, Ydivs, XPwr, Ypwr, J, K, Digits, Dot : INTEGER;
  934.   Nstr : STRING;
  935.   OldTextSettings : TextSettingsType;
  936.   OldColor : WORD;
  937.   TempPosMin, TempPos, TempY : REAL;
  938. (*-------------------------------------------------------------*)
  939.  
  940. PROCEDURE WriteTitles(Xtitle,Ytitle,MainTitle:string);
  941. VAR
  942.   Xpix1,Xpix2,Ypix1,Ypix2,Xlength,Ylength,XMainLength : INTEGER;
  943.   XpwrTen, YpwrTen : REAL;
  944.  
  945. begin
  946.   GetTextSettings(OldTextSettings);
  947.   XpwrTen := PwrI(10.0,Xpwr);
  948.   YpwrTen := PwrI(10.0,Ypwr);
  949.   SetTextStyle(SmallFont,HorizDir,5);
  950.   Xlength := TextWidth(Xtitle);
  951.   PlotMoveTo(0.5*(XpwrTen*(X2+X1)-Xlength*XperPixel),
  952.              0.5*(WorldYmin + TempY + TextHeight('H')*YperPixel));
  953.   (*PlotMoveTo(0.5*(XpwrTen*(X2+X1)-Xlength*XperPixel),
  954.              WorldYmin + 1.5*TextHeight('H')*YperPixel);*)
  955.   SetColor(XtitleColor);
  956.   OutText(Xtitle);
  957. (*  WITH GraphicWindow[WindowNum] DO
  958.   BEGIN
  959.     IF  Ymx-Ymn > 67.0 THEN YChrSize := 7
  960.     ELSE
  961.       IF  Ymx-Ymn > 37.0 THEN YChrSize := 6
  962.       ELSE
  963.         YChrSize := 5;
  964.   END;
  965.   YChrSize := 6;
  966. *)
  967.   SetTextStyle(SmallFont,VertDir,5);
  968.   Ylength := TextWidth(Ytitle);
  969.   PlotTextXY(0.5*(WorldXmin + TempPosMin - TextHeight('H')*XperPixel),
  970.              0.5*(WorldYmin+WorldYmax+Ylength*YperPixel),
  971.              Ytitle,YtitleColor);
  972.   (*PlotTextXY(WorldXmin + 0.5*TextHeight('H')*XperPixel,
  973.              0.5*(WorldYmin+WorldYmax+Ylength*YperPixel),
  974.              Ytitle,YtitleColor);*)
  975.   {SetColor(YtitleColor);
  976.   OutText(Ytitle);}
  977.   SetTextStyle(SmallFont,HorizDir,6);
  978.   XMainLength := TextWidth(MainTitle);
  979.   PlotMoveTo(0.5*(XpwrTen*(X2+X1)-XMainlength*XperPixel),
  980.              WorldYmax-0.25*TextHeight('H')*YperPixel);
  981.   SetColor(MainTitleColor);
  982.   OutText(MainTitle);
  983. end;
  984.  
  985.  
  986. (*------------------------------------------------------------------*)
  987.  
  988.   Procedure Scale(Zmin,Zmax:REAL;VAR Z1,Z2,Zinc:REAL;VAR Ndivs,Pwr:Integer);
  989. VAR
  990.  Temp : REAL;
  991.   Function Floor(X:REAL):REAL;
  992.   BEGIN
  993.     Floor := Int(X);
  994.   END;
  995.   Function Ceil(X:REAL):REAL;
  996.   BEGIN
  997.     IF X = Int(X) THEN Ceil := X
  998.     ELSE
  999.       IF X > 0.0 THEN Ceil := Int(X+1.0)
  1000.     ELSE Ceil := Int(X-1.0);
  1001.   END;
  1002.   Function Log10(X:REAL):REAL;
  1003.   BEGIN
  1004.     Log10 := Ln(X)/Ln(10.0);
  1005.   END;
  1006.  
  1007. BEGIN
  1008.   IF Zmin > Zmax THEN
  1009.   BEGIN
  1010.     Temp := Zmax;
  1011.     Zmax := Zmin;
  1012.     Zmin := Temp;
  1013.   END;
  1014.   IF (Zmin = 0.0) AND (Zmax = 0.0) THEN Zmax := 1.0;
  1015.   IF Zmin = Zmax THEN
  1016.   BEGIN
  1017.     IF Zmin < 0.0 THEN
  1018.       Zmax := 0.9*Zmin
  1019.     ELSE
  1020.       Zmax := 1.1*Zmin;
  1021.   END;
  1022.   Zinc := (Zmax-Zmin)*0.2;
  1023.   Temp := Log10(Zinc);
  1024.   IF Temp >= 0.0 THEN Pwr := Trunc(Floor(Temp))
  1025.   ELSE
  1026.     Pwr := Trunc(Ceil(Temp));
  1027.   IF Zinc > 1.0 THEN Inc(Pwr);
  1028.   Temp := Zinc*PwrI(10.0, -Pwr);
  1029.   Zinc := 0.1;
  1030.   IF Temp > 0.1 THEN Zinc := 0.2;
  1031.   IF Temp > 0.2 THEN Zinc := 0.25;
  1032.   IF Temp > 0.25 THEN Zinc := 0.5;
  1033.   IF Temp > 0.5 THEN Zinc := 1.0;
  1034.   Zinc := Zinc*PwrI(10.0,Pwr);
  1035.   IF Zmin < Int(Zmin/Zinc)*Zinc THEN
  1036.     Zmin := (Int(Zmin/Zinc) -1)*Zinc
  1037.   ELSE
  1038.     Zmin := Int(Zmin/Zinc)*Zinc;
  1039.   IF Zmax > Int(Zmax/Zinc)*Zinc THEN
  1040.     Zmax := (Int(Zmax/Zinc) +1)*Zinc
  1041.   ELSE
  1042.     Zmax := Int(Zmax/Zinc)*Zinc;
  1043.   Zinc := Zinc*PwrI(10.0,-Pwr);
  1044.   Z1 := Zmin*PwrI(10.0,-Pwr);
  1045.   Z2 := Zmax*PwrI(10.0,-Pwr);
  1046.   Ndivs := Round((Z2-Z1)/Zinc);
  1047. END;
  1048.  
  1049. (* -------------------------------------------------------*)
  1050.  
  1051. BEGIN                         { MakeWorldAndAxes }
  1052.   IF (NOT(WindowNum IN [1..10]))
  1053.   THEN
  1054.     BEGIN
  1055.       EndGraphic;
  1056.       WriteLn('MakeWorldAndAxes called with WindowNum = ',WindowNum);
  1057.       Writeln('Only ten windows may be designated');
  1058.       HALT;
  1059.     END;
  1060.    IF (NOT (WorldNum IN [1..10]))
  1061.    THEN
  1062.      BEGIN
  1063.       EndGraphic;
  1064.       WriteLn('MakeWorldAndAxes called with WorldNum = ',WorldNum);
  1065.       Writeln('Only ten worlds may be designated');
  1066.       HALT;
  1067.     END;
  1068.   OldColor := GetColor;
  1069.   scale(Xmin, Xmax, X1, X2, Dx, Xdivs, XPwr);
  1070.   scale(Ymin, Ymax, Y1, Y2, Dy, Ydivs, YPwr);
  1071.   TenXpwr := PwrI(10.0, XPwr);
  1072.   TenYpwr := PwrI(10.0, Ypwr);
  1073.   AxesXmin := X1*TenXpwr;    { passed as globals for MAIN's possible use }
  1074.   AxesXmax := X2*TenXpwr;
  1075.   AxesYmin := Y1*TenYpwr;
  1076.   AxesYmax := Y2*TenYpwr;
  1077.   DefineWorld(WorldNum,(X1-0.4*(X2-X1))*TenXpwr,
  1078.                        (X2+0.2*(X2-X1))*TenXpwr,
  1079.                        (Y1-0.3*(Y2-Y1))*TenYpwr,
  1080.                        (Y2+0.3*(Y2-Y1))*TenYpwr);
  1081.   SelectWindow(WindowNum);
  1082.   SelectWorld(WorldNum);
  1083.   BoxWorld(BoxColor);
  1084.   SetColor(AxesColor);
  1085.   { do x-axis }
  1086.   PlotLine(X1*TenXpwr, Y1*TenYpwr, X2*TenXpwr, Y1*TenYpwr, AxesColor);
  1087.  (* WITH GraphicWindow[WindowNum] DO
  1088.   BEGIN
  1089.     IF  Xmx-Xmn > 67.0 THEN XChrSize := 6
  1090.     ELSE
  1091.       IF  Xmx-Xmn > 37.0 THEN XChrSize := 5
  1092.       ELSE
  1093.         XChrSize := 4;
  1094.   END;
  1095. *)
  1096.   SetTextStyle(SmallFont,HorizDir,4);
  1097.   FOR J := 0 TO Xdivs DO  { draw x-axis and tics, draw x values }
  1098.     BEGIN
  1099.       PlotMoveTo((X1+J*Dx)*TenXpwr, Y1*TenYpwr);
  1100.       PlotLineRel(0, -0.5*TextHeight('H')*YperPixel, AxesColor);
  1101.       Str(((X1+J*Dx)*TenXpwr):0:5, Nstr);
  1102.       K := Pos('.',Nstr);
  1103.       Dot := K;
  1104.       REPEAT
  1105.         Inc(K);
  1106.       UNTIL (K=Length(Nstr)) OR (Nstr[K] <> '0');
  1107.       IF (K = Length(Nstr)) THEN
  1108.       BEGIN
  1109.         IF Nstr[K] = '0' THEN Digits := 0
  1110.         ELSE Digits := K-Dot;
  1111.       END
  1112.       ELSE
  1113.       BEGIN
  1114.         REPEAT
  1115.           Inc(K);
  1116.         UNTIL (K=Length(Nstr)) OR (Nstr[K] = '0');
  1117.         IF (Nstr[K] = '0') THEN
  1118.           Digits := K-1-Dot
  1119.         ELSE Digits := K-Dot;
  1120.       END;
  1121.       Str(((X1+J*Dx)*TenXpwr):0:Digits, Nstr);
  1122.       IF Nstr = '-0' THEN Nstr := '0';
  1123.       PlotMoveTo((X1+J*Dx)*TenXpwr-0.5*TextWidth(Nstr)*XperPixel,
  1124.                  AxesYmin-Textheight('1')*Yperpixel);
  1125.       TempY := NowY - TextHeight('1')*YperPixel;
  1126.       OutText(Nstr);
  1127.     END;
  1128.  
  1129.   { do y-axis }
  1130.   TempPosMin := WorldXmax;
  1131.   PlotLine(X1*TenXpwr, Y1*TenYpwr, X1*TenXpwr, Y2*TenYpwr,AxesColor);
  1132.   FOR J := 0 TO Ydivs DO
  1133.     BEGIN
  1134.       PlotMoveTo(X1*TenXpwr, (Y1+J*Dy)*TenYpwr);
  1135.       PlotLineRel(-0.5*TextWidth('H')*XperPixel, 0, AxesColor);
  1136.       Str(((Y1+J*Dy)*TenYpwr):0:5, Nstr);
  1137.       K := Pos('.',Nstr);
  1138.       Dot :=K;
  1139.       REPEAT
  1140.         Inc(k);
  1141.       UNTIL (K=Length(Nstr)) OR (Nstr[K] <> '0');
  1142.       IF (K = Length(Nstr)) THEN
  1143.       BEGIN
  1144.         IF Nstr[K] = '0' THEN Digits := 0
  1145.         ELSE Digits := K -Dot;
  1146.       END
  1147.       ELSE
  1148.       BEGIN
  1149.         REPEAT
  1150.           Inc(K);
  1151.         UNTIL (K=Length(Nstr)) OR (Nstr[K] = '0');
  1152.         IF (Nstr[K] = '0') THEN
  1153.           Digits := K-1-Dot
  1154.         ELSE Digits := K-Dot;
  1155.       END;
  1156.       Str(((Y1+J*Dy)*TenYpwr):0:Digits, Nstr);
  1157.       IF Nstr = '-0' THEN Nstr := '0';
  1158.       TempPos := X1*TenXpwr-(TextWidth('H')+TextWidth(Nstr))*XperPixel;
  1159.       IF TempPosMin > TempPos THEN TempPosMin := TempPos;
  1160.       PlotMoveTo(TempPos,(Y1+J*Dy)*TenYpwr+0.5*TextHeight('1')*YperPixel);
  1161.       OutText(Nstr);
  1162.     END;
  1163.   WriteTitles(Xtitle,Ytitle,MainTitle);
  1164.   WITH OldTextSettings DO
  1165.   BEGIN
  1166.     SetTextJustify(Horiz,Vert);
  1167.     SetTextStyle(Font,Direction,CharSize);
  1168.   END;
  1169.   MakeWindow(WindowNum,AxesXmin,AxesXmax,AxesYmin,AxesYmax);
  1170.   SelectWindow(WindowNum);
  1171.   DefineWorld(WorldNum,AxesXmin,AxesXmax,AxesYmin,AxesYmax);
  1172.   SelectWorld(WorldNum);
  1173.   SetColor(OldColor);
  1174. END;                          { MakeWorldAndAxes }
  1175.  
  1176. (**********************************************************************)
  1177.  
  1178. FUNCTION NowX : REAL;
  1179. VAR
  1180.   Xpix, Ypix : WORD;
  1181. BEGIN
  1182.   Xpix := GetX;
  1183.   Ypix := GetY;
  1184.   NowX := WorldXmin + XperPixel*Xpix;
  1185.   MoveTo(Xpix,Ypix);
  1186. END;
  1187.  
  1188. (***************************************************************************)
  1189.  
  1190. FUNCTION NowY : REAL;
  1191. VAR
  1192.   Xpix, Ypix : WORD;
  1193. BEGIN
  1194.   Xpix := GetX;
  1195.   Ypix := GetY;
  1196.   NowY := WorldYmax - YperPixel*Ypix;
  1197.   MoveTo(Xpix,Ypix);
  1198. END;
  1199.  
  1200. (***************************************************************************)
  1201.  
  1202. FUNCTION XtoYAspFac : REAL;
  1203. VAR
  1204.   Xasp, Yasp : WORD;
  1205. BEGIN
  1206.   GetAspectRatio(Xasp,Yasp);
  1207.   XtoYAspFac := YperPixel*Xasp/(XperPixel*Yasp);
  1208. END;
  1209.  
  1210. (***************************************************************************)
  1211.  
  1212. PROCEDURE CrossCursor(VAR CursorX, CursorY : REAL;
  1213.                       ColorCursor:WORD;ShowXY:Boolean;
  1214.                       Col, Row : INTEGER; ColorText : WORD);
  1215. VAR
  1216.   Ch : Char;
  1217.   X,Y,DelX,DelY : REAL;
  1218.   OldColor : WORD;
  1219.  
  1220. (* -------------------------------------------------------*)
  1221. PROCEDURE DrawCursor(x,y : REAL);
  1222. BEGIN
  1223.   PlotLine(x-DelX,y,x+delX,y, GetColor);
  1224.   PlotLine(x,y-DelY,x,y+delY,GetColor);
  1225. END;
  1226. (* -------------------------------------------------------*)
  1227. PROCEDURE ShowCursorXY;
  1228. BEGIN
  1229.   IF ShowXY THEN
  1230.   BEGIN
  1231.     GoToXY(Col,Row);
  1232.     write('X = ',CursorX:18,'   Y = ',CursorY:18);
  1233.   END;
  1234. END;
  1235. (* -------------------------------------------------------*)
  1236. PROCEDURE MoveCursor(x,y : REAL);
  1237. BEGIN
  1238.   DrawCursor(CursorX,CursorY);
  1239.   DrawCursor(x,y);
  1240. end;
  1241. (* -------------------------------------------------------*)
  1242. BEGIN                   { CrossCursor }
  1243.   WITH CurrentWorld DO
  1244.   BEGIN
  1245.     CursorX := 0.5*(Xmn+Xmx);
  1246.     CursorY := 0.5*(Ymn+Ymx);
  1247.   END; { WITH }
  1248.   DelX := 10.0*XperPixel;
  1249.   DelY := 10.0*YperPixel;
  1250.   TextColor(ColorText);
  1251.   OldColor := GetColor;
  1252.   SetColor(ColorCursor);
  1253.   SetWriteMode(XORput);
  1254.   DrawCursor(CursorX,CursorY);
  1255.   ShowCursorXY;
  1256.   REPEAT
  1257.     Ch := ReadKey;
  1258.     If Ch = #0 THEN
  1259.     BEGIN
  1260.       x := CursorX;
  1261.       y := CursorY;
  1262.       Ch := ReadKey;
  1263.       WITH CurrentWorld DO
  1264.       BEGIN
  1265.         CASE Ch of
  1266.           {RightArrow} #77 : IF (CursorX + Delx + XperPixel) <= Xmx THEN
  1267.                                x := CursorX + XperPixel;
  1268.           {LeftArrow}  #75 : IF (cursorX - DelX - XperPixel) >= Xmn THEN
  1269.                                x := CursorX - XperPixel;
  1270.           {UpArrow}    #72 : IF ( CursorY + DelY + YperPixel) <= Ymx THEN
  1271.                                y := CursorY + YperPixel;
  1272.           {DownArrow}  #80 : IF (CursorY -Dely - YperPixel) >= Ymn THEN
  1273.                                y := CursorY - YperPixel;
  1274.           { End }      #79 : IF (CursorX + DelX + 10.0*XperPixel) <= Xmx THEN
  1275.                                x := CursorX + 10.0*XperPixel;
  1276.           { Home }     #71 : IF (cursorX - DelX - 10.0*XperPixel) >= Xmn THEN
  1277.                                x := CursorX - 10.0*XperPixel;
  1278.           { PageUp }   #73 : IF ( CursorY + DelY + 10.0*YperPixel) <= Ymx THEN
  1279.                                y := CursorY + 10.0*YperPixel;
  1280.           { PageDown } #81 : IF (CursorY -DelY -10.0*YperPixel) >= Ymn THEN
  1281.                                y := CursorY - 10.0*YperPixel;
  1282.         END;  { CASE }
  1283.       END; { WITH }
  1284.       MoveCursor(x,y);
  1285.       CursorX := x;
  1286.       CursorY := y;
  1287.       ShowCursorXY;
  1288.       END;
  1289.   UNTIL (Ch = #13);
  1290.   DrawCursor(CursorX,CursorY);
  1291.   SetColor(OldColor);
  1292.   IF ShowXY THEN
  1293.     BEGIN
  1294.       GoToXY(Col, Row);
  1295.       FOR J := Col to 80 DO
  1296.         write(' ');
  1297.     END;
  1298.   SetWriteMode(NormalPut);
  1299. END; { CrossCursor }
  1300.  
  1301. (**************************************************************************)
  1302.  
  1303. PROCEDURE BoxCursor(VAR BoxXmin, BoxXmax, BoxYmin, BoxYmax : REAL;
  1304.                     ColorCursor : WORD; ShowXY : Boolean; Col, Row :integer;
  1305.                     ColorText : WORD);
  1306.  
  1307.                          { uses images 7, 8, 9 and 10 }
  1308.   CONST
  1309.     StepFraction = 0.2;
  1310.   VAR
  1311.     Xmin, Xmax, Ymin, Ymax, Xstep, Ystep : REAL;
  1312.     Ch : Char;
  1313.     OldColor : WORD;
  1314.     J : INTEGER;
  1315.     (* -------------------------------------------------------*)
  1316.     PROCEDURE DrawCursor;
  1317.     BEGIN
  1318.       PlotMoveTo(Xmin, Ymin);
  1319.       PlotLineTo(Xmin, Ymax, GetColor);
  1320.       PlotLineTo(Xmax, Ymax, GetColor);
  1321.       PlotLineTo(Xmax, Ymin, GetColor);
  1322.       PlotLineTo(Xmin, Ymin, GetColor);
  1323.     END;
  1324.     (* -------------------------------------------------------*)
  1325.     PROCEDURE MoveCursor(DelX, DelY : REAL);
  1326.     BEGIN
  1327.       DrawCursor;     { erase }
  1328.       Xmin := Xmin+DelX;
  1329.       Xmax := Xmax+DelX;
  1330.       Ymin := Ymin+DelY;
  1331.       Ymax := Ymax+DelY;
  1332.       DrawCursor;
  1333.     END;
  1334.     (* -------------------------------------------------------*)
  1335.     PROCEDURE ExpandCursor;   { no if any edge is within 1 pixel }
  1336.     VAR
  1337.       X1, X2, Y1, Y2, Xdist, Ydist : REAL;
  1338.     BEGIN
  1339.       Xdist := XperPixel;
  1340.       Ydist := YperPixel;
  1341.       BEGIN
  1342.         IF (((Xmin-Xstep) >= (WorldXmin+Xdist))
  1343.         AND ((Xmax+Xstep) <= (WorldXmax-Xdist))
  1344.         AND ((Ymin-Ystep) >= (WorldYmin+Ydist))
  1345.         AND ((Ymax+Ystep) <= (WorldYmax-Ydist)))
  1346.         THEN
  1347.           BEGIN
  1348.             X1 := Xmin-Xstep;
  1349.             X2 := Xmax+Xstep;
  1350.             Y1 := Ymin-Ystep;
  1351.             Y2 := Ymax+Ystep;
  1352.             DrawCursor;    { erase }
  1353.             Xmin := X1;
  1354.             Xmax := X2;
  1355.             Ymin := Y1;
  1356.             Ymax := Y2;
  1357.             Xstep := StepFraction*(Xmax-Xmin);
  1358.             Ystep := StepFraction*(Ymax-Ymin);
  1359.             DrawCursor;
  1360.           END;
  1361.       END;
  1362.     END;                      { ExpandCursor }
  1363.     (* -------------------------------------------------------*)
  1364.     PROCEDURE ShrinkCursor;
  1365.     VAR
  1366.       X1, X2, Y1, Y2 : REAL;
  1367.     BEGIN
  1368.       IF ((Xmax-Xmin) > (2.0*XperPixel))
  1369.       AND ((Ymax-Ymin) > (2.0*YperPixel)) THEN
  1370.         BEGIN
  1371.           X1 := Xmin+Xstep;
  1372.           X2 := Xmax-Xstep;
  1373.           Y1 := Ymin+Ystep;
  1374.           Y2 := Ymax-Ystep;
  1375.           DrawCursor;   { erase }
  1376.           Xmin := X1;
  1377.           Xmax := X2;
  1378.           Ymin := Y1;
  1379.           Ymax := Y2;
  1380.           Xstep := StepFraction*(Xmax-Xmin);
  1381.           Ystep := StepFraction*(Ymax-Ymin);
  1382.           DrawCursor;
  1383.         END;
  1384.     END;                      { ShrinkCursor }
  1385.   (* -------------------------------------------------------*)
  1386.  
  1387.   BEGIN                       {BoxCursor }
  1388.     OldColor := GetColor;
  1389.     SetColor(ColorCursor);
  1390.     TextColor(ColorText);
  1391.     Xmin := 0.5*(WorldXmax+WorldXmin)-0.1*(WorldXmax-WorldXmin);
  1392.     Xmax := 0.5*(WorldXmax+WorldXmin)+0.1*(WorldXmax-WorldXmin);
  1393.     Ymin := 0.5*(WorldYmax+WorldYmin)-0.1*(WorldYmax-WorldYmin);
  1394.     Ymax := 0.5*(WorldYmax+WorldYmin)+0.1*(WorldYmax-WorldYmin);
  1395.     Xstep := StepFraction*(Xmax-Xmin);
  1396.     Ystep := StepFraction*(Ymax-Ymin);
  1397.     SetWriteMode(XORput);
  1398.     DrawCursor;
  1399.     REPEAT
  1400.       IF ShowXY THEN
  1401.         BEGIN
  1402.           GoToXY(Col,Row);
  1403.           Write('Xcenter = ',(0.5*(Xmax+Xmin)):16,
  1404.                 '   Ycenter = ',(0.5*(Ymax+Ymin)):16);
  1405.         END;
  1406.       Ch := ReadKey;
  1407.       IF Ch = #0 THEN
  1408.         Ch := ReadKey;
  1409.       CASE Ch OF
  1410.         { UpArrow } #72 : IF ((Ymax+Ystep) <= WorldYmax-YperPixel) THEN
  1411.                             MoveCursor(0, Ystep)
  1412.                           ELSE
  1413.                             MoveCursor(0, WorldYmax-YperPixel-Ymax);
  1414.         { DownArrow } #80 : IF ((Ymin-Ystep) >= WorldYmin+YperPixel) THEN
  1415.                               MoveCursor(0, -Ystep)
  1416.                             ELSE
  1417.                               MoveCursor(0,WorldYmin+YperPixel-Ymin);
  1418.         {RightArrow } #77 : IF ((Xmax+Xstep) <= WorldXmax-XperPixel) THEN
  1419.                               MoveCursor(Xstep, 0)
  1420.                             ELSE MoveCursor(WorldXmax-XperPixel-Xmax,0);
  1421.         { LeftArrow } #75 : IF ((Xmin-Xstep) >= WorldXmin+XperPixel) THEN
  1422.                               MoveCursor(-Xstep, 0)
  1423.                             ELSE MoveCursor(WorldXmin+XperPixel-Xmin,0);
  1424.         { expand } '+' : ExpandCursor;
  1425.         { shrink } '-' : ShrinkCursor;
  1426.       END;                    {CASE }
  1427.       BoxXmin := Xmin;
  1428.       BoxXmax := Xmax;
  1429.       BoxYmin := Ymin;
  1430.       BoxYmax := Ymax;
  1431.     UNTIL Ch = #13;   { ENTER }
  1432.     DrawCursor;   { erase }
  1433.     SetColor(OldColor);
  1434.     IF ShowXY THEN
  1435.     BEGIN
  1436.       GoToXY(Col, Row);
  1437.       FOR J := Col to 79 DO
  1438.         write(' ');
  1439.     END;
  1440.     SetWriteMode(NormalPut);
  1441.   END;                        { BoxCursor }
  1442.  
  1443. (*************************************************************************)
  1444.  
  1445. PROCEDURE GetXYfromPixels(VAR X,Y : REAL; Xpos, Ypos : Integer);
  1446.   BEGIN
  1447.     X := WorldXmin + ((Xpos - WindowXMin)/(WindowXmax - WindowXmin))
  1448.                      *(WorldXmax - WorldXmin);
  1449.     Y := WorldYmin + ((WindowYmax - Ypos)/(WindowYmax - WindowYmin))
  1450.                      *(WorldYmax - WorldYmin);
  1451.   END;
  1452.  
  1453. (*************************************************************************)
  1454.  
  1455. FUNCTION MouseOK : Boolean;
  1456. BEGIN
  1457.   IF MouseDriverFound AND MouseReset THEN
  1458.     MouseOK := TRUE
  1459.   ELSE
  1460.     MouseOK := FALSE;
  1461. END;
  1462.  
  1463. (*************************************************************************)
  1464.  
  1465. PROCEDURE RestrictMouseToWindow;
  1466. BEGIN
  1467.   SetHorizCursorBounds(windowXmin,windowXmax);
  1468.   SetVertCursorbounds(windowYmin,windowYmax);
  1469. END;
  1470.  
  1471. (*************************************************************************)
  1472.  
  1473. FUNCTION LeftMouseXY(VAR X, Y :REAL): BOOLEAN;
  1474. VAR
  1475.   Xpos, Ypos : Integer;       { IF LeftButton Pressed THEN X Y are valid }
  1476. BEGIN                         { ELSE X Y NOT valid }
  1477.   IF LeftButtonPressed(Xpos, Ypos) THEN
  1478.       LeftMouseXY := TRUE
  1479.   ELSE
  1480.     LeftMouseXY := FALSE;
  1481.   GetXYfromPixels(X,Y,Xpos,Ypos);
  1482. END;
  1483.  
  1484. (*************************************************************************)
  1485.  
  1486. FUNCTION RightMouseXY(VAR X, Y :REAL): BOOLEAN;
  1487. VAR
  1488.   Xpos, Ypos : Integer;       { IF RightButton Pressed THEN X Y are valid }
  1489. BEGIN                         { ELSE X Y NOT valid }
  1490.   IF RightButtonPressed(Xpos, Ypos) THEN
  1491.       RightMouseXY := TRUE
  1492.   ELSE
  1493.     RightMouseXY := FALSE;
  1494.   GetXYfromPixels(X,Y,Xpos,Ypos);
  1495. END;
  1496.  
  1497. (*************************************************************************)
  1498.  
  1499. FUNCTION LeftButtonClicked(VAR X, Y : REAL) : Boolean;
  1500. VAR
  1501.   Xpos, Ypos : Integer;
  1502. Begin
  1503.   IF LeftButtonReleased(Xpos,Ypos) THEN
  1504.     LeftButtonClicked := TRUE
  1505.   ELSE
  1506.     LeftButtonClicked := FALSE;
  1507.   GetXYfromPixels(X, Y, Xpos, Ypos);
  1508. END;
  1509.  
  1510. (***************************************************************************)
  1511.  
  1512. FUNCTION RightButtonClicked(VAR X, Y : REAL) : Boolean;
  1513. VAR
  1514.   Xpos, Ypos : Integer;
  1515. Begin
  1516.   IF RightButtonReleased(Xpos,Ypos) THEN
  1517.     RightButtonClicked := TRUE
  1518.   ELSE
  1519.     RightButtonClicked := FALSE;
  1520.   GetXYfromPixels(X, Y, Xpos, Ypos);
  1521. END;
  1522.  
  1523. (***************************************************************************)
  1524.  
  1525. PROCEDURE GetMouseXY(VAR X,Y:REAL);  { returns mouse current position }
  1526. VAR
  1527.   Buttons, Xpos, Ypos : Integer;
  1528. BEGIN
  1529.   GetButtonsAndPosition(Buttons, Xpos, Ypos);
  1530.   GetXYfromPixels(X,Y,Xpos,Ypos);
  1531. END;
  1532.  
  1533. (*************************************************************************)
  1534.  
  1535. PROCEDURE MousePointer(VAR X, Y : REAL; Show : Boolean;
  1536.                        Row, Col : Integer; Color : BYTE);
  1537. VAR
  1538.   OldColor : BYTE;
  1539.   Xpos, Ypos : Integer;
  1540.   Xt, Yt : REAL;
  1541. BEGIN
  1542.   Xt := 1.0e20;
  1543.   Yt := 1.0E20;
  1544.   OldColor := TextAttr;
  1545.   If NOT MouseOk THEN
  1546.       BEGIN
  1547.         EndGraphic;
  1548.         WriteLn('MOUSE DRIVER NOT LOADED OR MOUSE HARDWARE NOT FOUND');
  1549.         HALT;
  1550.       END;
  1551.   RestrictMouseToWindow;
  1552.   ShowCursor;
  1553.   IF Show THEN
  1554.   BEGIN
  1555.     GoToXY(Col, Row);
  1556.     TextColor(Black);
  1557.     ClrEol;
  1558.     TextColor(Color);
  1559.   END;
  1560.   REPEAT
  1561.     GetMouseXY(X,Y);
  1562.     IF (X <> Xt) OR (Y <> Yt) THEN
  1563.     BEGIN
  1564.       Xt := X;
  1565.       Yt := Y;
  1566.       IF Show THEN
  1567.         BEGIN
  1568.           GOTOXY(Col, Row);
  1569.           Write('       X = ',X:12,'  Y = ',Y:12,
  1570.                   '     CLICK LEFT BUTTON TO EXIT');
  1571.         END;
  1572.     END;
  1573.   UNTIL  LeftButtonReleased(Xpos,Ypos);
  1574.   HideCursor;
  1575.   TextAttr := OldColor;
  1576. END; { MousePointer }
  1577.  
  1578. (*************************************************************************)
  1579.  
  1580. PROCEDURE MouseRubberBox(VAR X1,X2,Y1,Y2:REAL;Color : Word;
  1581.                          EraseBox : Boolean);
  1582. VAR
  1583.   x2t, y1t , xdum, ydum: REAL;
  1584.   Xpos, Ypos : INTEGER;
  1585.  
  1586.   BEGIN  { MouseRubberBox }
  1587.     If NOT MouseOk THEN
  1588.       BEGIN
  1589.         EndGraphic;
  1590.         WriteLn('MOUSE DRIVER NOT LOADED OR MOUSE HARDWARE NOT FOUND');
  1591.         HALT;
  1592.       END;
  1593.     RestrictMouseToWindow;
  1594.     ShowCursor;
  1595.     Repeat Until LeftButtonClicked(x1, y2); { initial upper left corner }
  1596.     REPEAT
  1597.       GetMouseXY(x2,y1);                    { initial lower right corner }
  1598.     UNTIL (x2 > x1)  AND (y1 < y2);
  1599.     hidecursor;
  1600.     SetWriteMode(XORput);
  1601.     plotrect(x1,x2,y1,y2,color);
  1602.     showcursor;
  1603.       x2t := x2;              { save initial lower right }
  1604.       y1t := y1;
  1605.     REPEAT
  1606.       REPEAT
  1607.         GetMouseXY(x2,y1);           { NEW lower right corner }
  1608.       UNTIL (x2 <> x2t) OR (y1 <> y1t);
  1609.       IF (x1 < x2) AND ( y1 < y2) THEN
  1610.       BEGIN
  1611.         hidecursor;
  1612.         PlotRect(x1,x2t,y1t,y2,color);  { erase old box }
  1613.         PlotRect(x1,x2,y1,y2,Color);  { show new box using new lower right }
  1614.         ShowCursor;
  1615.         x2t := x2; { save new lower right }
  1616.         y1t := y1;
  1617.       END;
  1618.     UNTIL LeftButtonClicked(xdum, ydum);
  1619.  
  1620.     HideCursor;           { drag box around }
  1621.       REPEAT
  1622.         GetMouseXY(x2t,y1t); { get new lower right corner for displacements }
  1623.         IF  (x2t <> x2) OR (y1t <> y1) THEN
  1624.         BEGIN
  1625.           PlotRect(x1,x2,y1,y2,color);  { erase old position }
  1626.           x1 := x1+x2t-x2;
  1627.           y2 := y2+y1t-y1;
  1628.           y1 := y1t;
  1629.           x2 := x2t;
  1630.           PlotRect(x1,x2,y1,y2,color);  { at new position }
  1631.         END;
  1632.       UNTIL LeftButtonClicked(x2t,y1t);
  1633.  
  1634.     IF EraseBox THEN
  1635.       plotrect(x1,x2,y1,y2,color);
  1636.     SetWriteMode(NormalPut);
  1637.     IF X1 > X2 THEN
  1638.     Begin
  1639.       X2t := X2;
  1640.       X2 := X1;
  1641.       X1 := X2t;
  1642.     End;
  1643.     IF Y1 > Y2 THEN
  1644.     Begin
  1645.       Y1t := Y1;
  1646.       Y1 := Y2;
  1647.       Y2 := Y1t;
  1648.     End;
  1649.   End; { MouseRubberBox }
  1650.  
  1651. (*************************************************************************)
  1652.  
  1653. PROCEDURE MouseRubberLine(VAR X1, Y1, X2, Y2 : REAL; Color : WORD;
  1654.                           EraseLine : Boolean);
  1655. VAR
  1656.   Xdum, Ydum, X2t, Y2t : REAL;
  1657.   OldColor : WORD;
  1658.  
  1659. BEGIN
  1660.   IF NOT MouseOk THEN
  1661.     BEGIN
  1662.       EndGraphic;
  1663.       WriteLn('NO MOUSE DRIVER LOADED OR NO MOUSE HARDWARE FOUND');
  1664.       HALT;
  1665.     END;
  1666.   OldColor := GetColor;
  1667.   RestrictMouseToWindow;
  1668.   ShowCursor;
  1669.   REPEAT UNTIL LeftButtonClicked(X1, Y1);
  1670.   HideCursor;
  1671.   X2 := X1;
  1672.   Y2 := Y1;
  1673.   SetWriteMode(XORput);
  1674.   PlotLine(X1,Y1,X2,Y2,Color);
  1675.   ShowCursor;
  1676.     REPEAT
  1677.       GetMouseXY(X2t, Y2t);
  1678.       IF (X2t <> X2) OR (Y2t <> Y2) THEN
  1679.       BEGIN
  1680.         HideCursor;
  1681.         PlotLine(X1,Y1,X2,Y2,Color);
  1682.         X2 := X2t;
  1683.         Y2 := Y2t;
  1684.         PlotLine(X1,Y1,X2,Y2,Color);
  1685.         ShowCursor;
  1686.       END;
  1687.     UNTIL LeftButtonClicked(Xdum, Ydum);
  1688.     HideCursor;
  1689.     If EraseLine THEN
  1690.       PlotLine(X1,Y1,X2,Y2,Color);
  1691.     SetWriteMode(NormalPut);
  1692.     SetColor(OldColor);
  1693. END;  { MouseRubberLine }
  1694.  
  1695. (*************************************************************************)
  1696.  
  1697. PROCEDURE MouseDraw(Color : WORD);
  1698.   VAR         { Draws while left button pressed.  Click right button to exit }
  1699.               { Drawing is left on screen }
  1700.     X1, Y1, X2, Y2, Xdum, Ydum : REAL;
  1701.     Xpos, Ypos : Integer;
  1702.     OldColor : WORD;
  1703.   BEGIN
  1704.     IF NOT MouseOK THEN
  1705.       BEGIN
  1706.         EndGraphic;
  1707.         WriteLn('Mouse Driver not loaded, or mouse hardware not found');
  1708.         Halt;
  1709.       END;
  1710.     OldColor := GetColor;
  1711.     SetColor(Color);
  1712.     ShowCursor;
  1713.     WHILE NOT RightButtonClicked(Xdum, Ydum) DO
  1714.       BEGIN
  1715.         WHILE LeftButtonPressed(Xpos, Ypos) DO
  1716.           BEGIN
  1717.             GetMouseXY(X1, Y1);
  1718.             REPEAT
  1719.               GetMouseXY(X2, Y2);
  1720.             UNTIL (X2 <> X1) OR (Y2 <> Y1);
  1721.             HideCursor;
  1722.             PlotLine(X1, Y1, X2, Y2, Color);
  1723.             ShowCursor;
  1724.             X1 := X2;
  1725.             Y1 := Y2;
  1726.           END;
  1727.       END;
  1728.     HideCursor;
  1729.     SetColor(OldColor);
  1730.   END;  { MouseDraw }
  1731.  
  1732. (*************************************************************************)
  1733.  
  1734. PROCEDURE GetPixelArea(CurveColor, RefillColor : Word; VAR Area : REAL);
  1735.   VAR
  1736.     X1, Y1 : Integer;
  1737.     F, D, Dx, Dy : Integer;
  1738.     Dfound : Boolean;
  1739.     Xmin, Xmax, Ymin, Ymax, X, Y : Integer;
  1740.     NumInside : LongInt;
  1741.     Xseed, Yseed : REAL;
  1742.  
  1743.   BEGIN
  1744.     IF MouseOK THEN
  1745.       MousePointer(Xseed, Yseed, False, 1, 1, Black)
  1746.     ELSE
  1747.       BEGIN
  1748.         SetWriteMode(XORput);
  1749.         CrossCursor(Xseed, Yseed, Green, False, 1, 1, Black);
  1750.         SetWriteMode(NormalPut);
  1751.       END;
  1752.     PlotMoveTo(Xseed, Yseed);
  1753.     REPEAT
  1754.       MoveRel(-1, 0);
  1755.     UNTIL GetPixel(GetX, GetY) = CurveColor;
  1756.     X1 := GetX;
  1757.     Y1 := GetY;
  1758.     Xmin := GetMaxX;
  1759.     Xmax := 0;
  1760.     Ymin := GetMaxY;
  1761.     Ymax := 0;
  1762.     F := 0;
  1763.     NumInside :=0;
  1764.     REPEAT
  1765.       Dfound := False;
  1766.         CASE F OF
  1767.           0 : D := 5;
  1768.           1 : D := 6;
  1769.           2 : D := 7;
  1770.           3 : D := 0;
  1771.           4 : D := 1;
  1772.           5 : D := 2;
  1773.           6 : D := 3;
  1774.           7 : D := 4;
  1775.         END;
  1776.       REPEAT
  1777.          CASE D OF
  1778.           6 : BEGIN  Dx := 0; Dy := -1; END;
  1779.           7 : BEGIN  Dx := -1; Dy := -1; END;
  1780.           0 : BEGIN  Dx := -1; Dy := 0; END;
  1781.           1 : BEGIN  Dx := -1; Dy := 1; END;
  1782.           2 : BEGIN  Dx := 0; Dy := 1; END;
  1783.           3 : BEGIN  Dx := 1; Dy := 1; END;
  1784.           4 : BEGIN  Dx := 1; Dy := 0; END;
  1785.           5 : BEGIN  Dx := 1; Dy := -1; END;
  1786.          END;
  1787.         MoveRel(Dx, Dy);
  1788.         X := GetX;
  1789.         Y := GetY;
  1790.         IF GetPixel(X, Y) = CurveColor THEN
  1791.           BEGIN
  1792.             Dfound := True;
  1793.             IF Xmin > X THEN Xmin := X
  1794.             ELSE
  1795.               IF Xmax < X THEN Xmax := X;
  1796.             IF Ymin > Y THEN Ymin := Y
  1797.             ELSE
  1798.               IF Ymax < Y THEN Ymax := Y;
  1799.           END
  1800.         ELSE
  1801.         BEGIN
  1802.           D := (D+1) MOD 8;
  1803.           MoveRel(-Dx, -Dy);
  1804.         END;
  1805.       UNTIL Dfound;
  1806.       F := D;
  1807.     UNTIL (X = X1) AND (Y = Y1);
  1808.     Flood(Xseed, Yseed, CurveColor, CurveColor);
  1809.     MoveTo(Xmin, Ymin);
  1810.     REPEAT
  1811.       X := GetX;
  1812.       REPEAT
  1813.         Y := GetY;
  1814.         IF GetPixel(X, Y) = CurveColor THEN
  1815.           BEGIN
  1816.             INC(NumInside);
  1817.             IF RefillColor <> Black THEN
  1818.               PutPixel(X, Y, RefillColor);
  1819.           END;
  1820.         INC(Y);
  1821.         MoveTo(X, Y);
  1822.       UNTIL Y > Ymax;
  1823.       INC(X);
  1824.       MoveTo(X, Ymin);
  1825.     UNTIL X > Xmax;
  1826.     Area := NumInside*XperPixel*YperPixel;
  1827.   END;
  1828.  
  1829. (*************************************************************************)
  1830.  
  1831. BEGIN                         { initialization of unit }
  1832.   WITH CurrentWorld DO
  1833.     BEGIN
  1834.       Xmn := -10.0;
  1835.       Xmx := 10.0;
  1836.       Ymn := -10.0;
  1837.       Ymx := 10.0;
  1838.     END;
  1839.   FOR J := 1 TO 10 DO
  1840.     BEGIN
  1841.       GraphicWorld[J] := CurrentWorld;
  1842.       ImageValid[J] := FALSE;
  1843.       SizeOfImage[J] := 0;
  1844.       WITH GraphicWindow[J] DO
  1845.         BEGIN
  1846.           Xmn := 0;           { full screen }
  1847.           Xmx := 100;
  1848.           Ymn := 0;
  1849.           Ymx := 100;
  1850.         END;
  1851.     END;
  1852.     Gdrvr := Detect;
  1853. END.
  1854.  
  1855.