Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. (*
  2.     Copyright 2016-2020, 2022 Anton Krotov
  3.  
  4.     This file is part of fb2read.
  5.  
  6.     fb2read is free software: you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation, either version 3 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     fb2read is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with fb2read. If not, see <http://www.gnu.org/licenses/>.
  18. *)
  19.  
  20. MODULE Graph;
  21.  
  22. IMPORT K := KOSAPI, sys := SYSTEM, SU := SysUtils, LibImg;
  23.  
  24.  
  25. TYPE
  26.  
  27.   TBuffer = RECORD Width*, Height*, adr*, Color: INTEGER END;
  28.   PBuffer* = POINTER TO TBuffer;
  29.  
  30.  
  31. VAR
  32.  
  33.   Buffer*, Buffer2, Buffer3*: PBuffer;
  34.  
  35.  
  36. PROCEDURE [stdcall-, "rasterworks.obj", ""] drawText (canvas, x, y, string, charQuantity, fontColor, params: INTEGER): INTEGER; END;
  37.  
  38. PROCEDURE Destroy*(VAR Buffer: PBuffer);
  39. BEGIN
  40.   IF Buffer # NIL THEN
  41.     IF Buffer.adr # 0 THEN
  42.       DEC(Buffer.adr, 8);
  43.       Buffer.adr := K.free(Buffer.adr)
  44.     END;
  45.     DISPOSE(Buffer)
  46.   END
  47. END Destroy;
  48.  
  49.  
  50. PROCEDURE Create*(Width, Height: INTEGER): PBuffer;
  51. VAR res: PBuffer;
  52. BEGIN
  53.   NEW(res);
  54.   res.adr := K.malloc(Width * Height * 4 + 8);
  55.   sys.PUT(res.adr, Width);
  56.   sys.PUT(res.adr + 4, Height);
  57.   res.Width := Width;
  58.   res.Height := Height;
  59.   INC(res.adr, 8);
  60.   RETURN res
  61. END Create;
  62.  
  63.  
  64. PROCEDURE getRGB* (color: INTEGER; VAR r, g, b: BYTE);
  65. BEGIN
  66.         b := color MOD 256;
  67.         g := color DIV 256 MOD 256;
  68.         r := color DIV 65536 MOD 256
  69. END getRGB;
  70.  
  71.  
  72. PROCEDURE Fill*(Buffer: PBuffer; Color: INTEGER);
  73. VAR p, n, i: INTEGER;
  74. BEGIN
  75.   p := Buffer.adr;
  76.   n := Buffer.Width * Buffer.Height;
  77.   FOR i := 1 TO n DO
  78.     sys.PUT(p, Color);
  79.     INC(p, 4)
  80.   END
  81. END Fill;
  82.  
  83.  
  84. PROCEDURE HLine*(X1, X2, Y: INTEGER);
  85. VAR
  86.     p1, p2, i, color: INTEGER;
  87.  
  88. BEGIN
  89.     IF X1 <= X2 THEN
  90.         SU.MinMax(Y, 0, Buffer.Height - 1);
  91.         color := Buffer.Color;
  92.         p1 := Buffer.adr + 4 * (Y * Buffer.Width + X1);
  93.         p2 := p1 + (X2 - X1) * 4;
  94.         FOR i := p1 TO p2 BY 4 DO
  95.             sys.PUT(i, color)
  96.         END
  97.     END
  98. END HLine;
  99.  
  100.  
  101. PROCEDURE HLineNotXOR (X1, X2, Y, color: INTEGER);
  102. VAR
  103.     p1, p2, i: INTEGER;
  104.     pix: SET;
  105.  
  106. BEGIN
  107.     IF X1 <= X2 THEN
  108.         SU.MinMax(Y, 0, Buffer.Height - 1);
  109.         p1 := Buffer.adr + 4 * (Y * Buffer.Width + X1);
  110.         p2 := p1 + (X2 - X1) * 4;
  111.         FOR i := p1 TO p2 BY 4 DO
  112.             sys.GET(i, pix);
  113.             pix := (-pix) / BITS(color) - {24..31};
  114.             sys.PUT(i, pix)
  115.         END
  116.     END
  117. END HLineNotXOR;
  118.  
  119.  
  120. PROCEDURE VLine*(X, Y1, Y2: INTEGER);
  121. VAR p1, p2, line_size, color: INTEGER;
  122. BEGIN
  123.   ASSERT(Y1 <= Y2);
  124.   SU.MinMax(Y1, 0, Buffer.Height - 1);
  125.   SU.MinMax(Y2, 0, Buffer.Height - 1);
  126.   color := Buffer.Color;
  127.   line_size := Buffer.Width * 4;
  128.   p1 := Buffer.adr + line_size * Y1 + 4 * X;
  129.   p2 := p1 + (Y2 - Y1) * line_size;
  130.   WHILE p1 <= p2 DO
  131.     sys.PUT(p1, color);
  132.     p1 := p1 + line_size
  133.   END
  134. END VLine;
  135.  
  136.  
  137. PROCEDURE Box(X1, Y1, X2, Y2: INTEGER);
  138. VAR y: INTEGER;
  139. BEGIN
  140.   FOR y := Y1 TO Y2 DO
  141.     HLine(X1, X2, y)
  142.   END
  143. END Box;
  144.  
  145.  
  146. PROCEDURE BoxNotXOR* (X1, Y1, X2, Y2, color: INTEGER);
  147. VAR y: INTEGER;
  148. BEGIN
  149.     FOR y := Y1 TO Y2 DO
  150.         HLineNotXOR(X1, X2, y, color)
  151.     END
  152. END BoxNotXOR;
  153.  
  154.  
  155. PROCEDURE SetColor*(color: INTEGER);
  156. BEGIN
  157.   Buffer.Color := color
  158. END SetColor;
  159.  
  160.  
  161. PROCEDURE GetColor*(): INTEGER;
  162.   RETURN Buffer.Color
  163. END GetColor;
  164.  
  165.  
  166. PROCEDURE TextOut*(X, Y: INTEGER; Text: INTEGER; length: INTEGER; size, params: INTEGER);
  167. BEGIN
  168.         drawText(Buffer.adr - 8, X, Y, Text, length, 0FF000000H + Buffer.Color, params)
  169. END TextOut;
  170.  
  171.  
  172. PROCEDURE Resize2*(Width, Height: INTEGER);
  173. BEGIN
  174.   Buffer2.Width := Width;
  175.   Buffer2.Height := Height;
  176. END Resize2;
  177.  
  178.  
  179. PROCEDURE Image* (X, Y, sizeX, sizeY, ptr, Ymin, Ymax: INTEGER);
  180. VAR
  181.         y: INTEGER;
  182. BEGIN
  183.         ASSERT(sizeX <= Buffer.Width);
  184.         FOR y := 0 TO sizeY - 1 DO
  185.                 IF (Ymin <= Y) & (Y < Ymax) THEN
  186.                         sys.MOVE(ptr + sizeX*4*y, Buffer.adr + (Buffer.Width*Y + X)*4, sizeX*4)
  187.                 END;
  188.                 INC(Y)
  189.         END
  190. END Image;
  191.  
  192.  
  193. PROCEDURE Image2(Buffer: PBuffer; X, Y, sizeX, sizeY, ptr: INTEGER);
  194. VAR x, y, pix, left: INTEGER;
  195. BEGIN
  196.   left := X;
  197.   FOR y := 0 TO sizeY - 1 DO
  198.       X := left;
  199.       FOR x := 0 TO sizeX - 1 DO
  200.         sys.GET32(ptr + (y*sizeX + x)*4, pix);
  201.         IF (X < Buffer.Width) & (Y < Buffer.Height) THEN
  202.           sys.PUT32(Buffer.adr + (Buffer.Width*Y + X)*4, pix)
  203.         END;
  204.         INC(X)
  205.       END;
  206.     INC(Y)
  207.   END
  208. END Image2;
  209.  
  210.  
  211. PROCEDURE BackImage*(sizeX, sizeY, ptr: INTEGER);
  212. VAR x, y: INTEGER;
  213. BEGIN
  214.   IF ptr # 0 THEN
  215.     y := 0;
  216.     WHILE y < Buffer3.Height DO
  217.       x := 0;
  218.       WHILE x < Buffer3.Width DO
  219.         Image2(Buffer3, x, y, sizeX, sizeY, ptr);
  220.         INC(x, sizeX)
  221.       END;
  222.       INC(y, sizeY)
  223.     END
  224.   END
  225. END BackImage;
  226.  
  227.  
  228. PROCEDURE Copy*(src, dst: PBuffer; y_src, lines, y_dst: INTEGER);
  229. BEGIN
  230.   sys.MOVE(src.adr + y_src * src.Width * 4, dst.adr + y_dst * dst.Width * 4, lines * dst.Width * 4)
  231. END Copy;
  232.  
  233.  
  234. PROCEDURE Clear*;
  235. VAR p, color: INTEGER;
  236. BEGIN
  237.   color := Buffer.Color;
  238.   FOR p := Buffer.adr TO Buffer.adr + Buffer.Width * Buffer.Height * 4 - 4 BY 4 DO
  239.     sys.PUT(p, color)
  240.   END
  241. END Clear;
  242.  
  243.  
  244. PROCEDURE Draw*(X, Y: INTEGER);
  245. BEGIN
  246.   K.sysfunc7(65, Buffer.adr, Buffer.Width * 65536 + Buffer.Height, X * 65536 + Y, 32, 0, 0)
  247. END Draw;
  248.  
  249.  
  250. PROCEDURE Rect*(X1, Y1, X2, Y2: INTEGER);
  251. BEGIN
  252.   VLine(X1, Y1, Y2);
  253.   VLine(X2, Y1, Y2);
  254.   HLine(X1, X2, Y1);
  255.   HLine(X1, X2, Y2)
  256. END Rect;
  257.  
  258.  
  259. PROCEDURE Progress*(value: REAL);
  260. VAR W4, W2, H2: INTEGER;
  261. BEGIN
  262.   W4 := Buffer2.Width DIV 4;
  263.   W2 := Buffer2.Width DIV 2;
  264.   H2 := Buffer2.Height DIV 2;
  265.   SetColor(0FFFFFFH);
  266.   Clear;
  267.   SetColor(0);
  268.   Rect(W4, H2 - 50, 3 * W4, H2 + 30);
  269.   TextOut(W2 - 10 * 8 DIV 2, H2 - 50 + 15, sys.SADR("Loading..."), 10, 1, 16 + 0 + LSL(3, 16) + LSL(128, 24));
  270.   SetColor(000000FFH);
  271.   Box(W4 + 10, H2, W4 + 10 + FLOOR( FLT(W2 - 20) * value ), H2 + 15);
  272. END Progress;
  273.  
  274.  
  275. PROCEDURE Resize3(Buffer: PBuffer; Width, Height: INTEGER);
  276. BEGIN
  277.   IF Buffer.adr # 0 THEN
  278.     DEC(Buffer.adr, 8)
  279.   END;
  280.   Buffer.adr := K.realloc(Buffer.adr, Width * Height * 4 + 8);
  281.   SU.MemError(Buffer.adr = 0);
  282.   sys.PUT(Buffer.adr, Width);
  283.   sys.PUT(Buffer.adr + 4, Height);
  284.   INC(Buffer.adr, 8);
  285.   Buffer.Width  := Width;
  286.   Buffer.Height := Height
  287. END Resize3;
  288.  
  289.  
  290. PROCEDURE Resize*(Width, Height: INTEGER);
  291. BEGIN
  292.   Resize3(Buffer,  Width, Height);
  293.   Resize3(Buffer3, Width, Height);
  294. END Resize;
  295.  
  296.  
  297. PROCEDURE Init;
  298. VAR Width, Height: INTEGER;
  299. BEGIN
  300.   NEW(Buffer);
  301.   NEW(Buffer2);
  302.   NEW(Buffer3);
  303.   SU.GetScreenSize(Width, Height);
  304.   Resize(Width, Height)
  305. END Init;
  306.  
  307.  
  308. BEGIN
  309.   Init
  310. END Graph.
  311.