Subversion Repositories Kolibri OS

Rev

Rev 9902 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. (*
  2.     Copyright 2021-2023 Anton Krotov
  3.  
  4.     This file is part of CEdit.
  5.  
  6.     CEdit 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.     CEdit 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 CEdit. If not, see <http://www.gnu.org/licenses/>.
  18. *)
  19.  
  20. MODULE Graph;
  21.  
  22. IMPORT SYSTEM, KOSAPI, Lines, Languages, E := Encodings;
  23.  
  24. CONST
  25.  
  26.         modeCOPY = 0;
  27.         modeNOT  = 1;
  28.         modeXOR  = 2;
  29.  
  30.         triUp* = FALSE;
  31.         triDown* = TRUE;
  32.         triLeft* = FALSE;
  33.         triRight* = TRUE;
  34.  
  35. TYPE
  36.  
  37.         tFont* = POINTER TO RECORD
  38.                 handle*: INTEGER;
  39.                 height*: INTEGER;
  40.                 width*:  INTEGER;
  41.                 size:    INTEGER;
  42.                 flags:   INTEGER;
  43.                 name*:   ARRAY 256 OF WCHAR
  44.         END;
  45.  
  46.         tCanvas* = POINTER TO RECORD
  47.                 bitmap: INTEGER;
  48.                 width*, height*, sizeY: INTEGER;
  49.                 color, backColor, textColor: INTEGER;
  50.                 font*: tFont;
  51.                 mode: INTEGER
  52.         END;
  53.  
  54. VAR
  55.  
  56.         fonts*: ARRAY 3 OF tFont;
  57.  
  58.  
  59. PROCEDURE getRGB* (color: INTEGER; VAR r, g, b: BYTE);
  60. BEGIN
  61.         b := color MOD 256;
  62.         g := color DIV 256 MOD 256;
  63.         r := color DIV 65536 MOD 256
  64. END getRGB;
  65.  
  66.  
  67. PROCEDURE DrawCanvas* (canvas: tCanvas; x, y: INTEGER);
  68. BEGIN
  69.         KOSAPI.sysfunc7(65, canvas.bitmap, canvas.width*65536 + canvas.height, x*65536 + y, 32, 0, 0)
  70. END DrawCanvas;
  71.  
  72.  
  73. PROCEDURE SetColor* (canvas: tCanvas; color: INTEGER);
  74. BEGIN
  75.         canvas.color := color
  76. END SetColor;
  77.  
  78.  
  79. PROCEDURE SetTextColor* (canvas: tCanvas; color: INTEGER);
  80. BEGIN
  81.         canvas.textColor := color
  82. END SetTextColor;
  83.  
  84.  
  85. PROCEDURE SetBkColor* (canvas: tCanvas; color: INTEGER);
  86. BEGIN
  87.         canvas.backColor := color
  88. END SetBkColor;
  89.  
  90.  
  91. PROCEDURE CreateFont (size: INTEGER; name: ARRAY OF WCHAR; attr: SET): tFont;
  92. VAR
  93.         font: tFont;
  94. BEGIN
  95.         ASSERT(size IN {0, 1, 2});
  96.         NEW(font);
  97.         font.size := size;
  98.         IF size = 0 THEN
  99.                 font.width := 6;
  100.                 font.height := 9;
  101.                 font.flags := 08000000H
  102.         ELSE
  103.                 font.width := size*8;
  104.                 font.height := size*16;
  105.                 IF size = 1 THEN
  106.                         font.flags := 28000000H
  107.                 ELSIF size = 2 THEN
  108.                         font.flags := 29000000H
  109.                 END
  110.         END;
  111.         font.name := name
  112.         RETURN font
  113. END CreateFont;
  114.  
  115.  
  116. PROCEDURE SetFont* (canvas: tCanvas; font: tFont);
  117. BEGIN
  118.         canvas.font := font
  119. END SetFont;
  120.  
  121.  
  122. PROCEDURE HLine* (canvas: tCanvas; y, x1, x2: INTEGER);
  123. VAR
  124.         X1, X2, i: INTEGER;
  125.         ptr: INTEGER;
  126.         color: INTEGER;
  127. BEGIN
  128.         X1 := MAX(MIN(x1, x2), 0);
  129.         X2 := MIN(MAX(x1, x2), canvas.width - 1);
  130.         IF (0 <= y) & (y < canvas.height) THEN
  131.                 color := canvas.color;
  132.                 ptr := canvas.bitmap + 4*(y*canvas.width + X1);
  133.                 FOR i := X1 TO X2 DO
  134.                         SYSTEM.PUT32(ptr, color);
  135.                         INC(ptr, 4)
  136.                 END
  137.         END
  138. END HLine;
  139.  
  140.  
  141. PROCEDURE VLine* (canvas: tCanvas; x, y1, y2: INTEGER);
  142. VAR
  143.         Y1, Y2, i: INTEGER;
  144.         ptr: INTEGER;
  145.         color: INTEGER;
  146. BEGIN
  147.         Y1 := MAX(MIN(y1, y2), 0);
  148.         Y2 := MIN(MAX(y1, y2), canvas.height - 1);
  149.         IF (0 <= x) & (x < canvas.width) THEN
  150.                 color := canvas.color;
  151.                 ptr := canvas.bitmap + 4*(Y1*canvas.width + x);
  152.                 FOR i := Y1 TO Y2 DO
  153.                         IF canvas.mode = modeNOT THEN
  154.                                 SYSTEM.GET32(ptr, color);
  155.                                 color := ORD(-BITS(color)*{0..23})
  156.                         ELSIF canvas.mode = modeXOR THEN
  157.                                 SYSTEM.GET32(ptr, color);
  158.                                 color := ORD((BITS(color)/BITS(canvas.color))*{0..23})
  159.                         END;
  160.                         SYSTEM.PUT32(ptr, color);
  161.                         INC(ptr, canvas.width*4)
  162.                 END
  163.         END
  164. END VLine;
  165.  
  166.  
  167. PROCEDURE notVLine* (canvas: tCanvas; x, y1, y2: INTEGER);
  168. BEGIN
  169.         canvas.mode := modeNOT;
  170.         VLine(canvas, x, y1, y2);
  171.         canvas.mode := modeCOPY
  172. END notVLine;
  173.  
  174.  
  175. PROCEDURE xorVLine* (canvas: tCanvas; x, y1, y2: INTEGER);
  176. BEGIN
  177.         canvas.mode := modeXOR;
  178.         SetColor(canvas, 0FF0000H);
  179.         VLine(canvas, x, y1, y2);
  180.         canvas.mode := modeCOPY
  181. END xorVLine;
  182.  
  183.  
  184. PROCEDURE DLine* (canvas: tCanvas; x1, x2, y: INTEGER; k: INTEGER);
  185. VAR
  186.         ptr: INTEGER;
  187.         color: INTEGER;
  188.         d: INTEGER;
  189. BEGIN
  190.         ASSERT(ABS(k) = 1);
  191.         color := canvas.color;
  192.         ptr := canvas.bitmap + 4*(y*canvas.width + x1);
  193.         d := 4*(1 - canvas.width*k);
  194.         WHILE x1 <= x2 DO
  195.                 SYSTEM.PUT32(ptr, color);
  196.                 INC(ptr, d);
  197.                 INC(x1)
  198.         END
  199. END DLine;
  200.  
  201.  
  202. PROCEDURE Triangle* (canvas: tCanvas; x1, y1, x2, y2: INTEGER; orientation: BOOLEAN);
  203. VAR
  204.         i, a, b, d: INTEGER;
  205.         line: PROCEDURE (canvas: tCanvas; c, c1, c2: INTEGER);
  206. BEGIN
  207.         line := NIL;
  208.         d := ORD(orientation)*2 - 1;
  209.         IF y1 = y2 THEN
  210.                 i := y1;
  211.                 a := MIN(x1, x2);
  212.                 b := MAX(x1, x2);
  213.                 line := HLine
  214.         ELSIF x1 = x2 THEN
  215.                 i := x1;
  216.                 a := MIN(y1, y2);
  217.                 b := MAX(y1, y2);
  218.                 line := VLine
  219.         END;
  220.         IF line # NIL THEN
  221.                 WHILE a <= b DO
  222.                         line(canvas, i, a, b);
  223.                         INC(i, d);
  224.                         INC(a);
  225.                         DEC(b)
  226.                 END
  227.         END
  228. END Triangle;
  229.  
  230.  
  231. PROCEDURE FillRect* (canvas: tCanvas; left, top, right, bottom: INTEGER);
  232. VAR
  233.         y: INTEGER;
  234. BEGIN
  235.         FOR y := top TO bottom DO
  236.                 HLine(canvas, y, left, right)
  237.         END
  238. END FillRect;
  239.  
  240.  
  241. PROCEDURE Rect* (canvas: tCanvas; left, top, right, bottom: INTEGER);
  242. BEGIN
  243.         HLine(canvas, top, left, right);
  244.         HLine(canvas, bottom, left, right);
  245.         VLine(canvas, left, top, bottom);
  246.         VLine(canvas, right, top, bottom)
  247. END Rect;
  248.  
  249.  
  250. PROCEDURE clear* (canvas: tCanvas);
  251. VAR
  252.         ptr, ptr2, w, i: INTEGER;
  253. BEGIN
  254.         HLine(canvas, 0, 0, canvas.width - 1);
  255.         w := canvas.width*4;
  256.         ptr := canvas.bitmap;
  257.         ptr2 := ptr;
  258.         i := canvas.sizeY - 1;
  259.         WHILE i > 0 DO
  260.                 INC(ptr2, w);
  261.                 SYSTEM.MOVE(ptr, ptr2, w);
  262.                 DEC(i)
  263.         END
  264. END clear;
  265.  
  266.  
  267. PROCEDURE TextOut* (canvas: tCanvas; x, y: INTEGER; text: INTEGER; n: INTEGER; delimColor: INTEGER);
  268. CONST
  269.         WCHAR_SIZE = 2;
  270. VAR
  271.         color, i: INTEGER;
  272.         font: tFont;
  273.         c: WCHAR;
  274. BEGIN
  275.         font := canvas.font;
  276.         IF (0 <= y) & (y <= canvas.sizeY - font.height - 1) THEN
  277.                 IF x < 0 THEN
  278.                         i := -(x DIV font.width);
  279.                         INC(x, i*font.width);
  280.                         DEC(n, i)
  281.                 ELSE
  282.                         i := 0
  283.                 END;
  284.                 IF n > 0 THEN
  285.                         n := MAX(MIN(n, (canvas.width - x) DIV font.width), 0);
  286.                         color := canvas.color;
  287.                         canvas.color := canvas.backColor;
  288.                         FillRect(canvas, x, y, x + n*font.width - 1, y + font.height);
  289.                         canvas.color := color;
  290.                         WHILE n > 0 DO
  291.                                 SYSTEM.GET(text + i*WCHAR_SIZE, c);
  292.                                 IF ~Lines.isSpace(c) THEN
  293.                                         IF Languages.isDelim(c) THEN
  294.                                                 color := delimColor
  295.                                         ELSE
  296.                                                 color := canvas.textColor
  297.                                         END;
  298.                                         IF c = Lines.NUL THEN
  299.                                                 c := 0X
  300.                                         END;
  301.                                         IF font = fonts[0] THEN
  302.                                                 c := WCHR(E.UNI[ORD(c), E.CP866])
  303.                                         END;
  304.                                         KOSAPI.sysfunc6(4, x*65536 + y, font.flags + color, SYSTEM.ADR(c), 1, canvas.bitmap - 8)
  305.                                 END;
  306.                                 INC(x, font.width);
  307.                                 INC(i);
  308.                                 DEC(n)
  309.                         END
  310.                 END
  311.         END
  312. END TextOut;
  313.  
  314.  
  315. PROCEDURE TextOut2* (canvas: tCanvas; x, y: INTEGER; text: ARRAY OF WCHAR; n: INTEGER);
  316. BEGIN
  317.         TextOut(canvas, x, y, SYSTEM.ADR(text[0]), n, canvas.textColor)
  318. END TextOut2;
  319.  
  320.  
  321. PROCEDURE CreateCanvas* (width, height: INTEGER): tCanvas;
  322. VAR
  323.         canvas: tCanvas;
  324. BEGIN
  325.         NEW(canvas);
  326.         canvas.bitmap := KOSAPI.malloc(width*height*4 + 8);
  327.         ASSERT(canvas.bitmap # 0);
  328.         SYSTEM.PUT32(canvas.bitmap, width);
  329.         SYSTEM.PUT32(canvas.bitmap + 4, height);
  330.         INC(canvas.bitmap, 8);
  331.         canvas.width := width;
  332.         canvas.height := height;
  333.         canvas.sizeY := height;
  334.         canvas.mode := modeCOPY
  335.         RETURN canvas
  336. END CreateCanvas;
  337.  
  338.  
  339. PROCEDURE destroy* (VAR canvas: tCanvas);
  340. BEGIN
  341.         IF canvas # NIL THEN
  342.                 canvas.bitmap := KOSAPI.free(canvas.bitmap - 8);
  343.                 DISPOSE(canvas)
  344.         END
  345. END destroy;
  346.  
  347.  
  348. BEGIN
  349.         fonts[0] := CreateFont(0, "", {});
  350.         fonts[1] := CreateFont(1, "", {});
  351.         fonts[2] := CreateFont(2, "", {});
  352. END Graph.