Subversion Repositories Kolibri OS

Rev

Rev 9891 | Rev 9902 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
9891 akron1 2
    Copyright 2021-2023 Anton Krotov
8728 leency 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 .
18
*)
19
 
20
MODULE Graph;
21
 
9668 akron1 22
IMPORT SYSTEM, KOSAPI, Lines, Languages, E := Encodings;
8728 leency 23
 
24
CONST
25
 
26
    modeCOPY = 0;
27
    modeNOT  = 1;
28
    modeXOR  = 2;
29
 
9174 akron1 30
    triUp* = FALSE;
31
    triDown* = TRUE;
32
    triLeft* = FALSE;
33
    triRight* = TRUE;
34
 
8728 leency 35
TYPE
36
 
37
    tFont* = POINTER TO RECORD
38
        handle*: INTEGER;
39
        height*: INTEGER;
40
        width*:  INTEGER;
41
        size:    INTEGER;
9668 akron1 42
        flags:   INTEGER;
8728 leency 43
        name*:   ARRAY 256 OF WCHAR
44
    END;
45
 
46
    tCanvas* = POINTER TO RECORD
47
        bitmap: INTEGER;
9892 akron1 48
        width*, height*, sizeY: INTEGER;
8728 leency 49
        color, backColor, textColor: INTEGER;
50
        font*: tFont;
51
        mode: INTEGER
52
    END;
53
 
9668 akron1 54
VAR
8728 leency 55
 
9671 akron1 56
	fonts*: ARRAY 3 OF tFont;
9668 akron1 57
 
58
 
9431 akron1 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
 
8728 leency 67
PROCEDURE DrawCanvas* (canvas: tCanvas; x, y: INTEGER);
68
BEGIN
9448 akron1 69
    KOSAPI.sysfunc7(65, canvas.bitmap, canvas.width*65536 + canvas.height, x*65536 + y, 32, 0, 0)
8728 leency 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
 
9668 akron1 91
PROCEDURE CreateFont (size: INTEGER; name: ARRAY OF WCHAR; attr: SET): tFont;
8728 leency 92
VAR
93
    font: tFont;
94
BEGIN
9668 akron1 95
	ASSERT(size IN {0, 1, 2});
8728 leency 96
    NEW(font);
9668 akron1 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;
8728 leency 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;
9295 akron1 132
        ptr := canvas.bitmap + 4*(y*canvas.width + X1);
8728 leency 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;
9295 akron1 151
        ptr := canvas.bitmap + 4*(Y1*canvas.width + x);
8728 leency 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
9892 akron1 169
	canvas.mode := modeNOT;
170
	VLine(canvas, x, y1, y2);
171
	canvas.mode := modeCOPY
8728 leency 172
END notVLine;
173
 
174
 
175
PROCEDURE xorVLine* (canvas: tCanvas; x, y1, y2: INTEGER);
176
BEGIN
9892 akron1 177
	canvas.mode := modeXOR;
178
	SetColor(canvas, 0FF0000H);
179
	VLine(canvas, x, y1, y2);
180
	canvas.mode := modeCOPY
8728 leency 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
9522 akron1 190
	ASSERT(ABS(k) = 1);
8728 leency 191
    color := canvas.color;
9295 akron1 192
    ptr := canvas.bitmap + 4*(y*canvas.width + x1);
9522 akron1 193
    d := 4*(1 - canvas.width*k);
8728 leency 194
    WHILE x1 <= x2 DO
195
        SYSTEM.PUT32(ptr, color);
196
        INC(ptr, d);
197
        INC(x1)
198
    END
199
END DLine;
200
 
201
 
9174 akron1 202
PROCEDURE Triangle* (canvas: tCanvas; x1, y1, x2, y2: INTEGER; orientation: BOOLEAN);
203
VAR
204
	i, a, b, d: INTEGER;
9208 akron1 205
	line: PROCEDURE (canvas: tCanvas; c, c1, c2: INTEGER);
9174 akron1 206
BEGIN
9208 akron1 207
	line := NIL;
9174 akron1 208
	d := ORD(orientation)*2 - 1;
209
	IF y1 = y2 THEN
210
		i := y1;
211
		a := MIN(x1, x2);
212
		b := MAX(x1, x2);
9208 akron1 213
		line := HLine
9174 akron1 214
	ELSIF x1 = x2 THEN
215
		i := x1;
216
		a := MIN(y1, y2);
217
		b := MAX(y1, y2);
9208 akron1 218
		line := VLine
219
	END;
220
	IF line # NIL THEN
9174 akron1 221
		WHILE a <= b DO
9208 akron1 222
			line(canvas, i, a, b);
9174 akron1 223
			INC(i, d);
224
			INC(a);
225
			DEC(b)
226
		END
227
	END
228
END Triangle;
229
 
230
 
8728 leency 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;
9892 akron1 258
    i := canvas.sizeY - 1;
8728 leency 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
 
9193 akron1 267
PROCEDURE TextOut* (canvas: tCanvas; x, y: INTEGER; text: INTEGER; n: INTEGER; delimColor: INTEGER);
8728 leency 268
CONST
269
    WCHAR_SIZE = 2;
270
VAR
9668 akron1 271
    color, i, ch: INTEGER;
272
    font: tFont;
9174 akron1 273
    c: WCHAR;
8728 leency 274
BEGIN
9668 akron1 275
	font := canvas.font;
9892 akron1 276
    IF (0 <= y) & (y <= canvas.sizeY - font.height - 1) THEN
8728 leency 277
        IF x < 0 THEN
9668 akron1 278
            i := -(x DIV font.width);
279
            INC(x, i*font.width);
8728 leency 280
            DEC(n, i)
281
        ELSE
282
            i := 0
283
        END;
284
        IF n > 0 THEN
9668 akron1 285
            n := MAX(MIN(n, (canvas.width - x) DIV font.width), 0);
8728 leency 286
            color := canvas.color;
287
            canvas.color := canvas.backColor;
9891 akron1 288
            FillRect(canvas, x, y, x + n*font.width - 1, y + font.height);
8728 leency 289
            canvas.color := color;
9174 akron1 290
            WHILE n > 0 DO
291
                SYSTEM.GET(text + i*WCHAR_SIZE, c);
292
                IF ~Lines.isSpace(c) THEN
9193 akron1 293
                	IF Languages.isDelim(c) THEN
9208 akron1 294
                		color := delimColor
9193 akron1 295
                	ELSE
9208 akron1 296
                		color := canvas.textColor
9193 akron1 297
                	END;
9560 akron1 298
					IF c = Lines.NUL THEN
299
                		c := 0X
300
					END;
9671 akron1 301
					IF font = fonts[0] THEN
9668 akron1 302
						ch := E.UNI[ORD(c), E.CP866];
303
						IF ch = E.UNDEF THEN
304
							c := "?"
305
						ELSE
306
							c := WCHR(ch)
307
						END
308
					END;
309
                    KOSAPI.sysfunc6(4, x*65536 + y, font.flags + color, SYSTEM.ADR(c), 1, canvas.bitmap - 8)
9174 akron1 310
                END;
9668 akron1 311
                INC(x, font.width);
8728 leency 312
                INC(i);
313
                DEC(n)
9174 akron1 314
            END
8728 leency 315
        END
316
    END
317
END TextOut;
318
 
319
 
320
PROCEDURE TextOut2* (canvas: tCanvas; x, y: INTEGER; text: ARRAY OF WCHAR; n: INTEGER);
321
BEGIN
9193 akron1 322
    TextOut(canvas, x, y, SYSTEM.ADR(text[0]), n, canvas.textColor)
8728 leency 323
END TextOut2;
324
 
325
 
326
PROCEDURE CreateCanvas* (width, height: INTEGER): tCanvas;
327
VAR
328
    canvas: tCanvas;
329
BEGIN
330
    NEW(canvas);
9448 akron1 331
    canvas.bitmap := KOSAPI.malloc(width*height*4 + 8);
8728 leency 332
    ASSERT(canvas.bitmap # 0);
333
    SYSTEM.PUT32(canvas.bitmap, width);
334
    SYSTEM.PUT32(canvas.bitmap + 4, height);
335
    INC(canvas.bitmap, 8);
336
    canvas.width := width;
337
    canvas.height := height;
9892 akron1 338
    canvas.sizeY := height;
8728 leency 339
    canvas.mode := modeCOPY
340
    RETURN canvas
341
END CreateCanvas;
342
 
343
 
344
PROCEDURE destroy* (VAR canvas: tCanvas);
345
BEGIN
346
    IF canvas # NIL THEN
9668 akron1 347
        canvas.bitmap := KOSAPI.free(canvas.bitmap - 8);
8728 leency 348
        DISPOSE(canvas)
349
    END
350
END destroy;
351
 
352
 
9668 akron1 353
BEGIN
9671 akron1 354
    fonts[0] := CreateFont(0, "", {});
355
    fonts[1] := CreateFont(1, "", {});
356
    fonts[2] := CreateFont(2, "", {});
8728 leency 357
END Graph.