Subversion Repositories Kolibri OS

Rev

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

  1. (*
  2.     Copyright 2021, 2022 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*: 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.     IF (0 <= y1) & (y1 < canvas.height) & (0 <= y2) & (y2 < canvas.height) THEN
  170.         canvas.mode := modeNOT;
  171.         VLine(canvas, x, y1, y2);
  172.         canvas.mode := modeCOPY
  173.     END
  174. END notVLine;
  175.  
  176.  
  177. PROCEDURE xorVLine* (canvas: tCanvas; x, y1, y2: INTEGER);
  178. BEGIN
  179.     IF (0 <= y1) & (y1 < canvas.height) & (0 <= y2) & (y2 < canvas.height) THEN
  180.         canvas.mode := modeXOR;
  181.         SetColor(canvas, 0FF0000H);
  182.         VLine(canvas, x, y1, y2);
  183.         canvas.mode := modeCOPY
  184.     END
  185. END xorVLine;
  186.  
  187.  
  188. PROCEDURE DLine* (canvas: tCanvas; x1, x2, y: INTEGER; k: INTEGER);
  189. VAR
  190.     ptr: INTEGER;
  191.     color: INTEGER;
  192.     d: INTEGER;
  193. BEGIN
  194.         ASSERT(ABS(k) = 1);
  195.     color := canvas.color;
  196.     ptr := canvas.bitmap + 4*(y*canvas.width + x1);
  197.     d := 4*(1 - canvas.width*k);
  198.     WHILE x1 <= x2 DO
  199.         SYSTEM.PUT32(ptr, color);
  200.         INC(ptr, d);
  201.         INC(x1)
  202.     END
  203. END DLine;
  204.  
  205.  
  206. PROCEDURE Triangle* (canvas: tCanvas; x1, y1, x2, y2: INTEGER; orientation: BOOLEAN);
  207. VAR
  208.         i, a, b, d: INTEGER;
  209.         line: PROCEDURE (canvas: tCanvas; c, c1, c2: INTEGER);
  210. BEGIN
  211.         line := NIL;
  212.         d := ORD(orientation)*2 - 1;
  213.         IF y1 = y2 THEN
  214.                 i := y1;
  215.                 a := MIN(x1, x2);
  216.                 b := MAX(x1, x2);
  217.                 line := HLine
  218.         ELSIF x1 = x2 THEN
  219.                 i := x1;
  220.                 a := MIN(y1, y2);
  221.                 b := MAX(y1, y2);
  222.                 line := VLine
  223.         END;
  224.         IF line # NIL THEN
  225.                 WHILE a <= b DO
  226.                         line(canvas, i, a, b);
  227.                         INC(i, d);
  228.                         INC(a);
  229.                         DEC(b)
  230.                 END
  231.         END
  232. END Triangle;
  233.  
  234.  
  235. PROCEDURE FillRect* (canvas: tCanvas; left, top, right, bottom: INTEGER);
  236. VAR
  237.     y: INTEGER;
  238. BEGIN
  239.     FOR y := top TO bottom DO
  240.         HLine(canvas, y, left, right)
  241.     END
  242. END FillRect;
  243.  
  244.  
  245. PROCEDURE Rect* (canvas: tCanvas; left, top, right, bottom: INTEGER);
  246. BEGIN
  247.     HLine(canvas, top, left, right);
  248.     HLine(canvas, bottom, left, right);
  249.     VLine(canvas, left, top, bottom);
  250.     VLine(canvas, right, top, bottom)
  251. END Rect;
  252.  
  253.  
  254. PROCEDURE clear* (canvas: tCanvas);
  255. VAR
  256.     ptr, ptr2, w, i: INTEGER;
  257. BEGIN
  258.     HLine(canvas, 0, 0, canvas.width - 1);
  259.     w := canvas.width*4;
  260.     ptr := canvas.bitmap;
  261.     ptr2 := ptr;
  262.     i := canvas.height - 1;
  263.     WHILE i > 0 DO
  264.         INC(ptr2, w);
  265.         SYSTEM.MOVE(ptr, ptr2, w);
  266.         DEC(i)
  267.     END
  268. END clear;
  269.  
  270.  
  271. PROCEDURE TextOut* (canvas: tCanvas; x, y: INTEGER; text: INTEGER; n: INTEGER; delimColor: INTEGER);
  272. CONST
  273.     WCHAR_SIZE = 2;
  274. VAR
  275.     color, i, ch: INTEGER;
  276.     font: tFont;
  277.     c: WCHAR;
  278. BEGIN
  279.         font := canvas.font;
  280.     IF (0 <= y) & (y <= canvas.height - font.height - 1) THEN
  281.         IF x < 0 THEN
  282.             i := -(x DIV font.width);
  283.             INC(x, i*font.width);
  284.             DEC(n, i)
  285.         ELSE
  286.             i := 0
  287.         END;
  288.         IF n > 0 THEN
  289.             n := MAX(MIN(n, (canvas.width - x) DIV font.width), 0);
  290.             color := canvas.color;
  291.             canvas.color := canvas.backColor;
  292.             FillRect(canvas, x, y, x + n*font.width, y + font.height);
  293.             canvas.color := color;
  294.             WHILE n > 0 DO
  295.                 SYSTEM.GET(text + i*WCHAR_SIZE, c);
  296.                 IF ~Lines.isSpace(c) THEN
  297.                         IF Languages.isDelim(c) THEN
  298.                                 color := delimColor
  299.                         ELSE
  300.                                 color := canvas.textColor
  301.                         END;
  302.                                         IF c = Lines.NUL THEN
  303.                                 c := 0X
  304.                                         END;
  305.                                         IF font = fonts[0] THEN
  306.                                                 ch := E.UNI[ORD(c), E.CP866];
  307.                                                 IF ch = E.UNDEF THEN
  308.                                                         c := "?"
  309.                                                 ELSE
  310.                                                         c := WCHR(ch)
  311.                                                 END
  312.                                         END;
  313.                     KOSAPI.sysfunc6(4, x*65536 + y, font.flags + color, SYSTEM.ADR(c), 1, canvas.bitmap - 8)
  314.                 END;
  315.                 INC(x, font.width);
  316.                 INC(i);
  317.                 DEC(n)
  318.             END
  319.         END
  320.     END
  321. END TextOut;
  322.  
  323.  
  324. PROCEDURE TextOut2* (canvas: tCanvas; x, y: INTEGER; text: ARRAY OF WCHAR; n: INTEGER);
  325. BEGIN
  326.     TextOut(canvas, x, y, SYSTEM.ADR(text[0]), n, canvas.textColor)
  327. END TextOut2;
  328.  
  329.  
  330. PROCEDURE CreateCanvas* (width, height: INTEGER): tCanvas;
  331. VAR
  332.     canvas: tCanvas;
  333. BEGIN
  334.     NEW(canvas);
  335.     canvas.bitmap := KOSAPI.malloc(width*height*4 + 8);
  336.     ASSERT(canvas.bitmap # 0);
  337.     SYSTEM.PUT32(canvas.bitmap, width);
  338.     SYSTEM.PUT32(canvas.bitmap + 4, height);
  339.     INC(canvas.bitmap, 8);
  340.     canvas.width := width;
  341.     canvas.height := height;
  342.     canvas.mode := modeCOPY
  343.     RETURN canvas
  344. END CreateCanvas;
  345.  
  346.  
  347. PROCEDURE destroy* (VAR canvas: tCanvas);
  348. BEGIN
  349.     IF canvas # NIL THEN
  350.         canvas.bitmap := KOSAPI.free(canvas.bitmap - 8);
  351.         DISPOSE(canvas)
  352.     END
  353. END destroy;
  354.  
  355.  
  356. BEGIN
  357.     fonts[0] := CreateFont(0, "", {});
  358.     fonts[1] := CreateFont(1, "", {});
  359.     fonts[2] := CreateFont(2, "", {});
  360. END Graph.