home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l048 / 1.ddi / KERNEL.SYS < prev    next >
Encoding:
Text File  |  1986-05-06  |  30.4 KB  |  1,256 lines

  1. (***********************************************************)
  2. (*                                                         *)
  3. (*                TURBO GRAPHIX version 1.06A              *)
  4. (*                                                         *)
  5. (*                  Graphics system kernel                 *)
  6. (*                   Module version 1.06A                  *)
  7. (*                                                         *)
  8. (*                  Copyright (C) 1985 by                  *)
  9. (*                  BORLAND International                  *)
  10. (*                                                         *)
  11. (***********************************************************)
  12.  
  13. procedure GotoXYTurbo(X, Y : integer);
  14. begin
  15.   GotoXY(X, Y);  { This will call Turbo's GotoXY }
  16. end; { GotoXYTurbo }
  17.  
  18. procedure GotoXY(X, Y : integer);
  19. { Further calls to GotoXY will call this procedure }
  20. begin
  21.   if not GrafModeGlb then
  22.     GotoXYTurbo(X, Y);
  23.   XTextGlb := X;
  24.   YTextGlb := Y;
  25. end; { GotoXY }
  26.  
  27. procedure ClrEOLTurbo;
  28. begin
  29.   ClrEOL;  { This will call Turbo's ClrEOL }
  30. end; { ClrEOLTurbo }
  31.  
  32. procedure ClrEOL;
  33. { Further calls to ClrEOL will call this procedure }
  34. var
  35.   Temp : integer;
  36. begin
  37.   if not GrafModeGlb then
  38.     ClrEOLTurbo
  39.   else
  40.     begin
  41.       Temp := XTextGlb;
  42.       for XTextGlb := Temp to 80 do
  43.         DC(32);
  44.       XTextGlb := Temp;
  45.     end;
  46. end; { ClrEOL }
  47.  
  48. procedure Error { declared in GRAPHIX.SYS: (ErrProc, ErrCode : integer) };
  49. type
  50.   String2 = string[2];
  51. var
  52.   NLevels, PCValue, XLoc, YLoc : integer;
  53.   Ch : char;
  54.  
  55. function HexString(Byt : byte) : string2;
  56. const
  57.   Hex : array[0..15] of char = '0123456789ABCDEF';
  58. begin
  59.   HexString := Hex[Byt shr 4] + Hex[Byt and 15];
  60. end; { HexString }
  61.  
  62. begin { Error }
  63.   if not (ErrProc in [0..MaxProcsGlb]) then
  64.   begin
  65.     LeaveGraphic;
  66.     WriteLn('FATAL Error 1: illegal procedure number ', ErrProc);
  67.     Halt;
  68.   end;
  69.   if not (ErrCode in [0..MaxErrsGlb]) then
  70.   begin
  71.     LeaveGraphic;
  72.     WriteLn('FATAL Error 2: illegal Error code ', ErrCode);
  73.     Halt;
  74.   end;
  75.   ErrCodeGlb := ErrCode;
  76.   if BrkGlb then
  77.     LeaveGraphic;
  78.   if MessageGlb or BrkGlb then
  79.   begin
  80.     XLoc := XTextGlb;
  81.     YLoc := YTextGlb;
  82.     GotoXY(1, 24);
  83.     ClrEOL;
  84.     WriteLn('Turbo Graphix Error #', ErrCode, ' in procedure #', ErrProc);
  85.     if MessageGlb then
  86.     begin
  87.       ClrEOL;
  88.       Write('(', ErrorCode[ErrCode]^, ' in ', ErrorProc[ErrProc]^, ')');
  89.     end;
  90.   end;
  91.   if MessageGlb and BrkGlb then
  92.     begin
  93.       WriteLn;
  94.       WriteLn('Traceback:');
  95.       NLevels := 0;
  96.       repeat
  97.         inline($89/$EB/$8B/$8E/ NLevels /$09/$C9/$74/$05/$8B/$6E/
  98.                $00/$E2/$FB/$8B/$46/$02/$89/$DD/$89/$86/ PCValue );
  99.         if PCValue <> 0 then
  100.           WriteLn(PcGlb, ' : ', HexString(Hi(PCValue - 1)),
  101.                   HexString(Lo(PCValue - 1)));
  102.         NLevels := NLevels + 1;
  103.       until (NLevels > 20) or (PCValue = 0); { Trace back no more than 20 levels }
  104.       Halt;
  105.     end
  106.   else if BrkGlb { and not MessageGlb } then
  107.     Halt
  108.   else if MessageGlb then
  109.     begin
  110.       Write('.  Hit enter: ');
  111.       repeat
  112.         Read(KBD, Ch);
  113.       until (Ch = ^M) or (Ch = ^C);
  114.       if Ch = ^C then
  115.       begin
  116.         LeaveGraphic;
  117.         Halt;
  118.       end;
  119.       GotoXY(XLoc, YLoc);
  120.     end;
  121. end; { Error }
  122.  
  123. procedure SetBreakOff;
  124. begin
  125.   BrkGlb := false;
  126. end; { SetBreakOff }
  127.  
  128. procedure SetBreakOn;
  129. begin
  130.   BrkGlb := true;
  131. end; { SetBreakOn }
  132.  
  133. function GetErrorCode : byte;
  134. begin
  135.   GetErrorCode := ErrCodeGlb;
  136.   ErrCodeGlb := 0;
  137. end; { GetErrorCode }
  138.  
  139. procedure SetWindowModeOff;
  140. begin
  141.   DirectModeGlb := true;
  142. end; { SetWindowModeOff }
  143.  
  144. procedure SetWindowModeOn;
  145. begin
  146.   DirectModeGlb := false;
  147. end; { SetWindowModeOn }
  148.  
  149. procedure SetClippingOn;
  150. begin
  151.   ClippingGlb := true;
  152. end; { SetClippingOn }
  153.  
  154. procedure SetClippingOff;
  155. begin
  156.   ClippingGlb := false;
  157. end; { SetClippingOff }
  158.  
  159. procedure SetMessageOn;
  160. begin
  161.   MessageGlb := true;
  162. end; { SetMessageOn }
  163.  
  164. procedure SetMessageOff;
  165. begin
  166.   MessageGlb := false;
  167. end; { SetMessageOff }
  168.  
  169. procedure SetHeaderOn;
  170. begin
  171.   HeaderGlb := true;
  172. end; { SetHeaderOn }
  173.  
  174. procedure SetHeaderOff;
  175. begin
  176.   HeaderGlb := false;
  177. end; { SetHeaderOff }
  178.  
  179. procedure SetHeaderToTop;
  180. begin
  181.   TopGlb := true;
  182. end; { SetHeaderToTop }
  183.  
  184. procedure SetHeaderToBottom;
  185. begin
  186.   TopGlb := false;
  187. end; { SetHeaderToBottom }
  188.  
  189. procedure RemoveHeader(I : integer);
  190. begin
  191.   if I in [1..MaxWindowsGlb] then
  192.     with Window[I] do
  193.     begin
  194.       Drawn := false;
  195.       Top := true;
  196.       Header := '';
  197.     end
  198.   else
  199.     Error(22, 2);
  200. end; { RemoveHeader }
  201.  
  202. procedure SetColorWhite;
  203. begin
  204.   ColorGlb := 255;
  205. end; { SetColorWhite }
  206.  
  207. procedure SetColorBlack;
  208. begin
  209.   ColorGlb := 0;
  210. end; { SetColorBlack }
  211.  
  212. function GetWindow : integer;
  213. begin
  214.   GetWindow := WindowNdxGlb;
  215. end; { GetWindow }
  216.  
  217. function GetColor : integer;
  218. begin
  219.   GetColor := ColorGlb;
  220. end; { GetColor }
  221.  
  222. function Clipping : boolean;
  223. begin
  224.     Clipping := ClippingGlb;
  225. end; { Clipping }
  226.  
  227. function WindowMode : boolean;
  228. begin
  229.   WindowMode := not DirectModeGlb;
  230. end; { WindowMode }
  231.  
  232. procedure SetScreenAspect(Aspect : real);
  233. begin
  234.   if Aspect <> 0.0 then
  235.     AspectGlb := abs(Aspect);
  236. end; { SetScreenAspect }
  237.  
  238. function GetScreenAspect : real;
  239. begin
  240.   GetScreenAspect := AspectGlb;
  241. end; { GetScreenAspect }
  242.  
  243. procedure SetAspect(Aspect : real);
  244. begin
  245.   if Aspect <> 0.0 then
  246.     AspectGlb := abs(Aspect) * AspectFactor;
  247. end; { SetAspect }
  248.  
  249. function GetAspect : real;
  250. begin
  251.   GetAspect := AspectGlb / AspectFactor;
  252. end; { GetAspect }
  253.  
  254. procedure SetLinestyle(Ls : integer);
  255. var
  256.   I : integer;
  257. const
  258.   Lsa : array[0..4] of byte = ($FF,$88,$F8,$E4,$EE);
  259.  
  260. begin
  261.   if not (Ls in [0..4]) then
  262.     Ls := Ls and $FF + $100;
  263.   LineStyleGlb := Ls;
  264.   if Ls < 5 then
  265.     Ls := Lsa[Ls];
  266.   for I := 0 to 7 do
  267.     LineStyleArrayGlb[7 - I] := ((Ls shr I) and 1) <> 0;
  268.   CntGlb := 7;
  269. end; { SetLinestyle }
  270.  
  271. function GetLinestyle : integer;
  272. begin
  273.   GetLinestyle := LinestyleGlb;
  274. end; { GetLinestyle }
  275.  
  276. procedure SetVStep(Vs : integer);
  277. begin
  278.   if Vs > 0 then
  279.     VStepGlb := Vs;
  280. end; { SetVStep }
  281.  
  282. function GetVStep : integer;
  283. begin
  284.   GetVStep := VStepGlb;
  285. end; { GetVStep }
  286.  
  287. procedure DefineHeader(I : integer; Hdr : WrkString);
  288. begin
  289.   if (I in [1..MaxWindowsGlb]) then
  290.     Window[I].Header := Hdr
  291.   else
  292.     Error(3, 2);
  293. end; { DefineHeader }
  294.  
  295. procedure SelectScreen(I : integer);
  296. begin
  297.   if RamScreenGlb and (I = 2) then
  298.     GrafBase := Seg(ScreenGlb^)
  299.   else
  300.     GrafBase := HardwareGrafBase;
  301. end; { SelectScreen }
  302.  
  303. function GetScreen : byte;
  304. begin
  305.   if GrafBase = HardwareGrafBase then
  306.     GetScreen := 1
  307.   else
  308.     GetScreen := 2;
  309. end; { GetScreen }
  310.  
  311. procedure DefineWorld(I : integer; X_1, Y_1, X_2, Y_2 : real);
  312. begin
  313.   if ((X_1 <> X_2) and (Y_1 <> Y_2)) and (I in [1..MaxWorldsGlb]) then
  314.     with World[I] do
  315.     begin
  316.       X1 := X_1; Y1 := Y_1; X2 := X_2; Y2 := Y_2;
  317.       if I > MaxWorldGlb then
  318.         MaxWorldGlb := I;
  319.     end
  320.   else if I in [1..MaxWorldsGlb] then
  321.     Error(1, 3)
  322.   else
  323.     Error(1, 2);
  324. end; { DefineWorld }
  325.  
  326. procedure SelectWorld(I : integer);
  327. begin
  328.   if (I in [1..MaxWorldGlb]) then
  329.     with World[I] do
  330.     begin
  331.       WorldNdxGlb := I;
  332.       X1WldGlb := X1;
  333.       Y1WldGlb := Y1;
  334.       X2WldGlb := X2;
  335.       Y2WldGlb := Y2;
  336.     end
  337.   else
  338.     Error(2, 2);
  339. end; { SelectWorld }
  340.  
  341. procedure ReDefineWindow(I, X_1, Y_1, X_2, Y_2 : integer);
  342. begin
  343.   if (I in [1..MaxWindowsGlb]) and (X_1 <= X_2) and (Y_1 <= Y_2) and (X_1 >= 0)
  344.      and (X_2 <= XScreenMaxGlb) and (Y_1 >= 0) and (Y_2 <= YMaxGlb) then
  345.     with Window[I] do
  346.     begin
  347.       X1 := X_1;
  348.       Y1 := Y_1;
  349.       X2 := X_2;
  350.       Y2 := Y_2;
  351.       if I > MaxWindowGlb then
  352.         MaxWindowGlb := I;
  353.     end
  354.   else if I in [1..MaxWindowsGlb] then
  355.     Error(3, 3)
  356.   else
  357.     Error(3, 2);
  358. end; { ReDefineWindow }
  359.  
  360. procedure DefineWindow(I, X_1, Y_1, X_2, Y_2 : integer);
  361. begin
  362.   ReDefineWindow(I, X_1, Y_1, X_2, Y_2);
  363.   with Window[I] do
  364.   begin
  365.     Header := '';
  366.     Top := true;
  367.     Drawn := false;
  368.   end;
  369. end; { DefineWindow }
  370.  
  371. function TextLeft(TX, Boundary : integer) : integer;
  372. var
  373.   TL : integer;
  374. begin
  375.   TL := ((TX - 1) * ((XScreenMaxGlb + 1) div 80) - Boundary) div 8;
  376.   if TL < 0 then
  377.     TL := 0
  378.   else if TL > XMaxGlb then
  379.     TL := XMaxGlb;
  380.   TextLeft := TL;
  381. end; { TextLeft }
  382.  
  383. function TextRight(TX, Boundary : integer) : integer;
  384. var
  385.   TR : integer;
  386. begin
  387.   TR := (XScreenMaxGlb + 1) div 80;
  388.   TR := (TX * TR + Boundary - 1) div 8;
  389.   if TR < 0 then
  390.     TR := 0
  391.   else if TR > XMaxGlb then
  392.     TR := XMaxGlb;
  393.   TextRight := TR;
  394. end; { TextRight }
  395.  
  396. function TextUp(TY, Boundary : integer) : integer;
  397. var
  398.   TU : integer;
  399. begin
  400.   TU := (TY - 1) * ((YMaxGlb + 1) div 25) - Boundary;
  401.   if TU < 0 then
  402.     TU := 0
  403.   else if TU > YMaxGlb then
  404.     TU := YMaxGlb;
  405.   TextUp := TU;
  406. end; { TextUp }
  407.  
  408. function TextDown(TY, Boundary : integer) : integer;
  409. var
  410.   TD : integer;
  411. begin
  412.   TD := TY * ((YMaxGlb + 1) div 25) + Boundary - 1;
  413.   if TD < 0 then
  414.     TD := 0
  415.   else if TD > YMaxGlb then
  416.     TD := YMaxGlb;
  417.   TextDown := TD;
  418. end; { TextDown }
  419.  
  420. procedure DefineTextWindow(I, X1, Y1, X2, Y2, B : integer);
  421. begin
  422.   DefineWindow(I, TextLeft(X1, B), TextUp(Y1, B),
  423.                TextRight(X2, B), TextDown(Y2, B));
  424. end; { DefineTextWindow }
  425.  
  426. procedure SelectWindow(I : integer);
  427. begin
  428.   if (I in [1..MaxWindowGlb]) then
  429.     with Window[I] do
  430.     begin
  431.       WindowNdxGlb := I;
  432.       X1RefGlb := X1;
  433.       Y1RefGlb := Y1;
  434.       X2RefGlb := X2;
  435.       Y2RefGlb := Y2;
  436.       BxGlb := ((X2 - X1) shl 3 + 7) / (X2WldGlb - X1WldGlb);
  437.       ByGlb := (Y2 - Y1) / (Y2WldGlb - Y1WldGlb);
  438.       AxGlb := (X1 shl 3) - X1WldGlb * BxGlb;
  439.       AyGlb := Y1 - Y1WldGlb * ByGlb;
  440.       if AxisGlb then
  441.       begin
  442.         AxisGlb := false;
  443.         X1Glb := 0;
  444.         Y1Glb := 0;
  445.         X2Glb := 0;
  446.         Y2Glb := 0;
  447.       end;
  448.     end
  449.   else
  450.     Error(4, 2);
  451. end; { SelectWindow }
  452.  
  453. function WindowX(X : real) : integer;
  454. var
  455.   Temp : real;
  456. begin
  457.   Temp := AxGlb + BxGlb * X;
  458.   if Temp > MaxInt then
  459.     WindowX := MaxInt
  460.   else if Temp < -32767 then
  461.     WindowX := -32767
  462.   else
  463.     WindowX := trunc(Temp);
  464. end; { WindowX }
  465.  
  466. function WindowY(Y : real) : integer;
  467. var
  468.   Temp : real;
  469. begin
  470.   Temp := AyGlb + ByGlb * Y;
  471.   if Temp > MaxInt then
  472.     WindowY := MaxInt
  473.   else if Temp < -32767 then
  474.     WindowY := -32767
  475.   else
  476.     WindowY := trunc(Temp);
  477. end; { WindowY }
  478.  
  479. procedure InitGraphic;
  480. var
  481.   Fil : file of CharArray;
  482.   Tfile : text;
  483.   Test : ^integer;
  484.   Temp : WrkString;
  485.   I : integer;
  486. begin
  487.   GotoXY(1, 1);
  488.   if not HardwarePresent then
  489.   begin
  490.     ClrScr;
  491.     GotoXY(1, 2);
  492.     WriteLn('Fatal Error: graphics hardware not found or not properly activated');
  493.     Halt;
  494.   end;
  495.   MessageGlb := true;
  496.   BrkGlb := false;
  497.   GrafModeGlb := false;
  498.   GetMem(ErrorProc[0], 16);
  499.   GetMem(ErrorCode[0], 24);
  500.   ErrorProc[0]^ := 'InitGraphic';
  501.   ErrorCode[0]^ := 'Error.MSG missing';
  502.   Assign(Tfile, 'Error.msg');
  503.   {$I-} Reset(Tfile); {$I+}
  504.   if IOresult = 0 then
  505.     begin
  506.       for I := 0 to MaxProcsGlb do
  507.       begin
  508.         ReadLn(Tfile, Temp);
  509.         if I <> 0 then
  510.           GetMem(ErrorProc[I], Length(Temp) + 1);
  511.         ErrorProc[I]^ := Temp;
  512.       end;
  513.       for I := 0 to MaxErrsGlb do
  514.       begin
  515.         ReadLn(Tfile, Temp);
  516.         if I <> 0 then
  517.           GetMem(ErrorCode[I], Length(Temp) + 1);
  518.         ErrorCode[I]^ := Temp;
  519.       end;
  520.       ReadLn(Tfile, PcGlb);
  521.       Close(Tfile);
  522.     end
  523.   else
  524.     begin
  525.       GetMem(ErrorProc[1], 14);
  526.       ErrorProc[1]^ := '** UNKNOWN **';
  527.       for I := 2 to MaxProcsGlb do
  528.         ErrorProc[I] := ErrorProc[1];
  529.       for I := 1 to MaxErrsGlb do
  530.         ErrorCode[I] := ErrorProc[1];
  531.       Error(0, 0);
  532.     end;
  533.   for I := 1 to MaxWorldsGlb do
  534.     DefineWorld(I, 0, 0, XScreenMaxGlb, YMaxGlb);
  535.   MaxWorldGlb := 1;
  536.   for I := 1 to MaxWindowsGlb do
  537.   begin
  538.     DefineWindow(I, 0, 0, XMaxGlb, YMaxGlb);
  539.     with Stack[I] do
  540.     begin
  541.       W.Size := 0;
  542.       Contents := nil;
  543.     end;
  544.     RemoveHeader(I);
  545.   end;
  546.   MaxWindowGlb := 1;
  547.   if CharFile <> '' then
  548.   begin
  549.     Assign(Fil, CharFile);
  550.     {$I-} Reset(Fil); {$I+}
  551.     if IOresult = 0 then
  552.       Read(Fil, CharSet)
  553.     else
  554.       Error(0, 1);
  555.     Close(Fil);
  556.   end;
  557.   BrkGlb := true;
  558.   if RamScreenGlb then
  559.   begin
  560.     AllocateRAMScreen;
  561.     SelectScreen(2);
  562.     ClearScreen;
  563.   end;
  564.   SelectScreen(1);
  565.   WindowNdxGlb := 1;
  566.   SelectWorld(1);
  567.   SelectWindow(1);
  568.   SetColorWhite;
  569.   SetClippingOn;
  570.   SetAspect(AspectFactor);
  571.   DirectModeGlb := false;
  572.   PieGlb := false;
  573.   SetMessageOn;
  574.   SetHeaderOff;
  575.   SetHeaderToTop;
  576.   ErrCodeGlb := 0;
  577.   SetLineStyle(0);
  578.   VStepGlb := IVStepGlb;
  579.   EnterGraphic;
  580.   X1Glb := 0;
  581.   X2Glb := 0;
  582.   Y1Glb := 0;
  583.   Y2Glb := 0;
  584.   AxisGlb := false;
  585.   HatchGlb := false;
  586. end; { InitGraphic }
  587.  
  588. procedure ResetWindows;
  589. var
  590.   I : integer;
  591. begin
  592.   for I := 1 to MaxWindowsGlb do
  593.   begin
  594.     DefineWindow(I, 0, 0, XMaxGlb, YMaxGlb);
  595.     RemoveHeader(I);
  596.   end;
  597.   SelectWindow(1);
  598. end; { ResetWindows }
  599.  
  600. procedure ResetWorlds;
  601. var
  602.   I : integer;
  603. begin
  604.   for I := 1 to MaxWorldsGlb do
  605.     DefineWorld(I, 0, 0, XScreenMaxGlb, YMaxGlb);
  606.   SelectWorld(1);
  607.   SelectWindow(WindowNdxGlb);
  608. end; { ResetWorlds }
  609.  
  610. function Clip(var X1, Y1, X2, Y2 : integer) : boolean;
  611. var
  612.   Ix1, Iy1, Ix2, Iy2, Dummy, X1Loc, X2Loc : integer;
  613.   ClipLoc : boolean;
  614.   Temp : real;
  615.  
  616. function Inside(X, Xx1, Xx2 : integer) : integer;
  617. begin
  618.   Inside := 0;
  619.   if X < Xx1 then
  620.     Inside := -1
  621.   else if X > Xx2 then
  622.     Inside := 1;
  623. end; { Inside }
  624.  
  625. begin  { Clip }
  626.   Clip := true;
  627.   ClipLoc := true;
  628.   if ClippingGlb then
  629.     begin
  630.       if HatchGlb then
  631.         begin
  632.           X1Loc := X1RefGlb;
  633.           X2Loc := X2RefGlb;
  634.         end
  635.       else
  636.         begin
  637.           X1Loc := X1RefGlb shl 3;
  638.           X2Loc := X2RefGlb shl 3 + 7;
  639.         end;
  640.       Ix1 := Inside(X1, X1Loc, X2Loc);
  641.       Iy1 := Inside(Y1, Y1RefGlb, Y2RefGlb);
  642.       Ix2 := Inside(X2, X1Loc, X2Loc);
  643.       Iy2 := Inside(Y2, Y1RefGlb, Y2RefGlb);
  644.       if (Ix1 or Ix2 or Iy1 or Iy2) <> 0 then
  645.       begin
  646.         if X1 <> X2 then
  647.         begin
  648.           if Ix1 <>0 then
  649.           begin
  650.             if Ix1 < 0 then
  651.               Dummy := X1Loc
  652.             else
  653.               Dummy := X2Loc;
  654.             if Y2 <> Y1 then
  655.             begin
  656.               Temp := (Y2 - Y1) / (X2 - X1) * (Dummy - X1);
  657.               if Temp > MaxInt then
  658.                 Temp := MaxInt
  659.               else if Temp < -32767 then
  660.                 Temp := -32767;
  661.               Y1 := Y1 + trunc(Temp);
  662.             end;
  663.             X1 := Dummy;
  664.           end;
  665.           if (Ix2 <> 0) and (X1 <> X2) then
  666.           begin
  667.             if Ix2 < 0 then
  668.               Dummy := X1Loc
  669.             else
  670.               Dummy := X2Loc;
  671.             if Y2 <> Y1 then
  672.             begin
  673.               Temp := (Y2 - Y1) / (X2 - X1) * (Dummy - X1);
  674.               if Temp > MaxInt then
  675.                 Temp := MaxInt
  676.               else if Temp < -32767 then
  677.                 Temp := -32767;
  678.               Y2 := Y1 + trunc(Temp);
  679.             end;
  680.             X2 := Dummy;
  681.           end;
  682.           Iy1 := Inside(Y1, Y1RefGlb, Y2RefGlb);
  683.           Iy2 := Inside(Y2, Y1RefGlb, Y2RefGlb);
  684.         end;
  685.         if Y1 <> Y2 then
  686.         begin
  687.           if Iy1 <> 0 then
  688.           begin
  689.             if Iy1 < 0 then
  690.               Dummy := Y1RefGlb
  691.             else
  692.               Dummy := Y2RefGlb;
  693.             if X1 <> X2 then
  694.             begin
  695.               Temp := (X2 - X1) / (Y2 - Y1) * (Dummy - Y1);
  696.               if Temp > MaxInt then
  697.                 Temp := MaxInt
  698.               else if Temp < -32767 then
  699.                 Temp := -32767;
  700.               X1 := X1 + trunc(Temp);
  701.             end;
  702.             Y1 := Dummy;
  703.           end;
  704.           if Iy2 <> 0 then
  705.           begin
  706.             if Iy2 < 0 then
  707.               Dummy := Y1RefGlb
  708.             else
  709.               Dummy := Y2RefGlb;
  710.             if X1 <> X2 then
  711.             begin
  712.               Temp := (X2 - X1) / (Y2 - Y1) * (Dummy - Y1);
  713.               if Temp > MaxInt then
  714.                 Temp := MaxInt
  715.               else if Temp < -32767 then
  716.                 Temp := -32767;
  717.               X2 := X1 + trunc(Temp);
  718.             end;
  719.             Y2 := Dummy;
  720.           end;
  721.         end;
  722.         Iy1 := Inside(Y1, Y1RefGlb, Y2RefGlb);
  723.         Iy2 := Inside(Y2, Y1RefGlb, Y2RefGlb);
  724.         if (Iy1 <> 0) or (Iy2 <> 0) then
  725.           ClipLoc := false;
  726.         if ClipLoc then
  727.         begin
  728.           Ix1 := Inside(X1, X1Loc, X2Loc);
  729.           Ix2 := Inside(X2, X1Loc, X2Loc);
  730.           if (Ix2 <> 0) or (Ix1 <> 0) then
  731.             ClipLoc := false;
  732.         end;
  733.         Clip := ClipLoc;
  734.       end;
  735.     end;
  736. end; { Clip }
  737.  
  738. procedure DrawPoint(Xr, Yr : real);
  739. var
  740.   X, Y : integer;
  741. begin
  742.   if DirectModeGlb then
  743.     DP(trunc(Xr), trunc(Yr))
  744.   else
  745.     begin
  746.       X := WindowX(Xr);
  747.       Y := WindowY(Yr);
  748.       if ClippingGlb then
  749.         begin
  750.           if (X >= X1RefGlb shl 3) and (X < X2RefGlb shl 3 + 7) then
  751.             if (Y >= Y1RefGlb) and (Y <= Y2RefGlb) then
  752.               DP(X, Y);
  753.         end
  754.       else
  755.         DP(X, Y);
  756.     end;
  757. end; { DrawPoint }
  758.  
  759. function PointDrawn(Xr, Yr : real) : boolean;
  760. begin
  761.   if DirectModeGlb then
  762.     PointDrawn := PD(trunc(Xr), trunc(Yr))
  763.   else
  764.     PointDrawn := PD(WindowX(Xr), WindowY(Yr));
  765. end; { PointDrawn }
  766.  
  767. procedure DrawLine(X1, Y1, X2, Y2 : real);
  768. var
  769.   X1Loc, Y1Loc, X2Loc, Y2Loc : integer;
  770.  
  771. procedure DrawLineDirect(X1, Y1, X2, Y2 : integer);
  772. var
  773.   X, Y, DeltaX, DeltaY, XStep, YStep, Direction : integer;
  774. begin
  775.   X := X1;
  776.   Y := Y1;
  777.   XStep := 1;
  778.   YStep := 1;
  779.   if X1 > X2 then
  780.     XStep := -1;
  781.   if Y1 > Y2 then
  782.     YStep := -1;
  783.   DeltaX := abs(X2 - X1);
  784.   DeltaY := abs(Y2 - Y1);
  785.   if DeltaX = 0 then
  786.     Direction := -1
  787.   else
  788.     Direction := 0;
  789.   while not ((X = X2) and (Y = Y2)) do
  790.   begin
  791.     if LinestyleGlb = 0 then
  792.       DP(X, Y)
  793.     else
  794.       begin
  795.         CntGlb := (CntGlb + 1) and 7;
  796.         if LineStyleArrayGlb[CntGlb] then
  797.           DP(X, Y);
  798.       end;
  799.     if Direction < 0 then
  800.       begin
  801.         Y := Y + YStep;
  802.         Direction := Direction + DeltaX;
  803.       end
  804.     else
  805.       begin
  806.         X := X + XStep;
  807.         Direction := Direction - DeltaY;
  808.       end;
  809.   end;
  810. end; { DrawLineDirect }
  811.  
  812. begin { DrawLine }
  813.   if DirectModeGlb then
  814.     DrawLineDirect(trunc(X1), trunc(Y1), trunc(X2), trunc(Y2))
  815.   else
  816.     begin
  817.       X1Loc := WindowX(X1);
  818.       Y1Loc := WindowY(Y1);
  819.       X2Loc := WindowX(X2);
  820.       Y2Loc := WindowY(Y2);
  821.       if Clip(X1Loc, Y1Loc, X2Loc, Y2Loc) then
  822.         DrawLineDirect(X1Loc, Y1Loc, X2Loc, Y2Loc);
  823.     end;
  824. end; { DrawLine }
  825.  
  826. procedure DrawLineClipped(X1, Y1, X2, Y2 : integer);
  827. begin
  828.   if Clip(X1, Y1, X2, Y2) then
  829.     DrawLine(X1, Y1, X2, Y2);
  830. end; { DrawLineClipped }
  831.  
  832. procedure DrawCrossDiag(X, Y, Scale : integer);
  833. begin
  834.   DrawLineClipped(X - Scale, Y + Scale, X + Scale + 1, Y - Scale - 1);
  835.   DrawLineClipped(X - Scale, Y - Scale, X + Scale + 1, Y + Scale + 1);
  836. end; { DrawCrossDiag }
  837.  
  838. procedure DrawWye(X, Y, Scale : integer);
  839. begin
  840.   DrawLineClipped(X - Scale, Y - Scale, X, Y);
  841.   DrawLineClipped(X + Scale, Y - Scale, X, Y);
  842.   DrawLineClipped(X, Y, X, Y + Scale);
  843. end; { DrawWye }
  844.  
  845. procedure DrawDiamond(X, Y, Scale : integer);
  846. begin
  847.   DrawLineClipped(X - Scale, Y, X, Y - Scale - 1);
  848.   DrawLineClipped(X, Y - Scale + 1, X + Scale, Y + 1);
  849.   DrawLineClipped(X + Scale, Y + 1, X, Y + Scale);
  850.   DrawLineClipped(X, Y + Scale, X - Scale, Y);
  851. end; { DrawDiamond }
  852.  
  853. procedure DrawCircleDirect(Xr, Yr, R : integer; DirectModeLoc : boolean);
  854. const
  855.   N = 14;
  856. type
  857.   Circ = array[1..N] of integer;
  858. const
  859.   X : Circ = (0,121,239,355,465,568,663,749,823,885,935,971,993,1000);
  860. var
  861.   Xk1, Xk2, Yk1, Yk2, Xp1, Yp1, Xp2, Yp2 : integer;
  862.   Xfact, Yfact : real;
  863.   I : integer;
  864.  
  865. procedure DrawLinW(X1, Y1, X2, Y2 : integer);
  866. var
  867.   DrawIt : boolean;
  868. begin
  869.   DrawIt := DirectModeLoc;
  870.   if not DrawIt then
  871.     DrawIt := Clip(X1, Y1, X2, Y2);
  872.   if DrawIt then
  873.     DrawLine(X1, Y1, X2, Y2);
  874. end; { DrawLinW }
  875.  
  876. begin { DrawCircleDirect }
  877.   Xfact := abs(R * 0.001);
  878.   Yfact := Xfact * AspectGlb;
  879.   if Xfact > 0.0 then
  880.     begin
  881.       Xk1 := trunc(X[1] * Xfact + 0.5);
  882.       Yk1 := trunc(X[N] * Yfact + 0.5);
  883.       for I := 2 to N do
  884.       begin
  885.         Xk2 := trunc(X[I] * Xfact + 0.5);
  886.         Yk2 := trunc(X[N - I + 1] * Yfact + 0.5);
  887.         Xp1 := Xr - Xk1;
  888.         Yp1 := Yr + Yk1;
  889.         Xp2 := Xr - Xk2;
  890.         Yp2 := Yr + Yk2;
  891.         DrawLinW(Xp1, Yp1, Xp2, Yp2);
  892.         Xp1 := Xr + Xk1;
  893.         Xp2 := Xr + Xk2;
  894.         DrawLinW(Xp1, Yp1, Xp2, Yp2);
  895.         Yp1 := Yr - Yk1;
  896.         Yp2 := Yr - Yk2;
  897.         DrawLinW(Xp1, Yp1 + 1, Xp2, Yp2 + 1);
  898.         Xp1 := Xr - Xk1;
  899.         Xp2 := Xr - Xk2;
  900.         DrawLinW(Xp1, Yp1 + 1, Xp2, Yp2 + 1);
  901.         Xk1 := Xk2;
  902.         Yk1 := Yk2;
  903.       end;
  904.     end
  905.   else
  906.     DP(Xr, Yr);
  907. end; { DrawCircleDirect }
  908.  
  909. procedure DrawCircle(X_R, Y_R, Xradius : real);
  910. var
  911.   DirectModeLoc : boolean;
  912. begin
  913.   DirectModeLoc := DirectModeGlb;
  914.   DirectModeGlb := true;
  915.   if DirectModeLoc then
  916.     DrawCircleDirect(trunc(X_R), trunc(Y_R), trunc(Xradius), true)
  917.   else
  918.     DrawCircleDirect(WindowX(X_R), WindowY(Y_R), trunc(Xradius * 100.0), false);
  919.   DirectModeGlb := DirectModeLoc;
  920. end; { DrawCircle }
  921.  
  922. procedure DrawCross(X1, Y1, Scale : integer);
  923. begin
  924.   DrawLineClipped(X1 - Scale, Y1, X1 + Scale + 2, Y1);
  925.   DrawLineClipped(X1, Y1 - Scale, X1, Y1 + Scale + 1);
  926. end; { DrawCross }
  927.  
  928. procedure DrawStar(X, Y, Scale : integer);
  929. begin
  930.   DrawLineClipped(X - Scale, Y + Scale, X + Scale + 1, Y - Scale - 1);
  931.   DrawLineClipped(X - Scale, Y - Scale, X + Scale + 1, Y + Scale + 1);
  932.   DrawLineClipped(X - Scale - 2, Y, X + Scale + 4, Y);
  933. end; { DrawStar }
  934.  
  935. procedure DrawSquareC(X1, Y1, X2, Y2 : integer; Fill : boolean);
  936. var
  937.   I : integer;
  938.  
  939. procedure DSC(X1, X2, Y : integer);
  940. begin
  941.   if Clip(X1, Y, X2, Y) then
  942.     if LineStyleGlb = 0 then
  943.       DrawStraight(X1, X2, Y)
  944.     else
  945.       DrawLine(X1, Y, X2, Y);
  946. end; { DSC }
  947.  
  948. begin { DrawSquareC }
  949.   if not Fill then
  950.     begin
  951.       DSC(X1, X2, Y1);
  952.       DrawLineClipped(X2, Y1, X2, Y2);
  953.       DSC(X1, X2, Y2);
  954.       DrawLineClipped(X1, Y2, X1, Y1);
  955.     end
  956.   else
  957.     for I := Y2 to Y1 do
  958.       DSC(X1, X2, I);
  959. end; { DrawSquareC }
  960.  
  961. procedure DrawSquare(X1, Y1, X2, Y2 : real; Fill : boolean);
  962. var
  963.   I, X1Loc, Y1Loc, X2Loc, Y2Loc : integer;
  964.   DirectModeLoc : boolean;
  965.  
  966. procedure DS(X1, X2, Y : integer);
  967. begin
  968.   if LineStyleGlb = 0 then
  969.     DrawStraight(X1, X2, Y)
  970.   else
  971.     DrawLine(X1, Y, X2, Y);
  972. end; { DS }
  973.  
  974. procedure DSC(X1, X2, Y : integer);
  975. begin
  976.   if Clip(X1, Y, X2, Y) then
  977.     DS(X1, X2, Y);
  978. end; { DSC }
  979.  
  980. procedure DrawSqr(X1, Y1, X2, Y2 : integer; Fill : boolean);
  981. var
  982.   I : integer;
  983. begin
  984.   if not Fill then
  985.     begin
  986.       DS(X1, X2, Y1);
  987.       DrawLine(X2, Y1, X2, Y2);
  988.       DS(X1, X2, Y2);
  989.       DrawLine(X1, Y2, X1, Y1);
  990.     end
  991.   else
  992.     for I := Y1 to Y2 do
  993.       DS(X1, X2, I);
  994. end; { DrawSqr }
  995.  
  996. begin { DrawSquare }
  997.   if DirectModeGlb then
  998.     DrawSqr(trunc(X1), trunc(Y1), trunc(X2), trunc(Y2), Fill)
  999.   else
  1000.     begin
  1001.       DirectModeLoc := DirectModeGlb;
  1002.       DirectModeGlb := true;
  1003.       X1Loc := WindowX(X1);
  1004.       Y1Loc := WindowY(Y1);
  1005.       X2Loc := WindowX(X2);
  1006.       Y2Loc := WindowY(Y2);
  1007.       if not Fill then
  1008.         begin
  1009.           DSC(X1Loc, X2Loc, Y1Loc);
  1010.           DrawLineClipped(X2Loc, Y1Loc, X2Loc, Y2Loc);
  1011.           DSC(X1Loc, X2Loc, Y2Loc);
  1012.           DrawLineClipped(X1Loc, Y2Loc, X1Loc, Y1Loc);
  1013.         end
  1014.       else
  1015.         for I := Y1Loc to Y2Loc do
  1016.           DSC(X1Loc, X2Loc, I);
  1017.       DirectModeGlb := DirectModeLoc;
  1018.     end;
  1019. end; { DrawSquare }
  1020.  
  1021. procedure DrawAscii(var X, Y : integer; Size, Ch : byte);
  1022. var
  1023.   X1Ref, X2Ref, Xpos, Ypos, Xstart, Ystart, Xend, Yend, Xx, Yy : integer;
  1024.   CharByte : byte;
  1025. begin
  1026.   X1Ref := X1RefGlb shl 3;
  1027.   X2Ref := X2RefGlb shl 3 + 7;
  1028.   for Ypos := 0 to 5 do
  1029.   begin
  1030.     CharByte := (CharSet[Ch, (7 - Ypos) shr 1] shr ((Ypos and 1) shl 2)) and $0F;
  1031.     for Xpos := 0 to 3 do
  1032.       if (CharByte shr (3 - Xpos)) and 1 <> 0 then
  1033.       begin
  1034.         Xstart := X + Xpos * Size;
  1035.         Xend := Xstart + Size - 1;
  1036.         Ystart := Y + 1 + (Ypos - 2) * Size;
  1037.         Yend := Ystart + Size - 1;
  1038.         if ClippingGlb then
  1039.         begin
  1040.           if Xstart < X1Ref then
  1041.             Xstart := X1Ref;
  1042.           if Xend > X2Ref then
  1043.             Xend := X2Ref;
  1044.           if Ystart < Y1RefGlb then
  1045.             Ystart := Y1RefGlb;
  1046.           if Yend > Y2RefGlb then
  1047.             Yend := Y2RefGlb;
  1048.         end;
  1049.         for Yy := Ystart to Yend do
  1050.           for Xx := Xstart to Xend do
  1051.             DP(Xx, Yy);
  1052.       end;
  1053.   end;
  1054.   X := X + Size * 6;
  1055. end; { DrawAscii }
  1056.  
  1057. procedure DrawText(X, Y, Scale : integer; Txt : WrkString);
  1058. var
  1059.   LineStyleLoc, Code, AsciiValue, StringLen,
  1060.   I, SymbolScale, SymbolCode : integer;
  1061.   DirectModeLoc : boolean;
  1062. begin
  1063.   DirectModeLoc := DirectModeGlb;
  1064.   DirectModeGlb := true;
  1065.   LineStyleLoc := LinestyleGlb;
  1066.   SetLineStyle(0);
  1067.   StringLen := Length(Txt);
  1068.   I := 1;
  1069.   while I <= StringLen do
  1070.   begin
  1071.     AsciiValue := Ord(Txt[I]);
  1072.     if AsciiValue = 27 then
  1073.       begin
  1074.         SymbolScale := Scale;
  1075.         I := I + 1;
  1076.         if I <= StringLen then
  1077.         begin
  1078.           Val(Txt[I], SymbolCode, Code);
  1079.           if (I + 2 <= StringLen) and (Ord(Txt[I + 1]) = 64) then
  1080.           begin
  1081.             Val(Txt[I + 2], SymbolScale, Code);
  1082.             I := I + 2;
  1083.           end;
  1084.           case SymbolCode of
  1085.             1   : DrawCross(X + SymbolScale, Y + Scale, SymbolScale);
  1086.             2   : DrawCrossDiag(X + SymbolScale, Y + Scale, SymbolScale);
  1087.             3,4 : DrawSquareC(X, Y + (SymbolScale shl 1) - 1,
  1088.                               X + (SymbolScale shl 1), Y - 1, (SymbolCode = 4));
  1089.             5   : begin
  1090.                     DrawDiamond(X + trunc(1.5 * SymbolScale),
  1091.                                 Y + SymbolScale - 1, SymbolScale + 1);
  1092.                     X := X + SymbolScale;
  1093.                   end;
  1094.             6   : DrawWye(X + SymbolScale, Y + SymbolScale - 1, SymbolScale);
  1095.             7   : begin
  1096.                     DrawStar(X + SymbolScale shl 1, Y + SymbolScale - 1, SymbolScale);
  1097.                     X := X + SymbolScale shl 1;
  1098.                   end;
  1099.             8   : DrawCircleDirect(X + SymbolScale, Y + (SymbolScale shr 1),
  1100.                                    SymbolScale + 1, false);
  1101.           end;
  1102.           X := X + 3 * SymbolScale;
  1103.           SymbolScale := Scale;
  1104.         end;
  1105.       end
  1106.     else
  1107.       DrawAscii(X, Y, Scale, AsciiValue);
  1108.     I := I + 1;
  1109.   end;
  1110.   DirectModeGlb := DirectModeLoc;
  1111.   SetLineStyle(LineStyleLoc);
  1112. end; { DrawText }
  1113.  
  1114. procedure DrawTextW(X, Y : real; Scale : integer; Txt : WrkString);
  1115. begin
  1116.   if DirectModeGlb then
  1117.     DrawText(trunc(X), trunc(Y), Scale, Txt)
  1118.   else
  1119.     DrawText(WindowX(X), WindowY(Y), Scale, Txt);
  1120. end; { DrawTextW }
  1121.  
  1122. procedure DrawBorder;
  1123. var
  1124.   ClipLoc, DirectModeLoc : boolean;
  1125.   Xl1, Xl2 : integer;
  1126.  
  1127. procedure DrawHeaderBackground(Y1, Y2 : integer);
  1128. var
  1129.   I : integer;
  1130. begin
  1131.   for I := Y1 to Y2 do
  1132.     DrawStraight(Xl1, Xl2, I);
  1133. end; { DrawHeaderBackground }
  1134.  
  1135. procedure DrawHeader;
  1136. var
  1137.   Y1Hdr, Y2Hdr, Yl1, Yl2 : integer;
  1138. begin
  1139.   with Window[WindowNdxGlb] do
  1140.   begin
  1141.     if Drawn then
  1142.       if Top then
  1143.         begin
  1144.           ReDefineWindow(WindowNdxGlb, X1RefGlb, Y1RefGlb - HeaderSizeGlb,
  1145.                          X2RefGlb, Y2RefGlb);
  1146.           SelectWindow(WindowNdxGlb);
  1147.         end
  1148.       else
  1149.         begin
  1150.           ReDefineWindow(WindowNdxGlb, X1RefGlb, Y1RefGlb, X2RefGlb,
  1151.                          Y2RefGlb + HeaderSizeGlb);
  1152.           SelectWindow(WindowNdxGlb);
  1153.         end;
  1154.     if TopGlb then
  1155.       begin
  1156.         Yl1 := Y1RefGlb + HeaderSizeGlb;
  1157.         Yl2 := Y2RefGlb;
  1158.         Y1Hdr := Y1RefGlb;
  1159.         Y2Hdr := Y1RefGlb + HeaderSizeGlb - 1;
  1160.       end
  1161.     else
  1162.       begin
  1163.         Yl1 := Y1RefGlb;
  1164.         Yl2 := Y2RefGlb - HeaderSizeGlb;
  1165.         Y1Hdr := Y2RefGlb - HeaderSizeGlb + 1;
  1166.         Y2Hdr := Y2RefGlb;
  1167.       end;
  1168.     Top := TopGlb;
  1169.     ReDefineWindow(WindowNdxGlb, X1RefGlb, Yl1, X2RefGlb, Yl2);
  1170.     SelectWindow(WindowNdxGlb);
  1171.     DrawHeaderBackground(Y1Hdr, Y2Hdr);
  1172.     ColorGlb := 255 - ColorGlb;
  1173.     DrawText(Xl1 + 2 + (Xl2 - Xl1 - Length(Header) * 6) shr 1,
  1174.              Y1Hdr + 3, 1, Header);
  1175.     DrawSquare(Xl1, Y1Hdr, Xl2, Y2Hdr, false);
  1176.     ColorGlb := 255 - ColorGlb;
  1177.     DrawSquare(Xl1, Y1RefGlb, Xl2, Y2RefGlb, false);
  1178.     Drawn := true;
  1179.   end;
  1180. end; { DrawHeader }
  1181.  
  1182. begin { DrawBorder }
  1183.   DirectModeLoc := DirectModeGlb;
  1184.   DirectModeGlb := true;
  1185.   ClipLoc := ClippingGlb;
  1186.   ClippingGlb := false;
  1187.   Xl1 := X1RefGlb shl 3;
  1188.   Xl2 := X2RefGlb shl 3 + 7;
  1189.   with Window[WindowNdxGlb] do
  1190.     if ((HeaderGlb) and (Length(Header) > 0)) and (Y2 - Y1 > HeaderSizeGlb) and
  1191.        ((Length(Header) * 6) < abs(Xl2 - Xl1) - 4) then
  1192.       DrawHeader
  1193.     else
  1194.       begin
  1195.         Drawn := false;
  1196.         DrawSquare(Xl1, Y1RefGlb, Xl2, Y2RefGlb, false);
  1197.       end;
  1198.     DirectModeGlb := DirectModeLoc;
  1199.     ClippingGlb := ClipLoc;
  1200. end; { DrawBorder }
  1201.  
  1202. procedure HardCopy(Inverse : boolean; Mode : byte); { EPSON }
  1203. var
  1204.   I, J, Top : integer;
  1205.   ColorLoc, PrintByte : byte;
  1206.  
  1207. procedure DoLine(Top:integer);
  1208.  
  1209. function ConstructByte(J, I : integer) : byte;
  1210. const
  1211.   Bits : array[0..7] of byte = (128,64,32,16,8,4,2,1);
  1212. var
  1213.   CByte, K : byte;
  1214. begin
  1215.   I := I shl 3;
  1216.   CByte := 0;
  1217.   for K := 0 to Top do
  1218.     if PD(J, I + K) then
  1219.       CByte := CByte or Bits[K];
  1220.   ConstructByte := CByte;
  1221. end; { ConstructByte }
  1222.  
  1223. begin { DoLine }
  1224.   if Mode = 1 then
  1225.     Write(Lst, ^['L')
  1226.   else
  1227.     Write(Lst, ^['*', Chr(Mode));
  1228.   Write(Lst, Chr(Lo(XScreenMaxGlb + 1)), Chr(Hi(XScreenMaxGlb + 1)));
  1229.   for J := 0 to XScreenMaxGlb do
  1230.   begin
  1231.     PrintByte := ConstructByte(J, I);
  1232.     if Inverse then
  1233.       PrintByte := not PrintByte;
  1234.     Write(Lst, Chr(PrintByte));
  1235.   end;
  1236.   if Mode <> 4 then
  1237.     WriteLn(Lst);
  1238. end; { DoLine }
  1239.  
  1240. begin { HardCopy }
  1241.   Top := 7;
  1242.   ColorLoc := ColorGlb;
  1243.   ColorGlb := 255;
  1244.   Mode := Mode and 7;
  1245.   if (Mode = 5) or (Mode = 0) then
  1246.     Mode := 4;
  1247.   Write(Lst, ^['3'#24);
  1248.   for I := 0 to ((YMaxGlb + 1) shr 3) - 1 do
  1249.     DoLine(7);
  1250.   I := ((YMaxGlb + 1) shr 3);
  1251.   if (YMaxGlb + 1) and 7 <> 0 then
  1252.     DoLine((YMaxGlb + 1) and 7);
  1253.   WriteLn(Lst, ^['2');
  1254.   ColorGlb := ColorLoc;
  1255. end; { HardCopy }
  1256.