Subversion Repositories Kolibri OS

Rev

Rev 9892 | Go to most recent revision | 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.